aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2014-07-23 13:56:43 +0200
committerSimon Hausmann <simon.hausmann@digia.com>2014-11-04 14:58:30 +0100
commit3f1d0b27a11a1d560c11057d2a801224d1613d60 (patch)
treea35184460b77be487fa15aaa0e823334e406b833 /src/qml
parent8daace55a2c43ec354e5d778a42f9c421f9f9232 (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 <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/compiler/qv4compileddata.cpp14
-rw-r--r--src/qml/compiler/qv4compileddata_p.h2
-rw-r--r--src/qml/jit/qv4assembler.cpp4
-rw-r--r--src/qml/jsruntime/qv4context.cpp15
-rw-r--r--src/qml/jsruntime/qv4context_p.h8
-rw-r--r--src/qml/jsruntime/qv4engine.cpp7
-rw-r--r--src/qml/jsruntime/qv4function.cpp4
-rw-r--r--src/qml/jsruntime/qv4function_p.h2
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp6
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h6
-rw-r--r--src/qml/jsruntime/qv4identifiertable.cpp3
-rw-r--r--src/qml/jsruntime/qv4managed_p.h16
-rw-r--r--src/qml/jsruntime/qv4memberdata.cpp2
-rw-r--r--src/qml/jsruntime/qv4mm.cpp5
-rw-r--r--src/qml/jsruntime/qv4mm_p.h43
-rw-r--r--src/qml/jsruntime/qv4objectiterator.cpp17
-rw-r--r--src/qml/jsruntime/qv4regexp.cpp3
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp8
-rw-r--r--src/qml/jsruntime/qv4scopedvalue_p.h22
-rw-r--r--src/qml/jsruntime/qv4script.cpp4
-rw-r--r--src/qml/jsruntime/qv4value_p.h54
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp4
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper.cpp4
-rw-r--r--src/qml/types/qqmldelegatemodel.cpp6
24 files changed, 148 insertions, 111 deletions
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index d242fb7b3a..fbef8b8566 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -65,9 +65,9 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
Q_ASSERT(!runtimeStrings);
Q_ASSERT(data);
- runtimeStrings = (QV4::StringValue *)malloc(data->stringTableSize * sizeof(QV4::StringValue));
+ runtimeStrings = (QV4::String **)malloc(data->stringTableSize * sizeof(QV4::String*));
// memset the strings to 0 in case a GC run happens while we're within the loop below
- memset(runtimeStrings, 0, data->stringTableSize * sizeof(QV4::StringValue));
+ memset(runtimeStrings, 0, data->stringTableSize * sizeof(QV4::String*));
for (uint i = 0; i < data->stringTableSize; ++i)
runtimeStrings[i] = engine->newIdentifier(data->stringAt(i));
@@ -109,7 +109,7 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
l->classList[j] = 0;
l->level = -1;
l->index = UINT_MAX;
- l->name = runtimeStrings[compiledLookups[i].nameIndex].asString();
+ l->name = runtimeStrings[compiledLookups[i].nameIndex];
if (type == CompiledData::Lookup::Type_IndexedGetter || type == CompiledData::Lookup::Type_IndexedSetter)
l->engine = engine;
}
@@ -123,7 +123,7 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
const CompiledData::JSClassMember *member = data->jsClassAt(i, &memberCount);
QV4::InternalClass *klass = engine->objectClass;
for (int j = 0; j < memberCount; ++j, ++member)
- klass = klass->addMember(runtimeStrings[member->nameOffset].asString(), member->isAccessor ? QV4::Attr_Accessor : QV4::Attr_Data);
+ klass = klass->addMember(runtimeStrings[member->nameOffset], member->isAccessor ? QV4::Attr_Accessor : QV4::Attr_Data);
runtimeClasses[i] = klass;
}
@@ -166,14 +166,16 @@ void CompilationUnit::unlink()
void CompilationUnit::markObjects(QV4::ExecutionEngine *e)
{
for (uint i = 0; i < data->stringTableSize; ++i)
- runtimeStrings[i].mark(e);
+ if (runtimeStrings[i])
+ runtimeStrings[i]->mark(e);
if (runtimeRegularExpressions) {
for (uint i = 0; i < data->regexpTableSize; ++i)
runtimeRegularExpressions[i].mark(e);
}
if (runtimeLookups) {
for (uint i = 0; i < data->lookupTableSize; ++i)
- runtimeLookups[i].name->mark(e);
+ if (runtimeLookups[i].name)
+ runtimeLookups[i].name->mark(e);
}
}
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index 6791970461..6ab7191358 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -588,7 +588,7 @@ struct Q_QML_PRIVATE_EXPORT CompilationUnit : public QQmlRefCount
ExecutionEngine *engine;
QString fileName() const { return data->stringAt(data->sourceFileIndex); }
- QV4::StringValue *runtimeStrings; // Array
+ QV4::String **runtimeStrings; // Array
QV4::Lookup *runtimeLookups;
QV4::Value *runtimeRegularExpressions;
QV4::InternalClass **runtimeClasses;
diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp
index ed342740ac..300f4b0fb2 100644
--- a/src/qml/jit/qv4assembler.cpp
+++ b/src/qml/jit/qv4assembler.cpp
@@ -214,7 +214,7 @@ Assembler::Pointer Assembler::loadStringAddress(RegisterID reg, const QString &s
loadPtr(Address(Assembler::ContextRegister, qOffsetOf(QV4::ExecutionContext::Data, compilationUnit)), Assembler::ScratchRegister);
loadPtr(Address(Assembler::ScratchRegister, qOffsetOf(QV4::CompiledData::CompilationUnit, runtimeStrings)), reg);
const int id = _isel->registerString(string);
- return Pointer(reg, id * sizeof(QV4::StringValue));
+ return Pointer(reg, id * sizeof(QV4::String*));
}
void Assembler::loadStringRef(RegisterID reg, const QString &string)
@@ -222,7 +222,7 @@ void Assembler::loadStringRef(RegisterID reg, const QString &string)
loadPtr(Address(Assembler::ContextRegister, qOffsetOf(QV4::ExecutionContext::Data, compilationUnit)), reg);
loadPtr(Address(reg, qOffsetOf(QV4::CompiledData::CompilationUnit, runtimeStrings)), reg);
const int id = _isel->registerString(string);
- loadPtr(Address(reg, id * sizeof(QV4::StringValue)), reg);
+ loadPtr(Address(reg, id * sizeof(QV4::String*)), reg);
}
void Assembler::storeValue(QV4::Primitive value, IR::Expr *destination)
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)
diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp
index b0125b4c13..8123a297fe 100644
--- a/src/qml/qml/qqmlvaluetypewrapper.cpp
+++ b/src/qml/qml/qqmlvaluetypewrapper.cpp
@@ -144,7 +144,7 @@ ReturnedValue QmlValueTypeWrapper::create(QV8Engine *v8, QObject *object, int pr
Scope scope(v4);
initProto(v4);
- QmlValueTypeReference *r = v4->memoryManager->alloc<QmlValueTypeReference>(v8);
+ Scoped<QmlValueTypeReference> r(scope, v4->memoryManager->alloc<QmlValueTypeReference>(v8));
r->d()->internalClass = r->d()->internalClass->changePrototype(v4->qmlExtensions()->valueTypeWrapperPrototype);
r->d()->type = type; r->d()->object = object; r->d()->property = property;
return r->asReturnedValue();
@@ -156,7 +156,7 @@ ReturnedValue QmlValueTypeWrapper::create(QV8Engine *v8, const QVariant &value,
Scope scope(v4);
initProto(v4);
- QmlValueTypeCopy *r = v4->memoryManager->alloc<QmlValueTypeCopy>(v8);
+ Scoped<QmlValueTypeCopy> r(scope, v4->memoryManager->alloc<QmlValueTypeCopy>(v8));
r->d()->internalClass = r->d()->internalClass->changePrototype(v4->qmlExtensions()->valueTypeWrapperPrototype);
r->d()->type = type; r->d()->value = value;
return r->asReturnedValue();
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp
index 639df4f846..b26557e0ff 100644
--- a/src/qml/types/qqmldelegatemodel.cpp
+++ b/src/qml/types/qqmldelegatemodel.cpp
@@ -67,7 +67,7 @@ struct DelegateModelGroupFunction: QV4::FunctionObject
};
V4_OBJECT(QV4::FunctionObject)
- static DelegateModelGroupFunction *create(QV4::ExecutionContext *scope, uint flag, QV4::ReturnedValue (*code)(QQmlDelegateModelItem *item, uint flag, const QV4::ValueRef arg))
+ static QV4::Returned<DelegateModelGroupFunction> *create(QV4::ExecutionContext *scope, uint flag, QV4::ReturnedValue (*code)(QQmlDelegateModelItem *item, uint flag, const QV4::ValueRef arg))
{
return scope->engine()->memoryManager->alloc<DelegateModelGroupFunction>(scope, flag, code);
}
@@ -3220,7 +3220,7 @@ struct QQmlDelegateModelGroupChange : QV4::Object
};
V4_OBJECT(QV4::Object)
- static QQmlDelegateModelGroupChange *create(QV4::ExecutionEngine *e) {
+ static QV4::Returned<QQmlDelegateModelGroupChange> *create(QV4::ExecutionEngine *e) {
return e->memoryManager->alloc<QQmlDelegateModelGroupChange>(e);
}
@@ -3267,7 +3267,7 @@ struct QQmlDelegateModelGroupChangeArray : public QV4::Object
};
V4_OBJECT(QV4::Object)
public:
- static QQmlDelegateModelGroupChangeArray *create(QV4::ExecutionEngine *engine, const QVector<QQmlChangeSet::Change> &changes)
+ static QV4::Returned<QQmlDelegateModelGroupChangeArray> *create(QV4::ExecutionEngine *engine, const QVector<QQmlChangeSet::Change> &changes)
{
return engine->memoryManager->alloc<QQmlDelegateModelGroupChangeArray>(engine, changes);
}