aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-05-14 14:12:33 +0200
committerLars Knoll <lars.knoll@qt.io>2018-05-14 19:32:42 +0000
commitc4ef0d6e4b5bb7de7b0ab08928d693988a60b25d (patch)
tree0ff9682886da081c2d8e89becfd90cfb7083540d /src/qml/jsruntime
parentd8eade23bc4fdd7040204f4374ef26975b94ea0a (diff)
Call iterator.return when required in destructuring assignments
Array destructuring assignments require a call to iterator.return if the iterator hasn't been exhausted during destructuring. Change-Id: I39fe4bc01bef6fb2ad3bda92caf6779fbbddc8e2 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r--src/qml/jsruntime/qv4engine.cpp1
-rw-r--r--src/qml/jsruntime/qv4engine_p.h2
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp33
-rw-r--r--src/qml/jsruntime/qv4runtimeapi_p.h1
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp6
5 files changed, 43 insertions, 0 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 8227fe0184..96855b6155 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -270,6 +270,7 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine)
jsStrings[String_lastIndex] = newIdentifier(QStringLiteral("lastIndex"));
jsStrings[String_next] = newIdentifier(QStringLiteral("next"));
jsStrings[String_done] = newIdentifier(QStringLiteral("done"));
+ jsStrings[String_return] = newIdentifier(QStringLiteral("return"));
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 46bf58de07..e90be8e896 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -329,6 +329,7 @@ public:
String_lastIndex,
String_next,
String_done,
+ String_return,
NJSStrings
};
@@ -389,6 +390,7 @@ public:
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); }
+ String *id_return() const { return reinterpret_cast<String *>(jsStrings + String_return); }
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 650f5c6735..6eff9c50db 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -737,6 +737,39 @@ ReturnedValue Runtime::method_iteratorNext(ExecutionEngine *engine, const Value
return Encode(done);
}
+ReturnedValue Runtime::method_iteratorClose(ExecutionEngine *engine, const Value &iterator, const Value &done)
+{
+ Q_ASSERT(iterator.isObject());
+ Q_ASSERT(done.isBoolean());
+ if (done.booleanValue())
+ return Encode::undefined();
+
+ Scope scope(engine);
+ bool hadException = engine->hasException;
+ ScopedValue e(scope);
+ if (hadException) {
+ e = *engine->exceptionValue;
+ engine->hasException = false;
+ }
+ ScopedFunctionObject f(scope, static_cast<const Object &>(iterator).get(engine->id_return()));
+ ScopedObject o(scope);
+ if (f) {
+ JSCallData cData(scope, 0, nullptr, &iterator);
+ o = f->call(cData);
+ }
+ if (hadException || !f) {
+ *engine->exceptionValue = e;
+ engine->hasException = hadException;
+ return Encode::undefined();
+ }
+ if (engine->hasException)
+ return Encode::undefined();
+
+ if (!o)
+ return engine->throwTypeError();
+ return Encode::undefined();
+}
+
ReturnedValue Runtime::method_destructureRestElement(ExecutionEngine *engine, const Value &iterator)
{
Q_ASSERT(iterator.isObject());
diff --git a/src/qml/jsruntime/qv4runtimeapi_p.h b/src/qml/jsruntime/qv4runtimeapi_p.h
index a22a053cd1..266dc36680 100644
--- a/src/qml/jsruntime/qv4runtimeapi_p.h
+++ b/src/qml/jsruntime/qv4runtimeapi_p.h
@@ -147,6 +147,7 @@ struct ExceptionCheck<void (*)(QV4::NoThrowEngine *, A, B, C)> {
/* 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, Value *value)) \
+ F(ReturnedValue, iteratorClose, (ExecutionEngine *engine, const Value &iterator, const Value &done)) \
F(ReturnedValue, destructureRestElement, (ExecutionEngine *engine, const Value &iterator)) \
\
/* unary operators */ \
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index 17ed1ae044..f39fd39a98 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -965,6 +965,12 @@ QV4::ReturnedValue VME::interpret(CppStackFrame &frame, const uchar *code)
CHECK_EXCEPTION;
MOTH_END_INSTR(IteratorNext)
+ MOTH_BEGIN_INSTR(IteratorClose)
+ STORE_ACC();
+ acc = Runtime::method_iteratorClose(engine, accumulator, STACK_VALUE(done));
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(IteratorClose)
+
MOTH_BEGIN_INSTR(DestructureRestElement)
STORE_ACC();
acc = Runtime::method_destructureRestElement(engine, ACC);