diff options
| author | Lars Knoll <lars.knoll@qt.io> | 2018-03-14 15:41:50 +0100 |
|---|---|---|
| committer | Lars Knoll <lars.knoll@qt.io> | 2018-04-26 20:26:45 +0000 |
| commit | 2ca47e49a25b92e70f6fa6c7a15cb7102a52435c (patch) | |
| tree | 4800473ad11ba4d239880769e7c304defc1068a1 /src | |
| parent | 3354628fd9e4c5f2255161a6ca8a5be63ff5bb89 (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.cpp | 12 | ||||
| -rw-r--r-- | src/qml/compiler/qv4instr_moth.cpp | 3 | ||||
| -rw-r--r-- | src/qml/compiler/qv4instr_moth_p.h | 2 | ||||
| -rw-r--r-- | src/qml/jit/qv4jit.cpp | 22 | ||||
| -rw-r--r-- | src/qml/jit/qv4jit_p.h | 1 | ||||
| -rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 5 |
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); |
