Bug 740259 - Tighten assertions around closed-var noting (r=bhackett)

This commit is contained in:
Luke Wagner 2012-03-28 16:36:57 -07:00
parent be583b5cab
commit cf110a1054
2 changed files with 46 additions and 17 deletions

View File

@ -981,6 +981,37 @@ BytecodeEmitter::shouldNoteClosedName(ParseNode *pn)
return !callsEval() && pn->isDefn() && pn->isClosed();
}
bool
BytecodeEmitter::noteClosedVar(ParseNode *pn)
{
#ifdef DEBUG
JS_ASSERT(shouldNoteClosedName(pn));
Definition *dn = (Definition *)pn;
JS_ASSERT(dn->kind() == Definition::VAR || dn->kind() == Definition::CONST ||
dn->kind() == Definition::FUNCTION);
JS_ASSERT(pn->pn_cookie.slot() < bindings.countVars());
for (size_t i = 0; i < closedVars.length(); ++i)
JS_ASSERT(closedVars[i] != pn->pn_cookie.slot());
#endif
flags |= TCF_FUN_HEAVYWEIGHT;
return closedVars.append(pn->pn_cookie.slot());
}
bool
BytecodeEmitter::noteClosedArg(ParseNode *pn)
{
#ifdef DEBUG
JS_ASSERT(shouldNoteClosedName(pn));
Definition *dn = (Definition *)pn;
JS_ASSERT(dn->kind() == Definition::ARG);
JS_ASSERT(pn->pn_cookie.slot() < bindings.countArgs());
for (size_t i = 0; i < closedArgs.length(); ++i)
JS_ASSERT(closedArgs[i] != pn->pn_cookie.slot());
#endif
flags |= TCF_FUN_HEAVYWEIGHT;
return closedArgs.append(pn->pn_cookie.slot());
}
/*
* Adjust the slot for a block local to account for the number of variables
* that share the same index space with locals. Due to the incremental code
@ -2751,10 +2782,10 @@ MaybeEmitVarDecl(JSContext *cx, BytecodeEmitter *bce, JSOp prologOp, ParseNode *
if (bce->inFunction() &&
JOF_OPTYPE(pn->getOp()) == JOF_LOCAL &&
pn->pn_cookie.slot() < bce->bindings.countVars() &&
!pn->isLet() &&
bce->shouldNoteClosedName(pn))
{
if (!bce->closedVars.append(pn->pn_cookie.slot()))
if (!bce->noteClosedVar(pn))
return false;
}
@ -4985,12 +5016,8 @@ EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
JS_ASSERT(kind == VARIABLE || kind == CONSTANT);
JS_ASSERT(index < JS_BIT(20));
pn->pn_index = index;
if (pn->isClosed() &&
!bce->callsEval() &&
!bce->closedVars.append(pn->pn_cookie.slot()))
{
if (bce->shouldNoteClosedName(pn) && !bce->noteClosedVar(pn))
return false;
}
if (NewSrcNote(cx, bce, SRC_CONTINUE) < 0)
return false;
@ -5993,7 +6020,7 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
if (!BindNameToSlot(cx, bce, pn2))
return JS_FALSE;
if (JOF_OPTYPE(pn2->getOp()) == JOF_QARG && bce->shouldNoteClosedName(pn2)) {
if (!bce->closedArgs.append(pn2->pn_cookie.slot()))
if (!bce->noteClosedArg(pn2))
return JS_FALSE;
}
}

View File

@ -563,25 +563,25 @@ struct BytecodeEmitter : public TreeContext
jsbytecode *limit; /* one byte beyond end of bytecode */
jsbytecode *next; /* pointer to next free bytecode */
jssrcnote *notes; /* source notes, see below */
unsigned noteCount; /* number of source notes so far */
unsigned noteLimit; /* limit number for source notes in notePool */
unsigned noteCount; /* number of source notes so far */
unsigned noteLimit; /* limit number for source notes in notePool */
ptrdiff_t lastNoteOffset; /* code offset for last source note */
unsigned currentLine; /* line number for tree-based srcnote gen */
unsigned currentLine; /* line number for tree-based srcnote gen */
} prolog, main, *current;
OwnedAtomIndexMapPtr atomIndices; /* literals indexed for mapping */
AtomDefnMapPtr roLexdeps;
unsigned firstLine; /* first line, for JSScript::NewScriptFromEmitter */
unsigned firstLine; /* first line, for JSScript::NewScriptFromEmitter */
int stackDepth; /* current stack depth in script frame */
unsigned maxStackDepth; /* maximum stack depth so far */
int stackDepth; /* current stack depth in script frame */
unsigned maxStackDepth; /* maximum stack depth so far */
unsigned ntrynotes; /* number of allocated so far try notes */
unsigned ntrynotes; /* number of allocated so far try notes */
TryNode *lastTryNode; /* the last allocated try node */
unsigned arrayCompDepth; /* stack depth of array in comprehension */
unsigned arrayCompDepth; /* stack depth of array in comprehension */
unsigned emitLevel; /* js::frontend::EmitTree recursion level */
unsigned emitLevel; /* js::frontend::EmitTree recursion level */
typedef HashMap<JSAtom *, Value> ConstMap;
ConstMap constMap; /* compile time constants */
@ -641,6 +641,8 @@ struct BytecodeEmitter : public TreeContext
JSVersion version() const { return parser->versionWithFlags(); }
bool shouldNoteClosedName(ParseNode *pn);
bool noteClosedVar(ParseNode *pn);
bool noteClosedArg(ParseNode *pn);
JS_ALWAYS_INLINE
bool makeAtomIndex(JSAtom *atom, jsatomid *indexp) {