Convert methods in RuntimeHelpers to take an engine pointer
authorLars Knoll <lars.knoll@theqtcompany.com>
Fri, 7 Nov 2014 17:51:19 +0000 (18:51 +0100)
committerSimon Hausmann <simon.hausmann@digia.com>
Wed, 12 Nov 2014 11:13:26 +0000 (12:13 +0100)
This is safer and cleaner than to use a context pointer.

Change-Id: Id5ef4e6667571897cd029125a0bdc18ce299da6d
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
12 files changed:
src/qml/jsruntime/qv4dateobject.cpp
src/qml/jsruntime/qv4jsonobject.cpp
src/qml/jsruntime/qv4lookup.cpp
src/qml/jsruntime/qv4numberobject.cpp
src/qml/jsruntime/qv4object_p.h
src/qml/jsruntime/qv4objectproto.cpp
src/qml/jsruntime/qv4regexpobject.cpp
src/qml/jsruntime/qv4runtime.cpp
src/qml/jsruntime/qv4runtime_p.h
src/qml/jsruntime/qv4stringobject.cpp
src/qml/jsruntime/qv4value.cpp
src/qml/jsruntime/qv4value_p.h

index 749574f..26004b5 100644 (file)
@@ -1298,7 +1298,7 @@ ReturnedValue DatePrototype::method_toISOString(CallContext *ctx)
 ReturnedValue DatePrototype::method_toJSON(CallContext *ctx)
 {
     Scope scope(ctx);
-    ScopedValue O(scope, RuntimeHelpers::toObject(ctx, ValueRef(&ctx->d()->callData->thisObject)));
+    ScopedValue O(scope, RuntimeHelpers::toObject(scope.engine, ValueRef(&ctx->d()->callData->thisObject)));
     ScopedValue tv(scope, RuntimeHelpers::toPrimitive(O, NUMBER_HINT));
 
     if (tv->isNumber() && !std::isfinite(tv->toNumber()))
index 4d8f96c..000ed32 100644 (file)
@@ -921,7 +921,7 @@ ReturnedValue JsonObject::method_stringify(CallContext *ctx)
             for (uint i = 0; i < arrayLen; ++i) {
                 v = o->getIndexed(i);
                 if (v->asNumberObject() || v->asStringObject() || v->isNumber())
-                    v = RuntimeHelpers::toString(ctx, v);
+                    v = RuntimeHelpers::toString(scope.engine, v);
                 if (v->isString()) {
                     String *s = v->stringValue();
                     if (!stringify.propertyList.contains(s))
index 258f03c..2435c9b 100644 (file)
@@ -133,7 +133,7 @@ ReturnedValue Lookup::indexedGetterFallback(Lookup *l, const ValueRef object, co
             return ctx->engine()->throwTypeError(message);
         }
 
-        o = RuntimeHelpers::convertToObject(ctx, object);
+        o = RuntimeHelpers::convertToObject(scope.engine, object);
         if (!o) // type error
             return Encode::undefined();
     }
@@ -701,7 +701,7 @@ void Lookup::setterGeneric(Lookup *l, const ValueRef object, const ValueRef valu
     Scope scope(l->name->engine());
     ScopedObject o(scope, object);
     if (!o) {
-        o = RuntimeHelpers::convertToObject(scope.engine->currentContext(), object);
+        o = RuntimeHelpers::convertToObject(scope.engine, object);
         if (!o) // type error
             return;
         ScopedString s(scope, l->name);
index 1cb2409..99028e7 100644 (file)
@@ -207,7 +207,7 @@ ReturnedValue NumberPrototype::method_toFixed(CallContext *ctx)
     else if (v < 1.e21)
         str = QString::number(v, 'f', int (fdigits));
     else
-        return RuntimeHelpers::stringFromNumber(ctx, v)->asReturnedValue();
+        return RuntimeHelpers::stringFromNumber(ctx->engine(), v)->asReturnedValue();
     return ctx->d()->engine->newString(str)->asReturnedValue();
 }
 
@@ -244,7 +244,7 @@ ReturnedValue NumberPrototype::method_toPrecision(CallContext *ctx)
         return Encode::undefined();
 
     if (!ctx->d()->callData->argc || ctx->d()->callData->args[0].isUndefined())
-        return RuntimeHelpers::toString(ctx, v);
+        return RuntimeHelpers::toString(scope.engine, v);
 
     double precision = ctx->d()->callData->args[0].toInt32();
     if (precision < 1 || precision > 21) {
index 5f2a224..3b1c4b7 100644 (file)
@@ -400,7 +400,7 @@ inline ArrayObject *value_cast(const Value &v) {
 template<>
 inline ReturnedValue value_convert<Object>(ExecutionEngine *e, const Value &v)
 {
-    return v.toObject(e->currentContext())->asReturnedValue();
+    return v.toObject(e)->asReturnedValue();
 }
 #endif
 
index f3d8aff..686d178 100644 (file)
@@ -67,14 +67,14 @@ ReturnedValue ObjectCtor::construct(Managed *that, CallData *callData)
             obj->setPrototype(proto.getPointer());
         return obj.asReturnedValue();
     }
-    return RuntimeHelpers::toObject(v4->currentContext(), ValueRef(&callData->args[0]));
+    return RuntimeHelpers::toObject(scope.engine, ValueRef(&callData->args[0]));
 }
 
 ReturnedValue ObjectCtor::call(Managed *m, CallData *callData)
 {
     if (!callData->argc || callData->args[0].isUndefined() || callData->args[0].isNull())
         return m->engine()->newObject()->asReturnedValue();
-    return RuntimeHelpers::toObject(m->engine()->currentContext(), ValueRef(&callData->args[0]));
+    return RuntimeHelpers::toObject(m->engine(), ValueRef(&callData->args[0]));
 }
 
 void ObjectPrototype::init(ExecutionEngine *v4, Object *ctor)
@@ -393,7 +393,7 @@ ReturnedValue ObjectPrototype::method_toString(CallContext *ctx)
     } else if (ctx->d()->callData->thisObject.isNull()) {
         return ctx->d()->engine->newString(QStringLiteral("[object Null]"))->asReturnedValue();
     } else {
-        ScopedObject obj(scope, RuntimeHelpers::toObject(ctx, ValueRef(&ctx->d()->callData->thisObject)));
+        ScopedObject obj(scope, RuntimeHelpers::toObject(scope.engine, ValueRef(&ctx->d()->callData->thisObject)));
         QString className = obj->className();
         return ctx->d()->engine->newString(QString::fromLatin1("[object %1]").arg(className))->asReturnedValue();
     }
index 85ab712..a1a0104 100644 (file)
@@ -269,7 +269,7 @@ ReturnedValue RegExpCtor::construct(Managed *m, CallData *callData)
     bool ignoreCase = false;
     bool multiLine = false;
     if (!f->isUndefined()) {
-        f = RuntimeHelpers::toString(ctx, f);
+        f = RuntimeHelpers::toString(scope.engine, f);
         if (scope.hasException())
             return Encode::undefined();
         QString str = f->stringValue()->toQString();
@@ -356,7 +356,7 @@ ReturnedValue RegExpPrototype::method_exec(CallContext *ctx)
         return ctx->engine()->throwTypeError();
 
     ScopedValue arg(scope, ctx->argument(0));
-    arg = RuntimeHelpers::toString(ctx, arg);
+    arg = RuntimeHelpers::toString(scope.engine, arg);
     if (scope.hasException())
         return Encode::undefined();
     QString s = arg->stringValue()->toQString();
index 6dca0c8..bb70203 100644 (file)
@@ -359,11 +359,11 @@ double RuntimeHelpers::stringToNumber(const QString &string)
     return d;
 }
 
-Returned<String> *RuntimeHelpers::stringFromNumber(ExecutionContext *ctx, double number)
+Returned<String> *RuntimeHelpers::stringFromNumber(ExecutionEngine *engine, double number)
 {
     QString qstr;
     RuntimeHelpers::numberToString(&qstr, number, 10);
-    return ctx->engine()->newString(qstr);
+    return engine->newString(qstr);
 }
 
 ReturnedValue RuntimeHelpers::objectDefaultValue(Object *object, int typeHint)
@@ -412,103 +412,103 @@ ReturnedValue RuntimeHelpers::objectDefaultValue(Object *object, int typeHint)
 
 
 
-Returned<Object> *RuntimeHelpers::convertToObject(ExecutionContext *ctx, const ValueRef value)
+Returned<Object> *RuntimeHelpers::convertToObject(ExecutionEngine *engine, const ValueRef value)
 {
-    assert(!value->isObject());
+    Q_ASSERT(!value->isObject());
     switch (value->type()) {
     case Value::Undefined_Type:
     case Value::Null_Type:
-        ctx->engine()->throwTypeError();
+        engine->throwTypeError();
         return 0;
     case Value::Boolean_Type:
-        return ctx->engine()->newBooleanObject(value);
+        return engine->newBooleanObject(value);
     case Value::Managed_Type:
         Q_ASSERT(value->isString());
-        return ctx->engine()->newStringObject(value);
+        return engine->newStringObject(value);
     case Value::Integer_Type:
     default: // double
-        return ctx->engine()->newNumberObject(value);
+        return engine->newNumberObject(value);
     }
 }
 
-Returned<String> *RuntimeHelpers::convertToString(ExecutionContext *ctx, const ValueRef value)
+Returned<String> *RuntimeHelpers::convertToString(ExecutionEngine *engine, const ValueRef value)
 {
     switch (value->type()) {
     case Value::Empty_Type:
         Q_ASSERT(!"empty Value encountered");
     case Value::Undefined_Type:
-        return ctx->engine()->id_undefined.ret();
+        return engine->id_undefined.ret();
     case Value::Null_Type:
-        return ctx->engine()->id_null.ret();
+        return engine->id_null.ret();
     case Value::Boolean_Type:
         if (value->booleanValue())
-            return ctx->engine()->id_true.ret();
+            return engine->id_true.ret();
         else
-            return ctx->engine()->id_false.ret();
+            return engine->id_false.ret();
     case Value::Managed_Type:
         if (value->isString())
             return value->stringValue()->asReturned<String>();
         {
-            Scope scope(ctx);
+            Scope scope(engine);
             ScopedValue prim(scope, RuntimeHelpers::toPrimitive(value, STRING_HINT));
-            return RuntimeHelpers::convertToString(ctx, prim);
+            return RuntimeHelpers::convertToString(engine, prim);
         }
     case Value::Integer_Type:
-        return RuntimeHelpers::stringFromNumber(ctx, value->int_32);
+        return RuntimeHelpers::stringFromNumber(engine, value->int_32);
     default: // double
-        return RuntimeHelpers::stringFromNumber(ctx, value->doubleValue());
+        return RuntimeHelpers::stringFromNumber(engine, value->doubleValue());
     } // switch
 }
 
 // This is slightly different from the method above, as
 // the + operator requires a slightly different conversion
-static Returned<String> *convert_to_string_add(ExecutionContext *ctx, const ValueRef value)
+static Returned<String> *convert_to_string_add(ExecutionEngine *engine, const ValueRef value)
 {
     switch (value->type()) {
     case Value::Empty_Type:
         Q_ASSERT(!"empty Value encountered");
     case Value::Undefined_Type:
-        return ctx->engine()->id_undefined.ret();
+        return engine->id_undefined.ret();
     case Value::Null_Type:
-        return ctx->engine()->id_null.ret();
+        return engine->id_null.ret();
     case Value::Boolean_Type:
         if (value->booleanValue())
-            return ctx->engine()->id_true.ret();
+            return engine->id_true.ret();
         else
-            return ctx->engine()->id_false.ret();
+            return engine->id_false.ret();
     case Value::Managed_Type:
         if (value->isString())
             return value->stringValue()->asReturned<String>();
         {
-            Scope scope(ctx);
+            Scope scope(engine);
             ScopedValue prim(scope, RuntimeHelpers::toPrimitive(value, PREFERREDTYPE_HINT));
-            return RuntimeHelpers::convertToString(ctx, prim);
+            return RuntimeHelpers::convertToString(engine, prim);
         }
     case Value::Integer_Type:
-        return RuntimeHelpers::stringFromNumber(ctx, value->int_32);
+        return RuntimeHelpers::stringFromNumber(engine, value->int_32);
     default: // double
-        return RuntimeHelpers::stringFromNumber(ctx, value->doubleValue());
+        return RuntimeHelpers::stringFromNumber(engine, value->doubleValue());
     } // switch
 }
 
-QV4::ReturnedValue RuntimeHelpers::addHelper(ExecutionContext *ctx, const ValueRef left, const ValueRef right)
+QV4::ReturnedValue RuntimeHelpers::addHelper(ExecutionEngine *engine, const ValueRef left, const ValueRef right)
 {
-    Scope scope(ctx);
+    Scope scope(engine);
 
     ScopedValue pleft(scope, RuntimeHelpers::toPrimitive(left, PREFERREDTYPE_HINT));
     ScopedValue pright(scope, RuntimeHelpers::toPrimitive(right, PREFERREDTYPE_HINT));
     if (pleft->isString() || pright->isString()) {
         if (!pleft->isString())
-            pleft = convert_to_string_add(ctx, pleft);
+            pleft = convert_to_string_add(engine, pleft);
         if (!pright->isString())
-            pright = convert_to_string_add(ctx, pright);
+            pright = convert_to_string_add(engine, pright);
         if (scope.engine->hasException)
             return Encode::undefined();
         if (!pleft->stringValue()->d()->length())
             return pright->asReturnedValue();
         if (!pright->stringValue()->d()->length())
             return pleft->asReturnedValue();
-        return (ctx->engine()->memoryManager->alloc<String>(ctx->d()->engine, pleft->stringValue()->d(), pright->stringValue()->d()))->asReturnedValue();
+        return (engine->memoryManager->alloc<String>(engine, pleft->stringValue()->d(), pright->stringValue()->d()))->asReturnedValue();
     }
     double x = RuntimeHelpers::toNumber(pleft);
     double y = RuntimeHelpers::toNumber(pright);
@@ -532,9 +532,9 @@ QV4::ReturnedValue Runtime::addString(QV4::ExecutionContext *ctx, const QV4::Val
     ScopedValue pright(scope, *right);
 
     if (!pleft->isString())
-        pleft = convert_to_string_add(ctx, left);
+        pleft = convert_to_string_add(ctx->engine(), left);
     if (!pright->isString())
-        pright = convert_to_string_add(ctx, right);
+        pright = convert_to_string_add(ctx->engine(), right);
     if (scope.engine->hasException)
         return Encode::undefined();
     if (!pleft->stringValue()->d()->length())
@@ -575,7 +575,7 @@ ReturnedValue Runtime::getElement(ExecutionContext *ctx, const ValueRef object,
             return ctx->engine()->throwTypeError(message);
         }
 
-        o = RuntimeHelpers::convertToObject(ctx, object);
+        o = RuntimeHelpers::convertToObject(scope.engine, object);
         if (!o) // type error
             return Encode::undefined();
     }
@@ -658,7 +658,7 @@ ReturnedValue Runtime::getProperty(ExecutionContext *ctx, const ValueRef object,
         return ctx->engine()->throwTypeError(message);
     }
 
-    o = RuntimeHelpers::convertToObject(ctx, object);
+    o = RuntimeHelpers::convertToObject(scope.engine, object);
     if (!o) // type error
         return Encode::undefined();
     return o->get(name);
@@ -936,7 +936,7 @@ ReturnedValue Runtime::callProperty(ExecutionContext *context, String *name, Cal
             return context->engine()->throwTypeError(message);
         }
 
-        baseObject = RuntimeHelpers::convertToObject(context, ValueRef(&callData->thisObject));
+        baseObject = RuntimeHelpers::convertToObject(scope.engine, ValueRef(&callData->thisObject));
         if (!baseObject) // type error
             return Encode::undefined();
         callData->thisObject = baseObject.asReturnedValue();
@@ -1237,19 +1237,19 @@ QV4::ReturnedValue Runtime::decrement(const QV4::ValueRef value)
 
 #ifndef V4_BOOTSTRAP
 
-QV4::ReturnedValue RuntimeHelpers::toString(QV4::ExecutionContext *ctx, const QV4::ValueRef value)
+QV4::ReturnedValue RuntimeHelpers::toString(ExecutionEngine *engine, const QV4::ValueRef value)
 {
     if (value->isString())
         return value.asReturnedValue();
-    return RuntimeHelpers::convertToString(ctx, value)->asReturnedValue();
+    return RuntimeHelpers::convertToString(engine, value)->asReturnedValue();
 }
 
-QV4::ReturnedValue RuntimeHelpers::toObject(QV4::ExecutionContext *ctx, const QV4::ValueRef value)
+QV4::ReturnedValue RuntimeHelpers::toObject(ExecutionEngine *engine, const QV4::ValueRef value)
 {
     if (value->isObject())
         return value.asReturnedValue();
 
-    Returned<Object> *o = RuntimeHelpers::convertToObject(ctx, value);
+    Returned<Object> *o = RuntimeHelpers::convertToObject(engine, value);
     if (!o) // type error
         return Encode::undefined();
 
index f69ea16..3ba8a78 100644 (file)
@@ -221,20 +221,20 @@ struct Q_QML_PRIVATE_EXPORT RuntimeHelpers {
     static ReturnedValue toPrimitive(const ValueRef value, int typeHint);
 
     static double stringToNumber(const QString &s);
-    static Returned<String> *stringFromNumber(ExecutionContext *ctx, double number);
+    static Returned<String> *stringFromNumber(ExecutionEngine *engine, double number);
     static double toNumber(const ValueRef value);
     static void numberToString(QString *result, double num, int radix = 10);
 
-    static ReturnedValue toString(ExecutionContext *ctx, const ValueRef value);
-    static Returned<String> *convertToString(ExecutionContext *ctx, const ValueRef value);
+    static ReturnedValue toString(ExecutionEngine *engine, const ValueRef value);
+    static Returned<String> *convertToString(ExecutionEngine *engine, const ValueRef value);
 
-    static ReturnedValue toObject(ExecutionContext *ctx, const ValueRef value);
-    static Returned<Object> *convertToObject(ExecutionContext *ctx, const ValueRef value);
+    static ReturnedValue toObject(ExecutionEngine *engine, const ValueRef value);
+    static Returned<Object> *convertToObject(ExecutionEngine *engine, const ValueRef value);
 
     static Bool equalHelper(const ValueRef x, const ValueRef y);
     static Bool strictEqual(const ValueRef x, const ValueRef y);
 
-    static ReturnedValue addHelper(ExecutionContext *ctx, const ValueRef left, const ValueRef right);
+    static ReturnedValue addHelper(ExecutionEngine *engine, const ValueRef left, const ValueRef right);
 };
 
 
@@ -334,7 +334,7 @@ inline ReturnedValue Runtime::add(ExecutionContext *ctx, const ValueRef left, co
     if (left->isNumber() && right->isNumber())
         return Primitive::fromDouble(left->asDouble() + right->asDouble()).asReturnedValue();
 
-    return RuntimeHelpers::addHelper(ctx, left, right);
+    return RuntimeHelpers::addHelper(ctx->engine(), left, right);
 }
 #endif // V4_BOOTSTRAP
 
index 95fb6e3..57c1239 100644 (file)
@@ -291,7 +291,7 @@ ReturnedValue StringPrototype::method_concat(CallContext *context)
 
     ScopedValue v(scope);
     for (int i = 0; i < context->d()->callData->argc; ++i) {
-        v = RuntimeHelpers::toString(context, ValueRef(&context->d()->callData->args[i]));
+        v = RuntimeHelpers::toString(scope.engine, ValueRef(&context->d()->callData->args[i]));
         if (scope.hasException())
             return Encode::undefined();
         Q_ASSERT(v->isString());
index e4f84b2..004f7cb 100644 (file)
@@ -269,21 +269,26 @@ double Primitive::toInteger(double number)
 #ifndef V4_BOOTSTRAP
 String *Value::toString(ExecutionEngine *e) const
 {
-    return toString(e->currentContext());
+    if (isString())
+        return stringValue();
+    return RuntimeHelpers::convertToString(e, ValueRef::fromRawValue(this))->getPointer();
 }
 
 String *Value::toString(ExecutionContext *ctx) const
 {
-    if (isString())
-        return stringValue();
-    return RuntimeHelpers::convertToString(ctx, ValueRef::fromRawValue(this))->getPointer();
+    return toString(ctx->engine());
 }
 
-Object *Value::toObject(ExecutionContext *ctx) const
+Object *Value::toObject(ExecutionEngine *e) const
 {
     if (isObject())
         return objectValue();
-    return RuntimeHelpers::convertToObject(ctx, ValueRef::fromRawValue(this))->getPointer();
+    return RuntimeHelpers::convertToObject(e, ValueRef::fromRawValue(this))->getPointer();
+}
+
+Object *Value::toObject(ExecutionContext *ctx) const
+{
+    return toObject(ctx->engine());
 }
 
 #endif // V4_BOOTSTRAP
index d948659..6f62b1c 100644 (file)
@@ -345,6 +345,7 @@ struct Q_QML_PRIVATE_EXPORT Value
     QString toQString() const;
     String *toString(ExecutionEngine *e) const;
     String *toString(ExecutionContext *ctx) const;
+    Object *toObject(ExecutionEngine *e) const;
     Object *toObject(ExecutionContext *ctx) const;
 
     inline bool isPrimitive() const;