mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 608473 - |var eval = otherWindow.eval; eval(...)| should behave like indirectly calling that eval from a script in that other window. r=jorendorff
--HG-- extra : rebase_source : 9accca7e9a2b8304c2c823852cfd71b13c595afe
This commit is contained in:
parent
5c723ace4f
commit
fc5075d1f7
@ -603,7 +603,7 @@ JS_SameValue(JSContext *cx, jsval v1, jsval v2, JSBool *same)
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_IsBuiltinEvalFunction(JSFunction *fun)
|
||||
{
|
||||
return IsBuiltinEvalFunction(fun);
|
||||
return IsAnyBuiltinEval(fun);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
|
@ -1980,13 +1980,14 @@ struct JSClass {
|
||||
#define JSCLASS_FREEZE_CTOR (1<<(JSCLASS_HIGH_FLAGS_SHIFT+6))
|
||||
|
||||
/* Additional global reserved slots, beyond those for standard prototypes. */
|
||||
#define JSRESERVED_GLOBAL_SLOTS_COUNT 6
|
||||
#define JSRESERVED_GLOBAL_SLOTS_COUNT 7
|
||||
#define JSRESERVED_GLOBAL_THIS (JSProto_LIMIT * 3)
|
||||
#define JSRESERVED_GLOBAL_THROWTYPEERROR (JSRESERVED_GLOBAL_THIS + 1)
|
||||
#define JSRESERVED_GLOBAL_REGEXP_STATICS (JSRESERVED_GLOBAL_THROWTYPEERROR + 1)
|
||||
#define JSRESERVED_GLOBAL_FUNCTION_NS (JSRESERVED_GLOBAL_REGEXP_STATICS + 1)
|
||||
#define JSRESERVED_GLOBAL_EVAL_ALLOWED (JSRESERVED_GLOBAL_FUNCTION_NS + 1)
|
||||
#define JSRESERVED_GLOBAL_FLAGS (JSRESERVED_GLOBAL_EVAL_ALLOWED + 1)
|
||||
#define JSRESERVED_GLOBAL_EVAL (JSRESERVED_GLOBAL_EVAL_ALLOWED + 1)
|
||||
#define JSRESERVED_GLOBAL_FLAGS (JSRESERVED_GLOBAL_EVAL + 1)
|
||||
|
||||
/* Global flags. */
|
||||
#define JSGLOBAL_FLAGS_CLEARED 0x1
|
||||
|
@ -1315,17 +1315,16 @@ InvokeConstructorWithGivenThis(JSContext *cx, JSObject *thisobj, const Value &fv
|
||||
}
|
||||
|
||||
bool
|
||||
DirectEval(JSContext *cx, JSFunction *evalfun, uint32 argc, Value *vp)
|
||||
DirectEval(JSContext *cx, uint32 argc, Value *vp)
|
||||
{
|
||||
JS_ASSERT(vp == cx->regs->sp - argc - 2);
|
||||
JS_ASSERT(vp[0].isObject());
|
||||
JS_ASSERT(vp[0].toObject().isFunction());
|
||||
JS_ASSERT(vp[0].toObject().getFunctionPrivate() == evalfun);
|
||||
JS_ASSERT(IsBuiltinEvalFunction(evalfun));
|
||||
|
||||
JSStackFrame *caller = cx->fp();
|
||||
JS_ASSERT(caller->isScriptFrame());
|
||||
AutoFunctionCallProbe callProbe(cx, evalfun, caller->script());
|
||||
JS_ASSERT(IsBuiltinEvalForScope(&caller->scopeChain(), vp[0]));
|
||||
AutoFunctionCallProbe callProbe(cx, vp[0].toObject().getFunctionPrivate(), caller->script());
|
||||
|
||||
JSObject *scopeChain =
|
||||
GetScopeChainFast(cx, caller, JSOP_EVAL, JSOP_EVAL_LENGTH + JSOP_LINENO_LENGTH);
|
||||
@ -4698,14 +4697,10 @@ BEGIN_CASE(JSOP_EVAL)
|
||||
argc = GET_ARGC(regs.pc);
|
||||
vp = regs.sp - (argc + 2);
|
||||
|
||||
if (!IsFunctionObject(*vp, &callee))
|
||||
if (!IsBuiltinEvalForScope(®s.fp->scopeChain(), *vp))
|
||||
goto call_using_invoke;
|
||||
|
||||
newfun = callee->getFunctionPrivate();
|
||||
if (!IsBuiltinEvalFunction(newfun))
|
||||
goto call_using_invoke;
|
||||
|
||||
if (!DirectEval(cx, newfun, argc, vp))
|
||||
if (!DirectEval(cx, argc, vp))
|
||||
goto error;
|
||||
}
|
||||
END_CASE(JSOP_EVAL)
|
||||
|
@ -964,13 +964,11 @@ ExternalInvokeConstructor(JSContext *cx, const Value &fval, uintN argc, Value *a
|
||||
|
||||
/*
|
||||
* Performs a direct eval for the given arguments, which must correspond to the
|
||||
* currently-executing stack frame, which must be a script frame. evalfun must
|
||||
* be the built-in eval function and must correspond to the callee in vp[0].
|
||||
* When this function succeeds it returns the result in *vp, adjusts the JS
|
||||
* stack pointer, and returns true.
|
||||
* currently-executing stack frame, which must be a script frame. On completion
|
||||
* the result is returned in *vp and the JS stack pointer is adjusted.
|
||||
*/
|
||||
extern JS_REQUIRES_STACK bool
|
||||
DirectEval(JSContext *cx, JSFunction *evalfun, uint32 argc, Value *vp);
|
||||
DirectEval(JSContext *cx, uint32 argc, Value *vp);
|
||||
|
||||
/*
|
||||
* Performs a direct eval for the given arguments, which must correspond to the
|
||||
|
@ -1187,7 +1187,7 @@ EvalKernel(JSContext *cx, uintN argc, Value *vp, EvalType evalType, JSStackFrame
|
||||
|
||||
/* ES5 15.1.2.1 steps 2-8. */
|
||||
JSObject *callee = JSVAL_TO_OBJECT(JS_CALLEE(cx, Jsvalify(vp)));
|
||||
JS_ASSERT(IsBuiltinEvalFunction(callee->getFunctionPrivate()));
|
||||
JS_ASSERT(IsAnyBuiltinEval(callee->getFunctionPrivate()));
|
||||
JSPrincipals *principals = js_EvalFramePrincipals(cx, callee, caller);
|
||||
|
||||
/*
|
||||
@ -1307,7 +1307,15 @@ EvalKernel(JSContext *cx, uintN argc, Value *vp, EvalType evalType, JSStackFrame
|
||||
}
|
||||
|
||||
bool
|
||||
IsBuiltinEvalFunction(JSFunction *fun)
|
||||
IsBuiltinEvalForScope(JSObject *scopeChain, const Value &v)
|
||||
{
|
||||
JSObject *global = scopeChain->getGlobal();
|
||||
JS_ASSERT((global->getClass()->flags & JSCLASS_GLOBAL_FLAGS) == JSCLASS_GLOBAL_FLAGS);
|
||||
return global->getReservedSlot(JSRESERVED_GLOBAL_EVAL) == v;
|
||||
}
|
||||
|
||||
bool
|
||||
IsAnyBuiltinEval(JSFunction *fun)
|
||||
{
|
||||
return fun->maybeNative() == eval;
|
||||
}
|
||||
@ -3777,8 +3785,13 @@ js_InitObjectClass(JSContext *cx, JSObject *obj)
|
||||
|
||||
/* ECMA (15.1.2.1) says 'eval' is a property of the global object. */
|
||||
jsid id = ATOM_TO_JSID(cx->runtime->atomState.evalAtom);
|
||||
if (!js_DefineFunction(cx, obj, id, eval, 1, JSFUN_STUB_GSOPS))
|
||||
JSObject *evalobj = js_DefineFunction(cx, obj, id, eval, 1, JSFUN_STUB_GSOPS);
|
||||
if (!evalobj)
|
||||
return NULL;
|
||||
if (obj->isGlobal()) {
|
||||
if (!js_SetReservedSlot(cx, obj, JSRESERVED_GLOBAL_EVAL, ObjectValue(*evalobj)))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return proto;
|
||||
}
|
||||
|
@ -1940,8 +1940,16 @@ extern bool
|
||||
EvalKernel(JSContext *cx, uintN argc, js::Value *vp, EvalType evalType, JSStackFrame *caller,
|
||||
JSObject *scopeobj);
|
||||
|
||||
/*
|
||||
* True iff |v| is the built-in eval function for the global object that
|
||||
* corresponds to |scopeChain|.
|
||||
*/
|
||||
extern bool
|
||||
IsBuiltinEvalFunction(JSFunction *fun);
|
||||
IsBuiltinEvalForScope(JSObject *scopeChain, const js::Value &v);
|
||||
|
||||
/* True iff fun is a built-in eval function. */
|
||||
extern bool
|
||||
IsAnyBuiltinEval(JSFunction *fun);
|
||||
|
||||
}
|
||||
|
||||
|
@ -437,19 +437,14 @@ stubs::Eval(VMFrame &f, uint32 argc)
|
||||
{
|
||||
Value *vp = f.regs.sp - (argc + 2);
|
||||
|
||||
JSObject *callee;
|
||||
JSFunction *fun;
|
||||
|
||||
if (!IsFunctionObject(*vp, &callee) ||
|
||||
!IsBuiltinEvalFunction((fun = callee->getFunctionPrivate())))
|
||||
{
|
||||
if (!IsBuiltinEvalForScope(&f.regs.fp->scopeChain(), *vp)) {
|
||||
if (!Invoke(f.cx, InvokeArgsAlreadyOnTheStack(vp, argc), 0))
|
||||
THROW();
|
||||
return;
|
||||
}
|
||||
|
||||
JS_ASSERT(f.regs.fp == f.cx->fp());
|
||||
if (!DirectEval(f.cx, fun, argc, vp))
|
||||
if (!DirectEval(f.cx, argc, vp))
|
||||
THROW();
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 608473;
|
||||
var summary =
|
||||
'|var eval = otherWindow.eval; eval(...)| should behave like indirectly ' +
|
||||
'calling that eval from a script in that other window';
|
||||
|
||||
print(BUGNUMBER + ": " + summary);
|
||||
|
||||
/**************
|
||||
* BEGIN TEST *
|
||||
**************/
|
||||
|
||||
var originalEval = eval;
|
||||
var res;
|
||||
|
||||
function f()
|
||||
{
|
||||
return [this, eval("this")];
|
||||
}
|
||||
|
||||
var otherGlobalSameCompartment = newGlobal("same-compartment");
|
||||
|
||||
eval = otherGlobalSameCompartment.eval;
|
||||
res = new f();
|
||||
assertEq(res[0] !== res[1], true);
|
||||
assertEq(res[0] !== this, true);
|
||||
assertEq(res[0] instanceof f, true);
|
||||
assertEq(res[1], otherGlobalSameCompartment);
|
||||
|
||||
res = f();
|
||||
assertEq(res[0] !== res[1], true);
|
||||
assertEq(res[0], this);
|
||||
assertEq(res[1], otherGlobalSameCompartment);
|
||||
|
||||
var otherGlobalDifferentCompartment = newGlobal("new-compartment");
|
||||
|
||||
eval = otherGlobalDifferentCompartment.eval;
|
||||
res = new f();
|
||||
assertEq(res[0] !== res[1], true);
|
||||
assertEq(res[0] !== this, true);
|
||||
assertEq(res[0] instanceof f, true);
|
||||
assertEq(res[1], otherGlobalDifferentCompartment);
|
||||
|
||||
res = f();
|
||||
assertEq(res[0] !== res[1], true);
|
||||
assertEq(res[0], this);
|
||||
assertEq(res[1], otherGlobalDifferentCompartment);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
||||
|
||||
print("All tests passed!");
|
@ -9,6 +9,7 @@ script bug352085.js
|
||||
script bug472534.js
|
||||
script bug496985.js
|
||||
script bug566661.js
|
||||
skip-if(!xulRuntime.shell) script cross-global-eval-is-indirect.js # needs newGlobal()
|
||||
script eval-native-callback-is-indirect.js
|
||||
script extension-methods-reject-null-undefined-this.js
|
||||
skip-if(!xulRuntime.shell) script function-definition-with.js # needs evaluate()
|
||||
|
Loading…
Reference in New Issue
Block a user