diff options
-rw-r--r-- | src/qml/jsruntime/qv4functionobject.cpp | 15 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4functionobject_p.h | 6 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4generatorobject.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4generatorobject_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4propertykey.cpp | 26 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4propertykey_p.h | 7 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 25 | ||||
-rw-r--r-- | tests/auto/qml/ecmascripttests/TestExpectations | 15 |
8 files changed, 65 insertions, 35 deletions
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index 8722ff65b6..b0f9f5198e 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -101,7 +101,7 @@ void Heap::FunctionObject::init(QV4::ExecutionContext *scope, QV4::String *name, -void Heap::FunctionObject::init(QV4::ExecutionContext *scope, Function *function, bool createProto) +void Heap::FunctionObject::init(QV4::ExecutionContext *scope, Function *function, QV4::String *n) { jsCall = vtable()->call; jsConstruct = vtable()->callAsConstructor; @@ -110,13 +110,10 @@ void Heap::FunctionObject::init(QV4::ExecutionContext *scope, Function *function setFunction(function); this->scope.set(scope->engine(), scope->d()); Scope s(scope->engine()); - ScopedString name(s, function->name()); + ScopedString name(s, n ? n->d() : function->name()); ScopedFunctionObject f(s, this); if (name) f->setName(name); - - if (createProto) - f->createDefaultPrototypeProperty(Heap::FunctionObject::Index_Prototype, Heap::FunctionObject::Index_ProtoConstructor); } void Heap::FunctionObject::init(QV4::ExecutionContext *scope, const QString &name, bool createProto) @@ -195,9 +192,9 @@ Heap::FunctionObject *FunctionObject::createConstructorFunction(ExecutionContext return c; } -Heap::FunctionObject *FunctionObject::createMemberFunction(ExecutionContext *scope, Function *function) +Heap::FunctionObject *FunctionObject::createMemberFunction(ExecutionContext *scope, Function *function, QV4::String *name) { - return scope->engine()->memoryManager->allocate<MemberFunction>(scope, function); + return scope->engine()->memoryManager->allocate<MemberFunction>(scope, function, name); } Heap::FunctionObject *FunctionObject::createBuiltinFunction(ExecutionEngine *engine, StringOrSymbol *nameOrSymbol, VTable::Call code, int argumentCount) @@ -515,7 +512,7 @@ ReturnedValue ScriptFunction::virtualCall(const FunctionObject *fo, const Value return result; } -void Heap::ScriptFunction::init(QV4::ExecutionContext *scope, Function *function) +void Heap::ScriptFunction::init(QV4::ExecutionContext *scope, Function *function, QV4::String *n) { FunctionObject::init(); this->scope.set(scope->engine(), scope->d()); @@ -526,7 +523,7 @@ void Heap::ScriptFunction::init(QV4::ExecutionContext *scope, Function *function Scope s(scope); ScopedFunctionObject f(s, this); - ScopedString name(s, function->name()); + ScopedString name(s, n ? n->d() : function->name()); if (name) f->setName(name); f->createDefaultPrototypeProperty(Heap::FunctionObject::Index_Prototype, Heap::FunctionObject::Index_ProtoConstructor); diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h index a9ffa90b90..8482189bb3 100644 --- a/src/qml/jsruntime/qv4functionobject_p.h +++ b/src/qml/jsruntime/qv4functionobject_p.h @@ -82,7 +82,7 @@ DECLARE_HEAP_OBJECT(FunctionObject, Object) { Q_QML_PRIVATE_EXPORT void init(QV4::ExecutionContext *scope, QV4::String *name, VTable::Call call); void init(QV4::ExecutionContext *scope, QV4::String *name = nullptr, bool createProto = false); - void init(QV4::ExecutionContext *scope, QV4::Function *function, bool createProto = false); + void init(QV4::ExecutionContext *scope, QV4::Function *function, QV4::String *n = nullptr); void init(QV4::ExecutionContext *scope, const QString &name, bool createProto = false); void init(); void destroy(); @@ -115,7 +115,7 @@ DECLARE_HEAP_OBJECT(ScriptFunction, FunctionObject) { Index_Name = FunctionObject::Index_Prototype + 1, Index_Length }; - void init(QV4::ExecutionContext *scope, Function *function); + void init(QV4::ExecutionContext *scope, Function *function, QV4::String *name = nullptr); }; struct ConstructorFunction : ScriptFunction @@ -181,7 +181,7 @@ struct Q_QML_EXPORT FunctionObject: Object { static Heap::FunctionObject *createScriptFunction(ExecutionContext *scope, Function *function); static Heap::FunctionObject *createConstructorFunction(ExecutionContext *scope, Function *function, bool isDerivedConstructor); - static Heap::FunctionObject *createMemberFunction(ExecutionContext *scope, Function *function); + static Heap::FunctionObject *createMemberFunction(ExecutionContext *scope, Function *function, String *name); static Heap::FunctionObject *createBuiltinFunction(ExecutionEngine *engine, StringOrSymbol *nameOrSymbol, VTable::Call code, int argumentCount); bool strictMode() const { return d()->function ? d()->function->isStrict() : false; } diff --git a/src/qml/jsruntime/qv4generatorobject.cpp b/src/qml/jsruntime/qv4generatorobject.cpp index 8c3cd8b863..4a784bff35 100644 --- a/src/qml/jsruntime/qv4generatorobject.cpp +++ b/src/qml/jsruntime/qv4generatorobject.cpp @@ -235,10 +235,10 @@ ReturnedValue GeneratorObject::resume(ExecutionEngine *engine, const Value &arg) DEFINE_OBJECT_VTABLE(MemberGeneratorFunction); -Heap::FunctionObject *MemberGeneratorFunction::create(ExecutionContext *context, Function *function) +Heap::FunctionObject *MemberGeneratorFunction::create(ExecutionContext *context, Function *function, String *name) { Scope scope(context); - Scoped<GeneratorFunction> g(scope, context->engine()->memoryManager->allocate<MemberGeneratorFunction>(context, function)); + Scoped<GeneratorFunction> g(scope, context->engine()->memoryManager->allocate<MemberGeneratorFunction>(context, function, name)); ScopedObject proto(scope, scope.engine->newObject()); proto->setPrototypeOf(scope.engine->generatorPrototype()); g->defineDefaultProperty(scope.engine->id_prototype(), proto, Attr_NotConfigurable|Attr_NotEnumerable); diff --git a/src/qml/jsruntime/qv4generatorobject_p.h b/src/qml/jsruntime/qv4generatorobject_p.h index a97050473c..017580e1a1 100644 --- a/src/qml/jsruntime/qv4generatorobject_p.h +++ b/src/qml/jsruntime/qv4generatorobject_p.h @@ -118,7 +118,7 @@ struct MemberGeneratorFunction : GeneratorFunction V4_OBJECT2(MemberGeneratorFunction, GeneratorFunction) V4_INTERNALCLASS(MemberGeneratorFunction) - static Heap::FunctionObject *create(ExecutionContext *scope, Function *function); + static Heap::FunctionObject *create(ExecutionContext *scope, Function *function, String *name); static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *); }; diff --git a/src/qml/jsruntime/qv4propertykey.cpp b/src/qml/jsruntime/qv4propertykey.cpp index e5e96bedb8..12a3653034 100644 --- a/src/qml/jsruntime/qv4propertykey.cpp +++ b/src/qml/jsruntime/qv4propertykey.cpp @@ -41,6 +41,7 @@ #include <QtCore/qstring.h> #include <qv4string_p.h> +#include <qv4engine_p.h> QV4::Heap::StringOrSymbol *QV4::PropertyKey::toStringOrSymbol(QV4::ExecutionEngine *e) { @@ -63,8 +64,27 @@ QString QV4::PropertyKey::toQString() const { if (isArrayIndex()) return QString::number(asArrayIndex()); - Heap::Base *b = asStringOrSymbol(); - Q_ASSERT(b->internalClass->vtable->isStringOrSymbol); - Heap::StringOrSymbol *s = static_cast<Heap::StringOrSymbol *>(b); + Heap::StringOrSymbol *s = asStringOrSymbol(); + Q_ASSERT(s->internalClass->vtable->isStringOrSymbol); return s->toQString(); } + +QV4::Heap::String *QV4::PropertyKey::asFunctionName(ExecutionEngine *engine, FunctionNamePrefix prefix) const +{ + QString n; + if (prefix == Getter) + n = QStringLiteral("get "); + else if (prefix == Setter) + n = QStringLiteral("set "); + if (isArrayIndex()) + n += QString::number(asArrayIndex()); + else { + Heap::StringOrSymbol *s = asStringOrSymbol(); + QString str = s->toQString(); + if (s->internalClass->vtable->isString) + n += s->toQString(); + else if (str.length() > 1) + n += QChar::fromLatin1('[') + str.midRef(1) + QChar::fromLatin1(']'); + } + return engine->newString(n); +} diff --git a/src/qml/jsruntime/qv4propertykey_p.h b/src/qml/jsruntime/qv4propertykey_p.h index 00bf8fb195..14f8e961ea 100644 --- a/src/qml/jsruntime/qv4propertykey_p.h +++ b/src/qml/jsruntime/qv4propertykey_p.h @@ -131,6 +131,13 @@ public: Heap::StringOrSymbol *toStringOrSymbol(ExecutionEngine *e); quint64 id() const { return val; } + enum FunctionNamePrefix { + None, + Getter, + Setter + }; + Heap::String *asFunctionName(ExecutionEngine *e, FunctionNamePrefix prefix) const; + bool operator ==(const PropertyKey &other) const { return val == other.val; } bool operator !=(const PropertyKey &other) const { return val != other.val; } bool operator <(const PropertyKey &other) const { return val < other.val; } diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index 768d010bdf..7839db8e01 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -1486,12 +1486,25 @@ ReturnedValue Runtime::method_objectLiteral(ExecutionEngine *engine, int classId ScopedPropertyKey name(scope); ScopedProperty pd(scope); + ScopedFunctionObject fn(scope); + ScopedString fnName(scope); for (int i = 0; i < additionalArgs; ++i) { Q_ASSERT(args->isInteger()); ObjectLiteralArgument arg = ObjectLiteralArgument(args->integerValue()); name = args[1].toPropertyKey(engine); if (engine->hasException) return Encode::undefined(); + if (args[2].isFunctionObject()) { + fn = static_cast<const FunctionObject &>(args[2]); + PropertyKey::FunctionNamePrefix prefix = PropertyKey::None; + if (arg == ObjectLiteralArgument::Getter) + prefix = PropertyKey::Getter; + else if (arg == ObjectLiteralArgument::Setter) + prefix = PropertyKey::Setter; + + fnName = name->asFunctionName(engine, prefix); + fn->setName(fnName); + } Q_ASSERT(arg == ObjectLiteralArgument::Value || args[2].isFunctionObject()); if (arg == ObjectLiteralArgument::Value || arg == ObjectLiteralArgument::Getter) { pd->value = args[2]; @@ -1569,10 +1582,18 @@ ReturnedValue Runtime::method_createClass(ExecutionEngine *engine, int classInde } QV4::Function *f = unit->runtimeFunctions[methods[i].function]; Q_ASSERT(f); + PropertyKey::FunctionNamePrefix prefix = PropertyKey::None; + if (methods[i].type == CompiledData::Method::Getter) + prefix = PropertyKey::Getter; + else if (methods[i].type == CompiledData::Method::Setter) + prefix = PropertyKey::Setter; + + name = propertyName->asFunctionName(engine, prefix); + if (f->isGenerator()) - function = MemberGeneratorFunction::create(current, f); + function = MemberGeneratorFunction::create(current, f, name); else - function = FunctionObject::createMemberFunction(current, f); + function = FunctionObject::createMemberFunction(current, f, name); Q_ASSERT(function); PropertyAttributes attributes; switch (methods[i].type) { diff --git a/tests/auto/qml/ecmascripttests/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations index 5e14120da0..186e4f6320 100644 --- a/tests/auto/qml/ecmascripttests/TestExpectations +++ b/tests/auto/qml/ecmascripttests/TestExpectations @@ -2104,25 +2104,14 @@ 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/non-ctor-err-realm.js fails -language/expressions/object/fn-name-accessor-get.js fails -language/expressions/object/fn-name-accessor-set.js fails -language/expressions/object/fn-name-arrow.js fails -language/expressions/object/fn-name-class.js fails -language/expressions/object/fn-name-cover.js fails -language/expressions/object/fn-name-fn.js fails -language/expressions/object/fn-name-gen.js fails language/expressions/object/let-non-strict-access.js sloppyFails language/expressions/object/let-non-strict-syntax.js sloppyFails -language/expressions/object/method-definition/fn-name-fn.js fails -language/expressions/object/method-definition/fn-name-gen.js fails language/expressions/object/method-definition/gen-meth-dflt-params-ref-later.js fails language/expressions/object/method-definition/gen-meth-dflt-params-ref-self.js fails language/expressions/object/method-definition/gen-yield-identifier-non-strict.js sloppyFails -language/expressions/object/method-definition/generator-name-prop-symbol.js fails language/expressions/object/method-definition/meth-dflt-params-ref-later.js fails language/expressions/object/method-definition/meth-dflt-params-ref-self.js fails language/expressions/object/method-definition/name-invoke-ctor.js fails -language/expressions/object/method-definition/name-name-prop-symbol.js fails language/expressions/object/method-definition/name-prototype-prop.js fails language/expressions/object/method-definition/object-method-returns-promise.js fails language/expressions/object/method-definition/yield-as-function-expression-binding-identifier.js sloppyFails @@ -2415,10 +2404,6 @@ language/statements/class/constructor-inferred-observable-iteration.js fails language/statements/class/cptn-decl.js fails language/statements/class/definition/accessors.js fails language/statements/class/definition/class-method-returns-promise.js fails -language/statements/class/definition/fn-name-accessor-get.js fails -language/statements/class/definition/fn-name-accessor-set.js fails -language/statements/class/definition/fn-name-gen-method.js fails -language/statements/class/definition/fn-name-method.js fails language/statements/class/definition/getters-non-configurable-err.js fails language/statements/class/definition/getters-prop-desc.js fails language/statements/class/definition/getters-restricted-ids.js fails |