Bug 1308578 - Consider .this bindings of derived class constructors to be always observable. (r=jandem)

This commit is contained in:
Shu-yu Guo 2016-11-08 15:46:05 -08:00
parent 612b09719c
commit 2c0854ccc2
4 changed files with 39 additions and 3 deletions

View File

@ -0,0 +1,10 @@
// |jit-test| error: ReferenceError
g = newGlobal();
g.parent = this;
g.eval("new Debugger(parent).onExceptionUnwind = function () {}");
a = new class extends Array {
constructor() {
for (;; ([] = p)) {}
}
}

View File

@ -7,6 +7,8 @@
#ifndef jit_CompileInfo_h
#define jit_CompileInfo_h
#include "mozilla/Maybe.h"
#include "jsfun.h"
#include "jit/JitAllocPolicy.h"
@ -221,6 +223,23 @@ class CompileInfo
nlocals_ = script->nfixed();
nstack_ = Max<unsigned>(script->nslots() - script->nfixed(), MinJITStackSize);
nslots_ = nimplicit_ + nargs_ + nlocals_ + nstack_;
// For derived class constructors, find and cache the frame slot for
// the .this binding. This slot is assumed to be always
// observable. See isObservableFrameSlot.
if (script->isDerivedClassConstructor()) {
MOZ_ASSERT(script->functionHasThisBinding());
CompileRuntime* runtime = GetJitContext()->runtime;
for (BindingIter bi(script); bi; bi++) {
if (bi.name() != runtime->names().dotThis)
continue;
BindingLocation loc = bi.location();
if (loc.kind() == BindingLocation::Kind::Frame) {
thisSlotForDerivedClassConstructor_ = mozilla::Some(localSlot(loc.slot()));
break;
}
}
}
}
explicit CompileInfo(unsigned nlocals)
@ -437,6 +456,13 @@ class CompileInfo
if (slot == thisSlot())
return true;
// The |this| frame slot in derived class constructors should never be
// optimized out, as a Debugger might need to perform TDZ checks on it
// via, e.g., an exceptionUnwind handler. The TDZ check is required
// for correctness if the handler decides to continue execution.
if (thisSlotForDerivedClassConstructor_ && *thisSlotForDerivedClassConstructor_ == slot)
return true;
if (funMaybeLazy()->needsSomeEnvironmentObject() && slot == environmentChainSlot())
return true;
@ -503,6 +529,7 @@ class CompileInfo
unsigned nlocals_;
unsigned nstack_;
unsigned nslots_;
mozilla::Maybe<unsigned> thisSlotForDerivedClassConstructor_;
JSScript* script_;
JSFunction* fun_;
jsbytecode* osrPc_;

View File

@ -1561,9 +1561,8 @@ CheckResumptionValue(JSContext* cx, AbstractFramePtr frame, const Maybe<HandleVa
const HandleValue& thisv = maybeThisv.ref();
if (status == JSTRAP_RETURN && vp.isPrimitive()) {
if (vp.isUndefined()) {
if (thisv.isMagic(JS_UNINITIALIZED_LEXICAL)) {
if (thisv.isMagic(JS_UNINITIALIZED_LEXICAL))
return ThrowUninitializedThis(cx, frame);
}
vp.set(thisv);
} else {

View File

@ -3133,7 +3133,7 @@ js::GetThisValueForDebuggerMaybeOptimizedOut(JSContext* cx, AbstractFramePtr fra
}
if (loc.kind() == BindingLocation::Kind::Frame && ei.withinInitialFrame())
res.set(frame.unaliasedLocal(bi.location().slot()));
res.set(frame.unaliasedLocal(loc.slot()));
else
res.setMagic(JS_OPTIMIZED_OUT);