mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 495325 - Follow ES about indirect eval being global eval. r=brendan/igor
--HG-- extra : rebase_source : 397bd79f787fc6d079fea1b2433a8e262626ca46
This commit is contained in:
parent
56a6b95359
commit
eb16f9a84d
@ -1488,7 +1488,7 @@ js_Execute(JSContext *cx, JSObject *chain, JSScript *script,
|
||||
frame.callobj = down->callobj;
|
||||
frame.argsobj = down->argsobj;
|
||||
frame.varobj = down->varobj;
|
||||
frame.fun = down->fun;
|
||||
frame.fun = (script->staticLevel > 0) ? down->fun : NULL;
|
||||
frame.thisv = down->thisv;
|
||||
if (down->flags & JSFRAME_COMPUTED_THIS)
|
||||
flags |= JSFRAME_COMPUTED_THIS;
|
||||
@ -1541,9 +1541,8 @@ js_Execute(JSContext *cx, JSObject *chain, JSScript *script,
|
||||
} else {
|
||||
sharps[0] = sharps[1] = JSVAL_VOID;
|
||||
}
|
||||
} else
|
||||
}
|
||||
#endif
|
||||
JS_ASSERT_IF(down, script->nfixed == 0);
|
||||
} else {
|
||||
frame.slots = NULL;
|
||||
}
|
||||
|
100
js/src/jsobj.cpp
100
js/src/jsobj.cpp
@ -1253,13 +1253,18 @@ obj_eval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
JSScript **bucket = NULL; /* avoid GCC warning with early decl&init */
|
||||
#if JS_HAS_EVAL_THIS_SCOPE
|
||||
JSObject *callerScopeChain = NULL, *callerVarObj = NULL;
|
||||
JSObject *setCallerScopeChain = NULL;
|
||||
JSBool setCallerVarObj = JS_FALSE;
|
||||
JSBool setCallerScopeChain = JS_FALSE, setCallerVarObj = JS_FALSE;
|
||||
#endif
|
||||
|
||||
fp = js_GetTopStackFrame(cx);
|
||||
caller = js_GetScriptedCaller(cx, fp);
|
||||
indirectCall = (caller && caller->regs && *caller->regs->pc != JSOP_EVAL);
|
||||
if (!caller) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_BAD_INDIRECT_CALL, js_eval_str);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
indirectCall = (caller->regs && *caller->regs->pc != JSOP_EVAL);
|
||||
|
||||
/*
|
||||
* This call to js_GetWrappedObject is safe because of the security checks
|
||||
@ -1301,7 +1306,7 @@ obj_eval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
* object, then we need to provide one for the compiler to stick any
|
||||
* declared (var) variables into.
|
||||
*/
|
||||
if (caller && !caller->varobj && !js_GetCallObject(cx, caller))
|
||||
if (!caller->varobj && !js_GetCallObject(cx, caller))
|
||||
return JS_FALSE;
|
||||
|
||||
/* Accept an optional trailing argument that overrides the scope object. */
|
||||
@ -1314,39 +1319,45 @@ obj_eval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
|
||||
/* From here on, control must exit through label out with ok set. */
|
||||
MUST_FLOW_THROUGH("out");
|
||||
uintN staticLevel = caller->script->staticLevel + 1;
|
||||
if (!scopeobj) {
|
||||
#if JS_HAS_EVAL_THIS_SCOPE
|
||||
/* If obj.eval(str), emulate 'with (obj) eval(str)' in the caller. */
|
||||
/*
|
||||
* If we see an indirect call, then run eval in the global scope. We do
|
||||
* this so the compiler can make assumptions about what bindings may or
|
||||
* may not exist in the current frame if it doesn't see 'eval'.
|
||||
*/
|
||||
if (indirectCall) {
|
||||
/* Pretend that we're top level. */
|
||||
staticLevel = 0;
|
||||
|
||||
callerScopeChain = js_GetScopeChain(cx, caller);
|
||||
if (!callerScopeChain) {
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
OBJ_TO_INNER_OBJECT(cx, obj);
|
||||
if (!obj) {
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
if (obj != callerScopeChain) {
|
||||
ok = js_CheckPrincipalsAccess(cx, obj,
|
||||
JS_StackFramePrincipals(cx, caller),
|
||||
cx->runtime->atomState.evalAtom);
|
||||
if (!ok)
|
||||
goto out;
|
||||
|
||||
scopeobj = js_NewWithObject(cx, obj, callerScopeChain, -1);
|
||||
if (!scopeobj) {
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
ok = js_CheckPrincipalsAccess(cx, obj,
|
||||
JS_StackFramePrincipals(cx, caller),
|
||||
cx->runtime->atomState.evalAtom);
|
||||
if (!ok)
|
||||
goto out;
|
||||
|
||||
/* Set fp->scopeChain too, for the compiler. */
|
||||
caller->scopeChain = fp->scopeChain = scopeobj;
|
||||
/* NB: We know obj is a global object here. */
|
||||
JS_ASSERT(!OBJ_GET_PARENT(cx, obj));
|
||||
scopeobj = obj;
|
||||
|
||||
/* Remember scopeobj so we can null its private when done. */
|
||||
setCallerScopeChain = scopeobj;
|
||||
}
|
||||
/* Set fp->scopeChain too, for the compiler. */
|
||||
caller->scopeChain = fp->scopeChain = scopeobj;
|
||||
|
||||
/* Remember scopeobj so we can null its private when done. */
|
||||
setCallerScopeChain = JS_TRUE;
|
||||
|
||||
callerVarObj = caller->varobj;
|
||||
if (obj != callerVarObj) {
|
||||
@ -1363,12 +1374,10 @@ obj_eval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
* NB: This means that native callers (who reach this point through
|
||||
* the C API) must use the two parameter form.
|
||||
*/
|
||||
if (caller) {
|
||||
scopeobj = js_GetScopeChain(cx, caller);
|
||||
if (!scopeobj) {
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
scopeobj = js_GetScopeChain(cx, caller);
|
||||
if (!scopeobj) {
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
scopeobj = js_GetWrappedObject(cx, scopeobj);
|
||||
@ -1377,19 +1386,15 @@ obj_eval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ok = js_CheckPrincipalsAccess(cx, scopeobj,
|
||||
JS_StackFramePrincipals(cx, caller),
|
||||
cx->runtime->atomState.evalAtom);
|
||||
if (!ok)
|
||||
goto out;
|
||||
|
||||
scopeobj = js_NewWithObject(cx, scopeobj,
|
||||
JS_GetGlobalForObject(cx, scopeobj), -1);
|
||||
if (!scopeobj) {
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
argv[1] = OBJECT_TO_JSVAL(scopeobj);
|
||||
/* We're pretending that we're in global code. */
|
||||
staticLevel = 0;
|
||||
}
|
||||
|
||||
/* Ensure we compile this eval with the right object in the scope chain. */
|
||||
@ -1399,23 +1404,16 @@ obj_eval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
goto out;
|
||||
}
|
||||
|
||||
tcflags = TCF_COMPILE_N_GO;
|
||||
if (caller) {
|
||||
tcflags |= TCF_PUT_STATIC_LEVEL(caller->script->staticLevel + 1);
|
||||
principals = JS_EvalFramePrincipals(cx, fp, caller);
|
||||
file = js_ComputeFilename(cx, caller, principals, &line);
|
||||
} else {
|
||||
principals = NULL;
|
||||
file = NULL;
|
||||
line = 0;
|
||||
}
|
||||
tcflags = TCF_COMPILE_N_GO | TCF_PUT_STATIC_LEVEL(staticLevel);
|
||||
principals = JS_EvalFramePrincipals(cx, fp, caller);
|
||||
file = js_ComputeFilename(cx, caller, principals, &line);
|
||||
|
||||
str = JSVAL_TO_STRING(argv[0]);
|
||||
script = NULL;
|
||||
|
||||
/* Cache local eval scripts indexed by source qualified by scope. */
|
||||
bucket = EvalCacheHash(cx, str);
|
||||
if (caller->fun) {
|
||||
if (!indirectCall && caller->fun) {
|
||||
uintN count = 0;
|
||||
JSScript **scriptp = bucket;
|
||||
|
||||
@ -1480,7 +1478,9 @@ obj_eval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
}
|
||||
|
||||
if (!script) {
|
||||
script = JSCompiler::compileScript(cx, scopeobj, caller, principals, tcflags,
|
||||
JSStackFrame *callerFrame = (staticLevel != 0) ? caller : NULL;
|
||||
script = JSCompiler::compileScript(cx, scopeobj, callerFrame,
|
||||
principals, tcflags,
|
||||
str->chars(), str->length(),
|
||||
NULL, file, line, str);
|
||||
if (!script) {
|
||||
@ -1491,8 +1491,7 @@ obj_eval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
|
||||
if (argc < 2) {
|
||||
/* Execute using caller's new scope object (might be a Call object). */
|
||||
if (caller)
|
||||
scopeobj = caller->scopeChain;
|
||||
scopeobj = caller->scopeChain;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1513,11 +1512,8 @@ obj_eval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
out:
|
||||
#if JS_HAS_EVAL_THIS_SCOPE
|
||||
/* Restore OBJ_GET_PARENT(scopeobj) not callerScopeChain in case of Call. */
|
||||
if (setCallerScopeChain) {
|
||||
if (setCallerScopeChain)
|
||||
caller->scopeChain = callerScopeChain;
|
||||
JS_ASSERT(OBJ_GET_CLASS(cx, setCallerScopeChain) == &js_WithClass);
|
||||
setCallerScopeChain->setPrivate(NULL);
|
||||
}
|
||||
if (setCallerVarObj)
|
||||
caller->varobj = callerVarObj;
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user