Bug 764249 - Fix the non-reentrant-closure fix in bug 762473 (r=dvander)

--HG--
extra : rebase_source : c5db1eda08f62721b5dc1aa92e13f9169c69c587
This commit is contained in:
Luke Wagner 2012-06-13 11:36:13 -07:00
parent b4f1792499
commit 4f2f1f18f9
5 changed files with 44 additions and 11 deletions

View File

@ -0,0 +1,20 @@
var g = newGlobal('new-compartment');
var dbg = new Debugger(g);
var fscript = null;
dbg.onNewScript = function(script) {
dbg.onNewScript = undefined;
fscript = script.getChildScripts()[0];
assertEq(fscript.staticLevel, 1);
}
g.eval("function f(x) { arguments[0] = 3; return x }");
assertEq(fscript !== null, true);
fscript.setBreakpoint(0, {hit:function(frame) {
assertEq(frame.eval('x').return, 1);
assertEq(frame.arguments[0], 1);
return {return:42};
}});
assertEq(g.f(1), 42);

View File

@ -3169,10 +3169,10 @@ DebuggerArguments_getArg(JSContext *cx, unsigned argc, Value *vp)
if (unsigned(i) < fp->numActualArgs()) { if (unsigned(i) < fp->numActualArgs()) {
if (unsigned(i) < fp->numFormalArgs() && fp->script()->formalLivesInCallObject(i)) if (unsigned(i) < fp->numFormalArgs() && fp->script()->formalLivesInCallObject(i))
arg = fp->callObj().arg(i); arg = fp->callObj().arg(i);
else if (fp->script()->argsObjAliasesFormals()) else if (fp->script()->argsObjAliasesFormals() && fp->hasArgsObj())
arg = fp->argsObj().arg(i); arg = fp->argsObj().arg(i);
else else
arg = fp->unaliasedActual(i); arg = fp->unaliasedActual(i, DONT_CHECK_ALIASING);
} else { } else {
arg.setUndefined(); arg.setUndefined();
} }

View File

@ -191,10 +191,10 @@ CallObject::copyUnaliasedValues(StackFrame *fp)
/* Copy the unaliased formals. */ /* Copy the unaliased formals. */
for (unsigned i = 0; i < script->bindings.numArgs(); ++i) { for (unsigned i = 0; i < script->bindings.numArgs(); ++i) {
if (!script->formalLivesInCallObject(i)) { if (!script->formalLivesInCallObject(i)) {
if (script->argsObjAliasesFormals()) if (script->argsObjAliasesFormals() && fp->hasArgsObj())
setArg(i, fp->argsObj().arg(i), DONT_CHECK_ALIASING); setArg(i, fp->argsObj().arg(i), DONT_CHECK_ALIASING);
else else
setArg(i, fp->unaliasedFormal(i), DONT_CHECK_ALIASING); setArg(i, fp->unaliasedFormal(i, DONT_CHECK_ALIASING), DONT_CHECK_ALIASING);
} }
} }
@ -1113,7 +1113,7 @@ class DebugScopeProxy : public BaseProxyHandler
* This function handles access to unaliased locals/formals. If such * This function handles access to unaliased locals/formals. If such
* accesses were passed on directly to the DebugScopeObject::scope, they * accesses were passed on directly to the DebugScopeObject::scope, they
* would not be reading/writing the canonical location for the variable, * would not be reading/writing the canonical location for the variable,
* which is on the stack. Thus, handleUn must translate would-be * which is on the stack. Thus, handleUnaliasedAccess must translate
* accesses to scope objects into analogous accesses of the stack frame. * accesses to scope objects into analogous accesses of the stack frame.
* *
* handleUnaliasedAccess returns 'true' if the access was unaliased and * handleUnaliasedAccess returns 'true' if the access was unaliased and
@ -1162,16 +1162,16 @@ class DebugScopeProxy : public BaseProxyHandler
return false; return false;
if (maybefp) { if (maybefp) {
if (script->argsObjAliasesFormals()) { if (script->argsObjAliasesFormals() && maybefp->hasArgsObj()) {
if (action == GET) if (action == GET)
*vp = maybefp->argsObj().arg(i); *vp = maybefp->argsObj().arg(i);
else else
maybefp->argsObj().setArg(i, *vp); maybefp->argsObj().setArg(i, *vp);
} else { } else {
if (action == GET) if (action == GET)
*vp = maybefp->unaliasedFormal(i); *vp = maybefp->unaliasedFormal(i, DONT_CHECK_ALIASING);
else else
maybefp->unaliasedFormal(i) = *vp; maybefp->unaliasedFormal(i, DONT_CHECK_ALIASING) = *vp;
} }
} else { } else {
if (action == GET) if (action == GET)

View File

@ -252,10 +252,10 @@ StackFrame::unaliasedFormal(unsigned i, MaybeCheckAliasing checkAliasing)
} }
inline Value & inline Value &
StackFrame::unaliasedActual(unsigned i) StackFrame::unaliasedActual(unsigned i, MaybeCheckAliasing checkAliasing)
{ {
JS_ASSERT(i < numActualArgs()); JS_ASSERT(i < numActualArgs());
JS_ASSERT(!script()->formalIsAliased(i)); JS_ASSERT_IF(checkAliasing && i < numFormalArgs(), !script()->formalIsAliased(i));
return i < numFormalArgs() ? formals()[i] : actuals()[i]; return i < numFormalArgs() ? formals()[i] : actuals()[i];
} }

View File

@ -591,7 +591,7 @@ class StackFrame
bool hasArgs() const { return isNonEvalFunctionFrame(); } bool hasArgs() const { return isNonEvalFunctionFrame(); }
inline Value &unaliasedFormal(unsigned i, MaybeCheckAliasing = CHECK_ALIASING); inline Value &unaliasedFormal(unsigned i, MaybeCheckAliasing = CHECK_ALIASING);
inline Value &unaliasedActual(unsigned i); inline Value &unaliasedActual(unsigned i, MaybeCheckAliasing = CHECK_ALIASING);
template <class Op> inline void forEachUnaliasedActual(Op op); template <class Op> inline void forEachUnaliasedActual(Op op);
inline unsigned numFormalArgs() const; inline unsigned numFormalArgs() const;
@ -1011,11 +1011,24 @@ class StackFrame
return !!(flags_ & CONSTRUCTING); return !!(flags_ & CONSTRUCTING);
} }
/*
* These two queries should not be used in general: the presence/absence of
* the call/args object is determined by the static(ish) properties of the
* JSFunction/JSScript. These queries should only be performed when probing
* a stack frame that may be in the middle of the prologue (during which
* time the call/args object are created).
*/
bool hasCallObj() const { bool hasCallObj() const {
JS_ASSERT(isStrictEvalFrame() || fun()->isHeavyweight()); JS_ASSERT(isStrictEvalFrame() || fun()->isHeavyweight());
return flags_ & HAS_CALL_OBJ; return flags_ & HAS_CALL_OBJ;
} }
bool hasArgsObj() const {
JS_ASSERT(script()->needsArgsObj());
return flags_ & HAS_ARGS_OBJ;
}
/* /*
* The method JIT call/apply optimization can erase Function.{call,apply} * The method JIT call/apply optimization can erase Function.{call,apply}
* invocations from the stack and push the callee frame directly. The base * invocations from the stack and push the callee frame directly. The base