mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 09:15:35 +00:00
Bug 1308578 - Consider .this bindings of derived class constructors to be always observable. (r=jandem)
This commit is contained in:
parent
612b09719c
commit
2c0854ccc2
10
js/src/jit-test/tests/debug/bug1308578.js
Normal file
10
js/src/jit-test/tests/debug/bug1308578.js
Normal 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)) {}
|
||||
}
|
||||
}
|
@ -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_;
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user