From 31084c37f60a54d0d1ab2e07a79e070268540498 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 7 Nov 2014 18:51:19 +0100 Subject: [PATCH] Convert methods in RuntimeHelpers to take an engine pointer This is safer and cleaner than to use a context pointer. Change-Id: Id5ef4e6667571897cd029125a0bdc18ce299da6d Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4dateobject.cpp | 2 +- src/qml/jsruntime/qv4jsonobject.cpp | 2 +- src/qml/jsruntime/qv4lookup.cpp | 4 +- src/qml/jsruntime/qv4numberobject.cpp | 4 +- src/qml/jsruntime/qv4object_p.h | 2 +- src/qml/jsruntime/qv4objectproto.cpp | 6 +-- src/qml/jsruntime/qv4regexpobject.cpp | 4 +- src/qml/jsruntime/qv4runtime.cpp | 80 +++++++++++++++++------------------ src/qml/jsruntime/qv4runtime_p.h | 14 +++--- src/qml/jsruntime/qv4stringobject.cpp | 2 +- src/qml/jsruntime/qv4value.cpp | 17 +++++--- src/qml/jsruntime/qv4value_p.h | 1 + 12 files changed, 72 insertions(+), 66 deletions(-) diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp index 749574f..26004b5 100644 --- a/src/qml/jsruntime/qv4dateobject.cpp +++ b/src/qml/jsruntime/qv4dateobject.cpp @@ -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())) diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp index 4d8f96c..000ed32 100644 --- a/src/qml/jsruntime/qv4jsonobject.cpp +++ b/src/qml/jsruntime/qv4jsonobject.cpp @@ -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)) diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp index 258f03c..2435c9b 100644 --- a/src/qml/jsruntime/qv4lookup.cpp +++ b/src/qml/jsruntime/qv4lookup.cpp @@ -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); diff --git a/src/qml/jsruntime/qv4numberobject.cpp b/src/qml/jsruntime/qv4numberobject.cpp index 1cb2409..99028e7 100644 --- a/src/qml/jsruntime/qv4numberobject.cpp +++ b/src/qml/jsruntime/qv4numberobject.cpp @@ -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) { diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index 5f2a224..3b1c4b7 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -400,7 +400,7 @@ inline ArrayObject *value_cast(const Value &v) { template<> inline ReturnedValue value_convert(ExecutionEngine *e, const Value &v) { - return v.toObject(e->currentContext())->asReturnedValue(); + return v.toObject(e)->asReturnedValue(); } #endif diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp index f3d8aff..686d178 100644 --- a/src/qml/jsruntime/qv4objectproto.cpp +++ b/src/qml/jsruntime/qv4objectproto.cpp @@ -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(); } diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp index 85ab712..a1a0104 100644 --- a/src/qml/jsruntime/qv4regexpobject.cpp +++ b/src/qml/jsruntime/qv4regexpobject.cpp @@ -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(); diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index 6dca0c8..bb70203 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -359,11 +359,11 @@ double RuntimeHelpers::stringToNumber(const QString &string) return d; } -Returned *RuntimeHelpers::stringFromNumber(ExecutionContext *ctx, double number) +Returned *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 *RuntimeHelpers::convertToObject(ExecutionContext *ctx, const ValueRef value) +Returned *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 *RuntimeHelpers::convertToString(ExecutionContext *ctx, const ValueRef value) +Returned *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(); { - 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 *convert_to_string_add(ExecutionContext *ctx, const ValueRef value) +static Returned *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(); { - 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(ctx->d()->engine, pleft->stringValue()->d(), pright->stringValue()->d()))->asReturnedValue(); + return (engine->memoryManager->alloc(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 *o = RuntimeHelpers::convertToObject(ctx, value); + Returned *o = RuntimeHelpers::convertToObject(engine, value); if (!o) // type error return Encode::undefined(); diff --git a/src/qml/jsruntime/qv4runtime_p.h b/src/qml/jsruntime/qv4runtime_p.h index f69ea16..3ba8a78 100644 --- a/src/qml/jsruntime/qv4runtime_p.h +++ b/src/qml/jsruntime/qv4runtime_p.h @@ -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 *stringFromNumber(ExecutionContext *ctx, double number); + static Returned *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 *convertToString(ExecutionContext *ctx, const ValueRef value); + static ReturnedValue toString(ExecutionEngine *engine, const ValueRef value); + static Returned *convertToString(ExecutionEngine *engine, const ValueRef value); - static ReturnedValue toObject(ExecutionContext *ctx, const ValueRef value); - static Returned *convertToObject(ExecutionContext *ctx, const ValueRef value); + static ReturnedValue toObject(ExecutionEngine *engine, const ValueRef value); + static Returned *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 diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp index 95fb6e3..57c1239 100644 --- a/src/qml/jsruntime/qv4stringobject.cpp +++ b/src/qml/jsruntime/qv4stringobject.cpp @@ -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()); diff --git a/src/qml/jsruntime/qv4value.cpp b/src/qml/jsruntime/qv4value.cpp index e4f84b2..004f7cb 100644 --- a/src/qml/jsruntime/qv4value.cpp +++ b/src/qml/jsruntime/qv4value.cpp @@ -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 diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h index d948659..6f62b1c 100644 --- a/src/qml/jsruntime/qv4value_p.h +++ b/src/qml/jsruntime/qv4value_p.h @@ -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; -- 2.7.4