summaryrefslogtreecommitdiff
path: root/src/qml/compiler/qv4codegen.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-06-05 13:07:50 +0200
committerLars Knoll <lars.knoll@qt.io>2018-06-21 13:30:44 +0000
commitce18e987d4ea623c0db6d10f2a97a16b639a234e (patch)
tree793ce0624f971de8015d5580e6c06d2b1a1b9aab /src/qml/compiler/qv4codegen.cpp
parenta12da297946b5a6e767b972bc635a3308683b2e5 (diff)
downloadqtdeclarative-ce18e987d4ea623c0db6d10f2a97a16b639a234e.tar.gz
Fix more issues with destructuring
Fix destructuring targets that are complex lhs expressions. There are still some failures remaining, but this fixes another larger chunk of test cases. Change-Id: Icf08f42d7c70d4e81be5d5d2e27ebe6249d25467 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/compiler/qv4codegen.cpp')
-rw-r--r--src/qml/compiler/qv4codegen.cpp31
1 files changed, 26 insertions, 5 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 1a47730979..d71d36845b 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -469,10 +469,27 @@ void Codegen::variableDeclarationList(VariableDeclarationList *ast)
}
}
-void Codegen::initializeAndDestructureBindingElement(AST::PatternElement *e, const Reference &baseRef)
+Codegen::Reference Codegen::targetForPatternElement(AST::PatternElement *p)
+{
+ if (!p->bindingIdentifier.isNull())
+ return referenceForName(p->bindingIdentifier, true);
+ if (!p->bindingTarget || p->destructuringPattern())
+ return Codegen::Reference::fromStackSlot(this);
+ Reference lhs = expression(p->bindingTarget);
+ if (hasError)
+ return lhs;
+ lhs = lhs.asLValue();
+ return lhs;
+}
+
+void Codegen::initializeAndDestructureBindingElement(AST::PatternElement *e, const Reference &base)
{
RegisterScope scope(this);
- Reference varToStore = e->bindingIdentifier.isNull() ? Reference::fromStackSlot(this, bytecodeGenerator->newRegister()) : referenceForName(e->bindingIdentifier, true);
+ Reference baseRef = (base.isAccumulator()) ? base.storeOnStack() : base;
+ Reference varToStore = targetForPatternElement(e);
+ if (hasError)
+ return;
+
if (e->initializer) {
if (!baseRef.isValid()) {
// assignment
@@ -508,13 +525,17 @@ void Codegen::initializeAndDestructureBindingElement(AST::PatternElement *e, con
baseRef.loadInAccumulator();
varToStore.storeConsumeAccumulator();
}
+ Pattern *p = e->destructuringPattern();
+ if (!p)
+ return;
+
if (!varToStore.isStackSlot())
varToStore = varToStore.storeOnStack();
if (PatternElementList *l = e->elementList()) {
destructureElementList(varToStore, l);
} else if (PatternPropertyList *p = e->propertyList()) {
destructurePropertyList(varToStore, p);
- } else if (e->bindingPattern) {
+ } else if (e->bindingTarget) {
// empty binding pattern. For spec compatibility, try to coerce the argument to an object
varToStore.loadInAccumulator();
Instruction::ToObject toObject;
@@ -537,7 +558,7 @@ void Codegen::destructurePropertyList(const Codegen::Reference &object, PatternP
if (hasError)
return;
computedName = computedName.storeOnStack();
- property = Reference::fromSubscript(object, computedName);
+ property = Reference::fromSubscript(object, computedName).asLValue();
} else {
QString propertyName = p->name->asString();
property = Reference::fromMember(object, propertyName);
@@ -2496,7 +2517,7 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast,
bytecodeGenerator->addInstruction(rest);
arg.storeConsumeAccumulator();
} else {
- if (e->bindingPattern || e->initializer) {
+ if (e->bindingTarget || e->initializer) {
initializeAndDestructureBindingElement(e, arg);
if (hasError)
break;