diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-05-12 22:54:27 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-05-13 12:55:32 +0000 |
commit | fbca1b7942fc58d5573c6ec95295c2d4472b80ff (patch) | |
tree | 25bc99ba2cc4b4c2742c3b799707415862b840dc /src/qml/compiler/qv4codegen.cpp | |
parent | 9e379e8fb72305aff1fb6758c23198c8b30829ac (diff) | |
download | qtdeclarative-fbca1b7942fc58d5573c6ec95295c2d4472b80ff.tar.gz |
Fix array destructuring
Array destructuring should use iterator objects, not integer
indexes.
Change-Id: I769bb1d63246da6bc45233f7a6e9a8e5ddc53a4d
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/compiler/qv4codegen.cpp')
-rw-r--r-- | src/qml/compiler/qv4codegen.cpp | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index 97b71ddbcc..ffb318168c 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -476,27 +476,44 @@ void Codegen::destructureElementList(const Codegen::Reference &array, PatternEle { RegisterScope scope(this); - int index = 0; + Reference iterator = Reference::fromStackSlot(this); + + array.loadInAccumulator(); + Instruction::GetIterator iteratorObjInstr; + iteratorObjInstr.iterator = 1; // ForEachType::Of + bytecodeGenerator->addInstruction(iteratorObjInstr); + iterator.storeConsumeAccumulator(); + + BytecodeGenerator::Label end = bytecodeGenerator->newLabel(); + for (PatternElementList *p = bindingList; p; p = p->next) { - for (Elision *elision = p->elision; elision; elision = elision->next) - ++index; + for (Elision *elision = p->elision; elision; elision = elision->next) { + iterator.loadInAccumulator(); + Instruction::IteratorNext next; + next.returnUndefinedWhenDone = true; + bytecodeGenerator->addInstruction(next); + } RegisterScope scope(this); - Reference idx = Reference::fromConst(this, Encode(index)); - Reference property = Reference::fromSubscript(array, idx); + iterator.loadInAccumulator(); + Instruction::IteratorNext next; + next.returnUndefinedWhenDone = true; + bytecodeGenerator->addInstruction(next); PatternElement *e = p->element; if (!e) continue; if (e->type != PatternElement::RestElement) { - initializeAndDestructureBindingElement(e, property); - if (hasError) + initializeAndDestructureBindingElement(e, Reference::fromAccumulator(this)); + if (hasError) { + end.link(); return; + } } else { throwSyntaxError(bindingList->firstSourceLocation(), QString::fromLatin1("Support for rest elements in binding arrays not implemented!")); } - ++index; } + end.link(); } void Codegen::destructurePattern(Pattern *p, const Reference &rhs) @@ -2666,6 +2683,7 @@ bool Codegen::visit(ForEachStatement *ast) in.link(); iterator.loadInAccumulator(); Instruction::IteratorNext next; + next.returnUndefinedWhenDone = false; bytecodeGenerator->addInstruction(next); Instruction::JumpEmpty jump; BytecodeGenerator::Jump done = bytecodeGenerator->addJumpInstruction(jump); |