diff options
25 files changed, 177 insertions, 121 deletions
diff --git a/src/qml/jsruntime/qv4argumentsobject_p.h b/src/qml/jsruntime/qv4argumentsobject_p.h index dec2f25c01..7862a602bd 100644 --- a/src/qml/jsruntime/qv4argumentsobject_p.h +++ b/src/qml/jsruntime/qv4argumentsobject_p.h @@ -50,32 +50,29 @@ namespace QV4 { struct ArgumentsGetterFunction: FunctionObject { + Q_MANAGED uint index; ArgumentsGetterFunction(ExecutionContext *scope, uint index) : FunctionObject(scope), index(index) { vtbl = &static_vtbl; } static ReturnedValue call(Managed *that, CallData *d); - -protected: - static const ManagedVTable static_vtbl; }; struct ArgumentsSetterFunction: FunctionObject { + Q_MANAGED uint index; ArgumentsSetterFunction(ExecutionContext *scope, uint index) : FunctionObject(scope), index(index) { vtbl = &static_vtbl; } static ReturnedValue call(Managed *that, CallData *callData); - -protected: - static const ManagedVTable static_vtbl; }; struct ArgumentsObject: Object { + Q_MANAGED CallContext *context; QVector<Value> mappedArguments; ArgumentsObject(CallContext *context); @@ -90,7 +87,6 @@ struct ArgumentsObject: Object { static void markObjects(Managed *that); protected: - static const ManagedVTable static_vtbl; static void destroy(Managed *); }; diff --git a/src/qml/jsruntime/qv4arrayobject_p.h b/src/qml/jsruntime/qv4arrayobject_p.h index 6bf9fcd409..a38a87f1f3 100644 --- a/src/qml/jsruntime/qv4arrayobject_p.h +++ b/src/qml/jsruntime/qv4arrayobject_p.h @@ -51,13 +51,11 @@ namespace QV4 { struct ArrayCtor: FunctionObject { + Q_MANAGED ArrayCtor(ExecutionContext *scope); static ReturnedValue construct(Managed *m, CallData *callData); static ReturnedValue call(Managed *that, CallData *callData); - -protected: - static const ManagedVTable static_vtbl; }; struct ArrayPrototype: ArrayObject diff --git a/src/qml/jsruntime/qv4booleanobject.cpp b/src/qml/jsruntime/qv4booleanobject.cpp index 6fb21433d6..86ddebd6c3 100644 --- a/src/qml/jsruntime/qv4booleanobject.cpp +++ b/src/qml/jsruntime/qv4booleanobject.cpp @@ -54,13 +54,13 @@ BooleanCtor::BooleanCtor(ExecutionContext *scope) ReturnedValue BooleanCtor::construct(Managed *m, CallData *callData) { bool n = callData->argc ? callData->args[0].toBoolean() : false; - return Value::fromObject(m->engine()->newBooleanObject(Value::fromBoolean(n))).asReturnedValue(); + return Encode(m->engine()->newBooleanObject(Value::fromBoolean(n))); } ReturnedValue BooleanCtor::call(Managed *, CallData *callData) { bool value = callData->argc ? callData->args[0].toBoolean() : 0; - return Value::fromBoolean(value).asReturnedValue(); + return Encode(value); } void BooleanPrototype::init(ExecutionContext *ctx, const Value &ctor) diff --git a/src/qml/jsruntime/qv4booleanobject_p.h b/src/qml/jsruntime/qv4booleanobject_p.h index db4dc881c1..ef74834a5c 100644 --- a/src/qml/jsruntime/qv4booleanobject_p.h +++ b/src/qml/jsruntime/qv4booleanobject_p.h @@ -51,13 +51,11 @@ namespace QV4 { struct BooleanCtor: FunctionObject { + Q_MANAGED BooleanCtor(ExecutionContext *scope); static ReturnedValue construct(Managed *, CallData *callData); static ReturnedValue call(Managed *that, CallData *callData); - -protected: - static const ManagedVTable static_vtbl; }; struct BooleanPrototype: BooleanObject diff --git a/src/qml/jsruntime/qv4dateobject_p.h b/src/qml/jsruntime/qv4dateobject_p.h index c405b5d9b5..b0e85606cb 100644 --- a/src/qml/jsruntime/qv4dateobject_p.h +++ b/src/qml/jsruntime/qv4dateobject_p.h @@ -64,13 +64,11 @@ protected: struct DateCtor: FunctionObject { + Q_MANAGED DateCtor(ExecutionContext *scope); static ReturnedValue construct(Managed *, CallData *callData); static ReturnedValue call(Managed *that, CallData *); - -protected: - static const ManagedVTable static_vtbl; }; struct DatePrototype: DateObject diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 3f9b8175bc..1d3087577d 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -381,16 +381,16 @@ Object *ExecutionEngine::newStringObject(const Value &value) return object; } -Object *ExecutionEngine::newNumberObject(const Value &value) +Returned<Object> *ExecutionEngine::newNumberObject(const Value &value) { NumberObject *object = new (memoryManager) NumberObject(this, value); - return object; + return object->asReturned<Object>(); } -Object *ExecutionEngine::newBooleanObject(const Value &value) +Returned<Object> *ExecutionEngine::newBooleanObject(const Value &value) { Object *object = new (memoryManager) BooleanObject(this, value); - return object; + return object->asReturned<Object>(); } ArrayObject *ExecutionEngine::newArrayObject(int count) diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index 60b3ddbf73..4ec4c2dad1 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -271,8 +271,8 @@ struct Q_QML_EXPORT ExecutionEngine String *newIdentifier(const QString &text); Object *newStringObject(const Value &value); - Object *newNumberObject(const Value &value); - Object *newBooleanObject(const Value &value); + Returned<Object> *newNumberObject(const Value &value); + Returned<Object> *newBooleanObject(const Value &value); ArrayObject *newArrayObject(int count = 0); ArrayObject *newArrayObject(const QStringList &list); diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h index d16057b035..73d9362a6d 100644 --- a/src/qml/jsruntime/qv4errorobject_p.h +++ b/src/qml/jsruntime/qv4errorobject_p.h @@ -93,11 +93,9 @@ struct ReferenceErrorObject: ErrorObject { }; struct SyntaxErrorObject: ErrorObject { + Q_MANAGED SyntaxErrorObject(ExecutionEngine *engine, const Value &msg); SyntaxErrorObject(ExecutionEngine *engine, const QString &msg, const QString &fileName, int lineNumber, int columnNumber); - -protected: - static const ManagedVTable static_vtbl; }; struct TypeErrorObject: ErrorObject { @@ -111,74 +109,60 @@ struct URIErrorObject: ErrorObject { struct ErrorCtor: FunctionObject { + Q_MANAGED ErrorCtor(ExecutionContext *scope); ErrorCtor(ExecutionContext *scope, String *name); static ReturnedValue construct(Managed *, CallData *callData); static ReturnedValue call(Managed *that, CallData *callData); - -protected: - static const ManagedVTable static_vtbl; }; struct EvalErrorCtor: ErrorCtor { + Q_MANAGED EvalErrorCtor(ExecutionContext *scope); static ReturnedValue construct(Managed *m, CallData *callData); - -protected: - static const ManagedVTable static_vtbl; }; struct RangeErrorCtor: ErrorCtor { + Q_MANAGED RangeErrorCtor(ExecutionContext *scope); static ReturnedValue construct(Managed *m, CallData *callData); - -protected: - static const ManagedVTable static_vtbl; }; struct ReferenceErrorCtor: ErrorCtor { + Q_MANAGED ReferenceErrorCtor(ExecutionContext *scope); static ReturnedValue construct(Managed *m, CallData *callData); - -protected: - static const ManagedVTable static_vtbl; }; struct SyntaxErrorCtor: ErrorCtor { + Q_MANAGED SyntaxErrorCtor(ExecutionContext *scope); static ReturnedValue construct(Managed *m, CallData *callData); - -protected: - static const ManagedVTable static_vtbl; }; struct TypeErrorCtor: ErrorCtor { + Q_MANAGED TypeErrorCtor(ExecutionContext *scope); static ReturnedValue construct(Managed *m, CallData *callData); - -protected: - static const ManagedVTable static_vtbl; }; struct URIErrorCtor: ErrorCtor { + Q_MANAGED URIErrorCtor(ExecutionContext *scope); static ReturnedValue construct(Managed *m, CallData *callData); - -protected: - static const ManagedVTable static_vtbl; }; diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h index 37f9d0bf46..333b95ad74 100644 --- a/src/qml/jsruntime/qv4functionobject_p.h +++ b/src/qml/jsruntime/qv4functionobject_p.h @@ -93,6 +93,7 @@ struct InternalClass; struct Lookup; struct Q_QML_EXPORT FunctionObject: Object { + Q_MANAGED // Used with Managed::subType enum FunctionType { RegularFunction = 0, @@ -135,7 +136,6 @@ struct Q_QML_EXPORT FunctionObject: Object { protected: FunctionObject(InternalClass *ic); - static const ManagedVTable static_vtbl; static void markObjects(Managed *that); static bool hasInstance(Managed *that, const Value &value); static void destroy(Managed *that) @@ -144,13 +144,11 @@ protected: struct FunctionCtor: FunctionObject { + Q_MANAGED FunctionCtor(ExecutionContext *scope); static ReturnedValue construct(Managed *that, CallData *callData); static ReturnedValue call(Managed *that, CallData *callData); - -protected: - static const ManagedVTable static_vtbl; }; struct FunctionPrototype: FunctionObject @@ -165,15 +163,13 @@ struct FunctionPrototype: FunctionObject }; struct BuiltinFunction: FunctionObject { + Q_MANAGED ReturnedValue (*code)(SimpleCallContext *); BuiltinFunction(ExecutionContext *scope, String *name, ReturnedValue (*code)(SimpleCallContext *)); static ReturnedValue construct(Managed *, CallData *); static ReturnedValue call(Managed *that, CallData *callData); - -protected: - static const ManagedVTable static_vtbl; }; struct IndexedBuiltinFunction: FunctionObject @@ -203,26 +199,23 @@ struct IndexedBuiltinFunction: FunctionObject struct ScriptFunction: FunctionObject { + Q_MANAGED ScriptFunction(ExecutionContext *scope, Function *function); static ReturnedValue construct(Managed *, CallData *callData); static ReturnedValue call(Managed *that, CallData *callData); - -protected: - static const ManagedVTable static_vtbl; }; struct SimpleScriptFunction: FunctionObject { + Q_MANAGED SimpleScriptFunction(ExecutionContext *scope, Function *function); static ReturnedValue construct(Managed *, CallData *callData); static ReturnedValue call(Managed *that, CallData *callData); - -protected: - static const ManagedVTable static_vtbl; }; struct BoundFunction: FunctionObject { + Q_MANAGED FunctionObject *target; Value boundThis; QVector<Value> boundArgs; @@ -234,7 +227,6 @@ struct BoundFunction: FunctionObject { static ReturnedValue construct(Managed *, CallData *d); static ReturnedValue call(Managed *that, CallData *dd); - static const ManagedVTable static_vtbl; static void destroy(Managed *); static void markObjects(Managed *that); static bool hasInstance(Managed *that, const Value &value); diff --git a/src/qml/jsruntime/qv4globalobject_p.h b/src/qml/jsruntime/qv4globalobject_p.h index b9219a210c..90b3395baa 100644 --- a/src/qml/jsruntime/qv4globalobject_p.h +++ b/src/qml/jsruntime/qv4globalobject_p.h @@ -50,15 +50,13 @@ namespace QV4 { struct Q_QML_EXPORT EvalFunction : FunctionObject { + Q_MANAGED EvalFunction(ExecutionContext *scope); ReturnedValue evalCall(Value thisObject, Value *args, int argc, bool directCall); using Managed::construct; static ReturnedValue call(Managed *that, CallData *callData); - -protected: - static const ManagedVTable static_vtbl; }; struct GlobalFunctions diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp index 2b609752c9..a4116b049e 100644 --- a/src/qml/jsruntime/qv4lookup.cpp +++ b/src/qml/jsruntime/qv4lookup.cpp @@ -436,7 +436,7 @@ void Lookup::setterGeneric(Lookup *l, const Value &object, const Value &value) { Object *o = object.asObject(); if (!o) { - o = __qmljs_convert_to_object(l->name->engine()->current, ValueRef::fromRawValue(&object)); + o = __qmljs_convert_to_object(l->name->engine()->current, ValueRef::fromRawValue(&object))->getPointer(); o->put(l->name, value); return; } diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h index df25bab64a..9ea1fe9f80 100644 --- a/src/qml/jsruntime/qv4managed_p.h +++ b/src/qml/jsruntime/qv4managed_p.h @@ -61,10 +61,22 @@ inline int qYouForgotTheQ_MANAGED_Macro(T, T) { return 0; } template <typename T1, typename T2> inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {} +template <typename T> +struct Returned : private T +{ + static Returned<T> *create(T *t) { return static_cast<Returned<T> *>(t); } + T *getPointer() { return this; } + template<typename X> + static T *getPointer(Returned<X> *x) { return x->getPointer(); } +}; + #define Q_MANAGED \ public: \ Q_MANAGED_CHECK \ - static const QV4::ManagedVTable static_vtbl; + static const QV4::ManagedVTable static_vtbl; \ + template <typename T> \ + QV4::Returned<T> *asReturned() { return QV4::Returned<T>::create(this); } \ + struct GCDeletable { @@ -162,6 +174,7 @@ const QV4::ManagedVTable classname::static_vtbl = \ struct Q_QML_EXPORT Managed { + Q_MANAGED private: void *operator new(size_t); Managed(const Managed &other); @@ -319,9 +332,6 @@ public: }; protected: - - static const ManagedVTable static_vtbl; - const ManagedVTable *vtbl; public: InternalClass *internalClass; diff --git a/src/qml/jsruntime/qv4numberobject.cpp b/src/qml/jsruntime/qv4numberobject.cpp index f335e73123..c83d08d450 100644 --- a/src/qml/jsruntime/qv4numberobject.cpp +++ b/src/qml/jsruntime/qv4numberobject.cpp @@ -59,7 +59,7 @@ NumberCtor::NumberCtor(ExecutionContext *scope) ReturnedValue NumberCtor::construct(Managed *m, CallData *callData) { double dbl = callData->argc ? callData->args[0].toNumber() : 0.; - return Value::fromObject(m->engine()->newNumberObject(Value::fromDouble(dbl))).asReturnedValue(); + return Encode(m->engine()->newNumberObject(Value::fromDouble(dbl))); } ReturnedValue NumberCtor::call(Managed *, CallData *callData) diff --git a/src/qml/jsruntime/qv4numberobject_p.h b/src/qml/jsruntime/qv4numberobject_p.h index 6d66a6b1c1..d2c4ce6569 100644 --- a/src/qml/jsruntime/qv4numberobject_p.h +++ b/src/qml/jsruntime/qv4numberobject_p.h @@ -51,13 +51,11 @@ namespace QV4 { struct NumberCtor: FunctionObject { + Q_MANAGED NumberCtor(ExecutionContext *scope); static ReturnedValue construct(Managed *that, CallData *callData); static ReturnedValue call(Managed *, CallData *callData); - -protected: - static const ManagedVTable static_vtbl; }; struct NumberPrototype: NumberObject diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index 5ae167d782..b7b08c2b34 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -105,6 +105,7 @@ typedef Value (*PropertyEnumeratorFunction)(Object *object); typedef PropertyAttributes (*PropertyQueryFunction)(const Object *object, String *name); struct Q_QML_EXPORT Object: Managed { + Q_MANAGED uint memberDataAlloc; Property *memberData; @@ -182,6 +183,9 @@ struct Q_QML_EXPORT Object: Managed { static Object *cast(const Value &v) { return v.asObject(); } + static Value toValue(Object *o) { + return Value::fromObject(o); + } // Array handling @@ -283,7 +287,8 @@ public: void ensureArrayAttributes(); inline bool protoHasArray() { - Object *p = this; + Scope scope(engine()); + Scoped<Object> p(scope, this); while ((p = p->prototype())) if (p->arrayDataLen) @@ -313,7 +318,6 @@ public: using Managed::setLookup; using Managed::advanceIterator; protected: - static const ManagedVTable static_vtbl; static void destroy(Managed *that); static void markObjects(Managed *that); static ReturnedValue get(Managed *m, String *name, bool *hasProperty); diff --git a/src/qml/jsruntime/qv4objectproto_p.h b/src/qml/jsruntime/qv4objectproto_p.h index f9f6853eb9..311d53864f 100644 --- a/src/qml/jsruntime/qv4objectproto_p.h +++ b/src/qml/jsruntime/qv4objectproto_p.h @@ -51,13 +51,11 @@ namespace QV4 { struct ObjectCtor: FunctionObject { + Q_MANAGED ObjectCtor(ExecutionContext *scope); static ReturnedValue construct(Managed *that, CallData *callData); static ReturnedValue call(Managed *that, CallData *callData); - -protected: - static const ManagedVTable static_vtbl; }; struct ObjectPrototype: Object diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 91adf7d3e3..abff3ac93d 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -559,7 +559,7 @@ ReturnedValue QObjectWrapper::wrap(ExecutionEngine *engine, QObject *object) } else { // If this object is tainted, we have to check to see if it is in our // tainted object list - Scoped<Object> alternateWrapper(scope, 0); + Scoped<Object> alternateWrapper(scope, (Object *)0); if (engine->m_multiplyWrappedQObjects && ddata->hasTaintedV8Object) alternateWrapper = Value::fromObject(engine->m_multiplyWrappedQObjects->value(object)); diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h index 65c1f49371..765e98176c 100644 --- a/src/qml/jsruntime/qv4regexpobject_p.h +++ b/src/qml/jsruntime/qv4regexpobject_p.h @@ -103,13 +103,11 @@ protected: struct RegExpCtor: FunctionObject { + Q_MANAGED RegExpCtor(ExecutionContext *scope); static ReturnedValue construct(Managed *m, CallData *callData); static ReturnedValue call(Managed *that, CallData *callData); - -protected: - static const ManagedVTable static_vtbl; }; struct RegExpPrototype: RegExpObject diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index 0a8b1b4055..cfb0a9f4a0 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -598,7 +598,7 @@ Bool __qmljs_to_boolean(const ValueRef value) } -Object *__qmljs_convert_to_object(ExecutionContext *ctx, const ValueRef value) +Returned<Object> *__qmljs_convert_to_object(ExecutionContext *ctx, const ValueRef value) { assert(!value->isObject()); switch (value->type()) { @@ -608,7 +608,7 @@ Object *__qmljs_convert_to_object(ExecutionContext *ctx, const ValueRef value) case Value::Boolean_Type: return ctx->engine->newBooleanObject(*value); case Value::String_Type: - return ctx->engine->newStringObject(*value); + return ctx->engine->newStringObject(*value)->asReturned<Object>(); break; case Value::Object_Type: Q_UNREACHABLE(); @@ -658,9 +658,10 @@ void __qmljs_set_property(ExecutionContext *ctx, const ValueRef object, String * ReturnedValue __qmljs_get_element(ExecutionContext *ctx, const ValueRef object, const ValueRef index) { + Scope scope(ctx); uint idx = index->asArrayIndex(); - Object *o = object->asObject(); + Scoped<Object> o(scope, object); if (!o) { if (idx < UINT_MAX) { if (String *str = object->asString()) { @@ -766,18 +767,19 @@ void __qmljs_set_activation_property(ExecutionContext *ctx, String *name, const ReturnedValue __qmljs_get_property(ExecutionContext *ctx, const ValueRef object, String *name) { - Value res; - Managed *m = object->asManaged(); - if (m) - return m->get(name); + Scope scope(ctx); + + Scoped<Object> o(scope, object); + if (o) + return o->get(name); if (object->isNullOrUndefined()) { QString message = QStringLiteral("Cannot read property '%1' of %2").arg(name->toQString()).arg(object->toQStringNoThrow()); ctx->throwTypeError(message); } - m = __qmljs_convert_to_object(ctx, object); - return m->get(name); + o = __qmljs_convert_to_object(ctx, object); + return o->get(name); } ReturnedValue __qmljs_get_activation_property(ExecutionContext *ctx, String *name) @@ -974,7 +976,7 @@ ReturnedValue __qmljs_call_activation_property(ExecutionContext *context, String ReturnedValue __qmljs_call_property(ExecutionContext *context, String *name, CallDataRef callData) { Scope scope(context); - Managed *baseObject = callData->thisObject.asManaged(); + Scoped<Object> baseObject(scope, callData->thisObject); if (!baseObject) { if (callData->thisObject.isNullOrUndefined()) { QString message = QStringLiteral("Cannot call method '%1' of %2").arg(name->toQString()).arg(callData->thisObject.toQStringNoThrow()); @@ -982,7 +984,7 @@ ReturnedValue __qmljs_call_property(ExecutionContext *context, String *name, Cal } baseObject = __qmljs_convert_to_object(context, ValueRef(&callData->thisObject)); - callData->thisObject = Value::fromObject(static_cast<Object *>(baseObject)); + callData->thisObject = baseObject.asValue(); } Scoped<FunctionObject> o(scope, baseObject->get(name)); @@ -1251,6 +1253,20 @@ QV4::ReturnedValue __qmljs_decrement(const QV4::ValueRef value) } } +QV4::ReturnedValue __qmljs_to_string(const QV4::ValueRef value, QV4::ExecutionContext *ctx) +{ + if (value->isString()) + return value.asReturnedValue(); + return __qmljs_convert_to_string(ctx, value)->asReturnedValue(); +} + +QV4::ReturnedValue __qmljs_to_object(QV4::ExecutionContext *ctx, const QV4::ValueRef value) +{ + if (value->isObject()) + return value.asReturnedValue(); + return Encode(__qmljs_convert_to_object(ctx, value)); +} + void __qmljs_value_to_double(double *result, const ValueRef value) { *result = value->toNumber(); diff --git a/src/qml/jsruntime/qv4runtime_p.h b/src/qml/jsruntime/qv4runtime_p.h index 4b15c1a17d..6e578bcaca 100644 --- a/src/qml/jsruntime/qv4runtime_p.h +++ b/src/qml/jsruntime/qv4runtime_p.h @@ -172,7 +172,7 @@ QV4::ReturnedValue __qmljs_to_string(const ValueRef value, QV4::ExecutionContext Q_QML_EXPORT QV4::String *__qmljs_convert_to_string(QV4::ExecutionContext *ctx, const ValueRef value); void __qmljs_numberToString(QString *result, double num, int radix = 10); ReturnedValue __qmljs_to_object(QV4::ExecutionContext *ctx, const ValueRef value); -QV4::Object *__qmljs_convert_to_object(QV4::ExecutionContext *ctx, const ValueRef value); +Returned<Object> *__qmljs_convert_to_object(QV4::ExecutionContext *ctx, const ValueRef value); QV4::Bool __qmljs_equal_helper(const ValueRef x, const ValueRef y); Q_QML_EXPORT QV4::Bool __qmljs_strict_equal(const ValueRef x, const ValueRef y); @@ -294,21 +294,6 @@ inline double __qmljs_to_number(const ValueRef value) return value->toNumber(); } -inline QV4::ReturnedValue __qmljs_to_string(const QV4::ValueRef value, QV4::ExecutionContext *ctx) -{ - if (value->isString()) - return value.asReturnedValue(); - return __qmljs_convert_to_string(ctx, value)->asReturnedValue(); -} - -inline QV4::ReturnedValue __qmljs_to_object(QV4::ExecutionContext *ctx, const QV4::ValueRef value) -{ - if (value->isObject()) - return value.asReturnedValue(); - return Value::fromObject(__qmljs_convert_to_object(ctx, value)).asReturnedValue(); -} - - inline QV4::ReturnedValue __qmljs_uplus(const QV4::ValueRef value) { TRACE1(value); diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h index 68cc2848b3..e192cf5477 100644 --- a/src/qml/jsruntime/qv4scopedvalue_p.h +++ b/src/qml/jsruntime/qv4scopedvalue_p.h @@ -138,6 +138,16 @@ struct ScopedValue #endif } + template<typename T> + ScopedValue(const Scope &scope, Returned<T> *t) + { + ptr = scope.engine->jsStackTop++; + ptr->val = T::toValue(t->getPointer()); +#ifndef QT_NO_DEBUG + ++scope.size; +#endif + } + ScopedValue &operator=(const Value &v) { *ptr = v; return *this; @@ -148,6 +158,12 @@ struct ScopedValue return *this; } + template<typename T> + ScopedValue &operator=(const Returned<T> *t) { + ptr->val = T::toValue(t->getPointer()); + return *this; + } + ScopedValue &operator=(const ScopedValue &other) { *ptr = *other.ptr; return *this; @@ -193,6 +209,27 @@ struct Scoped #endif } + Scoped(const Scope &scope, const ValueRef &v); + + Scoped(const Scope &scope, T *t) + { + ptr = scope.engine->jsStackTop++; + *ptr = T::toValue(t); +#ifndef QT_NO_DEBUG + ++scope.size; +#endif + } + template<typename X> + Scoped(const Scope &scope, Returned<X> *x) + { + ptr = scope.engine->jsStackTop++; + T *t = Returned<T>::getPointer(x); + *ptr = T::toValue(t); +#ifndef QT_NO_DEBUG + ++scope.size; +#endif + } + Scoped(const Scope &scope, const ReturnedValue &v) { ptr = scope.engine->jsStackTop++; @@ -213,6 +250,8 @@ struct Scoped return *this; } + Scoped<T> &operator=(const ValueRef &v); + Scoped<T> &operator=(const ReturnedValue &v) { if (T::cast(QV4::Value::fromReturnedValue(v))) ptr->val = v; @@ -226,17 +265,32 @@ struct Scoped return *this; } + Scoped<T> &operator=(T *t) { + *ptr = T::toValue(t); + return *this; + } + + template<typename X> + Scoped<T> &operator=(Returned<X> *x) { + *ptr = T::toValue(Returned<T>::getPointer(x)); + return *this; + } + + T *operator->() { return static_cast<T *>(ptr->managed()); } -// const Value *operator->() const { -// return T::cast(*ptr); -// } + const Value *operator->() const { + return T::cast(*ptr); + } bool operator!() const { return !ptr->managed(); } + operator bool() const { + return ptr->managed(); + } T *getPointer() { return static_cast<T *>(ptr->managed()); @@ -325,6 +379,29 @@ private: Value *ptr; }; +template<typename T> +Scoped<T>::Scoped(const Scope &scope, const ValueRef &v) +{ + ptr = scope.engine->jsStackTop++; + if (T::cast(*v.operator ->())) + *ptr = *v.operator ->(); + else + *ptr = QV4::Value::undefinedValue(); +#ifndef QT_NO_DEBUG + ++scope.size; +#endif +} + +template<typename T> +Scoped<T> &Scoped<T>::operator=(const ValueRef &v) +{ + if (T::cast(*v.operator ->())) + *ptr = *v.operator ->(); + else + *ptr = QV4::Value::undefinedValue(); + return *this; +} + struct CallDataRef { CallDataRef(const ScopedCallData &c) @@ -384,6 +461,14 @@ struct Encode : private Value { dbl = i; } } + Encode(ReturnedValue v) { + val = v; + } + + template<typename T> + Encode(Returned<T> *t) { + val = T::toValue(t->getPointer()).val; + } operator ReturnedValue() const { return val; diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h index 3e4ab54cc1..8d9347ac2f 100644 --- a/src/qml/jsruntime/qv4string_p.h +++ b/src/qml/jsruntime/qv4string_p.h @@ -52,6 +52,7 @@ struct ExecutionEngine; struct Identifier; struct Q_QML_EXPORT String : public Managed { + Q_MANAGED enum StringType { StringType_Unknown, StringType_Regular, @@ -122,6 +123,9 @@ struct Q_QML_EXPORT String : public Managed { static String *cast(const Value &v) { return v.asString(); } + static Value toValue(String *s) { + return Value::fromString(s); + } ReturnedValue asReturnedValue() { return Value::fromString(this).asReturnedValue(); } @@ -141,8 +145,6 @@ protected: static bool deleteProperty(Managed *, String *); static bool deleteIndexedProperty(Managed *m, uint index); static bool isEqualTo(Managed *that, Managed *o); - - static const ManagedVTable static_vtbl; }; } diff --git a/src/qml/jsruntime/qv4stringobject_p.h b/src/qml/jsruntime/qv4stringobject_p.h index 15607a209e..0932379843 100644 --- a/src/qml/jsruntime/qv4stringobject_p.h +++ b/src/qml/jsruntime/qv4stringobject_p.h @@ -68,13 +68,11 @@ protected: struct StringCtor: FunctionObject { + Q_MANAGED StringCtor(ExecutionContext *scope); static ReturnedValue construct(Managed *m, CallData *callData); static ReturnedValue call(Managed *that, CallData *callData); - -protected: - static const ManagedVTable static_vtbl; }; struct StringPrototype: StringObject diff --git a/src/qml/jsruntime/qv4value.cpp b/src/qml/jsruntime/qv4value.cpp index 384df32601..8f2c11b5da 100644 --- a/src/qml/jsruntime/qv4value.cpp +++ b/src/qml/jsruntime/qv4value.cpp @@ -312,7 +312,7 @@ Object *Value::toObject(ExecutionContext *ctx) const { if (isObject()) return objectValue(); - return __qmljs_convert_to_object(ctx, ValueRef::fromRawValue(this)); + return __qmljs_convert_to_object(ctx, ValueRef::fromRawValue(this))->getPointer(); } diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h index 663e0aafb2..8f980e032b 100644 --- a/src/qml/jsruntime/qv4value_p.h +++ b/src/qml/jsruntime/qv4value_p.h @@ -59,8 +59,6 @@ QT_BEGIN_NAMESPACE namespace QV4 { -QV4::Object *__qmljs_convert_to_object(QV4::ExecutionContext *ctx, const QV4::Value &value); - inline Managed *Value::asManaged() const { if (isManaged()) |