diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-07-01 12:00:57 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-07-03 08:09:17 +0000 |
commit | d31541fd9d7d52ef3eae29e7e5d36733d7f55375 (patch) | |
tree | c5d17bea0119c9f0eb26e97eb523b281e9900783 /src/qml/jsruntime | |
parent | 6e79a00cad2f5dd09bdf40e594a65af58b370d9d (diff) |
Add support for super properties
Those are mostly working now, but when calling super properties
the this object is not setup correctly.
Change-Id: Ib42129ae6e729eeca00275f707f480371b7e42a5
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 36 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtimeapi_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 17 |
3 files changed, 54 insertions, 1 deletions
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index eeb66509e3..7b2fd07f0b 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -856,6 +856,42 @@ ReturnedValue Runtime::method_loadName(ExecutionEngine *engine, int nameIndex) return static_cast<ExecutionContext &>(engine->currentStackFrame->jsFrame->context).getProperty(name); } +ReturnedValue Runtime::method_loadSuperProperty(ExecutionEngine *engine, const Value &property) +{ + Scope scope(engine); + ScopedObject base(scope, engine->currentStackFrame->thisObject()); + if (!base) + return engine->throwTypeError(); + ScopedObject proto(scope, base->getPrototypeOf()); + if (!proto) + return engine->throwTypeError(); + ScopedPropertyKey key(scope, property.toPropertyKey(engine)); + if (engine->hasException) + return Encode::undefined(); + return proto->get(key, base); +} + +void Runtime::method_storeSuperProperty(ExecutionEngine *engine, const Value &property, const Value &value) +{ + Scope scope(engine); + ScopedObject base(scope, engine->currentStackFrame->thisObject()); + if (!base) { + engine->throwTypeError(); + return; + } + ScopedObject proto(scope, base->getPrototypeOf()); + if (!proto) { + engine->throwTypeError(); + return; + } + ScopedPropertyKey key(scope, property.toPropertyKey(engine)); + if (engine->hasException) + return; + bool result = proto->put(key, value, base); + if (!result && engine->currentStackFrame->v4Function->isStrict()) + engine->throwTypeError(); +} + #endif // V4_BOOTSTRAP uint RuntimeHelpers::equalHelper(const Value &x, const Value &y) diff --git a/src/qml/jsruntime/qv4runtimeapi_p.h b/src/qml/jsruntime/qv4runtimeapi_p.h index b4d9d329c4..3f65e6c6d6 100644 --- a/src/qml/jsruntime/qv4runtimeapi_p.h +++ b/src/qml/jsruntime/qv4runtimeapi_p.h @@ -113,6 +113,8 @@ struct ExceptionCheck<void (*)(QV4::NoThrowEngine *, A, B, C)> { F(ReturnedValue, loadProperty, (ExecutionEngine *engine, const Value &object, int nameIndex)) \ F(ReturnedValue, loadName, (ExecutionEngine *engine, int nameIndex)) \ F(ReturnedValue, loadElement, (ExecutionEngine *engine, const Value &object, const Value &index)) \ + F(ReturnedValue, loadSuperProperty, (ExecutionEngine *engine, const Value &property)) \ + F(void, storeSuperProperty, (ExecutionEngine *engine, const Value &property, const Value &value)) \ \ /* typeof */ \ F(ReturnedValue, typeofValue, (ExecutionEngine *engine, const Value &val)) \ diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index 83d1aa3250..6c667110a9 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -610,6 +610,20 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine, CHECK_EXCEPTION; MOTH_END_INSTR(SetLookup) + MOTH_BEGIN_INSTR(LoadSuperProperty) + STORE_IP(); + STORE_ACC(); + acc = Runtime::method_loadSuperProperty(engine, STACK_VALUE(property)); + CHECK_EXCEPTION; + MOTH_END_INSTR(LoadSuperProperty) + + MOTH_BEGIN_INSTR(StoreSuperProperty) + STORE_IP(); + STORE_ACC(); + Runtime::method_storeSuperProperty(engine, STACK_VALUE(property), accumulator); + CHECK_EXCEPTION; + MOTH_END_INSTR(StoreSuperProperty) + MOTH_BEGIN_INSTR(StoreScopeObjectProperty) STORE_ACC(); Runtime::method_storeQmlScopeObjectProperty(engine, STACK_VALUE(base), propertyIndex, accumulator); @@ -666,7 +680,8 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine, acc = engine->throwTypeError(QStringLiteral("%1 is not a function").arg(func.toQStringNoThrow())); goto handleUnwind; } - acc = static_cast<const FunctionObject &>(func).call(nullptr, stack + argv, argc); + Value undef = Primitive::undefinedValue(); + acc = static_cast<const FunctionObject &>(func).call(&undef, stack + argv, argc); CHECK_EXCEPTION; MOTH_END_INSTR(CallValue) |