diff options
author | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2014-11-12 16:07:56 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2014-11-21 13:08:28 +0100 |
commit | f58b5229a31e9fec49b4eb055c56f9a78e423866 (patch) | |
tree | 6214fb89929fd9482c2154b0fe17c7cba0f509cb /src/qml/jsruntime | |
parent | e6db292366fa6ad25536fee08b2a972ea617d968 (diff) |
Fix run-time string handling with regards to the new heap
Changed runtimeStrings to be an array of Heap::String pointers instead of
indirect String pointers. Later that member along with other GC related members
will go into a managed subclass. Meanwhile the generated code no more loads
String pointers directly but just passes the index into the run-time strings to
the run-time functions, which in turn will load the heap string into a scoped
string.
Also replaced the template<T> Value::operator=(T *m) with a non-template
overload that takes a Managed *, in order to help the compiler choose the
non-template operator=(Heap::Base *) overload. This allows removing a bunch
of Value::fromHeapObject calls.
Change-Id: I20415c0549d33cca6813441a2495976b66d4c00e
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r-- | src/qml/jsruntime/qv4context.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 36 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4function.cpp | 9 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4function_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4functionobject.cpp | 14 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4functionobject_p.h | 1 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4jsonobject.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4lookup.cpp | 134 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4lookup_p.h | 62 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4object.cpp | 12 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 63 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime_p.h | 31 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4scopedvalue_p.h | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4stringobject.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4value_p.h | 8 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 38 |
17 files changed, 237 insertions, 189 deletions
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index 184d47db32..378bcde624 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -387,7 +387,7 @@ ReturnedValue ExecutionContext::getProperty(String *name) return v.asReturnedValue(); } if (f->function() && f->function()->isNamedExpression() - && name->equals(f->function()->name())) + && name->equals(ScopedString(scope, f->function()->name()))) return f.asReturnedValue(); } @@ -458,7 +458,7 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Object *&base) } } if (f->function() && f->function()->isNamedExpression() - && name->equals(f->function()->name())) + && name->equals(ScopedString(scope, f->function()->name()))) return c->d()->function->asReturnedValue(); } diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 78da27683d..8746015ab5 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -337,21 +337,21 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) sequencePrototype = ScopedValue(scope, memoryManager->alloc<SequencePrototype>(arrayClass)); - objectCtor = Value::fromHeapObject(memoryManager->alloc<ObjectCtor>(rootContext)); - stringCtor = Value::fromHeapObject(memoryManager->alloc<StringCtor>(rootContext)); - numberCtor = Value::fromHeapObject(memoryManager->alloc<NumberCtor>(rootContext)); - booleanCtor = Value::fromHeapObject(memoryManager->alloc<BooleanCtor>(rootContext)); - arrayCtor = Value::fromHeapObject(memoryManager->alloc<ArrayCtor>(rootContext)); - functionCtor = Value::fromHeapObject(memoryManager->alloc<FunctionCtor>(rootContext)); - dateCtor = Value::fromHeapObject(memoryManager->alloc<DateCtor>(rootContext)); - regExpCtor = Value::fromHeapObject(memoryManager->alloc<RegExpCtor>(rootContext)); - errorCtor = Value::fromHeapObject(memoryManager->alloc<ErrorCtor>(rootContext)); - evalErrorCtor = Value::fromHeapObject(memoryManager->alloc<EvalErrorCtor>(rootContext)); - rangeErrorCtor = Value::fromHeapObject(memoryManager->alloc<RangeErrorCtor>(rootContext)); - referenceErrorCtor = Value::fromHeapObject(memoryManager->alloc<ReferenceErrorCtor>(rootContext)); - syntaxErrorCtor = Value::fromHeapObject(memoryManager->alloc<SyntaxErrorCtor>(rootContext)); - typeErrorCtor = Value::fromHeapObject(memoryManager->alloc<TypeErrorCtor>(rootContext)); - uRIErrorCtor = Value::fromHeapObject(memoryManager->alloc<URIErrorCtor>(rootContext)); + objectCtor = memoryManager->alloc<ObjectCtor>(rootContext); + stringCtor = memoryManager->alloc<StringCtor>(rootContext); + numberCtor = memoryManager->alloc<NumberCtor>(rootContext); + booleanCtor = memoryManager->alloc<BooleanCtor>(rootContext); + arrayCtor = memoryManager->alloc<ArrayCtor>(rootContext); + functionCtor = memoryManager->alloc<FunctionCtor>(rootContext); + dateCtor = memoryManager->alloc<DateCtor>(rootContext); + regExpCtor = memoryManager->alloc<RegExpCtor>(rootContext); + errorCtor = memoryManager->alloc<ErrorCtor>(rootContext); + evalErrorCtor = memoryManager->alloc<EvalErrorCtor>(rootContext); + rangeErrorCtor = memoryManager->alloc<RangeErrorCtor>(rootContext); + referenceErrorCtor = memoryManager->alloc<ReferenceErrorCtor>(rootContext); + syntaxErrorCtor = memoryManager->alloc<SyntaxErrorCtor>(rootContext); + typeErrorCtor = memoryManager->alloc<TypeErrorCtor>(rootContext); + uRIErrorCtor = memoryManager->alloc<URIErrorCtor>(rootContext); static_cast<ObjectPrototype *>(objectPrototype.getPointer())->init(this, objectCtor.asObject()); static_cast<StringPrototype *>(stringPrototype.getPointer())->init(this, stringCtor.asObject()); @@ -375,18 +375,18 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) // typed arrays - arrayBufferCtor = Value::fromHeapObject(memoryManager->alloc<ArrayBufferCtor>(rootContext)); + arrayBufferCtor = memoryManager->alloc<ArrayBufferCtor>(rootContext); Scoped<ArrayBufferPrototype> arrayBufferPrototype(scope, memoryManager->alloc<ArrayBufferPrototype>(objectClass)); arrayBufferPrototype->init(this, arrayBufferCtor.asObject()); arrayBufferClass = InternalClass::create(this, ArrayBuffer::staticVTable(), arrayBufferPrototype); - dataViewCtor = Value::fromHeapObject(memoryManager->alloc<DataViewCtor>(rootContext)); + dataViewCtor = memoryManager->alloc<DataViewCtor>(rootContext); Scoped<DataViewPrototype> dataViewPrototype(scope, memoryManager->alloc<DataViewPrototype>(objectClass)); dataViewPrototype->init(this, dataViewCtor.asObject()); dataViewClass = InternalClass::create(this, DataView::staticVTable(), dataViewPrototype); for (int i = 0; i < Heap::TypedArray::NTypes; ++i) { - typedArrayCtors[i] = Value::fromHeapObject(memoryManager->alloc<TypedArrayCtor>(rootContext, Heap::TypedArray::Type(i))); + typedArrayCtors[i] = memoryManager->alloc<TypedArrayCtor>(rootContext, Heap::TypedArray::Type(i)); Scoped<TypedArrayPrototype> typedArrayPrototype(scope, memoryManager->alloc<TypedArrayPrototype>(this, Heap::TypedArray::Type(i))); typedArrayPrototype->init(this, static_cast<TypedArrayCtor *>(typedArrayCtors[i].asObject())); typedArrayClasses[i] = InternalClass::create(this, TypedArray::staticVTable(), typedArrayPrototype); diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index de6cc53770..60e6b2c285 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -104,7 +104,7 @@ public: } void pushForGC(Heap::Base *m) { - *jsStackTop = Value::fromHeapObject(m); + *jsStackTop = m; ++jsStackTop; } Heap::Base *popForGC() { diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp index aedbff21be..37e19c559b 100644 --- a/src/qml/jsruntime/qv4function.cpp +++ b/src/qml/jsruntime/qv4function.cpp @@ -56,9 +56,9 @@ Function::Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit, const quint32 *formalsIndices = compiledFunction->formalsTable(); // iterate backwards, so we get the right ordering for duplicate names Scope scope(engine); - ScopedString s(scope); + ScopedString arg(scope); for (int i = static_cast<int>(compiledFunction->nFormals - 1); i >= 0; --i) { - String *arg = compilationUnit->runtimeStrings[formalsIndices[i]]; + arg = compilationUnit->runtimeStrings[formalsIndices[i]]; while (1) { InternalClass *newClass = internalClass->addMember(arg, Attr_NotConfigurable); if (newClass != internalClass) { @@ -66,13 +66,14 @@ Function::Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit, break; } // duplicate arguments, need some trick to store them - arg = (s = engine->memoryManager->alloc<String>(engine, arg->d(), engine->newString(QString(0xfffe)))).getPointer(); + arg = engine->memoryManager->alloc<String>(engine, arg->d(), engine->newString(QString(0xfffe))); } } const quint32 *localsIndices = compiledFunction->localsTable(); + ScopedString local(scope); for (quint32 i = 0; i < compiledFunction->nLocals; ++i) { - String *local = compilationUnit->runtimeStrings[localsIndices[i]]; + 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 8edb8c6be8..47dfe9012e 100644 --- a/src/qml/jsruntime/qv4function_p.h +++ b/src/qml/jsruntime/qv4function_p.h @@ -54,7 +54,7 @@ struct Q_QML_EXPORT Function { ReturnedValue (*codePtr)(ExecutionEngine *, const uchar *)); ~Function(); - inline String *name() { + inline Heap::String *name() { 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 410be02639..7c2ab2cc80 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -71,6 +71,16 @@ Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, QV4::String * f->init(name, createProto); } +Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, Function *function, bool createProto) + : Heap::Object(scope->d()->engine->functionClass) + , scope(scope->d()) +{ + Scope s(scope->engine()); + ScopedString name(s, function->name()); + ScopedFunctionObject f(s, this); + f->init(name, createProto); +} + Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, const QString &name, bool createProto) : Heap::Object(scope->d()->engine->functionClass) , scope(scope->d()) @@ -429,7 +439,7 @@ ReturnedValue ScriptFunction::call(Managed *that, CallData *callData) DEFINE_OBJECT_VTABLE(SimpleScriptFunction); Heap::SimpleScriptFunction::SimpleScriptFunction(QV4::ExecutionContext *scope, Function *function, bool createProto) - : Heap::FunctionObject(scope, function->name(), createProto) + : Heap::FunctionObject(scope, function, createProto) { setVTable(QV4::SimpleScriptFunction::staticVTable()); @@ -468,7 +478,7 @@ ReturnedValue SimpleScriptFunction::construct(Managed *that, CallData *callData) Scoped<SimpleScriptFunction> f(scope, static_cast<SimpleScriptFunction *>(that)); InternalClass *ic = f->internalClassForConstructor(); - callData->thisObject = Value::fromHeapObject(v4->newObject(ic)); + callData->thisObject = v4->newObject(ic); ExecutionContext *context = v4->currentContext(); ExecutionContextSaver ctxSaver(context); diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h index 56d11b2450..6a629f6a49 100644 --- a/src/qml/jsruntime/qv4functionobject_p.h +++ b/src/qml/jsruntime/qv4functionobject_p.h @@ -58,6 +58,7 @@ struct Q_QML_PRIVATE_EXPORT FunctionObject : Object { }; FunctionObject(QV4::ExecutionContext *scope, QV4::String *name, bool createProto = false); + FunctionObject(QV4::ExecutionContext *scope, QV4::Function *function, bool createProto = false); FunctionObject(QV4::ExecutionContext *scope, const QString &name = QString(), bool createProto = false); FunctionObject(ExecutionContext *scope, const QString &name = QString(), bool createProto = false); FunctionObject(QV4::ExecutionContext *scope, const ReturnedValue name); diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp index e7490d2214..76bc757a8c 100644 --- a/src/qml/jsruntime/qv4jsonobject.cpp +++ b/src/qml/jsruntime/qv4jsonobject.cpp @@ -709,7 +709,7 @@ QString Stringify::Str(const QString &key, ValueRef v) if (!!toJSON) { ScopedCallData callData(scope, 1); callData->thisObject = value; - callData->args[0] = Value::fromHeapObject(ctx->d()->engine->newString(key)); + callData->args[0] = ctx->d()->engine->newString(key); value = toJSON->call(callData); } } @@ -718,7 +718,7 @@ QString Stringify::Str(const QString &key, ValueRef v) ScopedObject holder(scope, ctx->d()->engine->newObject()); holder->put(scope.engine, QString(), value); ScopedCallData callData(scope, 2); - callData->args[0] = Value::fromHeapObject(ctx->d()->engine->newString(key)); + callData->args[0] = ctx->d()->engine->newString(key); callData->args[1] = value; callData->thisObject = holder; value = replacerFunction->call(callData); diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp index dde1d6c39e..0266e0504b 100644 --- a/src/qml/jsruntime/qv4lookup.cpp +++ b/src/qml/jsruntime/qv4lookup.cpp @@ -41,6 +41,9 @@ using namespace QV4; ReturnedValue Lookup::lookup(ValueRef thisObject, Object *obj, PropertyAttributes *attrs) { + ExecutionEngine *engine = obj->engine(); + Scope scope(engine); + ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]); int i = 0; while (i < Size && obj) { classList[i] = obj->internalClass(); @@ -72,6 +75,9 @@ ReturnedValue Lookup::lookup(ValueRef thisObject, Object *obj, PropertyAttribute ReturnedValue Lookup::lookup(Object *obj, PropertyAttributes *attrs) { Object *thisObject = obj; + ExecutionEngine *engine = obj->engine(); + Scope scope(engine); + ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]); int i = 0; while (i < Size && obj) { classList[i] = obj->internalClass(); @@ -228,12 +234,11 @@ void Lookup::indexedSetterObjectInt(Lookup *l, const ValueRef object, const Valu indexedSetterFallback(l, object, index, v); } -ReturnedValue Lookup::getterGeneric(QV4::Lookup *l, const ValueRef object) +ReturnedValue Lookup::getterGeneric(Lookup *l, ExecutionEngine *engine, const ValueRef object) { if (Object *o = object->asObject()) return o->getLookup(l); - ExecutionEngine *engine = l->name->engine(); Object *proto; switch (object->type()) { case Value::Undefined_Type: @@ -242,15 +247,18 @@ ReturnedValue Lookup::getterGeneric(QV4::Lookup *l, const ValueRef object) case Value::Boolean_Type: proto = engine->booleanClass->prototype; break; - case Value::Managed_Type: + case Value::Managed_Type: { Q_ASSERT(object->isString()); proto = engine->stringObjectClass->prototype; - if (l->name->equals(engine->id_length.getPointer())) { + Scope scope(engine); + ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[l->nameIndex]); + if (name->equals(engine->id_length.getPointer())) { // special case, as the property is on the object itself l->getter = stringLengthGetter; - return stringLengthGetter(l, object); + return stringLengthGetter(l, engine, object); } break; + } case Value::Integer_Type: default: // Number proto = engine->numberClass->prototype; @@ -279,7 +287,7 @@ ReturnedValue Lookup::getterGeneric(QV4::Lookup *l, const ValueRef object) return Encode::undefined(); } -ReturnedValue Lookup::getterTwoClasses(Lookup *l, const ValueRef object) +ReturnedValue Lookup::getterTwoClasses(Lookup *l, ExecutionEngine *engine, const ValueRef object) { Lookup l1 = *l; @@ -312,20 +320,20 @@ ReturnedValue Lookup::getterTwoClasses(Lookup *l, const ValueRef object) } l->getter = getterFallback; - return getterFallback(l, object); + return getterFallback(l, engine, object); } -ReturnedValue Lookup::getterFallback(Lookup *l, const ValueRef object) +ReturnedValue Lookup::getterFallback(Lookup *l, ExecutionEngine *engine, const ValueRef object) { - QV4::Scope scope(l->name->engine()); + QV4::Scope scope(engine); QV4::ScopedObject o(scope, object->toObject(scope.engine)); if (!o) return Encode::undefined(); - QV4::ScopedString s(scope, l->name); - return o->get(s.getPointer()); + ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[l->nameIndex]); + return o->get(name); } -ReturnedValue Lookup::getter0(Lookup *l, const ValueRef object) +ReturnedValue Lookup::getter0(Lookup *l, ExecutionEngine *engine, const ValueRef object) { if (object->isManaged()) { // we can safely cast to a QV4::Object here. If object is actually a string, @@ -334,10 +342,10 @@ ReturnedValue Lookup::getter0(Lookup *l, const ValueRef object) if (l->classList[0] == o->internalClass()) return o->memberData()->data()[l->index].asReturnedValue(); } - return getterTwoClasses(l, object); + return getterTwoClasses(l, engine, object); } -ReturnedValue Lookup::getter1(Lookup *l, const ValueRef object) +ReturnedValue Lookup::getter1(Lookup *l, ExecutionEngine *engine, const ValueRef object) { if (object->isManaged()) { // we can safely cast to a QV4::Object here. If object is actually a string, @@ -347,10 +355,10 @@ ReturnedValue Lookup::getter1(Lookup *l, const ValueRef object) l->classList[1] == o->prototype()->internalClass()) return o->prototype()->memberData()->data()[l->index].asReturnedValue(); } - return getterTwoClasses(l, object); + return getterTwoClasses(l, engine, object); } -ReturnedValue Lookup::getter2(Lookup *l, const ValueRef object) +ReturnedValue Lookup::getter2(Lookup *l, ExecutionEngine *engine, const ValueRef object) { if (object->isManaged()) { // we can safely cast to a QV4::Object here. If object is actually a string, @@ -366,10 +374,10 @@ ReturnedValue Lookup::getter2(Lookup *l, const ValueRef object) } } l->getter = getterFallback; - return getterFallback(l, object); + return getterFallback(l, engine, object); } -ReturnedValue Lookup::getter0getter0(Lookup *l, const ValueRef object) +ReturnedValue Lookup::getter0getter0(Lookup *l, ExecutionEngine *engine, const ValueRef object) { if (object->isManaged()) { // we can safely cast to a QV4::Object here. If object is actually a string, @@ -381,10 +389,10 @@ ReturnedValue Lookup::getter0getter0(Lookup *l, const ValueRef object) return o->memberData()->data()[l->index2].asReturnedValue(); } l->getter = getterFallback; - return getterFallback(l, object); + return getterFallback(l, engine, object); } -ReturnedValue Lookup::getter0getter1(Lookup *l, const ValueRef object) +ReturnedValue Lookup::getter0getter1(Lookup *l, ExecutionEngine *engine, const ValueRef object) { if (object->isManaged()) { // we can safely cast to a QV4::Object here. If object is actually a string, @@ -397,10 +405,10 @@ ReturnedValue Lookup::getter0getter1(Lookup *l, const ValueRef object) return o->prototype()->memberData()->data()[l->index2].asReturnedValue(); } l->getter = getterFallback; - return getterFallback(l, object); + return getterFallback(l, engine, object); } -ReturnedValue Lookup::getter1getter1(Lookup *l, const ValueRef object) +ReturnedValue Lookup::getter1getter1(Lookup *l, ExecutionEngine *engine, const ValueRef object) { if (object->isManaged()) { // we can safely cast to a QV4::Object here. If object is actually a string, @@ -412,14 +420,14 @@ ReturnedValue Lookup::getter1getter1(Lookup *l, const ValueRef object) if (l->classList[2] == o->internalClass() && l->classList[3] == o->prototype()->internalClass()) return o->prototype()->memberData()->data()[l->index2].asReturnedValue(); - return getterFallback(l, object); + return getterFallback(l, engine, object); } l->getter = getterFallback; - return getterFallback(l, object); + return getterFallback(l, engine, object); } -ReturnedValue Lookup::getterAccessor0(Lookup *l, const ValueRef object) +ReturnedValue Lookup::getterAccessor0(Lookup *l, ExecutionEngine *engine, const ValueRef object) { if (object->isManaged()) { // we can safely cast to a QV4::Object here. If object is actually a string, @@ -437,10 +445,10 @@ ReturnedValue Lookup::getterAccessor0(Lookup *l, const ValueRef object) } } l->getter = getterFallback; - return getterFallback(l, object); + return getterFallback(l, engine, object); } -ReturnedValue Lookup::getterAccessor1(Lookup *l, const ValueRef object) +ReturnedValue Lookup::getterAccessor1(Lookup *l, ExecutionEngine *engine, const ValueRef object) { if (object->isManaged()) { // we can safely cast to a QV4::Object here. If object is actually a string, @@ -459,10 +467,10 @@ ReturnedValue Lookup::getterAccessor1(Lookup *l, const ValueRef object) } } l->getter = getterFallback; - return getterFallback(l, object); + return getterFallback(l, engine, object); } -ReturnedValue Lookup::getterAccessor2(Lookup *l, const ValueRef object) +ReturnedValue Lookup::getterAccessor2(Lookup *l, ExecutionEngine *engine, const ValueRef object) { if (object->isManaged()) { // we can safely cast to a QV4::Object here. If object is actually a string, @@ -486,10 +494,10 @@ ReturnedValue Lookup::getterAccessor2(Lookup *l, const ValueRef object) } } l->getter = getterFallback; - return getterFallback(l, object); + return getterFallback(l, engine, object); } -ReturnedValue Lookup::primitiveGetter0(Lookup *l, const ValueRef object) +ReturnedValue Lookup::primitiveGetter0(Lookup *l, ExecutionEngine *engine, const ValueRef object) { if (object->type() == l->type) { Object *o = l->proto; @@ -497,10 +505,10 @@ ReturnedValue Lookup::primitiveGetter0(Lookup *l, const ValueRef object) return o->memberData()->data()[l->index].asReturnedValue(); } l->getter = getterGeneric; - return getterGeneric(l, object); + return getterGeneric(l, engine, object); } -ReturnedValue Lookup::primitiveGetter1(Lookup *l, const ValueRef object) +ReturnedValue Lookup::primitiveGetter1(Lookup *l, ExecutionEngine *engine, const ValueRef object) { if (object->type() == l->type) { Object *o = l->proto; @@ -509,10 +517,10 @@ ReturnedValue Lookup::primitiveGetter1(Lookup *l, const ValueRef object) return o->prototype()->memberData()->data()[l->index].asReturnedValue(); } l->getter = getterGeneric; - return getterGeneric(l, object); + return getterGeneric(l, engine, object); } -ReturnedValue Lookup::primitiveGetterAccessor0(Lookup *l, const ValueRef object) +ReturnedValue Lookup::primitiveGetterAccessor0(Lookup *l, ExecutionEngine *engine, const ValueRef object) { if (object->type() == l->type) { Object *o = l->proto; @@ -528,10 +536,10 @@ ReturnedValue Lookup::primitiveGetterAccessor0(Lookup *l, const ValueRef object) } } l->getter = getterGeneric; - return getterGeneric(l, object); + return getterGeneric(l, engine, object); } -ReturnedValue Lookup::primitiveGetterAccessor1(Lookup *l, const ValueRef object) +ReturnedValue Lookup::primitiveGetterAccessor1(Lookup *l, ExecutionEngine *engine, const ValueRef object) { if (object->type() == l->type) { Object *o = l->proto; @@ -548,25 +556,25 @@ ReturnedValue Lookup::primitiveGetterAccessor1(Lookup *l, const ValueRef object) } } l->getter = getterGeneric; - return getterGeneric(l, object); + return getterGeneric(l, engine, object); } -ReturnedValue Lookup::stringLengthGetter(Lookup *l, const ValueRef object) +ReturnedValue Lookup::stringLengthGetter(Lookup *l, ExecutionEngine *engine, const ValueRef object) { if (String *s = object->asString()) return Encode(s->d()->length()); l->getter = getterGeneric; - return getterGeneric(l, object); + return getterGeneric(l, engine, object); } -ReturnedValue Lookup::arrayLengthGetter(Lookup *l, const ValueRef object) +ReturnedValue Lookup::arrayLengthGetter(Lookup *l, ExecutionEngine *engine, const ValueRef object) { if (ArrayObject *a = object->asArrayObject()) return a->memberData()->data()[Heap::ArrayObject::LengthPropertyIndex].asReturnedValue(); l->getter = getterGeneric; - return getterGeneric(l, object); + return getterGeneric(l, engine, object); } @@ -595,7 +603,7 @@ ReturnedValue Lookup::globalGetterGeneric(Lookup *l, ExecutionEngine *engine) } } Scope scope(engine); - Scoped<String> n(scope, l->name); + Scoped<String> n(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[l->nameIndex]); return engine->throwReferenceError(n); } @@ -694,22 +702,22 @@ ReturnedValue Lookup::globalGetterAccessor2(Lookup *l, ExecutionEngine *engine) return globalGetterGeneric(l, engine); } -void Lookup::setterGeneric(Lookup *l, const ValueRef object, const ValueRef value) +void Lookup::setterGeneric(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value) { - Scope scope(l->name->engine()); + Scope scope(engine); ScopedObject o(scope, object); if (!o) { o = RuntimeHelpers::convertToObject(scope.engine, object); if (!o) // type error return; - ScopedString s(scope, l->name); - o->put(s.getPointer(), value); + ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[l->nameIndex]); + o->put(name, value); return; } o->setLookup(l, value); } -void Lookup::setterTwoClasses(Lookup *l, const ValueRef object, const ValueRef value) +void Lookup::setterTwoClasses(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value) { Lookup l1 = *l; @@ -725,20 +733,20 @@ void Lookup::setterTwoClasses(Lookup *l, const ValueRef object, const ValueRef v } l->setter = setterFallback; - setterFallback(l, object, value); + setterFallback(l, engine, object, value); } -void Lookup::setterFallback(Lookup *l, const ValueRef object, const ValueRef value) +void Lookup::setterFallback(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value) { - QV4::Scope scope(l->name->engine()); + QV4::Scope scope(engine); QV4::ScopedObject o(scope, object->toObject(scope.engine)); if (o) { - QV4::ScopedString s(scope, l->name); - o->put(s.getPointer(), value); + ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[l->nameIndex]); + o->put(name, value); } } -void Lookup::setter0(Lookup *l, const ValueRef object, const ValueRef value) +void Lookup::setter0(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value) { Object *o = static_cast<Object *>(object->asManaged()); if (o && o->internalClass() == l->classList[0]) { @@ -746,10 +754,10 @@ void Lookup::setter0(Lookup *l, const ValueRef object, const ValueRef value) return; } - setterTwoClasses(l, object, value); + setterTwoClasses(l, engine, object, value); } -void Lookup::setterInsert0(Lookup *l, const ValueRef object, const ValueRef value) +void Lookup::setterInsert0(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value) { Object *o = static_cast<Object *>(object->asManaged()); if (o && o->internalClass() == l->classList[0]) { @@ -763,10 +771,10 @@ void Lookup::setterInsert0(Lookup *l, const ValueRef object, const ValueRef valu } l->setter = setterFallback; - setterFallback(l, object, value); + setterFallback(l, engine, object, value); } -void Lookup::setterInsert1(Lookup *l, const ValueRef object, const ValueRef value) +void Lookup::setterInsert1(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value) { Object *o = static_cast<Object *>(object->asManaged()); if (o && o->internalClass() == l->classList[0]) { @@ -781,10 +789,10 @@ void Lookup::setterInsert1(Lookup *l, const ValueRef object, const ValueRef valu } l->setter = setterFallback; - setterFallback(l, object, value); + setterFallback(l, engine, object, value); } -void Lookup::setterInsert2(Lookup *l, const ValueRef object, const ValueRef value) +void Lookup::setterInsert2(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value) { Object *o = static_cast<Object *>(object->asManaged()); if (o && o->internalClass() == l->classList[0]) { @@ -802,10 +810,10 @@ void Lookup::setterInsert2(Lookup *l, const ValueRef object, const ValueRef valu } l->setter = setterFallback; - setterFallback(l, object, value); + setterFallback(l, engine, object, value); } -void Lookup::setter0setter0(Lookup *l, const ValueRef object, const ValueRef value) +void Lookup::setter0setter0(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value) { Object *o = static_cast<Object *>(object->asManaged()); if (o) { @@ -820,7 +828,7 @@ void Lookup::setter0setter0(Lookup *l, const ValueRef object, const ValueRef val } l->setter = setterFallback; - setterFallback(l, object, value); + setterFallback(l, engine, object, value); } diff --git a/src/qml/jsruntime/qv4lookup_p.h b/src/qml/jsruntime/qv4lookup_p.h index a46e712606..d491a62ddc 100644 --- a/src/qml/jsruntime/qv4lookup_p.h +++ b/src/qml/jsruntime/qv4lookup_p.h @@ -49,9 +49,9 @@ struct Lookup { union { ReturnedValue (*indexedGetter)(Lookup *l, const ValueRef object, const ValueRef index); void (*indexedSetter)(Lookup *l, const ValueRef object, const ValueRef index, const ValueRef v); - ReturnedValue (*getter)(Lookup *l, const ValueRef object); + ReturnedValue (*getter)(Lookup *l, ExecutionEngine *engine, const ValueRef object); ReturnedValue (*globalGetter)(Lookup *l, ExecutionEngine *engine); - void (*setter)(Lookup *l, const ValueRef object, const ValueRef v); + void (*setter)(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef v); }; union { ExecutionEngine *engine; @@ -68,7 +68,7 @@ struct Lookup { uint index2; }; uint index; - String *name; + uint nameIndex; static ReturnedValue indexedGetterGeneric(Lookup *l, const ValueRef object, const ValueRef index); static ReturnedValue indexedGetterFallback(Lookup *l, const ValueRef object, const ValueRef index); @@ -78,26 +78,26 @@ struct Lookup { static void indexedSetterFallback(Lookup *l, const ValueRef object, const ValueRef index, const ValueRef value); static void indexedSetterObjectInt(Lookup *l, const ValueRef object, const ValueRef index, const ValueRef v); - static ReturnedValue getterGeneric(Lookup *l, const ValueRef object); - static ReturnedValue getterTwoClasses(Lookup *l, const ValueRef object); - static ReturnedValue getterFallback(Lookup *l, const ValueRef object); - - static ReturnedValue getter0(Lookup *l, const ValueRef object); - static ReturnedValue getter1(Lookup *l, const ValueRef object); - static ReturnedValue getter2(Lookup *l, const ValueRef object); - static ReturnedValue getter0getter0(Lookup *l, const ValueRef object); - static ReturnedValue getter0getter1(Lookup *l, const ValueRef object); - static ReturnedValue getter1getter1(Lookup *l, const ValueRef object); - static ReturnedValue getterAccessor0(Lookup *l, const ValueRef object); - static ReturnedValue getterAccessor1(Lookup *l, const ValueRef object); - static ReturnedValue getterAccessor2(Lookup *l, const ValueRef object); - - static ReturnedValue primitiveGetter0(Lookup *l, const ValueRef object); - static ReturnedValue primitiveGetter1(Lookup *l, const ValueRef object); - static ReturnedValue primitiveGetterAccessor0(Lookup *l, const ValueRef object); - static ReturnedValue primitiveGetterAccessor1(Lookup *l, const ValueRef object); - static ReturnedValue stringLengthGetter(Lookup *l, const ValueRef object); - static ReturnedValue arrayLengthGetter(Lookup *l, const ValueRef object); + static ReturnedValue getterGeneric(Lookup *l, ExecutionEngine *engine, const ValueRef object); + static ReturnedValue getterTwoClasses(Lookup *l, ExecutionEngine *engine, const ValueRef object); + static ReturnedValue getterFallback(Lookup *l, ExecutionEngine *engine, const ValueRef object); + + static ReturnedValue getter0(Lookup *l, ExecutionEngine *engine, const ValueRef object); + static ReturnedValue getter1(Lookup *l, ExecutionEngine *engine, const ValueRef object); + static ReturnedValue getter2(Lookup *l, ExecutionEngine *engine, const ValueRef object); + static ReturnedValue getter0getter0(Lookup *l, ExecutionEngine *engine, const ValueRef object); + static ReturnedValue getter0getter1(Lookup *l, ExecutionEngine *engine, const ValueRef object); + static ReturnedValue getter1getter1(Lookup *l, ExecutionEngine *engine, const ValueRef object); + static ReturnedValue getterAccessor0(Lookup *l, ExecutionEngine *engine, const ValueRef object); + static ReturnedValue getterAccessor1(Lookup *l, ExecutionEngine *engine, const ValueRef object); + static ReturnedValue getterAccessor2(Lookup *l, ExecutionEngine *engine, const ValueRef object); + + static ReturnedValue primitiveGetter0(Lookup *l, ExecutionEngine *engine, const ValueRef object); + static ReturnedValue primitiveGetter1(Lookup *l, ExecutionEngine *engine, const ValueRef object); + static ReturnedValue primitiveGetterAccessor0(Lookup *l, ExecutionEngine *engine, const ValueRef object); + static ReturnedValue primitiveGetterAccessor1(Lookup *l, ExecutionEngine *engine, const ValueRef object); + static ReturnedValue stringLengthGetter(Lookup *l, ExecutionEngine *engine, const ValueRef object); + static ReturnedValue arrayLengthGetter(Lookup *l, ExecutionEngine *engine, const ValueRef object); static ReturnedValue globalGetterGeneric(Lookup *l, ExecutionEngine *engine); static ReturnedValue globalGetter0(Lookup *l, ExecutionEngine *engine); @@ -107,14 +107,14 @@ struct Lookup { static ReturnedValue globalGetterAccessor1(Lookup *l, ExecutionEngine *engine); static ReturnedValue globalGetterAccessor2(Lookup *l, ExecutionEngine *engine); - static void setterGeneric(Lookup *l, const ValueRef object, const ValueRef value); - static void setterTwoClasses(Lookup *l, const ValueRef object, const ValueRef value); - static void setterFallback(Lookup *l, const ValueRef object, const ValueRef value); - static void setter0(Lookup *l, const ValueRef object, const ValueRef value); - static void setterInsert0(Lookup *l, const ValueRef object, const ValueRef value); - static void setterInsert1(Lookup *l, const ValueRef object, const ValueRef value); - static void setterInsert2(Lookup *l, const ValueRef object, const ValueRef value); - static void setter0setter0(Lookup *l, const ValueRef object, const ValueRef value); + static void setterGeneric(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value); + static void setterTwoClasses(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value); + static void setterFallback(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value); + static void setter0(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value); + static void setterInsert0(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value); + static void setterInsert1(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value); + static void setterInsert2(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value); + static void setter0setter0(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value); ReturnedValue lookup(ValueRef thisObject, Object *obj, PropertyAttributes *attrs); ReturnedValue lookup(Object *obj, PropertyAttributes *attrs); diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index 29c2528d95..d95c8cf444 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -458,9 +458,10 @@ void Object::setLookup(Managed *m, Lookup *l, const ValueRef value) { Scope scope(m->engine()); ScopedObject o(scope, static_cast<Object *>(m)); + ScopedString name(scope, scope.engine->currentContext()->d()->compilationUnit->runtimeStrings[l->nameIndex]); InternalClass *c = o->internalClass(); - uint idx = c->find(l->name); + uint idx = c->find(name); if (!o->isArrayObject() || idx != Heap::ArrayObject::LengthPropertyIndex) { if (idx != UINT_MAX && o->internalClass()->propertyData[idx].isData() && o->internalClass()->propertyData[idx].isWritable()) { l->classList[0] = o->internalClass(); @@ -476,12 +477,11 @@ void Object::setLookup(Managed *m, Lookup *l, const ValueRef value) } } - ScopedString s(scope, l->name); - o->put(s.getPointer(), value); + o->put(name, value); if (o->internalClass() == c) return; - idx = o->internalClass()->find(l->name); + idx = o->internalClass()->find(name); if (idx == UINT_MAX) return; l->classList[0] = c; @@ -1150,7 +1150,9 @@ Heap::ArrayObject::ArrayObject(ExecutionEngine *engine, const QStringList &list) ReturnedValue ArrayObject::getLookup(Managed *m, Lookup *l) { - if (l->name->equals(m->engine()->id_length)) { + Scope scope(m->engine()); + ScopedString name(scope, m->engine()->currentContext()->d()->compilationUnit->runtimeStrings[l->nameIndex]); + if (name->equals(m->engine()->id_length)) { // special case, as the property is on the object itself l->getter = Lookup::arrayLengthGetter; ArrayObject *a = static_cast<ArrayObject *>(m); diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index e4f97b2000..eab8498539 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -275,10 +275,17 @@ ReturnedValue Runtime::deleteElement(ExecutionEngine *engine, const ValueRef bas } ScopedString name(scope, index->toString(engine)); - return Runtime::deleteMember(engine, base, name.getPointer()); + return Runtime::deleteMemberString(engine, base, name.getPointer()); } -ReturnedValue Runtime::deleteMember(ExecutionEngine *engine, const ValueRef base, String *name) +ReturnedValue Runtime::deleteMember(ExecutionEngine *engine, const ValueRef base, int nameIndex) +{ + Scope scope(engine); + ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]); + return deleteMemberString(engine, base, name); +} + +ReturnedValue Runtime::deleteMemberString(ExecutionEngine *engine, const ValueRef base, String *name) { Scope scope(engine); ScopedObject obj(scope, base->toObject(engine)); @@ -287,9 +294,10 @@ ReturnedValue Runtime::deleteMember(ExecutionEngine *engine, const ValueRef base return Encode(obj->deleteProperty(name)); } -ReturnedValue Runtime::deleteName(ExecutionEngine *engine, String *name) +ReturnedValue Runtime::deleteName(ExecutionEngine *engine, int nameIndex) { Scope scope(engine); + ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]); return Encode(engine->currentContext()->deleteProperty(name)); } @@ -543,9 +551,10 @@ QV4::ReturnedValue Runtime::addString(ExecutionEngine *engine, const QV4::ValueR return (engine->memoryManager->alloc<String>(engine, pleft->stringValue()->d(), pright->stringValue()->d()))->asReturnedValue(); } -void Runtime::setProperty(ExecutionEngine *engine, const ValueRef object, String *name, const ValueRef value) +void Runtime::setProperty(ExecutionEngine *engine, const ValueRef object, int nameIndex, const ValueRef value) { Scope scope(engine); + ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]); ScopedObject o(scope, object->toObject(engine)); if (!o) return; @@ -639,14 +648,17 @@ ReturnedValue Runtime::foreachNextPropertyName(const ValueRef foreach_iterator) } -void Runtime::setActivationProperty(ExecutionEngine *engine, String *name, const ValueRef value) +void Runtime::setActivationProperty(ExecutionEngine *engine, int nameIndex, const ValueRef value) { + Scope scope(engine); + ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]); engine->currentContext()->setProperty(name, value); } -ReturnedValue Runtime::getProperty(ExecutionEngine *engine, const ValueRef object, String *name) +ReturnedValue Runtime::getProperty(ExecutionEngine *engine, const ValueRef object, int nameIndex) { Scope scope(engine); + ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]); Scoped<Object> o(scope, object); if (o) @@ -663,8 +675,10 @@ ReturnedValue Runtime::getProperty(ExecutionEngine *engine, const ValueRef objec return o->get(name); } -ReturnedValue Runtime::getActivationProperty(ExecutionEngine *engine, String *name) +ReturnedValue Runtime::getActivationProperty(ExecutionEngine *engine, int nameIndex) { + Scope scope(engine); + ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]); return engine->currentContext()->getProperty(name); } @@ -886,17 +900,19 @@ ReturnedValue Runtime::callGlobalLookup(ExecutionEngine *engine, uint index, Cal if (!o) return engine->throwTypeError(); - if (o.getPointer() == scope.engine->evalFunction && l->name->equals(scope.engine->id_eval)) + ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[l->nameIndex]); + if (o.getPointer() == scope.engine->evalFunction && name->equals(scope.engine->id_eval)) return static_cast<EvalFunction *>(o.getPointer())->evalCall(callData, true); return o->call(callData); } -ReturnedValue Runtime::callActivationProperty(ExecutionEngine *engine, String *name, CallData *callData) +ReturnedValue Runtime::callActivationProperty(ExecutionEngine *engine, int nameIndex, CallData *callData) { Q_ASSERT(callData->thisObject.isUndefined()); Scope scope(engine); + ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]); ScopedObject base(scope); Object *baseObj = 0; @@ -924,9 +940,10 @@ ReturnedValue Runtime::callActivationProperty(ExecutionEngine *engine, String *n return o->call(callData); } -ReturnedValue Runtime::callProperty(ExecutionEngine *engine, String *name, CallData *callData) +ReturnedValue Runtime::callProperty(ExecutionEngine *engine, int nameIndex, CallData *callData) { Scope scope(engine); + ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]); Scoped<Object> baseObject(scope, callData->thisObject); if (!baseObject) { Q_ASSERT(!callData->thisObject.isEmpty()); @@ -954,7 +971,7 @@ ReturnedValue Runtime::callPropertyLookup(ExecutionEngine *engine, uint index, C { Lookup *l = engine->currentContext()->d()->lookups + index; Value v; - v = l->getter(l, callData->thisObject); + v = l->getter(l, engine, callData->thisObject); if (!v.isObject()) return engine->throwTypeError(); @@ -1001,9 +1018,10 @@ ReturnedValue Runtime::constructGlobalLookup(ExecutionEngine *engine, uint index } -ReturnedValue Runtime::constructActivationProperty(ExecutionEngine *engine, String *name, CallData *callData) +ReturnedValue Runtime::constructActivationProperty(ExecutionEngine *engine, int nameIndex, CallData *callData) { Scope scope(engine); + ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]); ScopedValue func(scope, engine->currentContext()->getProperty(name)); if (scope.engine->hasException) return Encode::undefined(); @@ -1024,10 +1042,11 @@ ReturnedValue Runtime::constructValue(ExecutionEngine *engine, const ValueRef fu return f->construct(callData); } -ReturnedValue Runtime::constructProperty(ExecutionEngine *engine, String *name, CallData *callData) +ReturnedValue Runtime::constructProperty(ExecutionEngine *engine, int nameIndex, CallData *callData) { Scope scope(engine); ScopedObject thisObject(scope, callData->thisObject.toObject(engine)); + ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]); if (scope.engine->hasException) return Encode::undefined(); @@ -1042,7 +1061,7 @@ ReturnedValue Runtime::constructPropertyLookup(ExecutionEngine *engine, uint ind { Lookup *l = engine->currentContext()->d()->lookups + index; Value v; - v = l->getter(l, callData->thisObject); + v = l->getter(l, engine, callData->thisObject); if (!v.isObject()) return engine->throwTypeError(); @@ -1085,18 +1104,20 @@ ReturnedValue Runtime::typeofValue(ExecutionEngine *engine, const ValueRef value return res.asReturnedValue(); } -QV4::ReturnedValue Runtime::typeofName(ExecutionEngine *engine, String *name) +QV4::ReturnedValue Runtime::typeofName(ExecutionEngine *engine, int nameIndex) { Scope scope(engine); + ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]); ScopedValue prop(scope, engine->currentContext()->getProperty(name)); // typeof doesn't throw. clear any possible exception scope.engine->hasException = false; return Runtime::typeofValue(engine, prop); } -QV4::ReturnedValue Runtime::typeofMember(ExecutionEngine *engine, const ValueRef base, String *name) +QV4::ReturnedValue Runtime::typeofMember(ExecutionEngine *engine, const ValueRef base, int nameIndex) { Scope scope(engine); + ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]); ScopedObject obj(scope, base->toObject(engine)); if (scope.engine->hasException) return Encode::undefined(); @@ -1129,10 +1150,11 @@ ReturnedValue Runtime::unwindException(ExecutionEngine *engine) return engine->catchException(0); } -void Runtime::pushCatchScope(NoThrowEngine *engine, String *exceptionVarName) +void Runtime::pushCatchScope(NoThrowEngine *engine, int exceptionVarNameIndex) { Scope scope(engine); ScopedValue v(scope, engine->catchException(0)); + ScopedString exceptionVarName(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[exceptionVarNameIndex]); engine->currentContext()->newCatchContext(exceptionVarName, v); } @@ -1141,8 +1163,10 @@ void Runtime::popScope(ExecutionEngine *engine) engine->popContext(); } -void Runtime::declareVar(ExecutionEngine *engine, bool deletable, String *name) +void Runtime::declareVar(ExecutionEngine *engine, bool deletable, int nameIndex) { + Scope scope(engine); + ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]); engine->currentContext()->createMutableBinding(name, deletable); } @@ -1370,9 +1394,10 @@ ReturnedValue Runtime::getQmlImportedScripts(NoThrowEngine *engine) return context->importedScripts.value(); } -QV4::ReturnedValue Runtime::getQmlSingleton(QV4::NoThrowEngine *engine, String *name) +QV4::ReturnedValue Runtime::getQmlSingleton(QV4::NoThrowEngine *engine, int nameIndex) { Scope scope(engine); + ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]); Scoped<QmlContextWrapper> wrapper(scope, engine->qmlContextObject()); return wrapper->qmlSingletonWrapper(engine->v8Engine, name); } diff --git a/src/qml/jsruntime/qv4runtime_p.h b/src/qml/jsruntime/qv4runtime_p.h index 6be64aa8ea..ee3aeb2392 100644 --- a/src/qml/jsruntime/qv4runtime_p.h +++ b/src/qml/jsruntime/qv4runtime_p.h @@ -89,50 +89,51 @@ struct NoThrowEngine : public ExecutionEngine struct Q_QML_PRIVATE_EXPORT Runtime { // call static ReturnedValue callGlobalLookup(ExecutionEngine *engine, uint index, CallData *callData); - static ReturnedValue callActivationProperty(ExecutionEngine *engine, String *name, CallData *callData); - static ReturnedValue callProperty(ExecutionEngine *engine, String *name, CallData *callData); + static ReturnedValue callActivationProperty(ExecutionEngine *engine, int nameIndex, CallData *callData); + static ReturnedValue callProperty(ExecutionEngine *engine, int nameIndex, CallData *callData); static ReturnedValue callPropertyLookup(ExecutionEngine *engine, uint index, CallData *callData); static ReturnedValue callElement(ExecutionEngine *engine, const ValueRef index, CallData *callData); static ReturnedValue callValue(ExecutionEngine *engine, const ValueRef func, CallData *callData); // construct static ReturnedValue constructGlobalLookup(ExecutionEngine *engine, uint index, CallData *callData); - static ReturnedValue constructActivationProperty(ExecutionEngine *engine, String *name, CallData *callData); - static ReturnedValue constructProperty(ExecutionEngine *engine, String *name, CallData *callData); + static ReturnedValue constructActivationProperty(ExecutionEngine *engine, int nameIndex, CallData *callData); + static ReturnedValue constructProperty(ExecutionEngine *engine, int nameIndex, CallData *callData); static ReturnedValue constructPropertyLookup(ExecutionEngine *engine, uint index, CallData *callData); static ReturnedValue constructValue(ExecutionEngine *engine, const ValueRef func, CallData *callData); // set & get - static void setActivationProperty(ExecutionEngine *engine, String *name, const ValueRef value); - static void setProperty(ExecutionEngine *engine, const ValueRef object, String *name, const ValueRef value); + static void setActivationProperty(ExecutionEngine *engine, int nameIndex, const ValueRef value); + static void setProperty(ExecutionEngine *engine, const ValueRef object, int nameIndex, const ValueRef value); static void setElement(ExecutionEngine *engine, const ValueRef object, const ValueRef index, const ValueRef value); - static ReturnedValue getProperty(ExecutionEngine *engine, const ValueRef object, String *name); - static ReturnedValue getActivationProperty(ExecutionEngine *engine, String *name); + static ReturnedValue getProperty(ExecutionEngine *engine, const ValueRef object, int nameIndex); + static ReturnedValue getActivationProperty(ExecutionEngine *engine, int nameIndex); static ReturnedValue getElement(ExecutionEngine *engine, const ValueRef object, const ValueRef index); // typeof static ReturnedValue typeofValue(ExecutionEngine *engine, const ValueRef val); - static ReturnedValue typeofName(ExecutionEngine *engine, String *name); - static ReturnedValue typeofMember(ExecutionEngine *engine, const ValueRef base, String *name); + static ReturnedValue typeofName(ExecutionEngine *engine, int nameIndex); + static ReturnedValue typeofMember(ExecutionEngine *engine, const ValueRef base, int nameIndex); static ReturnedValue typeofElement(ExecutionEngine *engine, const ValueRef base, const ValueRef index); // delete static ReturnedValue deleteElement(ExecutionEngine *engine, const ValueRef base, const ValueRef index); - static ReturnedValue deleteMember(ExecutionEngine *engine, const ValueRef base, String *name); - static ReturnedValue deleteName(ExecutionEngine *engine, String *name); + static ReturnedValue deleteMember(ExecutionEngine *engine, const ValueRef base, int nameIndex); + static ReturnedValue deleteMemberString(ExecutionEngine *engine, const ValueRef base, String *name); + static ReturnedValue deleteName(ExecutionEngine *engine, int nameIndex); // exceptions & scopes static void throwException(ExecutionEngine *engine, const ValueRef value); static ReturnedValue unwindException(ExecutionEngine *engine); static void pushWithScope(const ValueRef o, NoThrowEngine *engine); - static void pushCatchScope(NoThrowEngine *engine, String *exceptionVarName); + static void pushCatchScope(NoThrowEngine *engine, int exceptionVarNameIndex); static void popScope(ExecutionEngine *engine); // closures static ReturnedValue closure(ExecutionEngine *engine, int functionId); // function header - static void declareVar(ExecutionEngine *engine, bool deletable, String *name); + static void declareVar(ExecutionEngine *engine, bool deletable, int nameIndex); static ReturnedValue setupArgumentsObject(ExecutionEngine *engine); static void convertThisToObject(ExecutionEngine *engine); @@ -209,7 +210,7 @@ struct Q_QML_PRIVATE_EXPORT Runtime { static ReturnedValue getQmlImportedScripts(NoThrowEngine *ctx); static ReturnedValue getQmlContextObject(NoThrowEngine *ctx); static ReturnedValue getQmlScopeObject(NoThrowEngine *ctx); - static ReturnedValue getQmlSingleton(NoThrowEngine *ctx, String *name); + static ReturnedValue getQmlSingleton(NoThrowEngine *ctx, int nameIndex); static ReturnedValue getQmlAttachedProperty(ExecutionEngine *engine, int attachedPropertiesId, int propertyIndex); static ReturnedValue getQmlQObjectProperty(ExecutionEngine *engine, const ValueRef object, int propertyIndex, bool captureRequired); static ReturnedValue getQmlSingletonQObjectProperty(ExecutionEngine *engine, const ValueRef object, int propertyIndex, bool captureRequired); diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h index f5729348f1..35e078a5f9 100644 --- a/src/qml/jsruntime/qv4scopedvalue_p.h +++ b/src/qml/jsruntime/qv4scopedvalue_p.h @@ -256,7 +256,7 @@ struct Scoped Scoped(const Scope &scope, typename T::Data *t) { ptr = scope.engine->jsStackTop++; - *ptr = Value::fromHeapObject(t); + *ptr = t; #ifndef QT_NO_DEBUG ++scope.size; #endif @@ -298,7 +298,7 @@ struct Scoped return *this; } Scoped<T> &operator=(typename T::Data *t) { - *ptr = Value::fromHeapObject(t); + *ptr = t; return *this; } Scoped<T> &operator=(const Value &v) { diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp index 64e373babb..d571584310 100644 --- a/src/qml/jsruntime/qv4stringobject.cpp +++ b/src/qml/jsruntime/qv4stringobject.cpp @@ -556,7 +556,7 @@ ReturnedValue StringPrototype::method_replace(CallContext *ctx) Q_ASSERT(matchStart >= static_cast<uint>(lastEnd)); uint matchEnd = matchOffsets[i * numCaptures * 2 + 1]; callData->args[numCaptures] = Primitive::fromUInt32(matchStart); - callData->args[numCaptures + 1] = Value::fromHeapObject(ctx->d()->engine->newString(string)); + callData->args[numCaptures + 1] = ctx->d()->engine->newString(string); replacement = searchCallback->call(callData); result += string.midRef(lastEnd, matchStart - lastEnd); diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h index c713f6a147..cbbe88bd76 100644 --- a/src/qml/jsruntime/qv4value_p.h +++ b/src/qml/jsruntime/qv4value_p.h @@ -373,13 +373,15 @@ struct Q_QML_PRIVATE_EXPORT Value Value &operator =(const ScopedValue &v); Value &operator=(ReturnedValue v) { val = v; return *this; } - template<typename T> - Value &operator=(T *t) { - val = Value::fromManaged(t).val; + Value &operator=(Managed *m) { + val = Value::fromManaged(m).val; return *this; } Value &operator=(Heap::Base *o) { m = o; +#if QT_POINTER_SIZE == 4 + tag = Managed_Type; +#endif return *this; } diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index 37dcb3487b..07f70d3604 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -184,8 +184,6 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code qDebug("Starting VME with context=%p and code=%p", context, code); #endif // DO_TRACE_INSTR - QV4::String ** const runtimeStrings = context->d()->compilationUnit->runtimeStrings; - // setup lookup scopes int scopeDepth = 0; { @@ -240,7 +238,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, 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) = context->d()->compilationUnit->runtimeStrings[instr.stringId]; MOTH_END_INSTR(LoadRuntimeString) MOTH_BEGIN_INSTR(LoadRegExp) @@ -254,7 +252,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code MOTH_BEGIN_INSTR(LoadName) TRACE(inline, "property name = %s", runtimeStrings[instr.name]->toQString().toUtf8().constData()); - STOREVALUE(instr.result, Runtime::getActivationProperty(engine, runtimeStrings[instr.name])); + STOREVALUE(instr.result, Runtime::getActivationProperty(engine, instr.name)); MOTH_END_INSTR(LoadName) MOTH_BEGIN_INSTR(GetGlobalLookup) @@ -265,7 +263,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code MOTH_BEGIN_INSTR(StoreName) TRACE(inline, "property name = %s", runtimeStrings[instr.name]->toQString().toUtf8().constData()); - Runtime::setActivationProperty(engine, runtimeStrings[instr.name], VALUEPTR(instr.source)); + Runtime::setActivationProperty(engine, instr.name, VALUEPTR(instr.source)); CHECK_EXCEPTION; MOTH_END_INSTR(StoreName) @@ -290,22 +288,22 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code MOTH_END_INSTR(StoreElementLookup) MOTH_BEGIN_INSTR(LoadProperty) - STOREVALUE(instr.result, Runtime::getProperty(engine, VALUEPTR(instr.base), runtimeStrings[instr.name])); + STOREVALUE(instr.result, Runtime::getProperty(engine, VALUEPTR(instr.base), instr.name)); MOTH_END_INSTR(LoadProperty) MOTH_BEGIN_INSTR(GetLookup) QV4::Lookup *l = context->d()->lookups + instr.index; - STOREVALUE(instr.result, l->getter(l, VALUEPTR(instr.base))); + STOREVALUE(instr.result, l->getter(l, engine, VALUEPTR(instr.base))); MOTH_END_INSTR(GetLookup) MOTH_BEGIN_INSTR(StoreProperty) - Runtime::setProperty(engine, VALUEPTR(instr.base), runtimeStrings[instr.name], VALUEPTR(instr.source)); + Runtime::setProperty(engine, VALUEPTR(instr.base), instr.name, VALUEPTR(instr.source)); CHECK_EXCEPTION; MOTH_END_INSTR(StoreProperty) MOTH_BEGIN_INSTR(SetLookup) QV4::Lookup *l = context->d()->lookups + instr.index; - l->setter(l, VALUEPTR(instr.base), VALUEPTR(instr.source)); + l->setter(l, engine, VALUEPTR(instr.base), VALUEPTR(instr.source)); CHECK_EXCEPTION; MOTH_END_INSTR(SetLookup) @@ -362,7 +360,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code callData->tag = QV4::Value::Integer_Type; callData->argc = instr.argc; callData->thisObject = VALUE(instr.base); - STOREVALUE(instr.result, Runtime::callProperty(engine, runtimeStrings[instr.name], callData)); + STOREVALUE(instr.result, Runtime::callProperty(engine, instr.name, callData)); MOTH_END_INSTR(CallProperty) MOTH_BEGIN_INSTR(CallPropertyLookup) @@ -391,7 +389,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code callData->tag = QV4::Value::Integer_Type; callData->argc = instr.argc; callData->thisObject = QV4::Primitive::undefinedValue(); - STOREVALUE(instr.result, Runtime::callActivationProperty(engine, runtimeStrings[instr.name], callData)); + STOREVALUE(instr.result, Runtime::callActivationProperty(engine, instr.name, callData)); MOTH_END_INSTR(CallActivationProperty) MOTH_BEGIN_INSTR(CallGlobalLookup) @@ -418,7 +416,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code MOTH_END_INSTR(CallBuiltinUnwindException) MOTH_BEGIN_INSTR(CallBuiltinPushCatchScope) - Runtime::pushCatchScope(static_cast<QV4::NoThrowEngine*>(engine), runtimeStrings[instr.name]); + Runtime::pushCatchScope(static_cast<QV4::NoThrowEngine*>(engine), instr.name); context = engine->currentContext(); MOTH_END_INSTR(CallBuiltinPushCatchScope) @@ -441,7 +439,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code MOTH_END_INSTR(CallBuiltinForeachNextPropertyName) MOTH_BEGIN_INSTR(CallBuiltinDeleteMember) - STOREVALUE(instr.result, Runtime::deleteMember(engine, VALUEPTR(instr.base), runtimeStrings[instr.member])); + STOREVALUE(instr.result, Runtime::deleteMember(engine, VALUEPTR(instr.base), instr.member)); MOTH_END_INSTR(CallBuiltinDeleteMember) MOTH_BEGIN_INSTR(CallBuiltinDeleteSubscript) @@ -449,11 +447,11 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code MOTH_END_INSTR(CallBuiltinDeleteSubscript) MOTH_BEGIN_INSTR(CallBuiltinDeleteName) - STOREVALUE(instr.result, Runtime::deleteName(engine, runtimeStrings[instr.name])); + STOREVALUE(instr.result, Runtime::deleteName(engine, instr.name)); MOTH_END_INSTR(CallBuiltinDeleteName) MOTH_BEGIN_INSTR(CallBuiltinTypeofMember) - STOREVALUE(instr.result, Runtime::typeofMember(engine, VALUEPTR(instr.base), runtimeStrings[instr.member])); + STOREVALUE(instr.result, Runtime::typeofMember(engine, VALUEPTR(instr.base), instr.member)); MOTH_END_INSTR(CallBuiltinTypeofMember) MOTH_BEGIN_INSTR(CallBuiltinTypeofSubscript) @@ -461,7 +459,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code MOTH_END_INSTR(CallBuiltinTypeofSubscript) MOTH_BEGIN_INSTR(CallBuiltinTypeofName) - STOREVALUE(instr.result, Runtime::typeofName(engine, runtimeStrings[instr.name])); + STOREVALUE(instr.result, Runtime::typeofName(engine, instr.name)); MOTH_END_INSTR(CallBuiltinTypeofName) MOTH_BEGIN_INSTR(CallBuiltinTypeofValue) @@ -469,7 +467,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code MOTH_END_INSTR(CallBuiltinTypeofValue) MOTH_BEGIN_INSTR(CallBuiltinDeclareVar) - Runtime::declareVar(engine, instr.isDeletable, runtimeStrings[instr.varName]); + Runtime::declareVar(engine, instr.isDeletable, instr.varName); MOTH_END_INSTR(CallBuiltinDeclareVar) MOTH_BEGIN_INSTR(CallBuiltinDefineArray) @@ -507,7 +505,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code callData->tag = QV4::Value::Integer_Type; callData->argc = instr.argc; callData->thisObject = VALUE(instr.base); - STOREVALUE(instr.result, Runtime::constructProperty(engine, runtimeStrings[instr.name], callData)); + STOREVALUE(instr.result, Runtime::constructProperty(engine, instr.name, callData)); MOTH_END_INSTR(CreateProperty) MOTH_BEGIN_INSTR(ConstructPropertyLookup) @@ -526,7 +524,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code callData->tag = QV4::Value::Integer_Type; callData->argc = instr.argc; callData->thisObject = QV4::Primitive::undefinedValue(); - STOREVALUE(instr.result, Runtime::constructActivationProperty(engine, runtimeStrings[instr.name], callData)); + STOREVALUE(instr.result, Runtime::constructActivationProperty(engine, instr.name, callData)); MOTH_END_INSTR(CreateActivationProperty) MOTH_BEGIN_INSTR(ConstructGlobalLookup) @@ -691,7 +689,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code MOTH_END_INSTR(LoadScopeObject) MOTH_BEGIN_INSTR(LoadQmlSingleton) - VALUE(instr.result) = Runtime::getQmlSingleton(static_cast<QV4::NoThrowEngine*>(engine), runtimeStrings[instr.name]); + VALUE(instr.result) = Runtime::getQmlSingleton(static_cast<QV4::NoThrowEngine*>(engine), instr.name); MOTH_END_INSTR(LoadQmlSingleton) #ifdef MOTH_THREADED_INTERPRETER |