aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-05-14 12:36:16 +0200
committerLars Knoll <lars.knoll@qt.io>2018-05-14 19:32:34 +0000
commitd8eade23bc4fdd7040204f4374ef26975b94ea0a (patch)
tree19542aa2a8ddf285a80f3fe528913cd630a7f601 /src/qml
parent16288498cf0e1eb389ac3acdce86eb74cc69e67a (diff)
Refactor InteratorNext instruction
The instruction now writes the value into a stack slot, and returns the done state in the accumulator. This should make it easier to implement the IteratorClose functionality required by the spec. Change-Id: I8cc497c54b0d044bd3c68a5a1b774eea8b2740ef Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/compiler/qv4codegen.cpp13
-rw-r--r--src/qml/compiler/qv4instr_moth.cpp2
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h2
-rw-r--r--src/qml/jit/qv4jit.cpp4
-rw-r--r--src/qml/jit/qv4jit_p.h2
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp20
-rw-r--r--src/qml/jsruntime/qv4runtimeapi_p.h2
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp2
8 files changed, 26 insertions, 21 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index f00a0fafdc..99c45d19fa 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -477,6 +477,7 @@ void Codegen::destructureElementList(const Codegen::Reference &array, PatternEle
RegisterScope scope(this);
Reference iterator = Reference::fromStackSlot(this);
+ Reference iteratorValue = Reference::fromStackSlot(this);
array.loadInAccumulator();
Instruction::GetIterator iteratorObjInstr;
@@ -490,7 +491,7 @@ void Codegen::destructureElementList(const Codegen::Reference &array, PatternEle
for (Elision *elision = p->elision; elision; elision = elision->next) {
iterator.loadInAccumulator();
Instruction::IteratorNext next;
- next.returnUndefinedWhenDone = true;
+ next.value = iteratorValue.stackSlot();
bytecodeGenerator->addInstruction(next);
}
@@ -503,12 +504,12 @@ void Codegen::destructureElementList(const Codegen::Reference &array, PatternEle
initializeAndDestructureBindingElement(e, Reference::fromAccumulator(this));
} else {
Instruction::IteratorNext next;
- next.returnUndefinedWhenDone = true;
+ next.value = iteratorValue.stackSlot();
bytecodeGenerator->addInstruction(next);
if (!e)
continue;
if (e->type != PatternElement::RestElement) {
- initializeAndDestructureBindingElement(e, Reference::fromAccumulator(this));
+ initializeAndDestructureBindingElement(e, iteratorValue);
if (hasError) {
end.link();
return;
@@ -2686,11 +2687,9 @@ bool Codegen::visit(ForEachStatement *ast)
in.link();
iterator.loadInAccumulator();
Instruction::IteratorNext next;
- next.returnUndefinedWhenDone = false;
+ next.value = lhsValue.stackSlot();
bytecodeGenerator->addInstruction(next);
- Instruction::JumpEmpty jump;
- BytecodeGenerator::Jump done = bytecodeGenerator->addJumpInstruction(jump);
- lhsValue.storeConsumeAccumulator();
+ BytecodeGenerator::Jump done = bytecodeGenerator->addJumpInstruction(Instruction::JumpTrue());
bytecodeGenerator->jump().link(body);
done.link();
diff --git a/src/qml/compiler/qv4instr_moth.cpp b/src/qml/compiler/qv4instr_moth.cpp
index 8c5dfefdf1..7d8a1774f1 100644
--- a/src/qml/compiler/qv4instr_moth.cpp
+++ b/src/qml/compiler/qv4instr_moth.cpp
@@ -434,7 +434,7 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
MOTH_END_INSTR(GetIterator)
MOTH_BEGIN_INSTR(IteratorNext)
- d << returnUndefinedWhenDone;
+ d << value;
MOTH_END_INSTR(IteratorNext)
MOTH_BEGIN_INSTR(DestructureRestElement)
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index 670d977a57..b4eaae4f6c 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -122,7 +122,7 @@ QT_BEGIN_NAMESPACE
#define INSTR_PopScriptContext(op) INSTRUCTION(op, PopScriptContext, 0)
#define INSTR_PopContext(op) INSTRUCTION(op, PopContext, 1, reg)
#define INSTR_GetIterator(op) INSTRUCTION(op, GetIterator, 1, iterator)
-#define INSTR_IteratorNext(op) INSTRUCTION(op, IteratorNext, 1, returnUndefinedWhenDone)
+#define INSTR_IteratorNext(op) INSTRUCTION(op, IteratorNext, 1, value)
#define INSTR_DestructureRestElement(op) INSTRUCTION(op, DestructureRestElement, 0)
#define INSTR_DeleteMember(op) INSTRUCTION(op, DeleteMember, 2, member, base)
#define INSTR_DeleteSubscript(op) INSTRUCTION(op, DeleteSubscript, 2, base, index)
diff --git a/src/qml/jit/qv4jit.cpp b/src/qml/jit/qv4jit.cpp
index ff139e6645..a480cfbc30 100644
--- a/src/qml/jit/qv4jit.cpp
+++ b/src/qml/jit/qv4jit.cpp
@@ -714,11 +714,11 @@ void BaselineJIT::generate_GetIterator(int iterator)
as->checkException();
}
-void BaselineJIT::generate_IteratorNext(int returnUndefinedWhenDone)
+void BaselineJIT::generate_IteratorNext(int value)
{
as->saveAccumulatorInFrame();
as->prepareCallWithArgCount(3);
- as->passInt32AsArg(returnUndefinedWhenDone, 2);
+ as->passRegAsArg(value, 2);
as->passAccumulatorAsArg(1);
as->passEngineAsArg(0);
JIT_GENERATE_RUNTIME_CALL(Runtime::method_iteratorNext, Assembler::ResultInAccumulator);
diff --git a/src/qml/jit/qv4jit_p.h b/src/qml/jit/qv4jit_p.h
index d57e043bc2..fa4a367e91 100644
--- a/src/qml/jit/qv4jit_p.h
+++ b/src/qml/jit/qv4jit_p.h
@@ -186,7 +186,7 @@ public:
void generate_PopScriptContext() override;
void generate_PopContext(int reg) override;
void generate_GetIterator(int iterator) override;
- void generate_IteratorNext(int returnUndefinedWhenDone) override;
+ void generate_IteratorNext(int value) override;
void generate_DestructureRestElement() override;
void generate_DeleteMember(int member, int base) override;
void generate_DeleteSubscript(int base, int index) override;
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 2c00826b46..650f5c6735 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -715,7 +715,7 @@ ReturnedValue Runtime::method_getIterator(ExecutionEngine *engine, const Value &
return engine->newForInIteratorObject(o)->asReturnedValue();
}
-ReturnedValue Runtime::method_iteratorNext(ExecutionEngine *engine, const Value &iterator, int returnUndefinedWhenDone)
+ReturnedValue Runtime::method_iteratorNext(ExecutionEngine *engine, const Value &iterator, Value *value)
{
Q_ASSERT(iterator.isObject());
@@ -727,10 +727,14 @@ ReturnedValue Runtime::method_iteratorNext(ExecutionEngine *engine, const Value
ScopedObject o(scope, f->call(cData));
if (!o)
return engine->throwTypeError();
- ScopedValue v(scope, o->get(engine->id_done()));
- if (v->toBoolean() == true)
- return returnUndefinedWhenDone ? Encode::undefined() : Primitive::emptyValue().asReturnedValue();
- return o->get(engine->id_value());
+ ScopedValue d(scope, o->get(engine->id_done()));
+ bool done = d->toBoolean();
+ if (done) {
+ *value = Encode::undefined();
+ } else {
+ *value = o->get(engine->id_value());
+ }
+ return Encode(done);
}
ReturnedValue Runtime::method_destructureRestElement(ExecutionEngine *engine, const Value &iterator)
@@ -742,10 +746,12 @@ ReturnedValue Runtime::method_destructureRestElement(ExecutionEngine *engine, co
array->arrayCreate();
uint index = 0;
while (1) {
- ScopedValue n(scope, method_iteratorNext(engine, iterator, false));
+ ScopedValue n(scope);
+ ScopedValue done(scope, method_iteratorNext(engine, iterator, n));
if (engine->hasException)
return Encode::undefined();
- if (n->isEmpty())
+ Q_ASSERT(done->isBoolean());
+ if (done->booleanValue())
break;
array->arraySet(index, n);
++index;
diff --git a/src/qml/jsruntime/qv4runtimeapi_p.h b/src/qml/jsruntime/qv4runtimeapi_p.h
index 0d27fbfe7b..a22a053cd1 100644
--- a/src/qml/jsruntime/qv4runtimeapi_p.h
+++ b/src/qml/jsruntime/qv4runtimeapi_p.h
@@ -146,7 +146,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, int returnUndefinedWhenDone)) \
+ F(ReturnedValue, iteratorNext, (ExecutionEngine *engine, const Value &iterator, Value *value)) \
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 8b45226fcd..17ed1ae044 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -961,7 +961,7 @@ QV4::ReturnedValue VME::interpret(CppStackFrame &frame, const uchar *code)
MOTH_BEGIN_INSTR(IteratorNext)
STORE_ACC();
- acc = Runtime::method_iteratorNext(engine, accumulator, returnUndefinedWhenDone);
+ acc = Runtime::method_iteratorNext(engine, accumulator, &STACK_VALUE(value));
CHECK_EXCEPTION;
MOTH_END_INSTR(IteratorNext)