From 3a5b927979b3055257c9dd23ba7c7fda3f1ca635 Mon Sep 17 00:00:00 2001
From: ksuprynowicz <ksuprynowicz@post.pl>
Date: Sat, 28 Jan 2023 19:11:29 +0100
Subject: [PATCH] Functions connected to signals now use context that was
 active during connecting

---
 libraries/script-engine/src/ScriptManager.cpp          |  3 ++-
 libraries/script-engine/src/v8/ScriptEngineV8.cpp      |  2 +-
 libraries/script-engine/src/v8/ScriptEngineV8.h        |  2 +-
 libraries/script-engine/src/v8/ScriptObjectV8Proxy.cpp |  8 +++++---
 libraries/script-engine/src/v8/ScriptObjectV8Proxy.h   | 10 +++++++++-
 5 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/libraries/script-engine/src/ScriptManager.cpp b/libraries/script-engine/src/ScriptManager.cpp
index 53d198269a..f17558a244 100644
--- a/libraries/script-engine/src/ScriptManager.cpp
+++ b/libraries/script-engine/src/ScriptManager.cpp
@@ -1122,6 +1122,7 @@ void ScriptManager::stopTimer(QTimer *timer) {
 }
 
 QUrl ScriptManager::resolvePath(const QString& include) const {
+    //qDebug(scriptengine) << "ScriptManager::resolvePath: getCurrentScriptURLs: " << _engine->getCurrentScriptURLs();
     QUrl url(include);
     // first lets check to see if it's already a full URL -- or a Windows path like "c:/"
     if (include.startsWith("/") || url.scheme().length() == 1) {
@@ -1139,7 +1140,7 @@ QUrl ScriptManager::resolvePath(const QString& include) const {
     do {
         auto contextInfo = context->functionContext();
         parentURL = QUrl(contextInfo->fileName());
-        qDebug(scriptengine) << "ScriptManager::resolvePath: URL get: " << parentURL << " backtrace: " << context->backtrace() << " " << _engine->getCurrentScriptURLs();
+        //qDebug(scriptengine) << "ScriptManager::resolvePath: URL get: " << parentURL << " backtrace: " << context->backtrace() << " " << _engine->getCurrentScriptURLs();
         parentContext = context->parentContext();
         context = parentContext.get();
     } while (parentURL.isRelative() && context);
diff --git a/libraries/script-engine/src/v8/ScriptEngineV8.cpp b/libraries/script-engine/src/v8/ScriptEngineV8.cpp
index 3736768e47..3664784720 100644
--- a/libraries/script-engine/src/v8/ScriptEngineV8.cpp
+++ b/libraries/script-engine/src/v8/ScriptEngineV8.cpp
@@ -1111,7 +1111,7 @@ QString ScriptEngineV8::formatErrorMessageFromTryCatch(v8::TryCatch &tryCatch) {
     return result;
 }
 
-ScriptContextV8Pointer ScriptEngineV8::pushContext(v8::Local<v8::Context> &context) {
+ScriptContextV8Pointer ScriptEngineV8::pushContext(v8::Local<v8::Context> context) {
     Q_ASSERT(!_contexts.isEmpty());
     ScriptContextPointer parent = _contexts.last();
     _contexts.append(std::make_shared<ScriptContextV8Wrapper>(this, context, ScriptContextPointer()));
diff --git a/libraries/script-engine/src/v8/ScriptEngineV8.h b/libraries/script-engine/src/v8/ScriptEngineV8.h
index b617844cc2..324ebb1292 100644
--- a/libraries/script-engine/src/v8/ScriptEngineV8.h
+++ b/libraries/script-engine/src/v8/ScriptEngineV8.h
@@ -199,7 +199,7 @@ public: // not for public use, but I don't like how Qt strings this along with p
     // V8TODO add a V8 callback that removes pointer from the map so that it gets deleted
     QMap<QObject*, QSharedPointer<ScriptObjectV8Proxy>> _qobjectWrapperMapV8;
 
-    ScriptContextV8Pointer pushContext(v8::Local<v8::Context> &context);
+    ScriptContextV8Pointer pushContext(v8::Local<v8::Context> context);
     void popContext();
 
 protected:
diff --git a/libraries/script-engine/src/v8/ScriptObjectV8Proxy.cpp b/libraries/script-engine/src/v8/ScriptObjectV8Proxy.cpp
index 7f88e6dd75..f81a1217d8 100644
--- a/libraries/script-engine/src/v8/ScriptObjectV8Proxy.cpp
+++ b/libraries/script-engine/src/v8/ScriptObjectV8Proxy.cpp
@@ -1094,9 +1094,11 @@ int ScriptSignalV8Proxy::qt_metacall(QMetaObject::Call call, int id, void** argu
         Q_ASSERT(conn.callback.get()->IsFunction());
         {
             v8::Local<v8::Function> callback = v8::Local<v8::Function>::Cast(conn.callback.get());
-            auto functionContext = callback->CreationContext();
-            _engine->pushContext(functionContext);
-            v8::Context::Scope functionContextScope(functionContext);
+            //auto functionContext = callback->CreationContext();
+            //_engine->pushContext(functionContext);
+            _engine->pushContext(_v8Context.Get(_engine->getIsolate()));
+            //v8::Context::Scope functionContextScope(functionContext);
+            v8::Context::Scope functionContextScope(_v8Context.Get(_engine->getIsolate()));
             v8::Local<v8::Value> v8This;
             if (conn.thisValue.get()->IsObject()) {
                 v8This = conn.thisValue.get();
diff --git a/libraries/script-engine/src/v8/ScriptObjectV8Proxy.h b/libraries/script-engine/src/v8/ScriptObjectV8Proxy.h
index 39de65bb87..d88ca24883 100644
--- a/libraries/script-engine/src/v8/ScriptObjectV8Proxy.h
+++ b/libraries/script-engine/src/v8/ScriptObjectV8Proxy.h
@@ -221,7 +221,13 @@ private:  // storage
 
 public:  // construction
     inline ScriptSignalV8Proxy(ScriptEngineV8* engine, QObject* object, V8ScriptValue lifetime, const QMetaMethod& meta) :
-        _engine(engine), _object(object), _objectLifetime(lifetime), _meta(meta), _metaCallId(discoverMetaCallIdx()) {}
+        _engine(engine), _object(object), _objectLifetime(lifetime), _meta(meta), _metaCallId(discoverMetaCallIdx()) {
+        v8::Locker locker(_engine->getIsolate());
+        v8::Isolate::Scope isolateScope(_engine->getIsolate());
+        v8::HandleScope handleScope(_engine->getIsolate());
+        v8::Context::Scope contextScope(_engine->getContext());
+        _v8Context.Reset(_engine->getIsolate(), _engine->getContext());
+    }
 
 private:  // implementation
     virtual int qt_metacall(QMetaObject::Call call, int id, void** arguments) override;
@@ -245,6 +251,8 @@ private:  // storage
     const int _metaCallId;
     ConnectionList _connections;
     bool _isConnected{ false };
+    // Context in which it was created
+    v8::UniquePersistent<v8::Context> _v8Context;
 
     Q_DISABLE_COPY(ScriptSignalV8Proxy)
 };