diff options
author | Lars Knoll <[email protected]> | 2018-06-26 14:18:16 +0200 |
---|---|---|
committer | Lars Knoll <[email protected]> | 2018-07-03 08:08:39 +0000 |
commit | 65e799a9dec58b4bde3a085149f8cbcf0f5f3fba (patch) | |
tree | 4a9473532f420d8f20fc34af60bf1f132d459b82 | |
parent | 61440411a979c7c317bafccfbf5201d969819a06 (diff) |
Implement support for new.target
Support the new.target meta property in the codegen, and
add support for passing the newtarget into the constructor
vtable methods and the execution context.
Change-Id: I62ea58e5e92d894035a76e35776203e9837c383b
Reviewed-by: Simon Hausmann <[email protected]>
46 files changed, 97 insertions, 99 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index 9bc9567be6..40aac8f7bb 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -2036,7 +2036,9 @@ bool Codegen::visit(FieldMemberExpression *ast) throwSyntaxError(ast->identifierToken, QLatin1String("Expected 'target' after 'new.'.")); return false; } - throwSyntaxError(ast->identifierToken, QLatin1String("Support for 'new.target' unimplemented.")); + Reference r = Reference::fromStackSlot(this, CallData::NewTarget); + _expr.setResult(r); + return false; } } diff --git a/src/qml/compiler/qv4instr_moth.cpp b/src/qml/compiler/qv4instr_moth.cpp index d8a1fa2dde..c3cee9c851 100644 --- a/src/qml/compiler/qv4instr_moth.cpp +++ b/src/qml/compiler/qv4instr_moth.cpp @@ -147,6 +147,8 @@ QString dumpRegister(int reg, int nFormals) return QStringLiteral("(context)"); else if (reg == CallData::Accumulator) return QStringLiteral("(accumulator)"); + else if (reg == CallData::NewTarget) + return QStringLiteral("(new.target)"); else if (reg == CallData::This) return QStringLiteral("(this)"); else if (reg == CallData::Argc) diff --git a/src/qml/jsruntime/qv4arraybuffer.cpp b/src/qml/jsruntime/qv4arraybuffer.cpp index a70fd26a6c..f80c9a0ab2 100644 --- a/src/qml/jsruntime/qv4arraybuffer.cpp +++ b/src/qml/jsruntime/qv4arraybuffer.cpp @@ -53,7 +53,7 @@ void Heap::ArrayBufferCtor::init(QV4::ExecutionContext *scope) Heap::FunctionObject::init(scope, QStringLiteral("ArrayBuffer")); } -ReturnedValue ArrayBufferCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc) +ReturnedValue ArrayBufferCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *) { ExecutionEngine *v4 = f->engine(); Scope scope(v4); @@ -76,7 +76,7 @@ ReturnedValue ArrayBufferCtor::virtualCallAsConstructor(const FunctionObject *f, ReturnedValue ArrayBufferCtor::virtualCall(const FunctionObject *f, const Value *, const Value *argv, int argc) { - return virtualCallAsConstructor(f, argv, argc); + return virtualCallAsConstructor(f, argv, argc, f); } ReturnedValue ArrayBufferCtor::method_isView(const FunctionObject *, const Value *, const Value *argv, int argc) diff --git a/src/qml/jsruntime/qv4arraybuffer_p.h b/src/qml/jsruntime/qv4arraybuffer_p.h index 4ace74a92e..089dbc522f 100644 --- a/src/qml/jsruntime/qv4arraybuffer_p.h +++ b/src/qml/jsruntime/qv4arraybuffer_p.h @@ -78,7 +78,7 @@ struct ArrayBufferCtor: FunctionObject { V4_OBJECT2(ArrayBufferCtor, FunctionObject) - static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *); static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); static ReturnedValue method_isView(const FunctionObject *, const Value *thisObject, const Value *argv, int argc); diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp index 1cfeadeb89..05f6b7dfec 100644 --- a/src/qml/jsruntime/qv4arrayobject.cpp +++ b/src/qml/jsruntime/qv4arrayobject.cpp @@ -59,7 +59,7 @@ void Heap::ArrayCtor::init(QV4::ExecutionContext *scope) Heap::FunctionObject::init(scope, QStringLiteral("Array")); } -ReturnedValue ArrayCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc) +ReturnedValue ArrayCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *) { ExecutionEngine *v4 = static_cast<const ArrayCtor *>(f)->engine(); Scope scope(v4); @@ -86,7 +86,7 @@ ReturnedValue ArrayCtor::virtualCallAsConstructor(const FunctionObject *f, const ReturnedValue ArrayCtor::virtualCall(const FunctionObject *f, const Value *, const Value *argv, int argc) { - return virtualCallAsConstructor(f, argv, argc); + return virtualCallAsConstructor(f, argv, argc, f); } void ArrayPrototype::init(ExecutionEngine *engine, Object *ctor) diff --git a/src/qml/jsruntime/qv4arrayobject_p.h b/src/qml/jsruntime/qv4arrayobject_p.h index 9fc0b62e48..04ec7e1607 100644 --- a/src/qml/jsruntime/qv4arrayobject_p.h +++ b/src/qml/jsruntime/qv4arrayobject_p.h @@ -70,7 +70,7 @@ struct ArrayCtor: FunctionObject { V4_OBJECT2(ArrayCtor, FunctionObject) - static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *); static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); }; diff --git a/src/qml/jsruntime/qv4booleanobject.cpp b/src/qml/jsruntime/qv4booleanobject.cpp index 13c486e9b3..f00abad871 100644 --- a/src/qml/jsruntime/qv4booleanobject.cpp +++ b/src/qml/jsruntime/qv4booleanobject.cpp @@ -50,7 +50,7 @@ void Heap::BooleanCtor::init(QV4::ExecutionContext *scope) Heap::FunctionObject::init(scope, QStringLiteral("Boolean")); } -ReturnedValue BooleanCtor::virtualCallAsConstructor(const FunctionObject *that, const Value *argv, int argc) +ReturnedValue BooleanCtor::virtualCallAsConstructor(const FunctionObject *that, const Value *argv, int argc, const Value *) { bool n = argc ? argv[0].toBoolean() : false; return Encode(that->engine()->newBooleanObject(n)); diff --git a/src/qml/jsruntime/qv4booleanobject_p.h b/src/qml/jsruntime/qv4booleanobject_p.h index 288da49512..276ec8393b 100644 --- a/src/qml/jsruntime/qv4booleanobject_p.h +++ b/src/qml/jsruntime/qv4booleanobject_p.h @@ -70,7 +70,7 @@ struct BooleanCtor: FunctionObject { V4_OBJECT2(BooleanCtor, FunctionObject) - static ReturnedValue virtualCallAsConstructor(const FunctionObject *, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *, const Value *argv, int argc, const Value *); static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); }; diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h index 657945b1a6..e2fb18720a 100644 --- a/src/qml/jsruntime/qv4context_p.h +++ b/src/qml/jsruntime/qv4context_p.h @@ -64,13 +64,15 @@ struct CallData Context = 1, Accumulator = 2, This = 3, - Argc = 4 + NewTarget = 4, + Argc = 5 }; Value function; Value context; Value accumulator; Value thisObject; + Value newTarget; Value _argc; int argc() const { @@ -94,7 +96,7 @@ struct CallData Q_STATIC_ASSERT(std::is_standard_layout<CallData>::value); Q_STATIC_ASSERT(offsetof(CallData, thisObject) == CallData::This*sizeof(Value)); -Q_STATIC_ASSERT(offsetof(CallData, args) == 5*sizeof(Value)); +Q_STATIC_ASSERT(offsetof(CallData, args) == 6*sizeof(Value)); namespace Heap { diff --git a/src/qml/jsruntime/qv4dataview.cpp b/src/qml/jsruntime/qv4dataview.cpp index 23ea40dcf9..d550e559d3 100644 --- a/src/qml/jsruntime/qv4dataview.cpp +++ b/src/qml/jsruntime/qv4dataview.cpp @@ -55,7 +55,7 @@ void Heap::DataViewCtor::init(QV4::ExecutionContext *scope) Heap::FunctionObject::init(scope, QStringLiteral("DataView")); } -ReturnedValue DataViewCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc) +ReturnedValue DataViewCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *) { Scope scope(f->engine()); Scoped<ArrayBuffer> buffer(scope, argc ? argv[0] : Primitive::undefinedValue()); @@ -79,7 +79,7 @@ ReturnedValue DataViewCtor::virtualCallAsConstructor(const FunctionObject *f, co ReturnedValue DataViewCtor::virtualCall(const FunctionObject *f, const Value *, const Value *argv, int argc) { - return virtualCallAsConstructor(f, argv, argc); + return virtualCallAsConstructor(f, argv, argc, f); } void DataViewPrototype::init(ExecutionEngine *engine, Object *ctor) diff --git a/src/qml/jsruntime/qv4dataview_p.h b/src/qml/jsruntime/qv4dataview_p.h index 50b31a4568..6a9f865c0f 100644 --- a/src/qml/jsruntime/qv4dataview_p.h +++ b/src/qml/jsruntime/qv4dataview_p.h @@ -79,7 +79,7 @@ struct DataViewCtor: FunctionObject { V4_OBJECT2(DataViewCtor, FunctionObject) - static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *); static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); }; diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp index 80221465ef..474c58d3fd 100644 --- a/src/qml/jsruntime/qv4dateobject.cpp +++ b/src/qml/jsruntime/qv4dateobject.cpp @@ -743,7 +743,7 @@ void Heap::DateCtor::init(QV4::ExecutionContext *scope) Heap::FunctionObject::init(scope, QStringLiteral("Date")); } -ReturnedValue DateCtor::virtualCallAsConstructor(const FunctionObject *that, const Value *argv, int argc) +ReturnedValue DateCtor::virtualCallAsConstructor(const FunctionObject *that, const Value *argv, int argc, const Value *) { ExecutionEngine *e = that->engine(); double t = 0; diff --git a/src/qml/jsruntime/qv4dateobject_p.h b/src/qml/jsruntime/qv4dateobject_p.h index e1e0cccb11..5b9934282c 100644 --- a/src/qml/jsruntime/qv4dateobject_p.h +++ b/src/qml/jsruntime/qv4dateobject_p.h @@ -108,7 +108,7 @@ struct DateCtor: FunctionObject { V4_OBJECT2(DateCtor, FunctionObject) - static ReturnedValue virtualCallAsConstructor(const FunctionObject *, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *, const Value *argv, int argc, const Value *); static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int); }; diff --git a/src/qml/jsruntime/qv4errorobject.cpp b/src/qml/jsruntime/qv4errorobject.cpp index 71604447db..e8b4e04e83 100644 --- a/src/qml/jsruntime/qv4errorobject.cpp +++ b/src/qml/jsruntime/qv4errorobject.cpp @@ -229,7 +229,7 @@ void Heap::ErrorCtor::init(QV4::ExecutionContext *scope, const QString &name) Heap::FunctionObject::init(scope, name); } -ReturnedValue ErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc) +ReturnedValue ErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *) { Value v = argc ? *argv : Primitive::undefinedValue(); return ErrorObject::create<ErrorObject>(f->engine(), v)->asReturnedValue(); @@ -245,7 +245,7 @@ void Heap::EvalErrorCtor::init(QV4::ExecutionContext *scope) Heap::ErrorCtor::init(scope, QStringLiteral("EvalError")); } -ReturnedValue EvalErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc) +ReturnedValue EvalErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *) { Value v = argc ? *argv : Primitive::undefinedValue(); return ErrorObject::create<EvalErrorObject>(f->engine(), v)->asReturnedValue(); @@ -256,7 +256,7 @@ void Heap::RangeErrorCtor::init(QV4::ExecutionContext *scope) Heap::ErrorCtor::init(scope, QStringLiteral("RangeError")); } -ReturnedValue RangeErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc) +ReturnedValue RangeErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *) { Value v = argc ? *argv : Primitive::undefinedValue(); return ErrorObject::create<RangeErrorObject>(f->engine(), v)->asReturnedValue(); @@ -267,7 +267,7 @@ void Heap::ReferenceErrorCtor::init(QV4::ExecutionContext *scope) Heap::ErrorCtor::init(scope, QStringLiteral("ReferenceError")); } -ReturnedValue ReferenceErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc) +ReturnedValue ReferenceErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *) { Value v = argc ? *argv : Primitive::undefinedValue(); return ErrorObject::create<ReferenceErrorObject>(f->engine(), v)->asReturnedValue(); @@ -278,7 +278,7 @@ void Heap::SyntaxErrorCtor::init(QV4::ExecutionContext *scope) Heap::ErrorCtor::init(scope, QStringLiteral("SyntaxError")); } -ReturnedValue SyntaxErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc) +ReturnedValue SyntaxErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *) { Value v = argc ? *argv : Primitive::undefinedValue(); return ErrorObject::create<SyntaxErrorObject>(f->engine(), v)->asReturnedValue(); @@ -289,7 +289,7 @@ void Heap::TypeErrorCtor::init(QV4::ExecutionContext *scope) Heap::ErrorCtor::init(scope, QStringLiteral("TypeError")); } -ReturnedValue TypeErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc) +ReturnedValue TypeErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *) { Value v = argc ? *argv : Primitive::undefinedValue(); return ErrorObject::create<TypeErrorObject>(f->engine(), v)->asReturnedValue(); @@ -300,7 +300,7 @@ void Heap::URIErrorCtor::init(QV4::ExecutionContext *scope) Heap::ErrorCtor::init(scope, QStringLiteral("URIError")); } -ReturnedValue URIErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc) +ReturnedValue URIErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *) { Value v = argc ? *argv : Primitive::undefinedValue(); return ErrorObject::create<URIErrorObject>(f->engine(), v)->asReturnedValue(); diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h index 969c39739a..90ef4dd842 100644 --- a/src/qml/jsruntime/qv4errorobject_p.h +++ b/src/qml/jsruntime/qv4errorobject_p.h @@ -229,7 +229,7 @@ struct ErrorCtor: FunctionObject { V4_OBJECT2(ErrorCtor, FunctionObject) - static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *); static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); }; @@ -237,42 +237,42 @@ struct EvalErrorCtor: ErrorCtor { V4_OBJECT2(EvalErrorCtor, ErrorCtor) - static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *); }; struct RangeErrorCtor: ErrorCtor { V4_OBJECT2(RangeErrorCtor, ErrorCtor) - static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *); }; struct ReferenceErrorCtor: ErrorCtor { V4_OBJECT2(ReferenceErrorCtor, ErrorCtor) - static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *); }; struct SyntaxErrorCtor: ErrorCtor { V4_OBJECT2(SyntaxErrorCtor, ErrorCtor) - static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *); }; struct TypeErrorCtor: ErrorCtor { V4_OBJECT2(TypeErrorCtor, ErrorCtor) - static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *); }; struct URIErrorCtor: ErrorCtor { V4_OBJECT2(URIErrorCtor, ErrorCtor) - static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *); }; diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index 8b912d16a9..27bdc7dd44 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -168,7 +168,7 @@ ReturnedValue FunctionObject::name() const return get(scope()->internalClass->engine->id_name()); } -ReturnedValue FunctionObject::virtualCallAsConstructor(const FunctionObject *f, const Value *, int) +ReturnedValue FunctionObject::virtualCallAsConstructor(const FunctionObject *f, const Value *, int, const Value *) { return f->engine()->throwTypeError(); } @@ -275,7 +275,7 @@ QQmlRefPointer<CompiledData::CompilationUnit> FunctionCtor::parse(ExecutionEngin return cg.generateCompilationUnit(); } -ReturnedValue FunctionCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc) +ReturnedValue FunctionCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *) { ExecutionEngine *engine = f->engine(); @@ -291,7 +291,7 @@ ReturnedValue FunctionCtor::virtualCallAsConstructor(const FunctionObject *f, co // 15.3.1: This is equivalent to new Function(...) ReturnedValue FunctionCtor::virtualCall(const FunctionObject *f, const Value *, const Value *argv, int argc) { - return virtualCallAsConstructor(f, argv, argc); + return virtualCallAsConstructor(f, argv, argc, f); } DEFINE_OBJECT_VTABLE(FunctionPrototype); @@ -450,7 +450,7 @@ ReturnedValue FunctionPrototype::method_hasInstance(const FunctionObject *f, con DEFINE_OBJECT_VTABLE(ScriptFunction); -ReturnedValue ScriptFunction::virtualCallAsConstructor(const FunctionObject *fo, const Value *argv, int argc) +ReturnedValue ScriptFunction::virtualCallAsConstructor(const FunctionObject *fo, const Value *argv, int argc, const Value *newTarget) { ExecutionEngine *v4 = fo->engine(); const ScriptFunction *f = static_cast<const ScriptFunction *>(fo); @@ -458,7 +458,7 @@ ReturnedValue ScriptFunction::virtualCallAsConstructor(const FunctionObject *fo, Scope scope(v4); ScopedValue thisObject(scope, v4->memoryManager->allocObject<Object>(f->classForConstructor())); - ReturnedValue result = Moth::VME::exec(fo, thisObject, argv, argc); + ReturnedValue result = Moth::VME::exec(fo, thisObject, argv, argc, newTarget); if (Q_UNLIKELY(v4->hasException)) return Encode::undefined(); @@ -516,14 +516,14 @@ ReturnedValue ConstructorFunction::virtualCall(const FunctionObject *f, const Va DEFINE_OBJECT_VTABLE(MemberFunction); -ReturnedValue MemberFunction::virtualCallAsConstructor(const FunctionObject *f, const Value *, int) +ReturnedValue MemberFunction::virtualCallAsConstructor(const FunctionObject *f, const Value *, int, const Value *) { return f->engine()->throwTypeError(QStringLiteral("Function is not a constructor.")); } DEFINE_OBJECT_VTABLE(DefaultClassConstructorFunction); -ReturnedValue DefaultClassConstructorFunction::virtualCallAsConstructor(const FunctionObject *f, const Value *, int) +ReturnedValue DefaultClassConstructorFunction::virtualCallAsConstructor(const FunctionObject *f, const Value *, int, const Value *) { Scope scope(f); ScopedObject proto(scope, f->get(scope.engine->id_prototype())); @@ -588,7 +588,7 @@ ReturnedValue BoundFunction::virtualCall(const FunctionObject *fo, const Value * return target->call(jsCallData); } -ReturnedValue BoundFunction::virtualCallAsConstructor(const FunctionObject *fo, const Value *argv, int argc) +ReturnedValue BoundFunction::virtualCallAsConstructor(const FunctionObject *fo, const Value *argv, int argc, const Value *) { const BoundFunction *f = static_cast<const BoundFunction *>(fo); Scope scope(f->engine()); diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h index 2cfc6fc764..d2af7fa432 100644 --- a/src/qml/jsruntime/qv4functionobject_p.h +++ b/src/qml/jsruntime/qv4functionobject_p.h @@ -169,14 +169,14 @@ struct Q_QML_EXPORT FunctionObject: Object { void createDefaultPrototypeProperty(uint protoSlot, uint protoConstructorSlot); inline ReturnedValue callAsConstructor(const JSCallData &data) const; - ReturnedValue callAsConstructor(const Value *argv, int argc) const { - return d()->jsConstruct(this, argv, argc); + ReturnedValue callAsConstructor(const Value *argv, int argc, const Value *newTarget = nullptr) const { + return d()->jsConstruct(this, argv, argc, newTarget ? newTarget : this); } inline ReturnedValue call(const JSCallData &data) const; ReturnedValue call(const Value *thisObject, const Value *argv, int argc) const { return d()->jsCall(this, thisObject, argv, argc); } - static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *); static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); static Heap::FunctionObject *createScriptFunction(ExecutionContext *scope, Function *function); @@ -201,7 +201,7 @@ struct FunctionCtor: FunctionObject { V4_OBJECT2(FunctionCtor, FunctionObject) - static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *); static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); protected: enum Type { @@ -243,7 +243,7 @@ struct ScriptFunction : FunctionObject { V4_INTERNALCLASS(ScriptFunction) enum { NInlineProperties = 3 }; - static ReturnedValue virtualCallAsConstructor(const FunctionObject *, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *, const Value *argv, int argc, const Value *); static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); Heap::InternalClass *classForConstructor() const; @@ -258,13 +258,13 @@ struct ConstructorFunction : ScriptFunction { struct MemberFunction : ScriptFunction { V4_OBJECT2(MemberFunction, ScriptFunction) V4_INTERNALCLASS(MemberFunction) - static ReturnedValue virtualCallAsConstructor(const FunctionObject *, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *, const Value *argv, int argc, const Value *); }; struct DefaultClassConstructorFunction : FunctionObject { V4_OBJECT2(DefaultClassConstructorFunction, FunctionObject) - static ReturnedValue virtualCallAsConstructor(const FunctionObject *, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *, const Value *argv, int argc, const Value *); static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); }; @@ -280,7 +280,7 @@ struct BoundFunction: FunctionObject { Value boundThis() const { return d()->boundThis; } Heap::MemberData *boundArgs() const { return d()->boundArgs; } - static ReturnedValue virtualCallAsConstructor(const FunctionObject *, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *, const Value *argv, int argc, const Value *); static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); }; diff --git a/src/qml/jsruntime/qv4generatorobject.cpp b/src/qml/jsruntime/qv4generatorobject.cpp index d08a6248b8..25da2d0a75 100644 --- a/src/qml/jsruntime/qv4generatorobject.cpp +++ b/src/qml/jsruntime/qv4generatorobject.cpp @@ -54,7 +54,7 @@ void Heap::GeneratorFunctionCtor::init(QV4::ExecutionContext *scope) Heap::FunctionObject::init(scope, QStringLiteral("GeneratorFunction")); } -ReturnedValue GeneratorFunctionCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc) +ReturnedValue GeneratorFunctionCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *) { ExecutionEngine *engine = f->engine(); @@ -70,7 +70,7 @@ ReturnedValue GeneratorFunctionCtor::virtualCallAsConstructor(const FunctionObje // 15.3.1: This is equivalent to new Function(...) ReturnedValue GeneratorFunctionCtor::virtualCall(const FunctionObject *f, const Value *, const Value *argv, int argc) { - return virtualCallAsConstructor(f, argv, argc); + return virtualCallAsConstructor(f, argv, argc, f); } Heap::FunctionObject *GeneratorFunction::create(ExecutionContext *context, Function *function) @@ -84,7 +84,7 @@ Heap::FunctionObject *GeneratorFunction::create(ExecutionContext *context, Funct return g->d(); } -ReturnedValue GeneratorFunction::virtualCallAsConstructor(const FunctionObject *f, const Value *, int) +ReturnedValue GeneratorFunction::virtualCallAsConstructor(const FunctionObject *f, const Value *, int, const Value *) { return f->engine()->throwTypeError(); } diff --git a/src/qml/jsruntime/qv4generatorobject_p.h b/src/qml/jsruntime/qv4generatorobject_p.h index 00ac366a44..46227c0df5 100644 --- a/src/qml/jsruntime/qv4generatorobject_p.h +++ b/src/qml/jsruntime/qv4generatorobject_p.h @@ -95,7 +95,7 @@ struct GeneratorFunctionCtor : FunctionCtor { V4_OBJECT2(GeneratorFunctionCtor, FunctionCtor) - static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *); static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); }; @@ -105,7 +105,7 @@ struct GeneratorFunction : ScriptFunction V4_INTERNALCLASS(GeneratorFunction) static Heap::FunctionObject *create(ExecutionContext *scope, Function *function); - static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *); static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); }; diff --git a/src/qml/jsruntime/qv4jscall_p.h b/src/qml/jsruntime/qv4jscall_p.h index 7feab36bec..9b616b755f 100644 --- a/src/qml/jsruntime/qv4jscall_p.h +++ b/src/qml/jsruntime/qv4jscall_p.h @@ -103,7 +103,7 @@ ReturnedValue FunctionObject::callAsConstructor(const JSCallData &data) const { if (!d()->jsConstruct) return engine()->throwTypeError(QStringLiteral("Object is not a constructor.")); - return d()->jsConstruct(this, data.args, data.argc); + return d()->jsConstruct(this, data.args, data.argc, this); } inline diff --git a/src/qml/jsruntime/qv4mapobject.cpp b/src/qml/jsruntime/qv4mapobject.cpp index 00de381c33..ca9e1723f9 100644 --- a/src/qml/jsruntime/qv4mapobject.cpp +++ b/src/qml/jsruntime/qv4mapobject.cpp @@ -53,7 +53,7 @@ void Heap::MapCtor::init(QV4::ExecutionContext *scope) Heap::FunctionObject::init(scope, QStringLiteral("Map")); } -ReturnedValue MapCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc) +ReturnedValue MapCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *) { Scope scope(f); Scoped<MapObject> a(scope, scope.engine->memoryManager->allocate<MapObject>()); diff --git a/src/qml/jsruntime/qv4mapobject_p.h b/src/qml/jsruntime/qv4mapobject_p.h index 96717cfce9..6793612bcb 100644 --- a/src/qml/jsruntime/qv4mapobject_p.h +++ b/src/qml/jsruntime/qv4mapobject_p.h @@ -81,7 +81,7 @@ struct MapCtor: FunctionObject { V4_OBJECT2(MapCtor, FunctionObject) - static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *); static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); }; diff --git a/src/qml/jsruntime/qv4numberobject.cpp b/src/qml/jsruntime/qv4numberobject.cpp index a6b636c6e3..d103f65d47 100644 --- a/src/qml/jsruntime/qv4numberobject.cpp +++ b/src/qml/jsruntime/qv4numberobject.cpp @@ -78,7 +78,7 @@ void Heap::NumberCtor::init(QV4::ExecutionContext *scope) Heap::FunctionObject::init(scope, QStringLiteral("Number")); } -ReturnedValue NumberCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc) +ReturnedValue NumberCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *) { double dbl = argc ? argv[0].toNumber() : 0.; return Encode(f->engine()->newNumberObject(dbl)); diff --git a/src/qml/jsruntime/qv4numberobject_p.h b/src/qml/jsruntime/qv4numberobject_p.h index 5407bf4989..576817cf36 100644 --- a/src/qml/jsruntime/qv4numberobject_p.h +++ b/src/qml/jsruntime/qv4numberobject_p.h @@ -79,7 +79,7 @@ struct NumberCtor: FunctionObject { V4_OBJECT2(NumberCtor, FunctionObject) - static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *); static ReturnedValue virtualCall(const FunctionObject *, const Value *thisObject, const Value *argv, int argc); }; diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index 3d65eeafb6..e4d670d4f3 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -307,7 +307,7 @@ PropertyIndex Object::getValueOrSetter(PropertyKey id, PropertyAttributes *attrs return { nullptr, nullptr }; } -ReturnedValue Object::virtualCallAsConstructor(const FunctionObject *f, const Value *, int) +ReturnedValue Object::virtualCallAsConstructor(const FunctionObject *f, const Value *, int, const Value *) { return f->engine()->throwTypeError(); } diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index ffd753564f..dea080f98a 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -360,7 +360,7 @@ public: { return vtable()->instanceOf(this, var); } protected: - static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *); static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); static ReturnedValue virtualGet(const Managed *m, PropertyKey id, const Value *receiver,bool *hasProperty); static bool virtualPut(Managed *m, PropertyKey id, const Value &value, Value *receiver); diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp index 4c57e617ae..2c8227887f 100644 --- a/src/qml/jsruntime/qv4objectproto.cpp +++ b/src/qml/jsruntime/qv4objectproto.cpp @@ -63,7 +63,7 @@ void Heap::ObjectCtor::init(QV4::ExecutionContext *scope) Heap::FunctionObject::init(scope, QStringLiteral("Object")); } -ReturnedValue ObjectCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc) +ReturnedValue ObjectCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *) { ExecutionEngine *v4 = f->engine(); const ObjectCtor *ctor = static_cast<const ObjectCtor *>(f); diff --git a/src/qml/jsruntime/qv4objectproto_p.h b/src/qml/jsruntime/qv4objectproto_p.h index d1c65a4895..0314c05766 100644 --- a/src/qml/jsruntime/qv4objectproto_p.h +++ b/src/qml/jsruntime/qv4objectproto_p.h @@ -70,7 +70,7 @@ struct ObjectCtor: FunctionObject { V4_OBJECT2(ObjectCtor, FunctionObject) - static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *); static ReturnedValue virtualCall(const FunctionObject *m, const Value *thisObject, const Value *argv, int argc); }; diff --git a/src/qml/jsruntime/qv4proxy.cpp b/src/qml/jsruntime/qv4proxy.cpp index 082438fc26..794aee8c24 100644 --- a/src/qml/jsruntime/qv4proxy.cpp +++ b/src/qml/jsruntime/qv4proxy.cpp @@ -477,7 +477,7 @@ bool ProxyObject::virtualSetPrototypeOf(Managed *m, const Object *p) return true; } -//ReturnedValue ProxyObject::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc) +//ReturnedValue ProxyObject::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *) //{ //} @@ -499,7 +499,7 @@ void Heap::Proxy::init(QV4::ExecutionContext *ctx) ctor->defineReadonlyConfigurableProperty(scope.engine->id_length(), Primitive::fromInt32(2)); } -ReturnedValue Proxy::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc) +ReturnedValue Proxy::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *) { Scope scope(f); if (argc < 2 || !argv[0].isObject() || !argv[1].isObject()) @@ -526,7 +526,7 @@ ReturnedValue Proxy::virtualCall(const FunctionObject *f, const Value *, const V ReturnedValue Proxy::method_revocable(const FunctionObject *f, const Value *, const Value *argv, int argc) { Scope scope(f); - ScopedObject proxy(scope, Proxy::virtualCallAsConstructor(f, argv, argc)); + ScopedObject proxy(scope, Proxy::virtualCallAsConstructor(f, argv, argc, f)); if (scope.hasException()) return Encode::undefined(); diff --git a/src/qml/jsruntime/qv4proxy_p.h b/src/qml/jsruntime/qv4proxy_p.h index 7c00ede834..4d631e882c 100644 --- a/src/qml/jsruntime/qv4proxy_p.h +++ b/src/qml/jsruntime/qv4proxy_p.h @@ -97,7 +97,7 @@ struct ProxyObject: Object { static bool virtualSetPrototypeOf(Managed *, const Object *); // those might require a second proxy object that derives from FunctionObject... -// static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc); +// static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *); // static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); }; @@ -105,7 +105,7 @@ struct Proxy : FunctionObject { V4_OBJECT2(Proxy, FunctionObject) - static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *); static ReturnedValue virtualCall(const FunctionObject *, const Value *thisObject, const Value *argv, int argc); static ReturnedValue method_revocable(const FunctionObject *, const Value *thisObject, const Value *argv, int argc); diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 32a4f57b7e..a17de5d94d 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -2064,7 +2064,7 @@ void QMetaObjectWrapper::init(ExecutionEngine *) { } } -ReturnedValue QMetaObjectWrapper::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc) +ReturnedValue QMetaObjectWrapper::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *) { const QMetaObjectWrapper *This = static_cast<const QMetaObjectWrapper*>(f); return This->constructInternal(argv, argc); diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h index 398d2f8556..7843289d33 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper_p.h +++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h @@ -254,7 +254,7 @@ struct Q_QML_EXPORT QMetaObjectWrapper : public QV4::FunctionObject const QMetaObject *metaObject() const { return d()->metaObject; } protected: - static ReturnedValue virtualCallAsConstructor(const FunctionObject *, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *, const Value *argv, int argc, const Value *); static bool virtualIsEqualTo(Managed *a, Managed *b); private: diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp index 0b3d85960b..8429b96baa 100644 --- a/src/qml/jsruntime/qv4regexpobject.cpp +++ b/src/qml/jsruntime/qv4regexpobject.cpp @@ -210,7 +210,7 @@ void Heap::RegExpCtor::clearLastMatch() lastMatchEnd = 0; } -ReturnedValue RegExpCtor::virtualCallAsConstructor(const FunctionObject *fo, const Value *argv, int argc) +ReturnedValue RegExpCtor::virtualCallAsConstructor(const FunctionObject *fo, const Value *argv, int argc, const Value *) { Scope scope(fo->engine()); ScopedValue r(scope, argc ? argv[0] : Primitive::undefinedValue()); @@ -266,7 +266,7 @@ ReturnedValue RegExpCtor::virtualCall(const FunctionObject *f, const Value *, co return Encode(argv[0]); } - return virtualCallAsConstructor(f, argv, argc); + return virtualCallAsConstructor(f, argv, argc, f); } void RegExpPrototype::init(ExecutionEngine *engine, Object *constructor) diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h index 15809dfaf6..0d4fe760eb 100644 --- a/src/qml/jsruntime/qv4regexpobject_p.h +++ b/src/qml/jsruntime/qv4regexpobject_p.h @@ -152,7 +152,7 @@ struct RegExpCtor: FunctionObject int lastMatchStart() { return d()->lastMatchStart; } int lastMatchEnd() { return d()->lastMatchEnd; } - static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *); static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); }; diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index 8b042f12ff..0fd3787730 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -1302,16 +1302,16 @@ ReturnedValue Runtime::method_callWithSpread(ExecutionEngine *engine, const Valu return static_cast<const FunctionObject &>(function).call(&thisObject, arguments.argv, arguments.argc); } -ReturnedValue Runtime::method_construct(ExecutionEngine *engine, const Value &function, const Value &/*newTarget*/, Value *argv, int argc) +ReturnedValue Runtime::method_construct(ExecutionEngine *engine, const Value &function, const Value &newTarget, Value *argv, int argc) { if (!function.isFunctionObject()) return engine->throwTypeError(); Q_ASSERT(function.sameValue(newTarget)); - return static_cast<const FunctionObject &>(function).callAsConstructor(argv, argc); + return static_cast<const FunctionObject &>(function).callAsConstructor(argv, argc, &newTarget); } -ReturnedValue Runtime::method_constructWithSpread(ExecutionEngine *engine, const Value &function, const Value &/*newTarget*/, Value *argv, int argc) +ReturnedValue Runtime::method_constructWithSpread(ExecutionEngine *engine, const Value &function, const Value &newTarget, Value *argv, int argc) { Q_UNIMPLEMENTED(); if (!function.isFunctionObject()) @@ -1323,7 +1323,7 @@ ReturnedValue Runtime::method_constructWithSpread(ExecutionEngine *engine, const if (engine->hasException) return Encode::undefined(); - return static_cast<const FunctionObject &>(function).callAsConstructor(arguments.argv, arguments.argc); + return static_cast<const FunctionObject &>(function).callAsConstructor(arguments.argv, arguments.argc, &newTarget); } void Runtime::method_throwException(ExecutionEngine *engine, const Value &value) diff --git a/src/qml/jsruntime/qv4setobject.cpp b/src/qml/jsruntime/qv4setobject.cpp index 1d8261845a..30e849bfed 100644 --- a/src/qml/jsruntime/qv4setobject.cpp +++ b/src/qml/jsruntime/qv4setobject.cpp @@ -53,7 +53,7 @@ void Heap::SetCtor::init(QV4::ExecutionContext *scope) Heap::FunctionObject::init(scope, QStringLiteral("Set")); } -ReturnedValue SetCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc) +ReturnedValue SetCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *) { Scope scope(f); Scoped<SetObject> a(scope, scope.engine->memoryManager->allocate<SetObject>()); diff --git a/src/qml/jsruntime/qv4setobject_p.h b/src/qml/jsruntime/qv4setobject_p.h index 4c81737db8..34649c3f01 100644 --- a/src/qml/jsruntime/qv4setobject_p.h +++ b/src/qml/jsruntime/qv4setobject_p.h @@ -81,7 +81,7 @@ struct SetCtor: FunctionObject { V4_OBJECT2(SetCtor, FunctionObject) - static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *); static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); }; diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp index 7750bf4aea..f2d0d52013 100644 --- a/src/qml/jsruntime/qv4stringobject.cpp +++ b/src/qml/jsruntime/qv4stringobject.cpp @@ -164,7 +164,7 @@ void Heap::StringCtor::init(QV4::ExecutionContext *scope) Heap::FunctionObject::init(scope, QStringLiteral("String")); } -ReturnedValue StringCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc) +ReturnedValue StringCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *) { ExecutionEngine *v4 = static_cast<const Object *>(f)->engine(); Scope scope(v4); @@ -514,7 +514,7 @@ ReturnedValue StringPrototype::method_match(const FunctionObject *b, const Value Scoped<RegExpObject> that(scope, argc ? argv[0] : Primitive::undefinedValue()); if (!that) { // convert args[0] to a regexp - that = RegExpCtor::virtualCallAsConstructor(b, argv, argc); + that = RegExpCtor::virtualCallAsConstructor(b, argv, argc, b); if (v4->hasException) return Encode::undefined(); } diff --git a/src/qml/jsruntime/qv4stringobject_p.h b/src/qml/jsruntime/qv4stringobject_p.h index 3a50de8127..2d37e36b34 100644 --- a/src/qml/jsruntime/qv4stringobject_p.h +++ b/src/qml/jsruntime/qv4stringobject_p.h @@ -109,7 +109,7 @@ struct StringCtor: FunctionObject { V4_OBJECT2(StringCtor, FunctionObject) - static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *); static ReturnedValue virtualCall(const FunctionObject *, const Value *thisObject, const Value *argv, int argc); static ReturnedValue method_fromCharCode(const FunctionObject *, const Value *thisObject, const Value *argv, int argc); diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp index 1f2f6ff5b4..cb9cdd8df5 100644 --- a/src/qml/jsruntime/qv4typedarray.cpp +++ b/src/qml/jsruntime/qv4typedarray.cpp @@ -214,7 +214,7 @@ void Heap::TypedArrayCtor::init(QV4::ExecutionContext *scope, TypedArray::Type t type = t; } -ReturnedValue TypedArrayCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc) +ReturnedValue TypedArrayCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *) { Scope scope(f->engine()); const TypedArrayCtor *that = static_cast<const TypedArrayCtor *>(f); @@ -640,7 +640,7 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_get_toStringTag(const Functio return a->engine()->newString(QString::fromLatin1(a->d()->type->name))->asReturnedValue(); } -ReturnedValue IntrinsicTypedArrayCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *, int) +ReturnedValue IntrinsicTypedArrayCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *, int, const Value *) { return f->engine()->throwTypeError(); } diff --git a/src/qml/jsruntime/qv4typedarray_p.h b/src/qml/jsruntime/qv4typedarray_p.h index d0c6b1c935..967d3235b2 100644 --- a/src/qml/jsruntime/qv4typedarray_p.h +++ b/src/qml/jsruntime/qv4typedarray_p.h @@ -148,7 +148,7 @@ struct IntrinsicTypedArrayCtor: FunctionObject { V4_OBJECT2(IntrinsicTypedArrayCtor, FunctionObject) - static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *); static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); }; @@ -156,7 +156,7 @@ struct TypedArrayCtor: FunctionObject { V4_OBJECT2(TypedArrayCtor, FunctionObject) - static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc); + static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *); static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); }; diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index 719891b164..8cdf0937ad 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -412,7 +412,7 @@ static bool compareEqualInt(QV4::Value &accumulator, QV4::Value lhs, int rhs) } \ } while (false) -QV4::ReturnedValue VME::exec(const FunctionObject *fo, const QV4::Value *thisObject, const QV4::Value *argv, int argc) +QV4::ReturnedValue VME::exec(const FunctionObject *fo, const QV4::Value *thisObject, const QV4::Value *argv, int argc, const Value *newTarget) { qt_v4ResolvePendingBreakpointsHook(); ExecutionEngine *engine; @@ -449,6 +449,7 @@ QV4::ReturnedValue VME::exec(const FunctionObject *fo, const QV4::Value *thisObj callData->function = fo ? fo->asReturnedValue() : Encode::undefined(); callData->context = scope; callData->accumulator = Encode::undefined(); + callData->newTarget = newTarget ? *newTarget : Primitive::undefinedValue(); callData->thisObject = thisObject ? *thisObject : Primitive::undefinedValue(); if (argc > int(function->nFormals)) argc = int(function->nFormals); diff --git a/src/qml/jsruntime/qv4vme_moth_p.h b/src/qml/jsruntime/qv4vme_moth_p.h index 67bfd537c5..c5c07d92cb 100644 --- a/src/qml/jsruntime/qv4vme_moth_p.h +++ b/src/qml/jsruntime/qv4vme_moth_p.h @@ -71,7 +71,7 @@ public: quintptr d = reinterpret_cast<quintptr>(&data) | 0x1; return exec(reinterpret_cast<const FunctionObject *>(d), thisObject, argv, argc); } - static QV4::ReturnedValue exec(const FunctionObject *fo, const Value *thisObject, const Value *argv, int argc); + static QV4::ReturnedValue exec(const FunctionObject *fo, const Value *thisObject, const Value *argv, int argc, const Value *newTarget = nullptr); static QV4::ReturnedValue interpret(CppStackFrame &frame, const char *codeEntry); }; diff --git a/src/qml/jsruntime/qv4vtable_p.h b/src/qml/jsruntime/qv4vtable_p.h index daf971e581..b4e868d45d 100644 --- a/src/qml/jsruntime/qv4vtable_p.h +++ b/src/qml/jsruntime/qv4vtable_p.h @@ -77,7 +77,7 @@ struct VTable typedef ReturnedValue (*InstanceOf)(const Object *typeObject, const Value &var); typedef ReturnedValue (*Call)(const FunctionObject *, const Value *thisObject, const Value *argv, int argc); - typedef ReturnedValue (*CallAsConstructor)(const FunctionObject *, const Value *argv, int argc); + typedef ReturnedValue (*CallAsConstructor)(const FunctionObject *, const Value *argv, int argc, const Value *newTarget); const VTable * const parent; quint32 inlinePropertyOffset : 16; diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp index 53581c2ccb..51e5be4b5b 100644 --- a/src/qml/qml/qqmlxmlhttprequest.cpp +++ b/src/qml/qml/qqmlxmlhttprequest.cpp @@ -1629,7 +1629,7 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject { V4_OBJECT2(QQmlXMLHttpRequestCtor, FunctionObject) - static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *, int) + static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *, int, const Value *) { Scope scope(f->engine()); const QQmlXMLHttpRequestCtor *ctor = static_cast<const QQmlXMLHttpRequestCtor *>(f); diff --git a/tests/auto/qml/ecmascripttests/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations index 2a54cd1a4f..cb35aaa3c7 100644 --- a/tests/auto/qml/ecmascripttests/TestExpectations +++ b/tests/auto/qml/ecmascripttests/TestExpectations @@ -416,10 +416,6 @@ built-ins/Function/prototype/Symbol.hasInstance/this-val-poisoned-prototype.js f built-ins/Function/prototype/Symbol.hasInstance/value-non-obj.js fails built-ins/Function/prototype/bind/BoundFunction_restricted-properties.js fails built-ins/Function/prototype/bind/get-fn-realm.js fails -built-ins/Function/prototype/bind/instance-construct-newtarget-boundtarget-bound.js fails -built-ins/Function/prototype/bind/instance-construct-newtarget-boundtarget.js fails -built-ins/Function/prototype/bind/instance-construct-newtarget-self-new.js fails -built-ins/Function/prototype/bind/instance-construct-newtarget-self-reflect.js fails built-ins/Function/prototype/bind/instance-name-chained.js fails built-ins/Function/prototype/bind/instance-name-non-string.js fails built-ins/Function/prototype/bind/instance-name.js fails @@ -1959,6 +1955,8 @@ language/computed-property-names/object/method/super.js fails language/eval-code/direct/lex-env-no-init-cls.js fails language/eval-code/direct/lex-env-no-init-const.js fails language/eval-code/direct/lex-env-no-init-let.js fails +language/eval-code/direct/new.target.js fails +language/eval-code/direct/new.target-arrow.js fails language/eval-code/direct/new.target-fn.js fails language/eval-code/direct/non-definable-function-with-function.js sloppyFails language/eval-code/direct/non-definable-function-with-variable.js sloppyFails @@ -1974,6 +1972,7 @@ language/eval-code/indirect/always-non-strict.js strictFails language/eval-code/indirect/lex-env-no-init-cls.js fails language/eval-code/indirect/lex-env-no-init-const.js fails language/eval-code/indirect/lex-env-no-init-let.js fails +language/eval-code/indirect/new.target.js fails language/eval-code/indirect/non-definable-function-with-function.js sloppyFails language/eval-code/indirect/non-definable-function-with-variable.js sloppyFails language/eval-code/indirect/non-definable-global-function.js fails @@ -2959,17 +2958,9 @@ language/expressions/instanceof/prototype-getter-with-object-throws.js fails language/expressions/instanceof/prototype-getter-with-object.js fails language/expressions/logical-and/tco-right.js strictFails language/expressions/logical-or/tco-right.js strictFails -language/expressions/new.target/asi.js fails -language/expressions/new.target/value-via-call.js fails -language/expressions/new.target/value-via-fpapply.js fails -language/expressions/new.target/value-via-fpcall.js fails -language/expressions/new.target/value-via-member.js fails -language/expressions/new.target/value-via-new.js fails -language/expressions/new.target/value-via-reflect-apply.js fails language/expressions/new.target/value-via-reflect-construct.js fails 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/object/concise-generator.js fails language/expressions/object/dstr-gen-meth-ary-ptrn-elem-id-init-fn-name-class.js fails |