aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-03-14 15:41:50 +0100
committerLars Knoll <lars.knoll@qt.io>2018-04-26 20:26:45 +0000
commit2ca47e49a25b92e70f6fa6c7a15cb7102a52435c (patch)
tree4800473ad11ba4d239880769e7c304defc1068a1 /src
parent3354628fd9e4c5f2255161a6ca8a5be63ff5bb89 (diff)
Fix some bugs in binding destructuring
Change-Id: I4b18a88e443f3b263cbb1e2b5ca1ebbd353afa98 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qml/compiler/qv4codegen.cpp12
-rw-r--r--src/qml/compiler/qv4instr_moth.cpp3
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h2
-rw-r--r--src/qml/jit/qv4jit.cpp22
-rw-r--r--src/qml/jit/qv4jit_p.h1
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp5
6 files changed, 42 insertions, 3 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index f7617c66de..99811c3779 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -421,6 +421,12 @@ void Codegen::initializeAndDestructureBindingElement(AST::BindingElement *e, con
destructureElementList(varToStore, l);
} else if (BindingPropertyList *p = e->propertyList()) {
destructurePropertyList(varToStore, p);
+ } else if (e->name.isNull()) {
+ // empty binding pattern. For spec compatibility, try to coerce the argument to an object
+ varToStore.loadInAccumulator();
+ Instruction::ToObject toObject;
+ bytecodeGenerator->addInstruction(toObject);
+ return;
}
}
@@ -449,10 +455,10 @@ void Codegen::destructureElementList(const Codegen::Reference &array, BindingEle
Reference idx = Reference::fromConst(this, Encode(index));
Reference property = Reference::fromSubscript(array, idx);
- BindingElement *e = p->bindingElement();
- if (e)
+ if (BindingElement *e = p->bindingElement())
initializeAndDestructureBindingElement(e, property);
- else {
+ else if (BindingRestElement *r = p->bindingRestElement()) {
+ Q_UNUSED(r);
throwSyntaxError(bindingList->firstSourceLocation(), QString::fromLatin1("Support for rest elements in binding arrays not implemented!"));
}
}
diff --git a/src/qml/compiler/qv4instr_moth.cpp b/src/qml/compiler/qv4instr_moth.cpp
index 3a9cecdae0..dbdef418a0 100644
--- a/src/qml/compiler/qv4instr_moth.cpp
+++ b/src/qml/compiler/qv4instr_moth.cpp
@@ -461,6 +461,9 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
MOTH_BEGIN_INSTR(ConvertThisToObject)
MOTH_END_INSTR(ConvertThisToObject)
+ MOTH_BEGIN_INSTR(ToObject)
+ MOTH_END_INSTR(ToObject)
+
MOTH_BEGIN_INSTR(Construct)
d << "new" << dumpRegister(func, nFormals) << dumpArguments(argc, argv, nFormals);
MOTH_END_INSTR(Construct)
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index 8ce72f4942..7047c74803 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -130,6 +130,7 @@ QT_BEGIN_NAMESPACE
#define INSTR_CreateUnmappedArgumentsObject(op) INSTRUCTION(op, CreateUnmappedArgumentsObject, 0)
#define INSTR_CreateRestParameter(op) INSTRUCTION(op, CreateRestParameter, 1, argIndex)
#define INSTR_ConvertThisToObject(op) INSTRUCTION(op, ConvertThisToObject, 0)
+#define INSTR_ToObject(op) INSTRUCTION(op, ToObject, 0)
#define INSTR_Construct(op) INSTRUCTION(op, Construct, 3, func, argc, argv)
#define INSTR_Jump(op) INSTRUCTION(op, Jump, 1, offset)
#define INSTR_JumpTrue(op) INSTRUCTION(op, JumpTrue, 1, offset)
@@ -248,6 +249,7 @@ QT_BEGIN_NAMESPACE
F(CreateUnmappedArgumentsObject) \
F(CreateRestParameter) \
F(ConvertThisToObject) \
+ F(ToObject) \
F(Construct) \
F(Jump) \
F(JumpTrue) \
diff --git a/src/qml/jit/qv4jit.cpp b/src/qml/jit/qv4jit.cpp
index b2dde4fca2..429d721ba2 100644
--- a/src/qml/jit/qv4jit.cpp
+++ b/src/qml/jit/qv4jit.cpp
@@ -809,6 +809,25 @@ void BaselineJIT::generate_ConvertThisToObject()
as->checkException();
}
+static ReturnedValue ToObjectHelper(ExecutionEngine *engine, const Value &obj)
+{
+ if (obj.isObject())
+ return obj.asReturnedValue();
+
+ return obj.toObject(engine)->asReturnedValue();
+}
+
+void BaselineJIT::generate_ToObject()
+{
+ STORE_ACC();
+ as->prepareCallWithArgCount(2);
+ as->passAccumulatorAsArg(1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(ToObjectHelper, Assembler::ResultInAccumulator);
+ as->checkException();
+
+}
+
void BaselineJIT::generate_Construct(int func, int argc, int argv)
{
STORE_IP();
@@ -1184,6 +1203,9 @@ void BaselineJIT::collectLabelsInBytecode()
MOTH_BEGIN_INSTR(CreateRestParameter)
MOTH_END_INSTR(CreateRestParameter)
+ MOTH_BEGIN_INSTR(ToObject)
+ MOTH_END_INSTR(ToObject)
+
MOTH_BEGIN_INSTR(ConvertThisToObject)
MOTH_END_INSTR(ConvertThisToObject)
diff --git a/src/qml/jit/qv4jit_p.h b/src/qml/jit/qv4jit_p.h
index 9ff2d99191..62866895c4 100644
--- a/src/qml/jit/qv4jit_p.h
+++ b/src/qml/jit/qv4jit_p.h
@@ -194,6 +194,7 @@ public:
void generate_CreateUnmappedArgumentsObject() override;
void generate_CreateRestParameter(int argIndex) override;
void generate_ConvertThisToObject() override;
+ void generate_ToObject() override;
void generate_Construct(int func, int argc, int argv) override;
void generate_Jump(int offset) override;
void generate_JumpTrue(int offset) override;
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index fae917dbb5..a2a602ac58 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -997,6 +997,11 @@ QV4::ReturnedValue VME::exec(const FunctionObject *fo, const Value *thisObject,
}
MOTH_END_INSTR(ConvertThisToObject)
+ MOTH_BEGIN_INSTR(ToObject)
+ acc = ACC.toObject(engine)->asReturnedValue();
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(ToObject)
+
MOTH_BEGIN_INSTR(Construct)
STORE_IP();
acc = Runtime::method_construct(engine, STACK_VALUE(func), stack + argv, argc);