зеркало из https://github.com/mozilla/pjs.git
Bug 398219: avoid storing references to the global scope in the compiled scripts. r,a=brendan
This commit is contained in:
Родитель
7f51d8d529
Коммит
2ec0592fe8
|
@ -1089,46 +1089,20 @@ fun_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
|
|||
*/
|
||||
atom = cx->runtime->atomState.classPrototypeAtom;
|
||||
if (id == ATOM_KEY(atom)) {
|
||||
JSObject *proto, *parentProto;
|
||||
jsval pval;
|
||||
|
||||
proto = parentProto = NULL;
|
||||
if (fun->object != obj &&
|
||||
(!cx->runtime->findObjectPrincipals ||
|
||||
cx->runtime->findObjectPrincipals(cx, obj) ==
|
||||
cx->runtime->findObjectPrincipals(cx, fun->object))) {
|
||||
/*
|
||||
* Clone of a function where the clone and the object owning fun
|
||||
* appear to be in the same trust domain: make the cloned function
|
||||
* object's 'prototype' property value have the same class as the
|
||||
* clone-parent's 'prototype' value.
|
||||
*/
|
||||
if (!OBJ_GET_PROPERTY(cx, fun->object, ATOM_TO_JSID(atom), &pval))
|
||||
return JS_FALSE;
|
||||
if (!JSVAL_IS_PRIMITIVE(pval)) {
|
||||
/*
|
||||
* We are about to allocate a new object, so hack the newborn
|
||||
* root until then to protect pval in case it is figuratively
|
||||
* up in the air, with no strong refs protecting it.
|
||||
*/
|
||||
cx->weakRoots.newborn[GCX_OBJECT] = JSVAL_TO_GCTHING(pval);
|
||||
parentProto = JSVAL_TO_OBJECT(pval);
|
||||
}
|
||||
}
|
||||
JSObject *proto;
|
||||
|
||||
/*
|
||||
* Beware of the wacky case of a user function named Object -- trying
|
||||
* to find a prototype for that will recur back here _ad perniciem_.
|
||||
*/
|
||||
if (!parentProto && fun->atom == CLASS_ATOM(cx, Object))
|
||||
if (fun->atom == CLASS_ATOM(cx, Object))
|
||||
return JS_TRUE;
|
||||
|
||||
/*
|
||||
* If resolving "prototype" in a clone, clone the parent's prototype.
|
||||
* Pass the constructor's (obj's) parent as the prototype parent, to
|
||||
* avoid defaulting to parentProto.constructor.__parent__.
|
||||
* Make the prototype object to have the same parent as the function
|
||||
* object itself.
|
||||
*/
|
||||
proto = js_NewObject(cx, &js_ObjectClass, parentProto,
|
||||
proto = js_NewObject(cx, &js_ObjectClass, NULL,
|
||||
OBJ_GET_PARENT(cx, obj));
|
||||
if (!proto)
|
||||
return JS_FALSE;
|
||||
|
@ -1216,6 +1190,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
|
||||
|
|
|
@ -4708,7 +4708,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 {
|
||||
|
@ -4872,8 +4872,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)
|
||||
|
|
|
@ -3845,6 +3845,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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче