diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/compiler/qv4codegen.cpp | 13 | ||||
-rw-r--r-- | src/qml/compiler/qv4instr_moth.cpp | 2 | ||||
-rw-r--r-- | src/qml/compiler/qv4instr_moth_p.h | 2 | ||||
-rw-r--r-- | src/qml/jit/qv4jit.cpp | 4 | ||||
-rw-r--r-- | src/qml/jit/qv4jit_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 20 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtimeapi_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 2 |
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) |