diff --git a/js/src/jit-test/tests/debug/breakpoint-10.js b/js/src/jit-test/tests/debug/breakpoint-10.js new file mode 100644 index 00000000000..35a8f14cc8e --- /dev/null +++ b/js/src/jit-test/tests/debug/breakpoint-10.js @@ -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); diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp index 26b4a361859..dd5c609522c 100644 --- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -3169,10 +3169,10 @@ DebuggerArguments_getArg(JSContext *cx, unsigned argc, Value *vp) if (unsigned(i) < fp->numActualArgs()) { if (unsigned(i) < fp->numFormalArgs() && fp->script()->formalLivesInCallObject(i)) arg = fp->callObj().arg(i); - else if (fp->script()->argsObjAliasesFormals()) + else if (fp->script()->argsObjAliasesFormals() && fp->hasArgsObj()) arg = fp->argsObj().arg(i); else - arg = fp->unaliasedActual(i); + arg = fp->unaliasedActual(i, DONT_CHECK_ALIASING); } else { arg.setUndefined(); } diff --git a/js/src/vm/ScopeObject.cpp b/js/src/vm/ScopeObject.cpp index 72ff3b6b93d..06369efd678 100644 --- a/js/src/vm/ScopeObject.cpp +++ b/js/src/vm/ScopeObject.cpp @@ -191,10 +191,10 @@ CallObject::copyUnaliasedValues(StackFrame *fp) /* Copy the unaliased formals. */ for (unsigned i = 0; i < script->bindings.numArgs(); ++i) { if (!script->formalLivesInCallObject(i)) { - if (script->argsObjAliasesFormals()) + if (script->argsObjAliasesFormals() && fp->hasArgsObj()) setArg(i, fp->argsObj().arg(i), DONT_CHECK_ALIASING); 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 * accesses were passed on directly to the DebugScopeObject::scope, they * 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. * * handleUnaliasedAccess returns 'true' if the access was unaliased and @@ -1162,16 +1162,16 @@ class DebugScopeProxy : public BaseProxyHandler return false; if (maybefp) { - if (script->argsObjAliasesFormals()) { + if (script->argsObjAliasesFormals() && maybefp->hasArgsObj()) { if (action == GET) *vp = maybefp->argsObj().arg(i); else maybefp->argsObj().setArg(i, *vp); } else { if (action == GET) - *vp = maybefp->unaliasedFormal(i); + *vp = maybefp->unaliasedFormal(i, DONT_CHECK_ALIASING); else - maybefp->unaliasedFormal(i) = *vp; + maybefp->unaliasedFormal(i, DONT_CHECK_ALIASING) = *vp; } } else { if (action == GET) diff --git a/js/src/vm/Stack-inl.h b/js/src/vm/Stack-inl.h index 76485a5b82a..9f21a3a3c1c 100644 --- a/js/src/vm/Stack-inl.h +++ b/js/src/vm/Stack-inl.h @@ -252,10 +252,10 @@ StackFrame::unaliasedFormal(unsigned i, MaybeCheckAliasing checkAliasing) } inline Value & -StackFrame::unaliasedActual(unsigned i) +StackFrame::unaliasedActual(unsigned i, MaybeCheckAliasing checkAliasing) { 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]; } diff --git a/js/src/vm/Stack.h b/js/src/vm/Stack.h index 0027015aecd..042c1167e7f 100644 --- a/js/src/vm/Stack.h +++ b/js/src/vm/Stack.h @@ -591,7 +591,7 @@ class StackFrame bool hasArgs() const { return isNonEvalFunctionFrame(); } inline Value &unaliasedFormal(unsigned i, MaybeCheckAliasing = CHECK_ALIASING); - inline Value &unaliasedActual(unsigned i); + inline Value &unaliasedActual(unsigned i, MaybeCheckAliasing = CHECK_ALIASING); template inline void forEachUnaliasedActual(Op op); inline unsigned numFormalArgs() const; @@ -1011,11 +1011,24 @@ class StackFrame 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 { JS_ASSERT(isStrictEvalFrame() || fun()->isHeavyweight()); 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} * invocations from the stack and push the callee frame directly. The base