Bug 410653: make sure that the generator cleanup code is called on all code paths. r,a=brendan

This commit is contained in:
igor@mir2.org 2008-01-03 10:13:42 -08:00
parent 14d026ed40
commit fe3f92bad0
3 changed files with 21 additions and 20 deletions

View File

@ -3176,7 +3176,7 @@ bad:
}
JSBool
js_EmitFunctionBytecode(JSContext *cx, JSCodeGenerator *cg, JSParseNode *body)
js_EmitFunctionScript(JSContext *cx, JSCodeGenerator *cg, JSParseNode *body)
{
if (cg->treeContext.flags & TCF_FUN_IS_GENERATOR) {
/* JSOP_GENERATOR must be the first instruction. */
@ -3188,7 +3188,8 @@ js_EmitFunctionBytecode(JSContext *cx, JSCodeGenerator *cg, JSParseNode *body)
}
return js_EmitTree(cx, cg, body) &&
js_Emit1(cx, cg, JSOP_STOP) >= 0;
js_Emit1(cx, cg, JSOP_STOP) >= 0 &&
js_NewScriptFromCG(cx, cg);
}
/* A macro for inlining at the top of js_EmitTree (whence it came). */
@ -3984,24 +3985,25 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
fun = GET_FUNCTION_PRIVATE(cx, pn->pn_funpob->object);
cg2->treeContext.fun = fun;
cg2->parent = cg;
if (!js_EmitFunctionBytecode(cx, cg2, pn->pn_body) ||
!js_NewScriptFromCG(cx, cg2)) {
return JS_FALSE;
}
/*
* We need an activation object if an inner peeks out, or if such
* inner-peeking caused one of our inners to become heavyweight.
*/
if (cg2->treeContext.flags &
(TCF_FUN_USES_NONLOCALS | TCF_FUN_HEAVYWEIGHT)) {
cg->treeContext.flags |= TCF_FUN_HEAVYWEIGHT;
if (!js_EmitFunctionScript(cx, cg2, pn->pn_body)) {
pn = NULL;
} else {
/*
* We need an activation object if an inner peeks out, or if such
* inner-peeking caused one of our inners to become heavyweight.
*/
if (cg2->treeContext.flags &
(TCF_FUN_USES_NONLOCALS | TCF_FUN_HEAVYWEIGHT)) {
cg->treeContext.flags |= TCF_FUN_HEAVYWEIGHT;
}
}
js_FinishCodeGenerator(cx, cg2);
JS_ASSERT(js_GuardedArenaMark(&cx->tempPool, cg2mark,
cg->treeContext.
parseContext->lastAllocMark));
JS_ARENA_RELEASE(&cx->tempPool, cg2mark);
if (!pn)
return JS_FALSE;
/* Make the function object a literal in the outer script's pool. */
index = IndexParsedObject(pn->pn_funpob, &cg->objectList);

View File

@ -509,10 +509,10 @@ extern JSBool
js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn);
/*
* Emit function code into cg for the tree rooted at body.
* Emit function code using cg for the tree rooted at body.
*/
extern JSBool
js_EmitFunctionBytecode(JSContext *cx, JSCodeGenerator *cg, JSParseNode *body);
js_EmitFunctionScript(JSContext *cx, JSCodeGenerator *cg, JSParseNode *body);
/*
* Source notes generated along with bytecode for decompiling and debugging.

View File

@ -935,8 +935,7 @@ js_CompileFunctionBody(JSContext *cx, JSFunction *fun, JSPrincipals *principals,
pn = NULL;
} else {
if (!js_FoldConstants(cx, pn, &funcg.treeContext) ||
!js_EmitFunctionBytecode(cx, &funcg, pn) ||
!js_NewScriptFromCG(cx, &funcg)) {
!js_EmitFunctionScript(cx, &funcg, pn)) {
pn = NULL;
}
}
@ -1358,8 +1357,8 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
*
* The TCF_FUN_USES_NONLOCALS flag is set only by the code generator,
* so it won't be set here. Assert that it's not. We have to check
* it later, in js_EmitTree, after js_EmitFunctionBytecode has
* traversed the function's body
* it later, in js_EmitTree, after js_EmitFunctionScript has traversed
* the function's body.
*/
JS_ASSERT(!(funtc.flags & TCF_FUN_USES_NONLOCALS));
if (lambda == 0 && funAtom && !AT_TOP_LEVEL(tc))