diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/compiler/qv4isel_moth.cpp | 4 | ||||
-rw-r--r-- | src/qml/jit/qv4isel_masm.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 104 |
3 files changed, 83 insertions, 29 deletions
diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp index aefb084971..dc6fe317e5 100644 --- a/src/qml/compiler/qv4isel_moth.cpp +++ b/src/qml/compiler/qv4isel_moth.cpp @@ -638,7 +638,7 @@ void InstructionSelection::getQObjectProperty(IR::Expr *base, int propertyIndex, void InstructionSelection::getElement(IR::Expr *base, IR::Expr *index, IR::Expr *target) { - if (useFastLookups) { + if (0 && useFastLookups) { Instruction::LoadElementLookup load; load.lookup = registerIndexedGetterLookup(); load.base = getParam(base); @@ -657,7 +657,7 @@ void InstructionSelection::getElement(IR::Expr *base, IR::Expr *index, IR::Expr void InstructionSelection::setElement(IR::Expr *source, IR::Expr *targetBase, IR::Expr *targetIndex) { - if (useFastLookups) { + if (0 && useFastLookups) { Instruction::StoreElementLookup store; store.lookup = registerIndexedSetterLookup(); store.base = getParam(targetBase); diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp index ac72d2e8f5..50d40f6f98 100644 --- a/src/qml/jit/qv4isel_masm.cpp +++ b/src/qml/jit/qv4isel_masm.cpp @@ -618,7 +618,7 @@ void InstructionSelection<JITAssembler>::setQObjectProperty(IR::Expr *source, IR template <typename JITAssembler> void InstructionSelection<JITAssembler>::getElement(IR::Expr *base, IR::Expr *index, IR::Expr *target) { - if (useFastLookups) { + if (0 && useFastLookups) { uint lookup = registerIndexedGetterLookup(); generateLookupCall(target, lookup, offsetof(QV4::Lookup, indexedGetter), PointerToValue(base), @@ -633,7 +633,7 @@ void InstructionSelection<JITAssembler>::getElement(IR::Expr *base, IR::Expr *in template <typename JITAssembler> void InstructionSelection<JITAssembler>::setElement(IR::Expr *source, IR::Expr *targetBase, IR::Expr *targetIndex) { - if (useFastLookups) { + if (0 && useFastLookups) { uint lookup = registerIndexedSetterLookup(); generateLookupCall(JITAssembler::Void, lookup, offsetof(QV4::Lookup, indexedSetter), PointerToValue(targetBase), PointerToValue(targetIndex), diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index 42bf24d7f3..4b440f5335 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -599,41 +599,53 @@ void Runtime::method_setProperty(ExecutionEngine *engine, const Value &object, i o->put(name, value); } -ReturnedValue Runtime::method_getElement(ExecutionEngine *engine, const Value &object, const Value &index) +static Q_NEVER_INLINE ReturnedValue getElementIntFallback(ExecutionEngine *engine, const Value &object, uint idx) { + Q_ASSERT(idx < UINT_MAX); Scope scope(engine); - uint idx = index.asArrayIndex(); ScopedObject o(scope, object); if (!o) { - if (idx < UINT_MAX) { - if (const String *str = object.as<String>()) { - if (idx >= (uint)str->toQString().length()) { - return Encode::undefined(); - } - const QString s = str->toQString().mid(idx, 1); - return scope.engine->newString(s)->asReturnedValue(); + if (const String *str = object.as<String>()) { + if (idx >= (uint)str->toQString().length()) { + return Encode::undefined(); } + const QString s = str->toQString().mid(idx, 1); + return scope.engine->newString(s)->asReturnedValue(); } if (object.isNullOrUndefined()) { - QString message = QStringLiteral("Cannot read property '%1' of %2").arg(index.toQStringNoThrow()).arg(object.toQStringNoThrow()); + QString message = QStringLiteral("Cannot read property '%1' of %2").arg(idx).arg(object.toQStringNoThrow()); return engine->throwTypeError(message); } o = RuntimeHelpers::convertToObject(scope.engine, object); - if (!o) // type error - return Encode::undefined(); + Q_ASSERT(!!o); // can't fail as null/undefined is covered above + } + + if (o->arrayData() && !o->arrayData()->attrs) { + ScopedValue v(scope, o->arrayData()->get(idx)); + if (!v->isEmpty()) + return v->asReturnedValue(); } - if (idx < UINT_MAX) { - if (o->arrayData() && !o->arrayData()->attrs) { - ScopedValue v(scope, o->arrayData()->get(idx)); - if (!v->isEmpty()) - return v->asReturnedValue(); + return o->getIndexed(idx); +} + +static Q_NEVER_INLINE ReturnedValue getElementFallback(ExecutionEngine *engine, const Value &object, const Value &index) +{ + Q_ASSERT(index.asArrayIndex() == UINT_MAX); + Scope scope(engine); + + ScopedObject o(scope, object); + if (!o) { + if (object.isNullOrUndefined()) { + QString message = QStringLiteral("Cannot read property '%1' of %2").arg(index.toQStringNoThrow()).arg(object.toQStringNoThrow()); + return engine->throwTypeError(message); } - return o->getIndexed(idx); + o = RuntimeHelpers::convertToObject(scope.engine, object); + Q_ASSERT(!!o); // can't fail as null/undefined is covered above } ScopedString name(scope, index.toString(engine)); @@ -642,18 +654,39 @@ ReturnedValue Runtime::method_getElement(ExecutionEngine *engine, const Value &o return o->get(name); } -void Runtime::method_setElement(ExecutionEngine *engine, const Value &object, const Value &index, const Value &value) +ReturnedValue Runtime::method_getElement(ExecutionEngine *engine, const Value &object, const Value &index) +{ + uint idx; + if (index.asArrayIndex(idx)) { + if (Heap::Base *b = object.heapObject()) { + if (b->vtable()->isObject) { + Heap::Object *o = static_cast<Heap::Object *>(b); + if (o->arrayData && o->arrayData->type == Heap::ArrayData::Simple) { + Heap::SimpleArrayData *s = o->arrayData.cast<Heap::SimpleArrayData>(); + if (idx < s->len) + if (!s->data(idx).isEmpty()) + return s->data(idx).asReturnedValue(); + } + } + } + return getElementIntFallback(engine, object, idx); + } + + return getElementFallback(engine, object, index); +} + +static Q_NEVER_INLINE void setElementFallback(ExecutionEngine *engine, const Value &object, const Value &index, const Value &value) { Scope scope(engine); ScopedObject o(scope, object.toObject(engine)); - if (scope.engine->hasException) + if (engine->hasException) return; - uint idx = index.asArrayIndex(); - if (idx < UINT_MAX) { - if (o->arrayType() == Heap::ArrayData::Simple) { - Heap::SimpleArrayData *s = static_cast<Heap::SimpleArrayData *>(o->arrayData()); - if (s && idx < s->len && !s->data(idx).isEmpty()) { + uint idx; + if (index.asArrayIndex(idx)) { + if (o->d()->arrayData && o->d()->arrayData->type == Heap::ArrayData::Simple) { + Heap::SimpleArrayData *s = o->d()->arrayData.cast<Heap::SimpleArrayData>(); + if (idx < s->len) { s->data(idx) = value; return; } @@ -666,6 +699,27 @@ void Runtime::method_setElement(ExecutionEngine *engine, const Value &object, co o->put(name, value); } +void Runtime::method_setElement(ExecutionEngine *engine, const Value &object, const Value &index, const Value &value) +{ + uint idx; + if (index.asArrayIndex(idx)) { + if (Heap::Base *b = object.heapObject()) { + if (b->vtable()->isObject) { + Heap::Object *o = static_cast<Heap::Object *>(b); + if (o->arrayData && o->arrayData->type == Heap::ArrayData::Simple) { + Heap::SimpleArrayData *s = o->arrayData.cast<Heap::SimpleArrayData>(); + if (idx < s->len) { + s->data(idx) = value; + return; + } + } + } + } + } + + return setElementFallback(engine, object, index, value); +} + ReturnedValue Runtime::method_foreachIterator(ExecutionEngine *engine, const Value &in) { Scope scope(engine); |