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 <simon.hausmann@qt.io>
This commit is contained in:
Lars Knoll 2018-06-26 14:18:16 +02:00
parent 61440411a9
commit 65e799a9de
46 changed files with 97 additions and 99 deletions

View File

@ -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;
}
}

View File

@ -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)

View File

@ -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)

View File

@ -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);

View File

@ -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)

View File

@ -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);
};

View File

@ -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));

View File

@ -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);
};

View File

@ -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 {

View File

@ -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)

View File

@ -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);
};

View File

@ -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;

View File

@ -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);
};

View File

@ -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();

View File

@ -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 *);
};

View File

@ -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());

View File

@ -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);
};

View File

@ -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();
}

View File

@ -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);
};

View File

@ -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

View File

@ -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>());

View File

@ -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);
};

View File

@ -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));

View File

@ -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);
};

View File

@ -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();
}

View File

@ -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);

View File

@ -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);

View File

@ -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);
};

View File

@ -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();

View File

@ -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);

View File

@ -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);

View File

@ -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:

View File

@ -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)

View File

@ -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);
};

View File

@ -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)

View File

@ -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>());

View File

@ -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);
};

View File

@ -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();
}

View File

@ -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);

View File

@ -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();
}

View File

@ -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);
};

View File

@ -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);

View File

@ -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);
};

View File

@ -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;

View File

@ -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);

View File

@ -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