aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/compiler/qv4bytecodehandler.cpp12
-rw-r--r--src/qml/compiler/qv4codegen.cpp88
-rw-r--r--src/qml/compiler/qv4codegen_p.h4
-rw-r--r--src/qml/compiler/qv4instr_moth.cpp16
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h8
-rw-r--r--src/qml/jit/qv4baselinejit.cpp51
-rw-r--r--src/qml/jit/qv4baselinejit_p.h4
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp68
-rw-r--r--src/qml/jsruntime/qv4runtimeapi_p.h2
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp24
-rw-r--r--tests/auto/qml/ecmascripttests/TestExpectations46
11 files changed, 235 insertions, 88 deletions
diff --git a/src/qml/compiler/qv4bytecodehandler.cpp b/src/qml/compiler/qv4bytecodehandler.cpp
index 3e4844a1ac..8d1ac0bfd9 100644
--- a/src/qml/compiler/qv4bytecodehandler.cpp
+++ b/src/qml/compiler/qv4bytecodehandler.cpp
@@ -263,6 +263,15 @@ std::vector<int> ByteCodeHandler::collectLabelsInBytecode(const char *code, uint
COLLECTOR_BEGIN_INSTR(CallContextObjectProperty)
COLLECTOR_END_INSTR(CallContextObjectProperty)
+ COLLECTOR_BEGIN_INSTR(CallWithSpread)
+ COLLECTOR_END_INSTR(CallWithSpread)
+
+ COLLECTOR_BEGIN_INSTR(Construct)
+ COLLECTOR_END_INSTR(Construct)
+
+ COLLECTOR_BEGIN_INSTR(ConstructWithSpread)
+ COLLECTOR_END_INSTR(ConstructWithSpread)
+
COLLECTOR_BEGIN_INSTR(SetUnwindHandler)
addLabel(code - start + offset);
COLLECTOR_END_INSTR(SetUnwindHandler)
@@ -355,9 +364,6 @@ std::vector<int> ByteCodeHandler::collectLabelsInBytecode(const char *code, uint
COLLECTOR_BEGIN_INSTR(ToObject)
COLLECTOR_END_INSTR(ToObject)
- COLLECTOR_BEGIN_INSTR(Construct)
- COLLECTOR_END_INSTR(Construct)
-
COLLECTOR_BEGIN_INSTR(Jump)
addLabel(code - start + offset);
COLLECTOR_END_INSTR(Jump)
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 6682f604de..fc2fb86666 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -1610,6 +1610,7 @@ bool Codegen::visit(CallExpression *ast)
RegisterScope scope(this);
Reference base = expression(ast->base);
+
if (hasError)
return false;
switch (base.type) {
@@ -1626,10 +1627,36 @@ bool Codegen::visit(CallExpression *ast)
break;
}
+ int thisObject = bytecodeGenerator->newRegister();
+ int functionObject = bytecodeGenerator->newRegister();
+
auto calldata = pushArgs(ast->arguments);
if (hasError)
return false;
+ if (calldata.hasSpread) {
+ Reference baseObject = base.baseObject();
+ if (!baseObject.isStackSlot()) {
+ baseObject.storeOnStack(thisObject);
+ baseObject = Reference::fromStackSlot(this, thisObject);
+ }
+ if (!base.isStackSlot()) {
+ base.storeOnStack(functionObject);
+ base = Reference::fromStackSlot(this, functionObject);
+ }
+
+ Instruction::CallWithSpread call;
+ call.func = base.stackSlot();
+ call.thisObject = baseObject.stackSlot();
+ call.argc = calldata.argc;
+ call.argv = calldata.argv;
+ bytecodeGenerator->addInstruction(call);
+
+ _expr.setResult(Reference::fromAccumulator(this));
+ return false;
+
+ }
+
handleCall(base, calldata);
return false;
}
@@ -1707,36 +1734,41 @@ void Codegen::handleCall(Reference &base, Arguments calldata)
Codegen::Arguments Codegen::pushArgs(ArgumentList *args)
{
+ bool hasSpread = false;
int argc = 0;
for (ArgumentList *it = args; it; it = it->next) {
if (it->isSpreadElement) {
- throwSyntaxError(it->firstSourceLocation(), QLatin1String("'...' in argument lists is unimplemented."));
- return { 0, 0 };
+ hasSpread = true;
+ ++argc;
}
++argc;
}
if (!argc)
- return { 0, 0 };
+ return { 0, 0, false };
int calldata = bytecodeGenerator->newRegisterArray(argc);
argc = 0;
for (ArgumentList *it = args; it; it = it->next) {
+ if (it->isSpreadElement) {
+ Reference::fromConst(this, Primitive::emptyValue().asReturnedValue()).storeOnStack(calldata + argc);
+ ++argc;
+ }
RegisterScope scope(this);
Reference e = expression(it->expression);
if (hasError)
break;
- if (!argc && !it->next) {
+ if (!argc && !it->next && !hasSpread) {
// avoid copy for functions taking a single argument
if (e.isStackSlot())
- return { 1, e.stackSlot() };
+ return { 1, e.stackSlot(), hasSpread };
}
(void) e.storeOnStack(calldata + argc);
++argc;
}
- return { argc, calldata };
+ return { argc, calldata, hasSpread };
}
Codegen::Arguments Codegen::pushTemplateArgs(TemplateLiteral *args)
@@ -1746,7 +1778,7 @@ Codegen::Arguments Codegen::pushTemplateArgs(TemplateLiteral *args)
++argc;
if (!argc)
- return { 0, 0 };
+ return { 0, 0, false };
int calldata = bytecodeGenerator->newRegisterArray(argc);
@@ -1760,7 +1792,7 @@ Codegen::Arguments Codegen::pushTemplateArgs(TemplateLiteral *args)
++argc;
}
- return { argc, calldata };
+ return { argc, calldata, false };
}
bool Codegen::visit(ConditionalExpression *ast)
@@ -2096,11 +2128,19 @@ bool Codegen::visit(NewMemberExpression *ast)
if (hasError)
return false;
- Instruction::Construct create;
- create.func = base.stackSlot();
- create.argc = calldata.argc;
- create.argv = calldata.argv;
- bytecodeGenerator->addInstruction(create);
+ if (calldata.hasSpread) {
+ Instruction::ConstructWithSpread create;
+ create.func = base.stackSlot();
+ create.argc = calldata.argc;
+ create.argv = calldata.argv;
+ bytecodeGenerator->addInstruction(create);
+ } else {
+ Instruction::Construct create;
+ create.func = base.stackSlot();
+ create.argc = calldata.argc;
+ create.argv = calldata.argv;
+ bytecodeGenerator->addInstruction(create);
+ }
_expr.setResult(Reference::fromAccumulator(this));
return false;
}
@@ -3640,6 +3680,28 @@ Codegen::Reference Codegen::Reference::storeConsumeAccumulator() const
return Reference();
}
+Codegen::Reference Codegen::Reference::baseObject() const
+{
+ if (type == Reference::QmlScopeObject || type == Reference::QmlContextObject) {
+ return Reference::fromStackSlot(codegen, qmlBase.stackSlot());
+ } else if (type == Reference::Member) {
+ RValue rval = propertyBase;
+ if (!rval.isValid())
+ return Reference::fromConst(codegen, Encode::undefined());
+ if (rval.isAccumulator())
+ return Reference::fromAccumulator(codegen);
+ if (rval.isStackSlot())
+ Reference::fromStackSlot(codegen, rval.stackSlot());
+ if (rval.isConst())
+ return Reference::fromConst(codegen, rval.constantValue());
+ Q_UNREACHABLE();
+ } else if (type == Reference::Subscript) {
+ return Reference::fromStackSlot(codegen, elementBase.stackSlot());
+ } else {
+ return Reference::fromConst(codegen, Encode::undefined());
+ }
+}
+
Codegen::Reference Codegen::Reference::storeOnStack() const
{ return doStoreOnStack(-1); }
diff --git a/src/qml/compiler/qv4codegen_p.h b/src/qml/compiler/qv4codegen_p.h
index 3750811eaf..83b8731179 100644
--- a/src/qml/compiler/qv4codegen_p.h
+++ b/src/qml/compiler/qv4codegen_p.h
@@ -325,6 +325,8 @@ public:
Q_REQUIRED_RESULT Reference storeRetainAccumulator() const;
Reference storeConsumeAccumulator() const;
+ Q_REQUIRED_RESULT Reference baseObject() const;
+
bool storeWipesAccumulator() const;
void loadInAccumulator() const;
@@ -637,7 +639,7 @@ public:
Reference binopHelper(QSOperator::Op oper, Reference &left, Reference &right);
Reference jumpBinop(QSOperator::Op oper, Reference &left, Reference &right);
- struct Arguments { int argc; int argv; };
+ struct Arguments { int argc; int argv; bool hasSpread; };
Arguments pushArgs(AST::ArgumentList *args);
void handleCall(Reference &base, Arguments calldata);
diff --git a/src/qml/compiler/qv4instr_moth.cpp b/src/qml/compiler/qv4instr_moth.cpp
index 6f603f9488..df5dd5610c 100644
--- a/src/qml/compiler/qv4instr_moth.cpp
+++ b/src/qml/compiler/qv4instr_moth.cpp
@@ -376,6 +376,18 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
d << dumpRegister(base, nFormals) << "." << name << dumpArguments(argc, argv, nFormals);
MOTH_END_INSTR(CallContextObjectProperty)
+ MOTH_BEGIN_INSTR(CallWithSpread)
+ d << "new" << dumpRegister(func, nFormals) << dumpRegister(thisObject, nFormals) << dumpArguments(argc, argv, nFormals);
+ MOTH_END_INSTR(CallWithSpread)
+
+ MOTH_BEGIN_INSTR(Construct)
+ d << "new" << dumpRegister(func, nFormals) << dumpArguments(argc, argv, nFormals);
+ MOTH_END_INSTR(Construct)
+
+ MOTH_BEGIN_INSTR(ConstructWithSpread)
+ d << "new" << dumpRegister(func, nFormals) << dumpArguments(argc, argv, nFormals);
+ MOTH_END_INSTR(ConstructWithSpread)
+
MOTH_BEGIN_INSTR(SetUnwindHandler)
if (offset)
d << ABSOLUTE_OFFSET();
@@ -486,10 +498,6 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
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)
-
MOTH_BEGIN_INSTR(Jump)
d << ABSOLUTE_OFFSET();
MOTH_END_INSTR(Jump)
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index d4d630dfaf..85b30507a1 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -109,6 +109,9 @@ QT_BEGIN_NAMESPACE
#define INSTR_CallGlobalLookup(op) INSTRUCTION(op, CallGlobalLookup, 3, index, argc, argv)
#define INSTR_CallScopeObjectProperty(op) INSTRUCTION(op, CallScopeObjectProperty, 4, name, base, argc, argv)
#define INSTR_CallContextObjectProperty(op) INSTRUCTION(op, CallContextObjectProperty, 4, name, base, argc, argv)
+#define INSTR_CallWithSpread(op) INSTRUCTION(op, CallWithSpread, 4, func, thisObject, argc, argv)
+#define INSTR_Construct(op) INSTRUCTION(op, Construct, 3, func, argc, argv)
+#define INSTR_ConstructWithSpread(op) INSTRUCTION(op, ConstructWithSpread, 3, func, argc, argv)
#define INSTR_SetUnwindHandler(op) INSTRUCTION(op, SetUnwindHandler, 1, offset)
#define INSTR_UnwindDispatch(op) INSTRUCTION(op, UnwindDispatch, 0)
#define INSTR_UnwindToLabel(op) INSTRUCTION(op, UnwindToLabel, 2, level, offset)
@@ -139,7 +142,6 @@ QT_BEGIN_NAMESPACE
#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)
#define INSTR_JumpFalse(op) INSTRUCTION(op, JumpFalse, 1, offset)
@@ -235,6 +237,9 @@ QT_BEGIN_NAMESPACE
F(CallGlobalLookup) \
F(CallScopeObjectProperty) \
F(CallContextObjectProperty) \
+ F(CallWithSpread) \
+ F(Construct) \
+ F(ConstructWithSpread) \
F(SetUnwindHandler) \
F(UnwindDispatch) \
F(UnwindToLabel) \
@@ -265,7 +270,6 @@ QT_BEGIN_NAMESPACE
F(CreateRestParameter) \
F(ConvertThisToObject) \
F(ToObject) \
- F(Construct) \
F(Jump) \
F(JumpTrue) \
F(JumpFalse) \
diff --git a/src/qml/jit/qv4baselinejit.cpp b/src/qml/jit/qv4baselinejit.cpp
index 7f9674c57f..c813ff7f2d 100644
--- a/src/qml/jit/qv4baselinejit.cpp
+++ b/src/qml/jit/qv4baselinejit.cpp
@@ -532,6 +532,45 @@ void BaselineJIT::generate_CallContextObjectProperty(int propIdx, int base, int
as->checkException();
}
+
+void BaselineJIT::generate_CallWithSpread(int func, int thisObject, int argc, int argv)
+{
+ STORE_IP();
+ as->prepareCallWithArgCount(5);
+ as->passInt32AsArg(argc, 4);
+ as->passRegAsArg(argv, 3);
+ as->passRegAsArg(thisObject, 2);
+ as->passRegAsArg(func, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_callWithSpread, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
+
+void BaselineJIT::generate_Construct(int func, int argc, int argv)
+{
+ STORE_IP();
+ as->prepareCallWithArgCount(4);
+ as->passInt32AsArg(argc, 3);
+ as->passRegAsArg(argv, 2);
+ as->passRegAsArg(func, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_construct, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
+void BaselineJIT::generate_ConstructWithSpread(int func, int argc, int argv)
+{
+ STORE_IP();
+ as->prepareCallWithArgCount(4);
+ as->passInt32AsArg(argc, 3);
+ as->passRegAsArg(argv, 2);
+ as->passRegAsArg(func, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_constructWithSpread, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
void BaselineJIT::generate_SetUnwindHandler(int offset)
{
if (offset)
@@ -841,18 +880,6 @@ void BaselineJIT::generate_ToObject()
}
-void BaselineJIT::generate_Construct(int func, int argc, int argv)
-{
- STORE_IP();
- as->prepareCallWithArgCount(4);
- as->passInt32AsArg(argc, 3);
- as->passRegAsArg(argv, 2);
- as->passRegAsArg(func, 1);
- as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(Runtime::method_construct, Assembler::ResultInAccumulator);
- as->checkException();
-}
-
void BaselineJIT::generate_Jump(int offset) { as->jump(instructionOffset() + offset); }
void BaselineJIT::generate_JumpTrue(int offset) { as->jumpTrue(instructionOffset() + offset); }
void BaselineJIT::generate_JumpFalse(int offset) { as->jumpFalse(instructionOffset() + offset); }
diff --git a/src/qml/jit/qv4baselinejit_p.h b/src/qml/jit/qv4baselinejit_p.h
index b09efb1680..11548219af 100644
--- a/src/qml/jit/qv4baselinejit_p.h
+++ b/src/qml/jit/qv4baselinejit_p.h
@@ -126,6 +126,9 @@ public:
void generate_CallGlobalLookup(int index, int argc, int argv) override;
void generate_CallScopeObjectProperty(int propIdx, int base, int argc, int argv) override;
void generate_CallContextObjectProperty(int propIdx, int base, int argc, int argv) override;
+ void generate_CallWithSpread(int func, int thisObject, int argc, int argv) override;
+ void generate_Construct(int func, int argc, int argv) override;
+ void generate_ConstructWithSpread(int func, int argc, int argv) override;
void generate_SetUnwindHandler(int offset) override;
void generate_UnwindDispatch() override;
void generate_UnwindToLabel(int level, int offset) override;
@@ -156,7 +159,6 @@ public:
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;
void generate_JumpFalse(int offset) override;
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 4c2477ded2..4e782fea00 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -1256,6 +1256,60 @@ ReturnedValue Runtime::method_callQmlContextObjectProperty(ExecutionEngine *engi
return fo->call(qmlContextValue, argv, argc);
}
+struct CallArgs {
+ Value *argv;
+ int argc;
+};
+
+static CallArgs createSpreadArguments(Scope &scope, Value *argv, int argc)
+{
+ ScopedValue it(scope);
+ ScopedValue done(scope);
+
+ int argCount = 0;
+
+ Value *v = scope.alloc<Scope::Uninitialized>();
+ Value *arguments = v;
+ for (int i = 0; i < argc; ++i) {
+ if (!argv[i].isEmpty()) {
+ *v = argv[i];
+ ++argCount;
+ v = scope.alloc<Scope::Uninitialized>();
+ continue;
+ }
+ // spread element
+ ++i;
+ it = Runtime::method_getIterator(scope.engine, argv[i], /* ForInIterator */ 1);
+ if (scope.engine->hasException)
+ return { nullptr, 0 };
+ while (1) {
+ done = Runtime::method_iteratorNext(scope.engine, it, v);
+ if (scope.engine->hasException)
+ return { nullptr, 0 };
+ Q_ASSERT(done->isBoolean());
+ if (done->booleanValue())
+ break;
+ ++argCount;
+ v = scope.alloc<Scope::Uninitialized>();
+ }
+ }
+ return { arguments, argCount };
+}
+
+ReturnedValue Runtime::method_callWithSpread(ExecutionEngine *engine, const Value &function, const Value &thisObject, Value *argv, int argc)
+{
+ Q_ASSERT(argc >= 1);
+ if (!function.isFunctionObject())
+ return engine->throwTypeError();
+
+ Scope scope(engine);
+ CallArgs arguments = createSpreadArguments(scope, argv, argc);
+ if (engine->hasException)
+ return Encode::undefined();
+
+ return static_cast<const FunctionObject &>(function).call(&thisObject, arguments.argv, arguments.argc);
+}
+
ReturnedValue Runtime::method_construct(ExecutionEngine *engine, const Value &function, Value *argv, int argc)
{
if (!function.isFunctionObject())
@@ -1264,6 +1318,20 @@ ReturnedValue Runtime::method_construct(ExecutionEngine *engine, const Value &fu
return static_cast<const FunctionObject &>(function).callAsConstructor(argv, argc);
}
+ReturnedValue Runtime::method_constructWithSpread(ExecutionEngine *engine, const Value &function, Value *argv, int argc)
+{
+ Q_UNIMPLEMENTED();
+ if (!function.isFunctionObject())
+ return engine->throwTypeError();
+
+ Scope scope(engine);
+ CallArgs arguments = createSpreadArguments(scope, argv, argc);
+ if (engine->hasException)
+ return Encode::undefined();
+
+ return static_cast<const FunctionObject &>(function).callAsConstructor(arguments.argv, arguments.argc);
+}
+
void Runtime::method_throwException(ExecutionEngine *engine, const Value &value)
{
if (!value.isEmpty())
diff --git a/src/qml/jsruntime/qv4runtimeapi_p.h b/src/qml/jsruntime/qv4runtimeapi_p.h
index 63f4f426aa..09f6a65dde 100644
--- a/src/qml/jsruntime/qv4runtimeapi_p.h
+++ b/src/qml/jsruntime/qv4runtimeapi_p.h
@@ -99,9 +99,11 @@ struct ExceptionCheck<void (*)(QV4::NoThrowEngine *, A, B, C)> {
F(ReturnedValue, callElement, (ExecutionEngine *engine, Value *base, const Value &index, Value *argv, int argc)) \
F(ReturnedValue, callValue, (ExecutionEngine *engine, const Value &func, Value *argv, int argc)) \
F(ReturnedValue, callPossiblyDirectEval, (ExecutionEngine *engine, Value *argv, int argc)) \
+ F(ReturnedValue, callWithSpread, (ExecutionEngine *engine, const Value &func, const Value &thisObject, Value *argv, int argc)) \
\
/* construct */ \
F(ReturnedValue, construct, (ExecutionEngine *engine, const Value &func, Value *argv, int argc)) \
+ F(ReturnedValue, constructWithSpread, (ExecutionEngine *engine, const Value &func, Value *argv, int argc)) \
\
/* load & store */ \
F(void, storeNameStrict, (ExecutionEngine *engine, int nameIndex, const Value &value)) \
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index 73a28557c2..9bd19cbe6b 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -877,6 +877,24 @@ QV4::ReturnedValue VME::interpret(CppStackFrame &frame, const char *code)
CHECK_EXCEPTION;
MOTH_END_INSTR(CallContextObjectProperty)
+ MOTH_BEGIN_INSTR(CallWithSpread)
+ STORE_IP();
+ acc = Runtime::method_callWithSpread(engine, STACK_VALUE(func), STACK_VALUE(thisObject), stack + argv, argc);
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(CallWithSpread)
+
+ MOTH_BEGIN_INSTR(Construct)
+ STORE_IP();
+ acc = Runtime::method_construct(engine, STACK_VALUE(func), stack + argv, argc);
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(Construct)
+
+ MOTH_BEGIN_INSTR(ConstructWithSpread)
+ STORE_IP();
+ acc = Runtime::method_constructWithSpread(engine, STACK_VALUE(func), stack + argv, argc);
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(ConstructWithSpread)
+
MOTH_BEGIN_INSTR(SetUnwindHandler)
frame.unwindHandler = offset ? code + offset : nullptr;
MOTH_END_INSTR(SetUnwindHandler)
@@ -1062,12 +1080,6 @@ QV4::ReturnedValue VME::interpret(CppStackFrame &frame, const char *code)
CHECK_EXCEPTION;
MOTH_END_INSTR(ToObject)
- MOTH_BEGIN_INSTR(Construct)
- STORE_IP();
- acc = Runtime::method_construct(engine, STACK_VALUE(func), stack + argv, argc);
- CHECK_EXCEPTION;
- MOTH_END_INSTR(Construct)
-
MOTH_BEGIN_INSTR(Jump)
code += offset;
MOTH_END_INSTR(Jump)
diff --git a/tests/auto/qml/ecmascripttests/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations
index 317ac1735e..edb24db8fb 100644
--- a/tests/auto/qml/ecmascripttests/TestExpectations
+++ b/tests/auto/qml/ecmascripttests/TestExpectations
@@ -2538,31 +2538,8 @@ language/expressions/call/11.2.3-3_3.js fails
language/expressions/call/eval-realm-indirect.js sloppyFails
language/expressions/call/eval-spread-empty-leading.js fails
language/expressions/call/eval-spread-empty-trailing.js fails
-language/expressions/call/eval-spread-empty.js fails
language/expressions/call/eval-spread.js fails
language/expressions/call/scope-lex-open.js fails
-language/expressions/call/spread-err-mult-err-expr-throws.js fails
-language/expressions/call/spread-err-mult-err-iter-get-value.js fails
-language/expressions/call/spread-err-mult-err-itr-get-call.js fails
-language/expressions/call/spread-err-mult-err-itr-get-get.js fails
-language/expressions/call/spread-err-mult-err-itr-step.js fails
-language/expressions/call/spread-err-mult-err-itr-value.js fails
-language/expressions/call/spread-err-mult-err-unresolvable.js fails
-language/expressions/call/spread-err-sngl-err-expr-throws.js fails
-language/expressions/call/spread-err-sngl-err-itr-get-call.js fails
-language/expressions/call/spread-err-sngl-err-itr-get-get.js fails
-language/expressions/call/spread-err-sngl-err-itr-get-value.js fails
-language/expressions/call/spread-err-sngl-err-itr-step.js fails
-language/expressions/call/spread-err-sngl-err-itr-value.js fails
-language/expressions/call/spread-err-sngl-err-unresolvable.js fails
-language/expressions/call/spread-mult-empty.js fails
-language/expressions/call/spread-mult-expr.js fails
-language/expressions/call/spread-mult-iter.js fails
-language/expressions/call/spread-mult-literal.js fails
-language/expressions/call/spread-sngl-empty.js fails
-language/expressions/call/spread-sngl-expr.js fails
-language/expressions/call/spread-sngl-iter.js fails
-language/expressions/call/spread-sngl-literal.js fails
language/expressions/call/tco-call-args.js strictFails
language/expressions/call/tco-cross-realm-class-construct.js fails
language/expressions/call/tco-cross-realm-class-derived-construct.js fails
@@ -2573,7 +2550,6 @@ language/expressions/call/tco-non-eval-function-dynamic.js sloppyFails
language/expressions/call/tco-non-eval-function.js sloppyFails
language/expressions/call/tco-non-eval-global.js sloppyFails
language/expressions/call/tco-non-eval-with.js sloppyFails
-language/expressions/call/trailing-comma.js fails
language/expressions/class/accessor-name-inst-computed-err-evaluation.js fails
language/expressions/class/accessor-name-inst-computed-err-to-prop-key.js fails
language/expressions/class/accessor-name-inst-computed-err-unresolvable.js fails
@@ -3472,28 +3448,6 @@ language/expressions/new.target/value-via-super-call.js fails
language/expressions/new.target/value-via-super-property.js fails
language/expressions/new.target/value-via-tagged-template.js fails
language/expressions/new/non-ctor-err-realm.js fails
-language/expressions/new/spread-err-mult-err-expr-throws.js fails
-language/expressions/new/spread-err-mult-err-iter-get-value.js fails
-language/expressions/new/spread-err-mult-err-itr-get-call.js fails
-language/expressions/new/spread-err-mult-err-itr-get-get.js fails
-language/expressions/new/spread-err-mult-err-itr-step.js fails
-language/expressions/new/spread-err-mult-err-itr-value.js fails
-language/expressions/new/spread-err-mult-err-unresolvable.js fails
-language/expressions/new/spread-err-sngl-err-expr-throws.js fails
-language/expressions/new/spread-err-sngl-err-itr-get-call.js fails
-language/expressions/new/spread-err-sngl-err-itr-get-get.js fails
-language/expressions/new/spread-err-sngl-err-itr-get-value.js fails
-language/expressions/new/spread-err-sngl-err-itr-step.js fails
-language/expressions/new/spread-err-sngl-err-itr-value.js fails
-language/expressions/new/spread-err-sngl-err-unresolvable.js fails
-language/expressions/new/spread-mult-empty.js fails
-language/expressions/new/spread-mult-expr.js fails
-language/expressions/new/spread-mult-iter.js fails
-language/expressions/new/spread-mult-literal.js fails
-language/expressions/new/spread-sngl-empty.js fails
-language/expressions/new/spread-sngl-expr.js fails
-language/expressions/new/spread-sngl-iter.js fails
-language/expressions/new/spread-sngl-literal.js fails
language/expressions/object/concise-generator.js fails
language/expressions/object/dstr-gen-meth-ary-ptrn-elem-id-init-fn-name-class.js fails
language/expressions/object/dstr-gen-meth-dflt-ary-ptrn-elem-id-init-fn-name-class.js fails