From 1137063b588cd2741ba529c08d5f143c76a688bf Mon Sep 17 00:00:00 2001 From: chris-james-displayr Date: Thu, 5 Mar 2026 13:41:46 +0800 Subject: [PATCH 1/2] Add debugger support --- .../Noesis.Javascript/JavaScript.Net.vcxproj | 2 + .../JavaScript.Net.vcxproj.filters | 6 + .../Noesis.Javascript/JavascriptContext.cpp | 33 +- Source/Noesis.Javascript/JavascriptContext.h | 10 +- .../Noesis.Javascript/JavascriptDebugger.cpp | 455 ++++++++++++++++++ Source/Noesis.Javascript/JavascriptDebugger.h | 167 +++++++ .../Noesis.Javascript.Tests/DebuggerTests.cs | 279 +++++++++++ 7 files changed, 948 insertions(+), 4 deletions(-) create mode 100644 Source/Noesis.Javascript/JavascriptDebugger.cpp create mode 100644 Source/Noesis.Javascript/JavascriptDebugger.h create mode 100644 Tests/Noesis.Javascript.Tests/DebuggerTests.cs diff --git a/Source/Noesis.Javascript/JavaScript.Net.vcxproj b/Source/Noesis.Javascript/JavaScript.Net.vcxproj index 7d8f6cf8..792f9357 100644 --- a/Source/Noesis.Javascript/JavaScript.Net.vcxproj +++ b/Source/Noesis.Javascript/JavaScript.Net.vcxproj @@ -166,6 +166,7 @@ + @@ -176,6 +177,7 @@ + diff --git a/Source/Noesis.Javascript/JavaScript.Net.vcxproj.filters b/Source/Noesis.Javascript/JavaScript.Net.vcxproj.filters index 3dff49a8..4ec8ba2c 100644 --- a/Source/Noesis.Javascript/JavaScript.Net.vcxproj.filters +++ b/Source/Noesis.Javascript/JavaScript.Net.vcxproj.filters @@ -36,6 +36,9 @@ Header Files + + Header Files + @@ -59,6 +62,9 @@ Source Files + + Source Files + diff --git a/Source/Noesis.Javascript/JavascriptContext.cpp b/Source/Noesis.Javascript/JavascriptContext.cpp index 21031fa2..bce1a91f 100644 --- a/Source/Noesis.Javascript/JavascriptContext.cpp +++ b/Source/Noesis.Javascript/JavascriptContext.cpp @@ -38,6 +38,7 @@ #include "JavascriptContext.h" #include "SystemInterop.h" +#include "JavascriptDebugger.h" #include "JavascriptException.h" #include "JavascriptExternal.h" #include "JavascriptFunction.h" @@ -172,15 +173,27 @@ JavascriptContext::JavascriptContext() HandleScope scope(isolate); mContext = new Persistent(isolate, Context::New(isolate)); terminateRuns = false; + mDebugger = nullptr; } //////////////////////////////////////////////////////////////////////////////////////////////////// JavascriptContext::~JavascriptContext() { + // Guard against double-Dispose: isolate is nulled at the end so a second call is a no-op. + if (isolate == nullptr) return; + { v8::Locker v8ThreadLock(isolate); v8::Isolate::Scope isolate_scope(isolate); + + // Notify attached debugger before V8 cleanup so it can disconnect cleanly. + if (mDebugger != nullptr) + { + mDebugger->OnContextDisposing(); + mDebugger = nullptr; + } + for each (WrappedJavascriptExternal wrapped in mExternals->Values) delete wrapped.Pointer; // Clean up JavascriptFunction wrappers @@ -216,7 +229,10 @@ JavascriptContext::~JavascriptContext() delete mTypeToConstructorMapping; } if (isolate != NULL) + { isolate->Dispose(); + isolate = nullptr; // Null so double-Dispose is safe (guard check above). + } } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -350,8 +366,14 @@ JavascriptContext::Run(System::String^ iScript) JavascriptScope scope(this); //SetStackLimit(); HandleScope handleScope(isolate); + + // Flush any queued debugger commands (e.g., Debugger.enable, setBreakpoint) + // before executing so they take effect for this run. + if (mDebugger != nullptr) + mDebugger->ProcessPendingCommands(); + MaybeLocal ret; - + Local