author | Jon Coppeard <jcoppeard@mozilla.com> |
Thu, 18 Oct 2018 10:33:33 +0100 | |
changeset 497663 | 6b952be63f69e244ab688cdb7a84d121b009a162 |
parent 497662 | 8f74f5dbf5c0d12bebf84841b8553b179b7d04a0 |
child 497664 | 9e81f9458926dbb1796ac5c3c0b06fa1ee1d10e9 |
push id | 10002 |
push user | archaeopteryx@coole-files.de |
push date | Fri, 19 Oct 2018 23:09:29 +0000 |
treeherder | mozilla-beta@01378c910610 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jorendorff |
bugs | 1498980 |
milestone | 64.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/modules/bug-1498980.js @@ -0,0 +1,24 @@ +dbgGlobal = newGlobal(); +dbg = new dbgGlobal.Debugger; +dbg.addDebuggee(this); + +function f() { + dbg.getNewestFrame().older.eval(""); +} + +function execModule(source) { + m = parseModule(source); + m.declarationInstantiation(); + m.evaluation(); +} + +execModule("f();"); +gc(); + +let caught; +try { + execModule("throw 'foo'"); +} catch (e) { + caught = e; +} +assertEq(caught, 'foo');
--- a/js/src/vm/EnvironmentObject.cpp +++ b/js/src/vm/EnvironmentObject.cpp @@ -2802,20 +2802,21 @@ DebugEnvironments::takeFrameSnapshot(JSC * copy of the unaliased variables' values in an array for later debugger * access via DebugEnvironmentProxy::handleUnaliasedAccess. * * Note: since it is simplest for this function to be infallible, failure * in this code will be silently ignored. This does not break any * invariants since DebugEnvironmentProxy::maybeSnapshot can already be nullptr. */ + JSScript* script = frame.script(); + // Act like no snapshot was taken if we run OOM while taking the snapshot. Rooted<GCVector<Value>> vec(cx, GCVector<Value>(cx)); if (debugEnv->environment().is<CallObject>()) { - JSScript* script = frame.script(); FunctionScope* scope = &script->bodyScope()->as<FunctionScope>(); uint32_t frameSlotCount = scope->nextFrameSlot(); MOZ_ASSERT(frameSlotCount <= script->nfixed()); // For simplicity, copy all frame slots from 0 to the frameSlotCount, // even if we don't need all of them (like in the case of a defaults // parameter scope having frame slots). @@ -2843,32 +2844,38 @@ DebugEnvironments::takeFrameSnapshot(JSC } else { uint32_t frameSlotStart; uint32_t frameSlotEnd; if (debugEnv->environment().is<LexicalEnvironmentObject>()) { LexicalScope* scope = &debugEnv->environment().as<LexicalEnvironmentObject>().scope(); frameSlotStart = scope->firstFrameSlot(); frameSlotEnd = scope->nextFrameSlot(); - } else { + } else if (debugEnv->environment().is<VarEnvironmentObject>()) { VarEnvironmentObject* env = &debugEnv->environment().as<VarEnvironmentObject>(); if (frame.isFunctionFrame()) { VarScope* scope = &env->scope().as<VarScope>(); frameSlotStart = scope->firstFrameSlot(); frameSlotEnd = scope->nextFrameSlot(); } else { EvalScope* scope = &env->scope().as<EvalScope>(); - MOZ_ASSERT(scope == frame.script()->bodyScope()); + MOZ_ASSERT(scope == script->bodyScope()); frameSlotStart = 0; frameSlotEnd = scope->nextFrameSlot(); } + } else { + MOZ_ASSERT(&debugEnv->environment().as<ModuleEnvironmentObject>() == + script->module()->environment()); + ModuleScope* scope = &script->bodyScope()->as<ModuleScope>(); + frameSlotStart = 0; + frameSlotEnd = scope->nextFrameSlot(); } uint32_t frameSlotCount = frameSlotEnd - frameSlotStart; - MOZ_ASSERT(frameSlotCount <= frame.script()->nfixed()); + MOZ_ASSERT(frameSlotCount <= script->nfixed()); if (!vec.resize(frameSlotCount)) { cx->recoverFromOutOfMemory(); return; } for (uint32_t slot = frameSlotStart; slot < frameSlotCount; slot++) { vec[slot - frameSlotStart].set(frame.unaliasedLocal(slot)); } @@ -3018,16 +3025,22 @@ DebugEnvironments::onPopWith(AbstractFra { Realm* realm = frame.realm(); if (DebugEnvironments* envs = realm->debugEnvs()) { envs->liveEnvs.remove(&frame.environmentChain()->as<WithEnvironmentObject>()); } } void +DebugEnvironments::onPopModule(JSContext* cx, const EnvironmentIter& ei) +{ + onPopGeneric<ModuleEnvironmentObject, ModuleScope>(cx, ei); +} + +void DebugEnvironments::onRealmUnsetIsDebuggee(Realm* realm) { if (DebugEnvironments* envs = realm->debugEnvs()) { envs->proxiedEnvs.clear(); envs->missingEnvs.clear(); envs->liveEnvs.clear(); } }
--- a/js/src/vm/EnvironmentObject.h +++ b/js/src/vm/EnvironmentObject.h @@ -1049,16 +1049,17 @@ class DebugEnvironments // In debug-mode, these must be called whenever exiting a scope that might // have stack-allocated locals. static void onPopCall(JSContext* cx, AbstractFramePtr frame); static void onPopVar(JSContext* cx, const EnvironmentIter& ei); static void onPopVar(JSContext* cx, AbstractFramePtr frame, jsbytecode* pc); static void onPopLexical(JSContext* cx, const EnvironmentIter& ei); static void onPopLexical(JSContext* cx, AbstractFramePtr frame, jsbytecode* pc); static void onPopWith(AbstractFramePtr frame); + static void onPopModule(JSContext* cx, const EnvironmentIter& ei); static void onRealmUnsetIsDebuggee(Realm* realm); }; } /* namespace js */ template <> inline bool JSObject::is<js::EnvironmentObject>() const
--- a/js/src/vm/Interpreter.cpp +++ b/js/src/vm/Interpreter.cpp @@ -1238,20 +1238,24 @@ PopEnvironment(JSContext* cx, Environmen case ScopeKind::StrictEval: if (MOZ_UNLIKELY(cx->realm()->isDebuggee())) { DebugEnvironments::onPopVar(cx, ei); } if (ei.scope().hasEnvironment()) { ei.initialFrame().popOffEnvironmentChain<VarEnvironmentObject>(); } break; + case ScopeKind::Module: + if (MOZ_UNLIKELY(cx->realm()->isDebuggee())) { + DebugEnvironments::onPopModule(cx, ei); + } + break; case ScopeKind::Eval: case ScopeKind::Global: case ScopeKind::NonSyntactic: - case ScopeKind::Module: break; case ScopeKind::WasmInstance: case ScopeKind::WasmFunction: MOZ_CRASH("wasm is not interpreted"); break; } }