From d046de0ddb7a8d8762821915d3973a1bea9d499c Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sat, 4 Aug 2018 10:39:09 +0200 Subject: Setup the prototype correctly when subclassing error objects Change-Id: I5e394ef8d4d6d87bedb26070d51660e3ebe3ab1b Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4engine.cpp | 4 ++-- src/qml/jsruntime/qv4errorobject.cpp | 28 ++++++++++++------------- src/qml/jsruntime/qv4errorobject_p.h | 7 ++++--- src/qml/jsruntime/qv4functionobject.cpp | 2 +- tests/auto/qml/ecmascripttests/TestExpectations | 7 ------- 5 files changed, 21 insertions(+), 27 deletions(-) diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 07340d502f..fcc2feced4 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -796,7 +796,7 @@ Heap::RegExpObject *ExecutionEngine::newRegExpObject(const QRegExp &re) Heap::Object *ExecutionEngine::newErrorObject(const Value &value) { - return ErrorObject::create(this, value); + return ErrorObject::create(this, value, errorCtor()); } Heap::Object *ExecutionEngine::newSyntaxErrorObject(const QString &message) @@ -833,7 +833,7 @@ Heap::Object *ExecutionEngine::newRangeErrorObject(const QString &message) Heap::Object *ExecutionEngine::newURIErrorObject(const Value &message) { - return ErrorObject::create(this, message); + return ErrorObject::create(this, message, uRIErrorCtor()); } Heap::Object *ExecutionEngine::newVariantObject(const QVariant &v) diff --git a/src/qml/jsruntime/qv4errorobject.cpp b/src/qml/jsruntime/qv4errorobject.cpp index 53c070898f..f8812b019d 100644 --- a/src/qml/jsruntime/qv4errorobject.cpp +++ b/src/qml/jsruntime/qv4errorobject.cpp @@ -229,10 +229,10 @@ 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, const Value *) +ReturnedValue ErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *newTarget) { Value v = argc ? *argv : Primitive::undefinedValue(); - return ErrorObject::create(f->engine(), v)->asReturnedValue(); + return ErrorObject::create(f->engine(), v, newTarget)->asReturnedValue(); } ReturnedValue ErrorCtor::virtualCall(const FunctionObject *f, const Value *, const Value *argv, int argc) @@ -245,10 +245,10 @@ void Heap::EvalErrorCtor::init(QV4::ExecutionContext *scope) Heap::FunctionObject::init(scope, QStringLiteral("EvalError")); } -ReturnedValue EvalErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *) +ReturnedValue EvalErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *newTarget) { Value v = argc ? *argv : Primitive::undefinedValue(); - return ErrorObject::create(f->engine(), v)->asReturnedValue(); + return ErrorObject::create(f->engine(), v, newTarget)->asReturnedValue(); } void Heap::RangeErrorCtor::init(QV4::ExecutionContext *scope) @@ -256,10 +256,10 @@ void Heap::RangeErrorCtor::init(QV4::ExecutionContext *scope) Heap::FunctionObject::init(scope, QStringLiteral("RangeError")); } -ReturnedValue RangeErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *) +ReturnedValue RangeErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *newTarget) { Value v = argc ? *argv : Primitive::undefinedValue(); - return ErrorObject::create(f->engine(), v)->asReturnedValue(); + return ErrorObject::create(f->engine(), v, newTarget)->asReturnedValue(); } void Heap::ReferenceErrorCtor::init(QV4::ExecutionContext *scope) @@ -267,10 +267,10 @@ void Heap::ReferenceErrorCtor::init(QV4::ExecutionContext *scope) Heap::FunctionObject::init(scope, QStringLiteral("ReferenceError")); } -ReturnedValue ReferenceErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *) +ReturnedValue ReferenceErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *newTarget) { Value v = argc ? *argv : Primitive::undefinedValue(); - return ErrorObject::create(f->engine(), v)->asReturnedValue(); + return ErrorObject::create(f->engine(), v, newTarget)->asReturnedValue(); } void Heap::SyntaxErrorCtor::init(QV4::ExecutionContext *scope) @@ -278,10 +278,10 @@ void Heap::SyntaxErrorCtor::init(QV4::ExecutionContext *scope) Heap::FunctionObject::init(scope, QStringLiteral("SyntaxError")); } -ReturnedValue SyntaxErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *) +ReturnedValue SyntaxErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *newTarget) { Value v = argc ? *argv : Primitive::undefinedValue(); - return ErrorObject::create(f->engine(), v)->asReturnedValue(); + return ErrorObject::create(f->engine(), v, newTarget)->asReturnedValue(); } void Heap::TypeErrorCtor::init(QV4::ExecutionContext *scope) @@ -289,10 +289,10 @@ void Heap::TypeErrorCtor::init(QV4::ExecutionContext *scope) Heap::FunctionObject::init(scope, QStringLiteral("TypeError")); } -ReturnedValue TypeErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *) +ReturnedValue TypeErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *newTarget) { Value v = argc ? *argv : Primitive::undefinedValue(); - return ErrorObject::create(f->engine(), v)->asReturnedValue(); + return ErrorObject::create(f->engine(), v, newTarget)->asReturnedValue(); } void Heap::URIErrorCtor::init(QV4::ExecutionContext *scope) @@ -300,10 +300,10 @@ void Heap::URIErrorCtor::init(QV4::ExecutionContext *scope) Heap::FunctionObject::init(scope, QStringLiteral("URIError")); } -ReturnedValue URIErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *) +ReturnedValue URIErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *newTarget) { Value v = argc ? *argv : Primitive::undefinedValue(); - return ErrorObject::create(f->engine(), v)->asReturnedValue(); + return ErrorObject::create(f->engine(), v, newTarget)->asReturnedValue(); } void ErrorPrototype::init(ExecutionEngine *engine, Object *ctor, Object *obj, Heap::ErrorObject::ErrorType t) diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h index fd042ca8f0..bce7e4abad 100644 --- a/src/qml/jsruntime/qv4errorobject_p.h +++ b/src/qml/jsruntime/qv4errorobject_p.h @@ -165,7 +165,7 @@ struct ErrorObject: Object { V4_NEEDS_DESTROY template - static Heap::Object *create(ExecutionEngine *e, const Value &message); + static Heap::Object *create(ExecutionEngine *e, const Value &message, const Value *newTarget); template static Heap::Object *create(ExecutionEngine *e, const QString &message); template @@ -333,10 +333,11 @@ inline SyntaxErrorObject *ErrorObject::asSyntaxError() template -Heap::Object *ErrorObject::create(ExecutionEngine *e, const Value &message) { +Heap::Object *ErrorObject::create(ExecutionEngine *e, const Value &message, const Value *newTarget) { EngineBase::InternalClassType klass = message.isUndefined() ? EngineBase::Class_ErrorObject : EngineBase::Class_ErrorObjectWithMessage; Scope scope(e); - Scoped ic(scope, e->internalClasses(klass)->changePrototype(T::defaultPrototype(e)->d())); + ScopedObject proto(scope, static_cast(newTarget)->get(scope.engine->id_prototype())); + Scoped ic(scope, e->internalClasses(klass)->changePrototype(proto->d())); return e->memoryManager->allocObject(ic->d(), message); } template diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index b0f9f5198e..35d8fe18e0 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -602,7 +602,7 @@ ReturnedValue DefaultClassConstructorFunction::virtualCallAsConstructor(const Fu Scope scope(v4); if (!c->d()->isDerivedConstructor) { - ScopedObject proto(scope, static_cast(newTarget) ->get(scope.engine->id_prototype())); + ScopedObject proto(scope, static_cast(newTarget)->get(scope.engine->id_prototype())); ScopedObject c(scope, scope.engine->newObject()); c->setPrototypeUnchecked(proto); return c->asReturnedValue(); diff --git a/tests/auto/qml/ecmascripttests/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations index 25693f7f47..038aa8a09c 100644 --- a/tests/auto/qml/ecmascripttests/TestExpectations +++ b/tests/auto/qml/ecmascripttests/TestExpectations @@ -2340,23 +2340,16 @@ language/statements/class/subclass/builtin-objects/ArrayBuffer/super-must-be-cal language/statements/class/subclass/builtin-objects/Boolean/super-must-be-called.js fails language/statements/class/subclass/builtin-objects/DataView/super-must-be-called.js fails language/statements/class/subclass/builtin-objects/Date/super-must-be-called.js fails -language/statements/class/subclass/builtin-objects/Error/message-property-assignment.js fails language/statements/class/subclass/builtin-objects/Error/super-must-be-called.js fails language/statements/class/subclass/builtin-objects/Function/super-must-be-called.js fails language/statements/class/subclass/builtin-objects/GeneratorFunction/super-must-be-called.js fails language/statements/class/subclass/builtin-objects/Map/regular-subclassing.js fails language/statements/class/subclass/builtin-objects/Map/super-must-be-called.js fails -language/statements/class/subclass/builtin-objects/NativeError/EvalError-message.js fails language/statements/class/subclass/builtin-objects/NativeError/EvalError-super.js fails -language/statements/class/subclass/builtin-objects/NativeError/RangeError-message.js fails language/statements/class/subclass/builtin-objects/NativeError/RangeError-super.js fails -language/statements/class/subclass/builtin-objects/NativeError/ReferenceError-message.js fails language/statements/class/subclass/builtin-objects/NativeError/ReferenceError-super.js fails -language/statements/class/subclass/builtin-objects/NativeError/SyntaxError-message.js fails language/statements/class/subclass/builtin-objects/NativeError/SyntaxError-super.js fails -language/statements/class/subclass/builtin-objects/NativeError/TypeError-message.js fails language/statements/class/subclass/builtin-objects/NativeError/TypeError-super.js fails -language/statements/class/subclass/builtin-objects/NativeError/URIError-message.js fails language/statements/class/subclass/builtin-objects/NativeError/URIError-super.js fails language/statements/class/subclass/builtin-objects/Number/super-must-be-called.js fails language/statements/class/subclass/builtin-objects/Object/constructor-return-undefined-throws.js fails -- cgit v1.2.3