diff options
author | Simon Hausmann <[email protected]> | 2014-07-23 13:56:43 +0200 |
---|---|---|
committer | Simon Hausmann <[email protected]> | 2014-11-04 14:58:30 +0100 |
commit | 3f1d0b27a11a1d560c11057d2a801224d1613d60 (patch) | |
tree | a35184460b77be487fa15aaa0e823334e406b833 /src/qml/jsruntime | |
parent | 8daace55a2c43ec354e5d778a42f9c421f9f9232 (diff) |
Changed Value to store Managed::Data pointers directly
This is a step towards storing direct heap object pointers for the values
on the JS stack, to avoid the costly indirection for data access.
Change-Id: Ibb57ed6cf52a7088bbc95ee04ae3a4cb25b8c045
Reviewed-by: Simon Hausmann <[email protected]>
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r-- | src/qml/jsruntime/qv4context.cpp | 15 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4context_p.h | 8 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 7 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4function.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4function_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4functionobject.cpp | 6 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4functionobject_p.h | 6 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4identifiertable.cpp | 3 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4managed_p.h | 16 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4memberdata.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4mm.cpp | 5 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4mm_p.h | 43 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4objectiterator.cpp | 17 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4regexp.cpp | 3 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 8 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4scopedvalue_p.h | 22 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4script.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4value_p.h | 54 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 4 |
19 files changed, 132 insertions, 97 deletions
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index 5ca47a80b1..8f9f8cc423 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -48,7 +48,7 @@ DEFINE_MANAGED_VTABLE(CallContext); DEFINE_MANAGED_VTABLE(WithContext); DEFINE_MANAGED_VTABLE(GlobalContext); -HeapObject *ExecutionContext::newCallContext(FunctionObject *function, CallData *callData) +Returned<ExecutionContext> *ExecutionContext::newCallContext(FunctionObject *function, CallData *callData) { Q_ASSERT(function->function()); @@ -78,24 +78,25 @@ HeapObject *ExecutionContext::newCallContext(FunctionObject *function, CallData std::fill(c->callData->args + c->callData->argc, c->callData->args + compiledFunction->nFormals, Primitive::undefinedValue()); c->callData->argc = qMax((uint)callData->argc, compiledFunction->nFormals); - return c; + return Returned<ExecutionContext>::create(c); } -WithContext *ExecutionContext::newWithContext(Object *with) +Returned<WithContext> *ExecutionContext::newWithContext(Object *with) { return d()->engine->memoryManager->alloc<WithContext>(d()->engine, with); } -CatchContext *ExecutionContext::newCatchContext(String *exceptionVarName, const ValueRef exceptionValue) +Returned<CatchContext> *ExecutionContext::newCatchContext(String *exceptionVarName, const ValueRef exceptionValue) { return d()->engine->memoryManager->alloc<CatchContext>(d()->engine, exceptionVarName, exceptionValue); } -CallContext *ExecutionContext::newQmlContext(FunctionObject *f, Object *qml) +Returned<CallContext> *ExecutionContext::newQmlContext(FunctionObject *f, Object *qml) { - CallContext *c = reinterpret_cast<CallContext*>(d()->engine->memoryManager->allocManaged(requiredMemoryForExecutionContect(f, 0))); + Scope scope(this); + Scoped<CallContext> c(scope, static_cast<CallContext*>(d()->engine->memoryManager->allocManaged(requiredMemoryForExecutionContect(f, 0)))); new (c->d()) CallContext::Data(d()->engine, qml, f); - return c; + return c.asReturned(); } diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h index 74530e7ae9..4f7cdd8105 100644 --- a/src/qml/jsruntime/qv4context_p.h +++ b/src/qml/jsruntime/qv4context_p.h @@ -127,10 +127,10 @@ struct Q_QML_EXPORT ExecutionContext : public Managed engine->current = this; } - HeapObject *newCallContext(FunctionObject *f, CallData *callData); - WithContext *newWithContext(Object *with); - CatchContext *newCatchContext(String *exceptionVarName, const ValueRef exceptionValue); - CallContext *newQmlContext(FunctionObject *f, Object *qml); + Returned<ExecutionContext> *newCallContext(FunctionObject *f, CallData *callData); + Returned<WithContext> *newWithContext(Object *with); + Returned<CatchContext> *newCatchContext(String *exceptionVarName, const ValueRef exceptionValue); + Returned<CallContext> *newQmlContext(FunctionObject *f, Object *qml); void createMutableBinding(String *name, bool deletable); diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 99050b04aa..ec1ea80e47 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -508,11 +508,12 @@ InternalClass *ExecutionEngine::newClass(const InternalClass &other) ExecutionContext *ExecutionEngine::pushGlobalContext() { - GlobalContext *g = memoryManager->alloc<GlobalContext>(this); + Scope scope(this); + Scoped<GlobalContext> g(scope, memoryManager->alloc<GlobalContext>(this)); g->d()->callData = rootContext->d()->callData; - Q_ASSERT(currentContext() == g); - return g; + Q_ASSERT(currentContext() == g.getPointer()); + return g.getPointer(); } diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp index c7fe2128ce..6bc48157c0 100644 --- a/src/qml/jsruntime/qv4function.cpp +++ b/src/qml/jsruntime/qv4function.cpp @@ -58,7 +58,7 @@ Function::Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit, Scope scope(engine); ScopedString s(scope); for (int i = static_cast<int>(compiledFunction->nFormals - 1); i >= 0; --i) { - String *arg = compilationUnit->runtimeStrings[formalsIndices[i]].asString(); + String *arg = compilationUnit->runtimeStrings[formalsIndices[i]]; while (1) { InternalClass *newClass = internalClass->addMember(arg, Attr_NotConfigurable); if (newClass != internalClass) { @@ -72,7 +72,7 @@ Function::Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit, const quint32 *localsIndices = compiledFunction->localsTable(); for (quint32 i = 0; i < compiledFunction->nLocals; ++i) { - String *local = compilationUnit->runtimeStrings[localsIndices[i]].asString(); + String *local = compilationUnit->runtimeStrings[localsIndices[i]]; internalClass = internalClass->addMember(local, Attr_NotConfigurable); } } diff --git a/src/qml/jsruntime/qv4function_p.h b/src/qml/jsruntime/qv4function_p.h index 465489b83f..b2c4d2e09d 100644 --- a/src/qml/jsruntime/qv4function_p.h +++ b/src/qml/jsruntime/qv4function_p.h @@ -87,7 +87,7 @@ struct Q_QML_EXPORT Function { ~Function(); inline String *name() { - return compilationUnit->runtimeStrings[compiledFunction->nameIndex].getPointer(); + return compilationUnit->runtimeStrings[compiledFunction->nameIndex]; } inline QString sourceFile() const { return compilationUnit->fileName(); } diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index f3ad8ef892..ea87ff1f0f 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -165,14 +165,14 @@ void FunctionObject::markObjects(Managed *that, ExecutionEngine *e) Object::markObjects(that, e); } -FunctionObject *FunctionObject::createScriptFunction(ExecutionContext *scope, Function *function, bool createProto) +Returned<FunctionObject> *FunctionObject::createScriptFunction(ExecutionContext *scope, Function *function, bool createProto) { if (function->needsActivation() || function->compiledFunction->flags & CompiledData::Function::HasCatchOrWith || function->compiledFunction->nFormals > QV4::Global::ReservedArgumentCount || function->isNamedExpression()) - return scope->d()->engine->memoryManager->alloc<ScriptFunction>(scope, function); - return scope->d()->engine->memoryManager->alloc<SimpleScriptFunction>(scope, function, createProto); + return scope->d()->engine->memoryManager->alloc<ScriptFunction>(scope, function)->as<FunctionObject>(); + return scope->d()->engine->memoryManager->alloc<SimpleScriptFunction>(scope, function, createProto)->as<FunctionObject>(); } DEFINE_OBJECT_VTABLE(FunctionCtor); diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h index c8edb765de..2d57f6c015 100644 --- a/src/qml/jsruntime/qv4functionobject_p.h +++ b/src/qml/jsruntime/qv4functionobject_p.h @@ -138,7 +138,7 @@ struct Q_QML_EXPORT FunctionObject: Object { return v.asFunctionObject(); } - static FunctionObject *createScriptFunction(ExecutionContext *scope, Function *function, bool createProto = true); + static Returned<FunctionObject> *createScriptFunction(ExecutionContext *scope, Function *function, bool createProto = true); ReturnedValue protoProperty() { return memberData()[Index_Prototype].asReturnedValue(); } @@ -188,7 +188,7 @@ struct Q_QML_EXPORT BuiltinFunction: FunctionObject { }; V4_OBJECT(FunctionObject) - static BuiltinFunction *create(ExecutionContext *scope, String *name, ReturnedValue (*code)(CallContext *)) + static Returned<BuiltinFunction> *create(ExecutionContext *scope, String *name, ReturnedValue (*code)(CallContext *)) { return scope->engine()->memoryManager->alloc<BuiltinFunction>(scope, name, code); } @@ -253,7 +253,7 @@ struct BoundFunction: FunctionObject { }; V4_OBJECT(FunctionObject) - static BoundFunction *create(ExecutionContext *scope, FunctionObject *target, const ValueRef boundThis, const QV4::Members &boundArgs) + static Returned<BoundFunction> *create(ExecutionContext *scope, FunctionObject *target, const ValueRef boundThis, const QV4::Members &boundArgs) { return scope->engine()->memoryManager->alloc<BoundFunction>(scope, target, boundThis, boundArgs); } diff --git a/src/qml/jsruntime/qv4identifiertable.cpp b/src/qml/jsruntime/qv4identifiertable.cpp index d7ed7a8db0..5554b68db3 100644 --- a/src/qml/jsruntime/qv4identifiertable.cpp +++ b/src/qml/jsruntime/qv4identifiertable.cpp @@ -121,7 +121,8 @@ String *IdentifierTable::insertString(const QString &s) idx %= alloc; } - String *str = engine->newString(s)->getPointer(); + Returned<String> *_s = engine->newString(s); + String *str = _s->getPointer(); addEntry(str); return str; } diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h index c062ec4f5b..c73ad10230 100644 --- a/src/qml/jsruntime/qv4managed_p.h +++ b/src/qml/jsruntime/qv4managed_p.h @@ -207,7 +207,7 @@ struct Q_QML_PRIVATE_EXPORT Managed void setVTable(const ManagedVTable *vt); ReturnedValue asReturnedValue() const { - return reinterpret_cast<Managed *>(const_cast<Data *>(this))->asReturnedValue(); + return Value::fromHeapObject(const_cast<Data *>(this)).asReturnedValue(); } void *operator new(size_t, Managed *m) { return m; } @@ -377,6 +377,20 @@ inline FunctionObject *managed_cast(Managed *m) return m ? m->asFunctionObject() : 0; } +inline Value Value::fromManaged(Managed *m) +{ + if (!m) + return QV4::Primitive::undefinedValue(); + Value v; +#if QT_POINTER_SIZE == 8 + v.m = &m->data; +#else + v.tag = Managed_Type; + v.m = &m->data; +#endif + return v; +} + } diff --git a/src/qml/jsruntime/qv4memberdata.cpp b/src/qml/jsruntime/qv4memberdata.cpp index 405594ca9b..418323445a 100644 --- a/src/qml/jsruntime/qv4memberdata.cpp +++ b/src/qml/jsruntime/qv4memberdata.cpp @@ -57,6 +57,6 @@ void Members::ensureIndex(QV4::ExecutionEngine *e, uint idx) else new (newMemberData) MemberData(e->memberDataClass); newMemberData->d()->size = newAlloc; - m = newMemberData; + m = &newMemberData->data; } } diff --git a/src/qml/jsruntime/qv4mm.cpp b/src/qml/jsruntime/qv4mm.cpp index b9a4a55b4a..3877dde251 100644 --- a/src/qml/jsruntime/qv4mm.cpp +++ b/src/qml/jsruntime/qv4mm.cpp @@ -535,6 +535,11 @@ MemoryManager::~MemoryManager() #endif } +ExecutionEngine *MemoryManager::engine() const +{ + return m_d->engine; +} + void MemoryManager::setExecutionEngine(ExecutionEngine *engine) { m_d->engine = engine; diff --git a/src/qml/jsruntime/qv4mm_p.h b/src/qml/jsruntime/qv4mm_p.h index d5e28f7f84..cf9a14861e 100644 --- a/src/qml/jsruntime/qv4mm_p.h +++ b/src/qml/jsruntime/qv4mm_p.h @@ -96,57 +96,64 @@ public: } template <typename ManagedType> - ManagedType *alloc() + Returned<ManagedType> *alloc() { - ManagedType *t = static_cast<ManagedType*>(allocManaged(sizeof(typename ManagedType::Data))); + Scope scope(engine()); + Scoped<ManagedType> t(scope, static_cast<ManagedType*>(allocManaged(sizeof(typename ManagedType::Data)))); (void)new (t->d()) typename ManagedType::Data(); - return t; + return t.asReturned(); } template <typename ManagedType, typename Arg1> - ManagedType *alloc(Arg1 arg1) + Returned<ManagedType> *alloc(Arg1 arg1) { - ManagedType *t = static_cast<ManagedType*>(allocManaged(sizeof(typename ManagedType::Data))); + Scope scope(engine()); + Scoped<ManagedType> t(scope, static_cast<ManagedType*>(allocManaged(sizeof(typename ManagedType::Data)))); (void)new (t->d()) typename ManagedType::Data(arg1); - return t; + return t.asReturned(); } template <typename ManagedType, typename Arg1, typename Arg2> - ManagedType *alloc(Arg1 arg1, Arg2 arg2) + Returned<ManagedType> *alloc(Arg1 arg1, Arg2 arg2) { - ManagedType *t = static_cast<ManagedType*>(allocManaged(sizeof(typename ManagedType::Data))); + Scope scope(engine()); + Scoped<ManagedType> t(scope, static_cast<ManagedType*>(allocManaged(sizeof(typename ManagedType::Data)))); (void)new (t->d()) typename ManagedType::Data(arg1, arg2); - return t; + return t.asReturned(); } template <typename ManagedType, typename Arg1, typename Arg2, typename Arg3> - ManagedType *alloc(Arg1 arg1, Arg2 arg2, Arg3 arg3) + Returned<ManagedType> *alloc(Arg1 arg1, Arg2 arg2, Arg3 arg3) { - ManagedType *t = static_cast<ManagedType*>(allocManaged(sizeof(typename ManagedType::Data))); + Scope scope(engine()); + Scoped<ManagedType> t(scope, static_cast<ManagedType*>(allocManaged(sizeof(typename ManagedType::Data)))); (void)new (t->d()) typename ManagedType::Data(arg1, arg2, arg3); - return t; + return t.asReturned(); } template <typename ManagedType, typename Arg1, typename Arg2, typename Arg3, typename Arg4> - ManagedType *alloc(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) + Returned<ManagedType> *alloc(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { - ManagedType *t = static_cast<ManagedType*>(allocManaged(sizeof(typename ManagedType::Data))); + Scope scope(engine()); + Scoped<ManagedType> t(scope, static_cast<ManagedType*>(allocManaged(sizeof(typename ManagedType::Data)))); (void)new (t->d()) typename ManagedType::Data(arg1, arg2, arg3, arg4); - return t; + return t.asReturned(); } template <typename ManagedType, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5> - ManagedType *alloc(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) + Returned<ManagedType> *alloc(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) { - ManagedType *t = static_cast<ManagedType*>(allocManaged(sizeof(typename ManagedType::Data))); + Scope scope(engine()); + Scoped<ManagedType> t(scope, static_cast<ManagedType*>(allocManaged(sizeof(typename ManagedType::Data)))); (void)new (t->d()) typename ManagedType::Data(arg1, arg2, arg3, arg4, arg5); - return t; + return t.asReturned(); } bool isGCBlocked() const; void setGCBlocked(bool blockGC); void runGC(); + ExecutionEngine *engine() const; void setExecutionEngine(ExecutionEngine *engine); void dumpStats() const; diff --git a/src/qml/jsruntime/qv4objectiterator.cpp b/src/qml/jsruntime/qv4objectiterator.cpp index f9ccb8f829..b2875a192d 100644 --- a/src/qml/jsruntime/qv4objectiterator.cpp +++ b/src/qml/jsruntime/qv4objectiterator.cpp @@ -68,15 +68,15 @@ ObjectIterator::ObjectIterator(Value *scratch1, Value *scratch2, uint flags) , memberIndex(0) , flags(flags) { - object->m = (Object*)0; - current->m = (Object*)0; + object->m = 0; + current->m = 0; // Caller needs to call init! } void ObjectIterator::init(Object *o) { - object->m = o; - current->m = o; + object->m = o ? &o->data : 0; + current->m = o ? &o->data : 0; #if QT_POINTER_SIZE == 4 object->tag = QV4::Value::Managed_Type; @@ -125,10 +125,11 @@ void ObjectIterator::next(String *&name, uint *index, Property *pd, PropertyAttr return; } - if (flags & WithProtoChain) - current->m = current->objectValue()->prototype(); - else - current->m = (Object *)0; + if (flags & WithProtoChain) { + Object *proto = current->objectValue()->prototype(); + current->m = proto ? &proto->data : 0; + } else + current->m = (HeapObject *)0; arrayIndex = 0; memberIndex = 0; diff --git a/src/qml/jsruntime/qv4regexp.cpp b/src/qml/jsruntime/qv4regexp.cpp index e84c96f417..ed672892c2 100644 --- a/src/qml/jsruntime/qv4regexp.cpp +++ b/src/qml/jsruntime/qv4regexp.cpp @@ -73,7 +73,8 @@ RegExp* RegExp::create(ExecutionEngine* engine, const QString& pattern, bool ign return result; } - RegExp *result = engine->memoryManager->alloc<RegExp>(engine, pattern, ignoreCase, multiline); + Scope scope(engine); + Scoped<RegExp> result(scope, engine->memoryManager->alloc<RegExp>(engine, pattern, ignoreCase, multiline)); if (!cache) cache = engine->regExpCache = new RegExpCache; diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index cb7e219354..957f8cd42f 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -881,9 +881,9 @@ ReturnedValue Runtime::callActivationProperty(ExecutionContext *context, String Scope scope(context); ScopedObject base(scope); - Object *baseObj = base.ptr->objectValue(); + Object *baseObj = 0; ScopedValue func(scope, context->getPropertyAndBase(name, baseObj)); - base.ptr->m = baseObj; + base.ptr->m = baseObj ? &baseObj->data : 0; if (scope.engine->hasException) return Encode::undefined(); @@ -1101,7 +1101,7 @@ ExecutionContext *Runtime::pushWithScope(const ValueRef o, ExecutionContext *ctx { Scope scope(ctx); ScopedObject obj(scope, o->toObject(ctx)); - return reinterpret_cast<ExecutionContext *>(ctx->newWithContext(obj)); + return ctx->newWithContext(obj)->getPointer(); } ReturnedValue Runtime::unwindException(ExecutionContext *ctx) @@ -1115,7 +1115,7 @@ ExecutionContext *Runtime::pushCatchScope(ExecutionContext *ctx, String *excepti { Scope scope(ctx); ScopedValue v(scope, ctx->engine()->catchException(ctx, 0)); - return reinterpret_cast<ExecutionContext *>(ctx->newCatchContext(exceptionVarName, v)); + return ctx->newCatchContext(exceptionVarName, v)->getPointer(); } ExecutionContext *Runtime::popScope(ExecutionContext *ctx) diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h index b1b4d5da8d..5cc8495bba 100644 --- a/src/qml/jsruntime/qv4scopedvalue_p.h +++ b/src/qml/jsruntime/qv4scopedvalue_p.h @@ -112,7 +112,7 @@ struct ScopedValue ScopedValue(const Scope &scope, HeapObject *o) { ptr = scope.engine->jsStackTop++; - ptr->m = reinterpret_cast<Managed *>(o); + ptr->m = o; #if QT_POINTER_SIZE == 4 ptr->tag = QV4::Value::Managed_Type; #endif @@ -155,7 +155,7 @@ struct ScopedValue } ScopedValue &operator=(HeapObject *o) { - ptr->m = reinterpret_cast<Managed *>(o); + ptr->m = o; #if QT_POINTER_SIZE == 4 ptr->tag = QV4::Value::Managed_Type; #endif @@ -204,7 +204,7 @@ struct Scoped inline void setPointer(Managed *p) { #if QT_POINTER_SIZE == 8 - ptr->val = (quint64)p; + ptr->val = (quint64)(p ? &p->data : 0); #else *ptr = p ? QV4::Value::fromManaged(p) : QV4::Primitive::undefinedValue(); #endif @@ -230,7 +230,7 @@ struct Scoped Scoped(const Scope &scope, HeapObject *o) { Value v; - v.m = reinterpret_cast<Managed *>(o); + v.m = o; #if QT_POINTER_SIZE == 4 v.tag = QV4::Value::Managed_Type; #endif @@ -317,7 +317,7 @@ struct Scoped Scoped<T> &operator=(HeapObject *o) { Value v; - v.m = reinterpret_cast<Managed *>(o); + v.m = o; #if QT_POINTER_SIZE == 4 v.tag = QV4::Value::Managed_Type; #endif @@ -361,10 +361,10 @@ struct Scoped } bool operator!() const { - return !ptr->managed(); + return !ptr->m; } operator void *() const { - return ptr->managed(); + return ptr->m; } T *getPointer() { @@ -379,6 +379,8 @@ struct Scoped #endif } + Returned<T> *asReturned() const { return Returned<T>::create(static_cast<typename T::Data*>(ptr->heapObject())); } + Value *ptr; }; @@ -478,7 +480,7 @@ inline Returned<T> *Value::as() template<typename T> inline TypedValue<T> &TypedValue<T>::operator =(T *t) { - m = t; + m = t ? &t->data : 0; #if QT_POINTER_SIZE == 4 tag = Managed_Type; #endif @@ -488,7 +490,7 @@ inline TypedValue<T> &TypedValue<T>::operator =(T *t) template<typename T> inline TypedValue<T> &TypedValue<T>::operator =(const Scoped<T> &v) { - m = v.ptr->managed(); + m = v.ptr->m; #if QT_POINTER_SIZE == 4 tag = Managed_Type; #endif @@ -519,7 +521,7 @@ inline TypedValue<T> &TypedValue<T>::operator=(const TypedValue<T> &t) template<typename T> inline Returned<T> * TypedValue<T>::ret() const { - return Returned<T>::create(static_cast<T *>(managed())); + return Returned<T>::create(static_cast<typename T::Data *>(heapObject())); } inline Primitive::operator ValueRef() diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index fa4b4b1894..20b0832a96 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -70,7 +70,7 @@ QmlBindingWrapper::Data::Data(ExecutionContext *scope, Function *f, Object *qml) o->defineReadonlyProperty(scope->d()->engine->id_length, Primitive::fromInt32(1)); - o->d()->qmlContext = reinterpret_cast<CallContext *>(s.engine->currentContext()->newQmlContext(o, qml)); + o->d()->qmlContext = s.engine->currentContext()->newQmlContext(o, qml)->getPointer(); s.engine->popContext(); } @@ -88,7 +88,7 @@ QmlBindingWrapper::Data::Data(ExecutionContext *scope, Object *qml) o->defineReadonlyProperty(scope->d()->engine->id_length, Primitive::fromInt32(1)); - o->d()->qmlContext = reinterpret_cast<CallContext *>(s.engine->currentContext()->newQmlContext(o, qml)); + o->d()->qmlContext = s.engine->currentContext()->newQmlContext(o, qml)->getPointer(); s.engine->popContext(); } diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h index f215162c2f..9c6bd60792 100644 --- a/src/qml/jsruntime/qv4value_p.h +++ b/src/qml/jsruntime/qv4value_p.h @@ -44,19 +44,21 @@ namespace QV4 { typedef uint Bool; +struct HeapObject {}; + template <typename T> -struct Returned : private T +struct Returned : private HeapObject { - static Returned<T> *create(T *t) { return static_cast<Returned<T> *>(t); } - T *getPointer() { return this; } + static Returned<T> *create(T *t) { Q_ASSERT((void *)&t->data == (void *)t); return static_cast<Returned<T> *>(static_cast<HeapObject*>(t ? &t->data : 0)); } + static Returned<T> *create(typename T::Data *t) { return static_cast<Returned<T> *>(static_cast<HeapObject*>(t)); } + T *getPointer() { return reinterpret_cast<T *>(this); } template<typename X> static T *getPointer(Returned<X> *x) { return x->getPointer(); } template<typename X> Returned<X> *as() { return Returned<X>::create(Returned<X>::getPointer(this)); } - using T::asReturnedValue; -}; -struct HeapObject {}; + inline ReturnedValue asReturnedValue(); +}; struct Q_QML_PRIVATE_EXPORT Value { @@ -86,7 +88,7 @@ struct Q_QML_PRIVATE_EXPORT Value union { quint64 val; #if QT_POINTER_SIZE == 8 - Managed *m; + HeapObject *m; #else double dbl; #endif @@ -98,7 +100,7 @@ struct Q_QML_PRIVATE_EXPORT Value uint uint_32; int int_32; #if QT_POINTER_SIZE == 4 - Managed *m; + HeapObject *m; #endif }; #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN @@ -266,12 +268,15 @@ struct Q_QML_PRIVATE_EXPORT Value } String *stringValue() const { - return reinterpret_cast<String*>(m); + return m ? reinterpret_cast<String*>(m) : 0; } Object *objectValue() const { - return reinterpret_cast<Object*>(m); + return m ? reinterpret_cast<Object*>(m) : 0; } Managed *managed() const { + return m ? reinterpret_cast<Managed*>(m) : 0; + } + HeapObject *heapObject() const { return m; } @@ -279,6 +284,16 @@ struct Q_QML_PRIVATE_EXPORT Value return val; } + static inline Value fromHeapObject(HeapObject *m) + { + Value v; + v.m = m; +#if QT_POINTER_SIZE == 4 + v.tag = Managed_Type; +#endif + return v; + } + static inline Value fromManaged(Managed *m); int toUInt16() const; @@ -338,7 +353,7 @@ struct Q_QML_PRIVATE_EXPORT Value return *this; } Value &operator=(HeapObject *o) { - m = reinterpret_cast<Managed *>(o); + m = o; return *this; } @@ -405,20 +420,6 @@ inline Primitive Primitive::emptyValue() return v; } -inline Value Value::fromManaged(Managed *m) -{ - if (!m) - return QV4::Primitive::undefinedValue(); - Value v; -#if QT_POINTER_SIZE == 8 - v.m = m; -#else - v.tag = Managed_Type; - v.m = m; -#endif - return v; -} - template <typename T> struct TypedValue : public Value { @@ -557,7 +558,8 @@ T *value_cast(const Value &v) template<typename T> ReturnedValue value_convert(ExecutionEngine *e, const Value &v); - +template <typename T> +ReturnedValue Returned<T>::asReturnedValue() { return Value::fromHeapObject(this).asReturnedValue(); } } diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index cd73314bce..35ac5eac5f 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -184,7 +184,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code qDebug("Starting VME with context=%p and code=%p", context, code); #endif // DO_TRACE_INSTR - QV4::StringValue * const runtimeStrings = context->d()->compilationUnit->runtimeStrings; + QV4::String ** const runtimeStrings = context->d()->compilationUnit->runtimeStrings; // setup lookup scopes int scopeDepth = 0; @@ -240,7 +240,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code MOTH_BEGIN_INSTR(LoadRuntimeString) // TRACE(value, "%s", instr.value.toString(context)->toQString().toUtf8().constData()); - VALUE(instr.result) = runtimeStrings[instr.stringId].asReturnedValue(); + VALUE(instr.result) = runtimeStrings[instr.stringId]->asReturnedValue(); MOTH_END_INSTR(LoadRuntimeString) MOTH_BEGIN_INSTR(LoadRegExp) |