diff options
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine_p.h | 5 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 18 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtimeapi_p.h | 3 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 11 |
5 files changed, 38 insertions, 1 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index b703f6e4f3..8227fe0184 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -268,6 +268,8 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine) jsStrings[String_byteOffset] = newIdentifier(QStringLiteral("byteOffset")); jsStrings[String_buffer] = newIdentifier(QStringLiteral("buffer")); jsStrings[String_lastIndex] = newIdentifier(QStringLiteral("lastIndex")); + jsStrings[String_next] = newIdentifier(QStringLiteral("next")); + jsStrings[String_done] = newIdentifier(QStringLiteral("done")); jsSymbols[Symbol_hasInstance] = Symbol::create(this, QStringLiteral("@Symbol.hasInstance")); jsSymbols[Symbol_isConcatSpreadable] = Symbol::create(this, QStringLiteral("@Symbol.isConcatSpreadable")); diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index e8218d0d1c..46bf58de07 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -327,6 +327,9 @@ public: String_byteOffset, String_buffer, String_lastIndex, + String_next, + String_done, + NJSStrings }; Value *jsStrings; @@ -384,6 +387,8 @@ public: String *id_byteOffset() const { return reinterpret_cast<String *>(jsStrings + String_byteOffset); } String *id_buffer() const { return reinterpret_cast<String *>(jsStrings + String_buffer); } String *id_lastIndex() const { return reinterpret_cast<String *>(jsStrings + String_lastIndex); } + String *id_next() const { return reinterpret_cast<String *>(jsStrings + String_next); } + String *id_done() const { return reinterpret_cast<String *>(jsStrings + String_done); } Symbol *symbol_hasInstance() const { return reinterpret_cast<Symbol *>(jsSymbols + Symbol_hasInstance); } Symbol *symbol_isConcatSpreadable() const { return reinterpret_cast<Symbol *>(jsSymbols + Symbol_isConcatSpreadable); } diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index 986684302c..eadbcb9557 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -715,6 +715,24 @@ ReturnedValue Runtime::method_getIterator(ExecutionEngine *engine, const Value & return engine->newForInIteratorObject(o)->asReturnedValue(); } +ReturnedValue Runtime::method_iteratorNext(ExecutionEngine *engine, const Value &iterator) +{ + Q_ASSERT(iterator.isObject()); + + Scope scope(engine); + ScopedFunctionObject f(scope, static_cast<const Object &>(iterator).get(engine->id_next())); + if (!f) + return engine->throwTypeError(); + JSCallData cData(scope, 0, nullptr, &iterator); + ScopedObject o(scope, f->call(cData)); + if (!o) + return engine->throwTypeError(); + ScopedValue v(scope, o->get(engine->id_done())); + if (v->toBoolean() == true) + return Primitive::emptyValue().asReturnedValue(); + return o->get(engine->id_value()); +} + void Runtime::method_storeNameSloppy(ExecutionEngine *engine, int nameIndex, const Value &value) { Scope scope(engine); diff --git a/src/qml/jsruntime/qv4runtimeapi_p.h b/src/qml/jsruntime/qv4runtimeapi_p.h index c98433359b..1e14c23d7e 100644 --- a/src/qml/jsruntime/qv4runtimeapi_p.h +++ b/src/qml/jsruntime/qv4runtimeapi_p.h @@ -144,8 +144,9 @@ struct ExceptionCheck<void (*)(QV4::NoThrowEngine *, A, B, C)> { F(ReturnedValue, arrayLiteral, (ExecutionEngine *engine, Value *values, uint length)) \ F(ReturnedValue, objectLiteral, (ExecutionEngine *engine, const Value *args, int classId, int arrayValueCount, int arrayGetterSetterCountAndFlags)) \ \ - /* for-in and for-of */ \ + /* for-in, for-of and array destructuring */ \ F(ReturnedValue, getIterator, (ExecutionEngine *engine, const Value &in, int iterator)) \ + F(ReturnedValue, iteratorNext, (ExecutionEngine *engine, const Value &iterator)) \ \ /* unary operators */ \ F(ReturnedValue, uMinus, (const Value &value)) \ diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index 5daead19d2..9fd57e0dcb 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -959,6 +959,12 @@ QV4::ReturnedValue VME::interpret(CppStackFrame &frame, const uchar *code) CHECK_EXCEPTION; MOTH_END_INSTR(GetIterator) + MOTH_BEGIN_INSTR(IteratorNext) + STORE_ACC(); + acc = Runtime::method_iteratorNext(engine, accumulator); + CHECK_EXCEPTION; + MOTH_END_INSTR(IteratorNext) + MOTH_BEGIN_INSTR(DeleteMember) if (!Runtime::method_deleteMember(engine, STACK_VALUE(base), member)) { if (function->isStrict()) { @@ -1086,6 +1092,11 @@ QV4::ReturnedValue VME::interpret(CppStackFrame &frame, const uchar *code) code += offset; MOTH_END_INSTR(JumpNotUndefined) + MOTH_BEGIN_INSTR(JumpEmpty) + if (Q_UNLIKELY(acc == QV4::Primitive::emptyValue().asReturnedValue())) + code += offset; + MOTH_END_INSTR(JumpEmpty) + MOTH_BEGIN_INSTR(CmpEqNull) acc = Encode(ACC.isNullOrUndefined()); MOTH_END_INSTR(CmpEqNull) |