Skip to content

Commit

Permalink
Bug 619565 - Fix activation object handling by InvokeSessionGuard (r=…
Browse files Browse the repository at this point in the history
…waldo,a=shaver)

--HG--
extra : rebase_source : 24e4d6ecf1cb9696fda7468eb631f13d92d7ab7a
  • Loading branch information
Luke Wagner committed Feb 24, 2011
1 parent 52b61d8 commit bfdc0fa
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 19 deletions.
8 changes: 8 additions & 0 deletions js/src/jit-test/tests/jaeger/invokeSessionGuard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// |jit-test| mjitalways;debug

[1,2,3,4,5,6,7,8].forEach(
function(x) {
// evalInFrame means lightweight gets call obj
assertEq(evalInFrame(0, "x"), x);
}
);
12 changes: 12 additions & 0 deletions js/src/jit-test/tests/testCrossGlobalInvokeSession.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
otherGlobal = newGlobal("same-compartment");
otherGlobal.poison = Proxy.create({});
callee = new otherGlobal.Function("return this.poison;");

var caught = false;
try {
[1,2,3,4,5,6,7,8].sort(callee);
} catch(e) {
assertEq(e instanceof Error, true);
caught = true;
}
assertEq(caught, true);
1 change: 1 addition & 0 deletions js/src/jscntxt.h
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,7 @@ class InvokeFrameGuard
InvokeFrameGuard() : cx_(NULL) {}
~InvokeFrameGuard() { if (pushed()) pop(); }
bool pushed() const { return cx_ != NULL; }
JSContext *pushedFrameContext() const { JS_ASSERT(pushed()); return cx_; }
void pop();
JSStackFrame *fp() const { return regs_.fp; }
};
Expand Down
9 changes: 8 additions & 1 deletion js/src/jsinterp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -775,7 +775,14 @@ InvokeSessionGuard::start(JSContext *cx, const Value &calleev, const Value &this
if (fun->isNative())
break;
script_ = fun->script();
if (fun->isHeavyweight() || script_->isEmpty() || cx->compartment->debugMode)
if (fun->isHeavyweight() || script_->isEmpty())
break;

/*
* The frame will remain pushed even when the callee isn't active which
* will affect the observable current global, so avoid any change.
*/
if (callee.getGlobal() != GetGlobalForScopeChain(cx))
break;

/* Push the stack frame once for the session. */
Expand Down
29 changes: 11 additions & 18 deletions js/src/jsinterpinlines.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,9 @@ JSStackFrame::resetInvokeCallFrame()
{
/* Undo changes to frame made during execution; see initCallFrame */

if (hasArgsObj())
args.nactual = argsObj().getArgsInitialLength();

JS_ASSERT(!(flags_ & ~(JSFRAME_FUNCTION |
JSFRAME_OVERFLOW_ARGS |
JSFRAME_UNDERFLOW_ARGS |
JSFRAME_HAS_CALL_OBJ |
JSFRAME_HAS_ARGS_OBJ |
JSFRAME_OVERRIDE_ARGS |
JSFRAME_HAS_PREVPC |
JSFRAME_HAS_RVAL |
Expand All @@ -121,16 +116,8 @@ JSStackFrame::resetInvokeCallFrame()
JSFRAME_HAS_PREVPC |
JSFRAME_UNDERFLOW_ARGS;

JS_ASSERT_IF(!hasCallObj(), scopeChain_ == calleeValue().toObject().getParent());
JS_ASSERT_IF(hasCallObj(), scopeChain_ == callObj().getParent());
if (hasCallObj())
scopeChain_ = callObj().getParent();

JS_ASSERT(exec.fun == calleeValue().toObject().getFunctionPrivate());
JS_ASSERT(!hasImacropc());
JS_ASSERT(!hasHookData());
JS_ASSERT(annotation() == NULL);
JS_ASSERT(!hasCallObj());
JS_ASSERT(exec.fun == callee().getFunctionPrivate());
scopeChain_ = callee().getParent();
}

inline void
Expand Down Expand Up @@ -566,7 +553,7 @@ class InvokeSessionGuard

public:
InvokeSessionGuard() : args_(), frame_() {}
~InvokeSessionGuard() {}
inline ~InvokeSessionGuard();

bool start(JSContext *cx, const Value &callee, const Value &thisv, uintN argc);
bool invoke(JSContext *cx) const;
Expand All @@ -592,6 +579,13 @@ class InvokeSessionGuard
}
};

inline
InvokeSessionGuard::~InvokeSessionGuard()
{
if (frame_.pushed())
PutActivationObjects(frame_.pushedFrameContext(), frame_.fp());
}

inline bool
InvokeSessionGuard::invoke(JSContext *cx) const
{
Expand All @@ -612,6 +606,7 @@ InvokeSessionGuard::invoke(JSContext *cx) const
/* Clear any garbage left from the last Invoke. */
JSStackFrame *fp = frame_.fp();
fp->clearMissingArgs();
PutActivationObjects(cx, frame_.fp());
fp->resetInvokeCallFrame();
SetValueRangeToUndefined(fp->slots(), script_->nfixed);

Expand All @@ -630,8 +625,6 @@ InvokeSessionGuard::invoke(JSContext *cx) const
Probes::exitJSFun(cx, fp->fun(), script_);
}

PutActivationObjects(cx, fp);

/* Don't clobber callee with rval; rval gets read from fp->rval. */
return ok;
}
Expand Down

0 comments on commit bfdc0fa

Please sign in to comment.