Fix missing object markings in QV4::Script
authorSimon Hausmann <simon.hausmann@digia.com>
Sat, 1 Jun 2013 13:08:17 +0000 (15:08 +0200)
committerLars Knoll <lars.knoll@digia.com>
Sun, 2 Jun 2013 13:13:39 +0000 (15:13 +0200)
Store the qml activation object as Persistent value, as the script object is
often stored on the heap. Also make sure to mark it in QmlBindingWrapper. Fixes
various valgrind errors in tst_qqmlecmascript.

Change-Id: I7edf1e18db0e6a5ab9dcbfd57e258d72fe62cd77
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
src/qml/qml/qqmlvme.cpp
src/qml/qml/v4/qv4script.cpp
src/qml/qml/v4/qv4script_p.h

index 1fc9a7e..f12f5dd 100644 (file)
@@ -1159,7 +1159,7 @@ QV4::PersistentValue QQmlVME::run(QQmlContextData *parentCtxt, QQmlScriptData *s
 
     QV4::ExecutionContext *ctx = QV8Engine::getV4(v8engine)->current;
     try {
-        script->m_program->qml = qmlglobal.asObject();
+        script->m_program->qml = qmlglobal;
         script->m_program->run();
     } catch (QV4::Exception &e) {
         e.accept(ctx);
index 0d629e2..c0e2495 100644 (file)
@@ -72,6 +72,13 @@ struct QmlBindingWrapper : FunctionObject
     }
 
     static Value call(Managed *that, ExecutionContext *, const Value &, Value *, int);
+    static void markObjects(Managed *m)
+    {
+        QmlBindingWrapper *wrapper = static_cast<QmlBindingWrapper*>(m);
+        if (wrapper->qml)
+            wrapper->qml->mark();
+        FunctionObject::markObjects(m);
+    }
 
 protected:
     static const ManagedVTable static_vtbl;
@@ -177,7 +184,7 @@ Value Script::run()
     if (engine->debugger)
         engine->debugger->aboutToCall(0, scope);
 
-    if (!qml) {
+    if (qml.isEmpty()) {
         TemporaryAssignment<Function*> savedGlobalCode(engine->globalCode, vmFunction);
 
         bool strict = scope->strictMode;
@@ -203,7 +210,7 @@ Value Script::run()
         return result;
 
     } else {
-        FunctionObject *f = new (engine->memoryManager) QmlBindingWrapper(scope, vmFunction, qml);
+        FunctionObject *f = new (engine->memoryManager) QmlBindingWrapper(scope, vmFunction, qml.value().asObject());
         return f->call(Value::undefinedValue(), 0, 0);
     }
 }
@@ -220,7 +227,7 @@ Value Script::qmlBinding()
     if (!parsed)
         parse();
     QV4::ExecutionEngine *v4 = scope->engine;
-    return Value::fromObject(new (v4->memoryManager) QmlBindingWrapper(scope, vmFunction, qml));
+    return Value::fromObject(new (v4->memoryManager) QmlBindingWrapper(scope, vmFunction, qml.value().asObject()));
 }
 
 QV4::Value Script::evaluate(ExecutionEngine *engine,  const QString &script, Object *scopeObject)
index 53eeda0..388d0fa 100644 (file)
@@ -53,12 +53,12 @@ struct ExecutionContext;
 struct Q_QML_EXPORT Script {
     Script(ExecutionContext *scope, const QString &sourceCode, const QString &source = QString(), int line = 1, int column = 0)
         : sourceFile(source), line(line), column(column), sourceCode(sourceCode)
-        , scope(scope), strictMode(false), inheritContext(false), parsed(false), qml(0)
+        , scope(scope), strictMode(false), inheritContext(false), parsed(false)
         , vmFunction(0) {}
     Script(ExecutionEngine *engine, Object *qml, const QString &sourceCode, const QString &source = QString(), int line = 1, int column = 0)
         : sourceFile(source), line(line), column(column), sourceCode(sourceCode)
         , scope(engine->rootContext), strictMode(true), inheritContext(true), parsed(false)
-        , qml(qml), vmFunction(0) {}
+        , qml(Value::fromObject(qml)), vmFunction(0) {}
     QString sourceFile;
     int line;
     int column;
@@ -67,7 +67,7 @@ struct Q_QML_EXPORT Script {
     bool strictMode;
     bool inheritContext;
     bool parsed;
-    Object *qml;
+    QV4::PersistentValue qml;
     Function *vmFunction;
 
     void parse();