From fca89004d75412dd378cc44ad79ed3c1e05c765b Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Tue, 14 Nov 2017 09:39:36 +0100 Subject: Convert global getters to use the id in internalclass Change-Id: Id443245ee9f02af48abbf5ba4811ac69ad409059 Reviewed-by: Erik Verbruggen --- src/qml/jsruntime/qv4lookup.cpp | 150 ++++++++-------------------------------- src/qml/jsruntime/qv4lookup_p.h | 10 +-- 2 files changed, 33 insertions(+), 127 deletions(-) diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp index 63e22181f7..c690c59270 100644 --- a/src/qml/jsruntime/qv4lookup.cpp +++ b/src/qml/jsruntime/qv4lookup.cpp @@ -207,6 +207,26 @@ ReturnedValue Lookup::resolvePrimitiveGetter(ExecutionEngine *engine, const Valu return getter(this, engine, object); } +ReturnedValue Lookup::resolveGlobalGetter(ExecutionEngine *engine) +{ + Object *o = engine->globalObject; + Identifier *name = engine->identifierTable->identifier(engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]); + protoLookup.icIdentifier = o->internalClass()->id; + resolveProtoGetter(name, o->d()); + + if (getter == getterProto) + globalGetter = globalGetterProto; + else if (getter == getterProtoAccessor) + globalGetter = globalGetterProtoAccessor; + else { + globalGetter = globalGetterGeneric; + Scope scope(engine); + ScopedString n(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]); + return engine->throwReferenceError(n); + } + return globalGetter(this, engine); +} + ReturnedValue Lookup::getterGeneric(Lookup *l, ExecutionEngine *engine, const Value &object) { if (const Object *o = object.as()) @@ -462,137 +482,27 @@ ReturnedValue Lookup::stringLengthGetter(Lookup *l, ExecutionEngine *engine, con ReturnedValue Lookup::globalGetterGeneric(Lookup *l, ExecutionEngine *engine) { - Object *o = engine->globalObject; - PropertyAttributes attrs; - ReturnedValue v = l->lookup(o, &attrs); - if (v != Primitive::emptyValue().asReturnedValue()) { - if (attrs.isData()) { - if (l->level == 0) { - uint nInline = o->d()->vtable()->nInlineProperties; - if (l->index < nInline) { - l->index += o->d()->vtable()->inlinePropertyOffset; - l->globalGetter = globalGetter0Inline; - } else { - l->index -= nInline; - l->globalGetter = globalGetter0MemberData; - } - } else if (l->level == 1) - l->globalGetter = globalGetter1; - else if (l->level == 2) - l->globalGetter = globalGetter2; - return v; - } else { - if (l->level == 0) - l->globalGetter = globalGetterAccessor0; - else if (l->level == 1) - l->globalGetter = globalGetterAccessor1; - else if (l->level == 2) - l->globalGetter = globalGetterAccessor2; - return v; - } - } - Scope scope(engine); - ScopedString n(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[l->nameIndex]); - return engine->throwReferenceError(n); -} - -ReturnedValue Lookup::globalGetter0Inline(Lookup *l, ExecutionEngine *engine) -{ - Object *o = engine->globalObject; - if (l->classList[0] == o->internalClass()) - return o->d()->inlinePropertyDataWithOffset(l->index)->asReturnedValue(); - - l->globalGetter = globalGetterGeneric; - return globalGetterGeneric(l, engine); -} - -ReturnedValue Lookup::globalGetter0MemberData(Lookup *l, ExecutionEngine *engine) -{ - Object *o = engine->globalObject; - if (l->classList[0] == o->internalClass()) - return o->d()->memberData->values.data()[l->index].asReturnedValue(); - - l->globalGetter = globalGetterGeneric; - return globalGetterGeneric(l, engine); -} - -ReturnedValue Lookup::globalGetter1(Lookup *l, ExecutionEngine *engine) -{ - Object *o = engine->globalObject; - if (l->classList[0] == o->internalClass() && - l->classList[1] == o->prototype()->internalClass) - return o->prototype()->propertyData(l->index)->asReturnedValue(); - - l->globalGetter = globalGetterGeneric; - return globalGetterGeneric(l, engine); + return l->resolveGlobalGetter(engine); } -ReturnedValue Lookup::globalGetter2(Lookup *l, ExecutionEngine *engine) +ReturnedValue Lookup::globalGetterProto(Lookup *l, ExecutionEngine *engine) { Heap::Object *o = engine->globalObject->d(); - if (l->classList[0] == o->internalClass) { - o = o->prototype(); - if (l->classList[1] == o->internalClass) { - o = o->prototype(); - if (l->classList[2] == o->internalClass) { - return o->prototype()->propertyData(l->index)->asReturnedValue(); - } - } - } + if (l->protoLookup.icIdentifier == o->internalClass->id) + return l->protoLookup.data->asReturnedValue(); l->globalGetter = globalGetterGeneric; return globalGetterGeneric(l, engine); } -ReturnedValue Lookup::globalGetterAccessor0(Lookup *l, ExecutionEngine *engine) +ReturnedValue Lookup::globalGetterProtoAccessor(Lookup *l, ExecutionEngine *engine) { - Object *o = engine->globalObject; - if (l->classList[0] == o->internalClass()) { - Scope scope(o->engine()); - ScopedFunctionObject getter(scope, o->propertyData(l->index + Object::GetterOffset)); - if (!getter) - return Encode::undefined(); - - JSCallData jsCallData(scope); - return getter->call(jsCallData); - } - l->globalGetter = globalGetterGeneric; - return globalGetterGeneric(l, engine); -} - -ReturnedValue Lookup::globalGetterAccessor1(Lookup *l, ExecutionEngine *engine) -{ - Object *o = engine->globalObject; - if (l->classList[0] == o->internalClass() && - l->classList[1] == o->prototype()->internalClass) { - Scope scope(o->engine()); - ScopedFunctionObject getter(scope, o->prototype()->propertyData(l->index + Object::GetterOffset)); - if (!getter) + Heap::Object *o = engine->globalObject->d(); + if (l->protoLookup.icIdentifier == o->internalClass->id) { + const Value *getter = l->protoLookup.data; + if (!getter->isFunctionObject()) // ### catch at resolve time return Encode::undefined(); - JSCallData jsCallData(scope); - return getter->call(jsCallData); - } - l->globalGetter = globalGetterGeneric; - return globalGetterGeneric(l, engine); -} - -ReturnedValue Lookup::globalGetterAccessor2(Lookup *l, ExecutionEngine *engine) -{ - Heap::Object *o = engine->globalObject->d(); - if (l->classList[0] == o->internalClass) { - o = o->prototype(); - if (l->classList[1] == o->internalClass) { - o = o->prototype(); - if (l->classList[2] == o->internalClass) { - Scope scope(o->internalClass->engine); - ScopedFunctionObject getter(scope, o->propertyData(l->index + Object::GetterOffset)); - if (!getter) - return Encode::undefined(); - - JSCallData jsCallData(scope); - return getter->call(jsCallData); - } - } + return static_cast(getter)->call(engine->globalObject, nullptr, 0); } l->globalGetter = globalGetterGeneric; return globalGetterGeneric(l, engine); diff --git a/src/qml/jsruntime/qv4lookup_p.h b/src/qml/jsruntime/qv4lookup_p.h index 6a9a5cf419..450d2d4364 100644 --- a/src/qml/jsruntime/qv4lookup_p.h +++ b/src/qml/jsruntime/qv4lookup_p.h @@ -111,6 +111,7 @@ struct Lookup { ReturnedValue resolveGetter(ExecutionEngine *engine, const Object *object); ReturnedValue resolvePrimitiveGetter(ExecutionEngine *engine, const Value &object); + ReturnedValue resolveGlobalGetter(ExecutionEngine *engine); void resolveProtoGetter(Identifier *name, const Heap::Object *proto); static ReturnedValue getterGeneric(Lookup *l, ExecutionEngine *engine, const Value &object); @@ -133,13 +134,8 @@ struct Lookup { static ReturnedValue stringLengthGetter(Lookup *l, ExecutionEngine *engine, const Value &object); static ReturnedValue globalGetterGeneric(Lookup *l, ExecutionEngine *engine); - static ReturnedValue globalGetter0Inline(Lookup *l, ExecutionEngine *engine); - static ReturnedValue globalGetter0MemberData(Lookup *l, ExecutionEngine *engine); - static ReturnedValue globalGetter1(Lookup *l, ExecutionEngine *engine); - static ReturnedValue globalGetter2(Lookup *l, ExecutionEngine *engine); - static ReturnedValue globalGetterAccessor0(Lookup *l, ExecutionEngine *engine); - static ReturnedValue globalGetterAccessor1(Lookup *l, ExecutionEngine *engine); - static ReturnedValue globalGetterAccessor2(Lookup *l, ExecutionEngine *engine); + static ReturnedValue globalGetterProto(Lookup *l, ExecutionEngine *engine); + static ReturnedValue globalGetterProtoAccessor(Lookup *l, ExecutionEngine *engine); static bool setterGeneric(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value); static bool setterTwoClasses(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value); -- cgit v1.2.3