From d8da213ed5ff7ee8fddc3d2e40c20b6e51941ae9 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sat, 1 Sep 2018 10:54:49 +0200 Subject: Throw a reference error if the super constructor is not called And return the correct this object from the subclass constructor. Change-Id: I8d68f07c3080f8c5ff8b10ad2cc85e017bf710d8 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4functionobject.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'src/qml/jsruntime/qv4functionobject.cpp') diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index a2afeb87d7..ec041ab064 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -564,6 +564,7 @@ ReturnedValue ConstructorFunction::virtualCallAsConstructor(const FunctionObject v4->jsStackTop += frame.requiredJSStackFrameSize(); ReturnedValue result = Moth::VME::exec(&frame, v4); + ReturnedValue thisObject = frame.jsFrame->thisObject.asReturnedValue(); frame.pop(); @@ -571,9 +572,14 @@ ReturnedValue ConstructorFunction::virtualCallAsConstructor(const FunctionObject return Encode::undefined(); else if (Value::fromReturnedValue(result).isObject()) return result; - else if (!Value::fromReturnedValue(result).isUndefined() || frame.jsFrame->thisObject.isEmpty()) + else if (!Value::fromReturnedValue(result).isUndefined()) return v4->throwTypeError(); - return frame.jsFrame->thisObject.asReturnedValue(); + else if (Primitive::fromReturnedValue(thisObject).isEmpty()) { + Scope scope(v4); + ScopedString s(scope, v4->newString(QStringLiteral("this"))); + return v4->throwReferenceError(s); + } + return thisObject; } ReturnedValue ConstructorFunction::virtualCall(const FunctionObject *f, const Value *, const Value *, int) @@ -613,6 +619,7 @@ ReturnedValue DefaultClassConstructorFunction::virtualCallAsConstructor(const Fu // Do a super call ReturnedValue result = super->callAsConstructor(argv, argc, newTarget); + ReturnedValue thisObject = frame.jsFrame->thisObject.asReturnedValue(); frame.pop(); @@ -622,7 +629,13 @@ ReturnedValue DefaultClassConstructorFunction::virtualCallAsConstructor(const Fu return result; else if (!Value::fromReturnedValue(result).isUndefined()) return v4->throwTypeError(); - return frame.jsFrame->thisObject.asReturnedValue(); + else if (Primitive::fromReturnedValue(thisObject).isEmpty()) { + Scope scope(v4); + ScopedString s(scope, v4->newString(QStringLiteral("this"))); + return v4->throwReferenceError(s); + } + + return thisObject; } ReturnedValue DefaultClassConstructorFunction::virtualCall(const FunctionObject *f, const Value *, const Value *, int) -- cgit v1.2.3