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 | |
parent | 3354628fd9e4c5f2255161a6ca8a5be63ff5bb89 (diff) |
Fix some bugs in binding destructuring
Change-Id: I4b18a88e443f3b263cbb1e2b5ca1ebbd353afa98
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
-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 | ||||
-rw-r--r-- | tests/auto/qml/ecmascripttests/TestExpectations | 13 |
7 files changed, 42 insertions, 16 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); diff --git a/tests/auto/qml/ecmascripttests/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations index e227163fe6..f9c54d099c 100644 --- a/tests/auto/qml/ecmascripttests/TestExpectations +++ b/tests/auto/qml/ecmascripttests/TestExpectations @@ -4058,11 +4058,6 @@ language/computed-property-names/to-name-side-effects/class language/computed-property-names/to-name-side-effects/numbers-class language/computed-property-names/to-name-side-effects/numbers-object language/computed-property-names/to-name-side-effects/object -language/destructuring/binding/initialization-requires-object-coercible-null -language/destructuring/binding/initialization-requires-object-coercible-undefined -language/destructuring/binding/syntax/array-elements-with-object-patterns -language/destructuring/binding/syntax/array-pattern-with-elisions -language/destructuring/binding/syntax/array-pattern-with-no-elements language/destructuring/binding/syntax/array-rest-elements language/destructuring/binding/syntax/recursive-array-and-object-patterns language/eval-code/direct/lex-env-distinct-cls @@ -5681,8 +5676,6 @@ language/expressions/function/dstr-dflt-ary-ptrn-rest-id-iter-step-err language/expressions/function/dstr-dflt-ary-ptrn-rest-id-iter-val-err language/expressions/function/dstr-dflt-ary-ptrn-rest-obj-id language/expressions/function/dstr-dflt-ary-ptrn-rest-obj-prop-id -language/expressions/function/dstr-dflt-obj-init-null -language/expressions/function/dstr-dflt-obj-init-undefined language/expressions/function/dstr-dflt-obj-ptrn-id-init-fn-name-arrow language/expressions/function/dstr-dflt-obj-ptrn-id-init-fn-name-class language/expressions/function/dstr-dflt-obj-ptrn-id-init-fn-name-cover @@ -5691,8 +5684,6 @@ language/expressions/function/dstr-dflt-obj-ptrn-id-init-fn-name-gen language/expressions/function/dstr-dflt-obj-ptrn-prop-ary language/expressions/function/dstr-dflt-obj-ptrn-prop-ary-init language/expressions/function/dstr-dflt-obj-ptrn-prop-eval-err -language/expressions/function/dstr-obj-init-null -language/expressions/function/dstr-obj-init-undefined language/expressions/function/dstr-obj-ptrn-id-init-fn-name-arrow language/expressions/function/dstr-obj-ptrn-id-init-fn-name-class language/expressions/function/dstr-obj-ptrn-id-init-fn-name-cover @@ -8912,8 +8903,6 @@ language/statements/function/dstr-dflt-ary-ptrn-rest-id-iter-step-err language/statements/function/dstr-dflt-ary-ptrn-rest-id-iter-val-err language/statements/function/dstr-dflt-ary-ptrn-rest-obj-id language/statements/function/dstr-dflt-ary-ptrn-rest-obj-prop-id -language/statements/function/dstr-dflt-obj-init-null -language/statements/function/dstr-dflt-obj-init-undefined language/statements/function/dstr-dflt-obj-ptrn-id-init-fn-name-arrow language/statements/function/dstr-dflt-obj-ptrn-id-init-fn-name-class language/statements/function/dstr-dflt-obj-ptrn-id-init-fn-name-cover @@ -8922,8 +8911,6 @@ language/statements/function/dstr-dflt-obj-ptrn-id-init-fn-name-gen language/statements/function/dstr-dflt-obj-ptrn-prop-ary language/statements/function/dstr-dflt-obj-ptrn-prop-ary-init language/statements/function/dstr-dflt-obj-ptrn-prop-eval-err -language/statements/function/dstr-obj-init-null -language/statements/function/dstr-obj-init-undefined language/statements/function/dstr-obj-ptrn-id-init-fn-name-arrow language/statements/function/dstr-obj-ptrn-id-init-fn-name-class language/statements/function/dstr-obj-ptrn-id-init-fn-name-cover |