Bug 398219: avoid storing references to the global scope in the compiled scripts. r,a=brendan

This commit is contained in:
igor@mir2.org 2007-12-12 10:47:56 -08:00
Родитель 5a4be57cca
Коммит 32bd2824e1
4 изменённых файлов: 29 добавлений и 16 удалений

Просмотреть файл

@ -1216,6 +1216,8 @@ fun_xdrObject(JSXDRState *xdr, JSObject **objp)
fun = js_NewFunction(cx, NULL, NULL, 0, JSFUN_INTERPRETED, NULL, NULL);
if (!fun)
return JS_FALSE;
STOBJ_SET_PARENT(fun->object, NULL);
STOBJ_SET_PROTO(fun->object, NULL);
#ifdef __GNUC__
nvars = nargs = 0; /* quell GCC uninitialized warning */
#endif

Просмотреть файл

@ -5047,7 +5047,7 @@ interrupt:
* scope needed to parent the function object's clone.
*/
parent = OBJ_GET_PARENT(cx, obj);
if (OBJ_GET_CLASS(cx, parent) == &js_BlockClass)
if (parent && OBJ_GET_CLASS(cx, parent) == &js_BlockClass)
fp->blockChain = parent;
parent = js_GetScopeChain(cx, fp);
} else {
@ -5211,8 +5211,7 @@ interrupt:
/*
* Clone the function object with the current scope chain as the
* clone's parent. The original function object is the prototype
* of the clone. Do this only if re-parenting; the compiler may
* clone's parent. Do this only if re-parenting; the compiler may
* have seen the right parent already and created a sufficiently
* well-scoped function object.
*/

Просмотреть файл

@ -1039,19 +1039,25 @@ BindDestructuringArg(JSContext *cx, BindData *data, JSAtom *atom,
static JSFunction *
NewCompilerFunction(JSContext *cx, JSTreeContext *tc, JSAtom *atom,
JSBool lambda)
uintN lambda)
{
JSObject *parent;
JSFunction *fun;
JS_ASSERT((lambda & ~JSFUN_LAMBDA) == 0);
parent = (tc->flags & TCF_IN_FUNCTION) ? tc->fun->object : cx->fp->varobj;
return js_NewFunction(cx, NULL, NULL, 0,
JSFUN_INTERPRETED | (lambda ? JSFUN_LAMBDA : 0),
parent, atom);
fun = js_NewFunction(cx, NULL, NULL, 0, JSFUN_INTERPRETED | lambda,
parent, atom);
if (fun && !(tc->flags & TCF_COMPILE_N_GO)) {
STOBJ_SET_PARENT(fun->object, NULL);
STOBJ_SET_PROTO(fun->object, NULL);
}
return fun;
}
static JSParseNode *
FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
JSBool lambda)
uintN lambda)
{
JSOp op, prevop;
JSParseNode *pn, *body, *result;
@ -1080,7 +1086,7 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
if (tt == TOK_NAME) {
funAtom = CURRENT_TOKEN(ts).t_atom;
} else {
if (!lambda && (cx->options & JSOPTION_ANONFUNFIX)) {
if (lambda == 0 && (cx->options & JSOPTION_ANONFUNFIX)) {
js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
JSMSG_SYNTAX_ERROR);
return NULL;
@ -1093,7 +1099,7 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
* Record names for function statements in tc->decls so we know when to
* avoid optimizing variable references that might name a function.
*/
if (!lambda && funAtom) {
if (lambda == 0 && funAtom) {
ATOM_LIST_SEARCH(ale, &tc->decls, funAtom);
if (ale) {
prevop = ALE_JSOP(ale);
@ -1271,7 +1277,7 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
#if JS_HAS_EXPR_CLOSURES
if (tt == TOK_LC)
MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_BODY);
else if (!lambda)
else if (lambda == 0)
js_MatchToken(cx, ts, TOK_SEMI);
#else
MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_BODY);
@ -1337,12 +1343,12 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
* traversed the function's body
*/
JS_ASSERT(!(funtc.flags & TCF_FUN_USES_NONLOCALS));
if (!lambda && funAtom && !AT_TOP_LEVEL(tc))
if (lambda == 0 && funAtom && !AT_TOP_LEVEL(tc))
tc->flags |= TCF_FUN_HEAVYWEIGHT;
}
result = pn;
if (lambda) {
if (lambda != 0) {
/*
* ECMA ed. 3 standard: function expression, possibly anonymous.
*/
@ -1385,13 +1391,13 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
static JSParseNode *
FunctionStmt(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
{
return FunctionDef(cx, ts, tc, JS_FALSE);
return FunctionDef(cx, ts, tc, 0);
}
static JSParseNode *
FunctionExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
{
return FunctionDef(cx, ts, tc, JS_TRUE);
return FunctionDef(cx, ts, tc, JSFUN_LAMBDA);
}
/*
@ -4259,7 +4265,7 @@ GeneratorExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
* Make the generator function and flag it as interpreted ASAP (see the
* comment in FunctionBody).
*/
fun = NewCompilerFunction(cx, tc, NULL, JS_TRUE);
fun = NewCompilerFunction(cx, tc, NULL, JSFUN_LAMBDA);
if (!fun)
return NULL;
@ -5720,6 +5726,10 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
CURRENT_TOKEN(ts).t_reflags);
if (!obj)
return NULL;
if (!(tc->flags & TCF_COMPILE_N_GO)) {
STOBJ_SET_PARENT(obj, NULL);
STOBJ_SET_PROTO(obj, NULL);
}
pn->pn_pob = js_NewParsedObjectBox(cx, tc->parseContext, obj);
if (!pn->pn_pob)

Просмотреть файл

@ -3838,6 +3838,8 @@ regexp_xdrObject(JSXDRState *xdr, JSObject **objp)
obj = js_NewObject(xdr->cx, &js_RegExpClass, NULL, NULL);
if (!obj)
return JS_FALSE;
STOBJ_SET_PARENT(obj, NULL);
STOBJ_SET_PROTO(obj, NULL);
re = js_NewRegExp(xdr->cx, NULL, source, (uint8)flagsword, JS_FALSE);
if (!re)
return JS_FALSE;