Fix v8::Persistent
authorLars Knoll <lars.knoll@digia.com>
Sat, 9 Mar 2013 22:18:25 +0000 (23:18 +0100)
committerSimon Hausmann <simon.hausmann@digia.com>
Sun, 10 Mar 2013 11:50:56 +0000 (12:50 +0100)
Implement it in a similar way as PersistentValue

Change-Id: If4adba61a8bfedce657f07ee24662c3b13384fd9
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
src/v4/qv4v8.cpp
src/v4/qv4v8.h

index bed2bf1..0bf4f13 100644 (file)
@@ -69,18 +69,29 @@ namespace v8 {
 #define ValuePtr(obj) reinterpret_cast<QQmlJS::VM::Value*>(obj)
 #define ConstValuePtr(obj) reinterpret_cast<const QQmlJS::VM::Value*>(obj)
 
-void gcProtect(void *handle)
+void *gcProtect(void *handle)
 {
     Q_D(handle);
-    if (VM::Managed *m = d->asManaged())
+    if (VM::Managed *m = d->asManaged()) {
         currentEngine()->memoryManager->protect(m);
+        return currentEngine()->memoryManager;
+    }
+}
+
+void gcProtect(void *memoryManager, void *handle)
+{
+    Q_D(handle);
+    if (VM::Managed *m = d->asManaged())
+        if (memoryManager)
+            static_cast<VM::MemoryManager *>(memoryManager)->protect(m);
 }
 
-void gcUnprotect(void *handle)
+void gcUnprotect(void *memoryManager, void *handle)
 {
     Q_D(handle);
     if (VM::Managed *m = d->asManaged())
-        currentEngine()->memoryManager->unprotect(m);
+        if (memoryManager)
+            static_cast<VM::MemoryManager *>(memoryManager)->unprotect(m);
 }
 
 struct V8AccessorGetter: FunctionObject {
@@ -177,6 +188,7 @@ Local<Script> Script::New(Handle<String> source,
     s->m_script = source->ToString()->asQString();
     if (origin)
         s->m_origin = *origin;
+    qDebug() << "script" << s << (flags & QmlMode) << source->asQString();
     s->m_flags = flags;
     s->m_context = Handle<Context>();
     return Local<Script>::New(Handle<Script>(s));
@@ -197,6 +209,7 @@ Local<Script> Script::Compile(Handle<String> source, ScriptOrigin *origin, Scrip
     s->m_script = source->ToString()->asQString();
     if (origin)
         s->m_origin = *origin;
+    qDebug() << "script" << s << (flags & QmlMode) << source->asQString();
     s->m_flags = flags;
     s->m_context = Context::GetCurrent();
     return Local<Script>::New(Handle<Script>(s));
@@ -213,6 +226,7 @@ Local<Script> Script::Compile(Handle<String> source,
 
 Local<Value> Script::Run()
 {
+    qDebug() << "run" << this;
     Handle<Context> context = m_context;
     if (context.IsEmpty())
         context = Context::GetCurrent();
@@ -242,6 +256,7 @@ Local<Value> Script::Run()
 
 Local<Value> Script::Run(Handle<Object> qml)
 {
+    qDebug() << "runQml" << this;
     Handle<Context> context = m_context;
     if (context.IsEmpty())
         context = Context::GetCurrent();
index 422ad45..e2e275f 100644 (file)
@@ -137,8 +137,9 @@ class StackFrame;
 class Isolate;
 class TryCatch;
 
-void V8EXPORT gcProtect(void *handle);
-void V8EXPORT gcUnprotect(void *handle);
+V8EXPORT void *gcProtect(void *handle);
+V8EXPORT void gcProtect(void *memoryManager, void *handle);
+V8EXPORT void gcUnprotect(void *memoryManager, void *handle);
 
 // --- Weak Handles ---
 
@@ -212,14 +213,19 @@ struct HandleOperations
     {
     }
 
-    static void protect(Handle<T> *handle)
+    static void *protect(Handle<T> *handle)
     {
-        gcProtect(handle);
+        return gcProtect(handle);
     }
 
-    static void unProtect(Handle<T> *handle)
+    static void protect(void *memoryManager, Handle<T> *handle)
     {
-        gcUnprotect(handle);
+        gcProtect(memoryManager, handle);
+    }
+
+    static void unProtect(void *memoryManager, Handle<T> *handle)
+    {
+        gcUnprotect(memoryManager, handle);
     }
 
     static bool isEmpty(const Handle<T> *handle)
@@ -255,8 +261,9 @@ struct HandleOperations
                 handle->object = 0; \
             } \
         } \
-        static void protect(Handle<Type> *) {} \
-        static void unProtect(Handle<Type> *) {} \
+        static void *protect(Handle<Type> *) { return 0; } \
+        static void protect(void *, Handle<Type> *) {} \
+        static void unProtect(void *, Handle<Type> *) {} \
         static bool isEmpty(const Handle<Type> *handle) \
         { \
             return handle->object == 0; \
@@ -460,7 +467,24 @@ template <class T> class Persistent : public Handle<T> {
    */
   Persistent() {}
   ~Persistent() {
-      HandleOperations<T>::unProtect(this);
+      HandleOperations<T>::unProtect(m_memoryManager, this);
+  }
+
+  Persistent(const Persistent &other)
+      : Handle<T>(other)
+      , m_memoryManager(other.m_memoryManager)
+  {
+      HandleOperations<T>::protect(m_memoryManager, this);
+  }
+
+  Persistent &operator =(const Persistent &other)
+  {
+      if (&other == this)
+          return *this;
+      HandleOperations<T>::unProtect(m_memoryManager, this);
+      Handle<T>::operator =(other);
+      m_memoryManager = other.m_memoryManager;
+      HandleOperations<T>::protect(m_memoryManager, this);
   }
 
   /**
@@ -476,12 +500,13 @@ template <class T> class Persistent : public Handle<T> {
    */
   template <class S> Persistent(Persistent<S> that)
       : Handle<T>(Handle<T>::Cast(that)) {
-      HandleOperations<T>::protect(this);
+      m_memoryManager = that.m_memoryManager;
+      HandleOperations<T>::protect(m_memoryManager, this);
   }
 
   template <class S> Persistent(S* that) : Handle<T>(that)
   {
-      HandleOperations<T>::protect(this);
+      m_memoryManager = HandleOperations<T>::protect(this);
   }
 
   /**
@@ -491,7 +516,7 @@ template <class T> class Persistent : public Handle<T> {
   template <class S> explicit Persistent(Handle<S> that)
       : Handle<T>(*that)
   {
-      HandleOperations<T>::protect(this);
+      m_memoryManager = HandleOperations<T>::protect(this);
   }
 
   template <class S> static Persistent<T> Cast(Persistent<S> that) {
@@ -510,7 +535,7 @@ template <class T> class Persistent : public Handle<T> {
   {
       Persistent<T> result;
       result.Handle<T>::operator =(that);
-      HandleOperations<T>::protect(&result);
+      result.m_memoryManager = HandleOperations<T>::protect(&result);
       return result;
   }
 
@@ -521,7 +546,8 @@ template <class T> class Persistent : public Handle<T> {
    * cell remain and IsEmpty will still return false.
    */
   void Dispose() {
-       HandleOperations<T>::unProtect(this);
+       HandleOperations<T>::unProtect(m_memoryManager, this);
+       m_memoryManager = 0;
        HandleOperations<T>::deref(this);
        HandleOperations<T>::init(this);
   }
@@ -537,6 +563,8 @@ template <class T> class Persistent : public Handle<T> {
    * it the object reference and the given parameters.
    */
   void MakeWeak(void* parameters, WeakReferenceCallback callback);
+public:
+  void *m_memoryManager;
 };