зеркало из https://github.com/mozilla/pjs.git
Bug 619565 - Fix activation object handling by InvokeSessionGuard (r=waldo,a=shaver)
--HG-- extra : rebase_source : 24e4d6ecf1cb9696fda7468eb631f13d92d7ab7a
This commit is contained in:
Родитель
c4d7674859
Коммит
b36cbb2d7a
|
@ -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);
|
||||
}
|
||||
);
|
|
@ -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);
|
|
@ -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; }
|
||||
};
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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 |
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -592,6 +579,13 @@ class InvokeSessionGuard
|
|||
}
|
||||
};
|
||||
|
||||
inline
|
||||
InvokeSessionGuard::~InvokeSessionGuard()
|
||||
{
|
||||
if (frame_.pushed())
|
||||
PutActivationObjects(frame_.pushedFrameContext(), frame_.fp());
|
||||
}
|
||||
|
||||
inline bool
|
||||
InvokeSessionGuard::invoke(JSContext *cx) const
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче