summaryrefslogtreecommitdiffstats
path: root/js/src/debugger
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/debugger')
-rw-r--r--js/src/debugger/DebugAPI-inl.h8
-rw-r--r--js/src/debugger/DebugAPI.h5
-rw-r--r--js/src/debugger/Debugger.cpp18
-rw-r--r--js/src/debugger/Environment.cpp18
-rw-r--r--js/src/debugger/Frame.cpp18
-rw-r--r--js/src/debugger/Frame.h1
6 files changed, 57 insertions, 11 deletions
diff --git a/js/src/debugger/DebugAPI-inl.h b/js/src/debugger/DebugAPI-inl.h
index 3762fcf05e..77f81b800f 100644
--- a/js/src/debugger/DebugAPI-inl.h
+++ b/js/src/debugger/DebugAPI-inl.h
@@ -96,6 +96,14 @@ bool DebugAPI::onNewGenerator(JSContext* cx, AbstractFramePtr frame,
}
/* static */
+void DebugAPI::onGeneratorClosed(JSContext* cx,
+ AbstractGeneratorObject* genObj) {
+ if (cx->realm()->isDebuggee()) {
+ slowPathOnGeneratorClosed(cx, genObj);
+ }
+}
+
+/* static */
bool DebugAPI::checkNoExecute(JSContext* cx, HandleScript script) {
if (!cx->realm()->isDebuggee() || !cx->noExecuteDebuggerTop) {
return true;
diff --git a/js/src/debugger/DebugAPI.h b/js/src/debugger/DebugAPI.h
index c821dd412f..df082ab5ba 100644
--- a/js/src/debugger/DebugAPI.h
+++ b/js/src/debugger/DebugAPI.h
@@ -342,6 +342,9 @@ class DebugAPI {
JSContext* cx, AbstractFramePtr frame,
Handle<AbstractGeneratorObject*> genObj);
+ static inline void onGeneratorClosed(JSContext* cx,
+ AbstractGeneratorObject* genObj);
+
// If necessary, record an object that was just allocated for any observing
// debuggers.
[[nodiscard]] static inline bool onLogAllocationSite(
@@ -371,6 +374,8 @@ class DebugAPI {
[[nodiscard]] static bool slowPathOnNewGenerator(
JSContext* cx, AbstractFramePtr frame,
Handle<AbstractGeneratorObject*> genObj);
+ static void slowPathOnGeneratorClosed(JSContext* cx,
+ AbstractGeneratorObject* genObj);
[[nodiscard]] static bool slowPathCheckNoExecute(JSContext* cx,
HandleScript script);
[[nodiscard]] static bool slowPathOnEnterFrame(JSContext* cx,
diff --git a/js/src/debugger/Debugger.cpp b/js/src/debugger/Debugger.cpp
index 8a99f8d4fe..37c1e79a9d 100644
--- a/js/src/debugger/Debugger.cpp
+++ b/js/src/debugger/Debugger.cpp
@@ -1794,7 +1794,7 @@ static bool CheckResumptionValue(JSContext* cx, AbstractFramePtr frame,
}
// 2. The generator must be closed.
- genObj->setClosed();
+ genObj->setClosed(cx);
// Async generators have additionally bookkeeping which must be adjusted
// when switching over to the closed state.
@@ -1823,7 +1823,7 @@ static bool CheckResumptionValue(JSContext* cx, AbstractFramePtr frame,
vp.setObject(*promise);
// 2. The generator must be closed.
- generator->setClosed();
+ generator->setClosed(cx);
} else {
// We're before entering the actual function code.
@@ -2855,6 +2855,20 @@ void DebugAPI::slowPathOnNewGlobalObject(JSContext* cx,
}
/* static */
+void DebugAPI::slowPathOnGeneratorClosed(JSContext* cx,
+ AbstractGeneratorObject* genObj) {
+ JS::AutoAssertNoGC nogc;
+ for (Realm::DebuggerVectorEntry& entry : cx->global()->getDebuggers(nogc)) {
+ Debugger* dbg = entry.dbg;
+ if (Debugger::GeneratorWeakMap::Ptr frameEntry =
+ dbg->generatorFrames.lookup(genObj)) {
+ DebuggerFrame* frameObj = frameEntry->value();
+ frameObj->onGeneratorClosed(cx->gcContext());
+ }
+ }
+}
+
+/* static */
void DebugAPI::slowPathNotifyParticipatesInGC(uint64_t majorGCNumber,
Realm::DebuggerVector& dbgs,
const JS::AutoRequireNoGC& nogc) {
diff --git a/js/src/debugger/Environment.cpp b/js/src/debugger/Environment.cpp
index 9c90573c25..8549b47471 100644
--- a/js/src/debugger/Environment.cpp
+++ b/js/src/debugger/Environment.cpp
@@ -289,12 +289,12 @@ bool DebuggerEnvironment::CallData::findMethod() {
return false;
}
- if (!environment->requireDebuggee(cx)) {
+ RootedId id(cx);
+ if (!ValueToIdentifier(cx, args[0], &id)) {
return false;
}
- RootedId id(cx);
- if (!ValueToIdentifier(cx, args[0], &id)) {
+ if (!environment->requireDebuggee(cx)) {
return false;
}
@@ -312,12 +312,12 @@ bool DebuggerEnvironment::CallData::getVariableMethod() {
return false;
}
- if (!environment->requireDebuggee(cx)) {
+ RootedId id(cx);
+ if (!ValueToIdentifier(cx, args[0], &id)) {
return false;
}
- RootedId id(cx);
- if (!ValueToIdentifier(cx, args[0], &id)) {
+ if (!environment->requireDebuggee(cx)) {
return false;
}
@@ -329,12 +329,12 @@ bool DebuggerEnvironment::CallData::setVariableMethod() {
return false;
}
- if (!environment->requireDebuggee(cx)) {
+ RootedId id(cx);
+ if (!ValueToIdentifier(cx, args[0], &id)) {
return false;
}
- RootedId id(cx);
- if (!ValueToIdentifier(cx, args[0], &id)) {
+ if (!environment->requireDebuggee(cx)) {
return false;
}
diff --git a/js/src/debugger/Frame.cpp b/js/src/debugger/Frame.cpp
index 9767e2e7ed..63978b90ab 100644
--- a/js/src/debugger/Frame.cpp
+++ b/js/src/debugger/Frame.cpp
@@ -439,6 +439,24 @@ void DebuggerFrame::terminate(JS::GCContext* gcx, AbstractFramePtr frame) {
gcx->delete_(this, info, MemoryUse::DebuggerFrameGeneratorInfo);
}
+void DebuggerFrame::onGeneratorClosed(JS::GCContext* gcx) {
+ GeneratorInfo* info = generatorInfo();
+
+ // If the generator is closed, eagerly drop the onStep handler, to make sure
+ // the stepper counter matches in the assertion in DebugAPI::onSingleStep.
+ // Also clear the slot in order to suppress the decrementStepperCounter in
+ // DebuggerFrame::terminate.
+ if (!info->isGeneratorScriptAboutToBeFinalized()) {
+ JSScript* generatorScript = info->generatorScript();
+ OnStepHandler* handler = onStepHandler();
+ if (handler) {
+ decrementStepperCounter(gcx, generatorScript);
+ setReservedSlot(ONSTEP_HANDLER_SLOT, UndefinedValue());
+ handler->drop(gcx, this);
+ }
+ }
+}
+
void DebuggerFrame::suspend(JS::GCContext* gcx) {
// There must be generator info because otherwise this would be the same
// overall behavior as terminate() except that here we do not properly
diff --git a/js/src/debugger/Frame.h b/js/src/debugger/Frame.h
index 675accbcf7..44ee39d9db 100644
--- a/js/src/debugger/Frame.h
+++ b/js/src/debugger/Frame.h
@@ -287,6 +287,7 @@ class DebuggerFrame : public NativeObject {
FrameIter getFrameIter(JSContext* cx);
void terminate(JS::GCContext* gcx, AbstractFramePtr frame);
+ void onGeneratorClosed(JS::GCContext* gcx);
void suspend(JS::GCContext* gcx);
[[nodiscard]] bool replaceFrameIterData(JSContext* cx, const FrameIter&);