зеркало из https://github.com/mozilla/gecko-dev.git
Bug 398219: avoid storing references to the global scope in the compiled scripts. r,a=brendan
This commit is contained in:
Родитель
5a4be57cca
Коммит
32bd2824e1
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче