diff options
author | Lars Knoll <[email protected]> | 2018-06-23 23:07:23 +0200 |
---|---|---|
committer | Lars Knoll <[email protected]> | 2018-07-02 19:29:43 +0000 |
commit | 56bff8f7abc2f0eeadd4d197667132af6eed6f3a (patch) | |
tree | 13990d34f9239e1845dedaa452bc1093f38b027a | |
parent | 86f88521fbea59e8ec53e50cc1e3e68a61f53c40 (diff) |
Clean up the property key API in StringOrSymbol
Get rid of makeIdentifier(), as toPropertyKey() will take
care of it.
Rename identifier() to propertyKey() and check that the
key is valid.
Remove String/StringOrSymbol::asArrayIndex(), we don't need it
anymore.
Change-Id: I3c490fabc1475c9ea288b49b1638b6fa1bc237b7
Reviewed-by: Simon Hausmann <[email protected]>
23 files changed, 105 insertions, 156 deletions
diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp index 01e8600574..bf8000bdd8 100644 --- a/src/qml/jsapi/qjsvalue.cpp +++ b/src/qml/jsapi/qjsvalue.cpp @@ -1058,12 +1058,7 @@ QJSValue QJSValue::property(const QString& name) const return QJSValue(); ScopedString s(scope, engine->newString(name)); - uint idx = s->asArrayIndex(); - if (idx < UINT_MAX) - return property(idx); - - s->makeIdentifier(); - QV4::ScopedValue result(scope, o->get(s)); + QV4::ScopedValue result(scope, o->get(s->toPropertyKey())); if (engine->hasException) result = engine->catchException(); @@ -1148,15 +1143,8 @@ void QJSValue::setProperty(const QString& name, const QJSValue& value) } ScopedString s(scope, engine->newString(name)); - uint idx = s->asArrayIndex(); - if (idx < UINT_MAX) { - setProperty(idx, value); - return; - } - - s->makeIdentifier(); QV4::ScopedValue v(scope, QJSValuePrivate::convertedToValue(engine, value)); - o->put(s, v); + o->put(s->toPropertyKey(), v); if (engine->hasException) engine->catchException(); } @@ -1209,7 +1197,7 @@ void QJSValue::setProperty(quint32 arrayIndex, const QJSValue& value) } QV4::ScopedValue v(scope, QJSValuePrivate::convertedToValue(engine, value)); - PropertyKey id = arrayIndex != UINT_MAX ? PropertyKey::fromArrayIndex(arrayIndex) : engine->id_uintMax()->identifier(); + PropertyKey id = arrayIndex != UINT_MAX ? PropertyKey::fromArrayIndex(arrayIndex) : engine->id_uintMax()->propertyKey(); o->put(id, v); if (engine->hasException) engine->catchException(); @@ -1289,7 +1277,7 @@ bool QJSValue::hasOwnProperty(const QString &name) const return false; ScopedString s(scope, engine->newIdentifier(name)); - return o->getOwnProperty(s->identifier()) != Attr_Invalid; + return o->getOwnProperty(s->propertyKey()) != Attr_Invalid; } /*! diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp index ab242ddd92..5b04c9f60b 100644 --- a/src/qml/jsruntime/qv4argumentsobject.cpp +++ b/src/qml/jsruntime/qv4argumentsobject.cpp @@ -63,11 +63,11 @@ void Heap::ArgumentsObject::init(QV4::CppStackFrame *frame) this->context.set(v4, context->d()); Q_ASSERT(vtable() == QV4::ArgumentsObject::staticVTable()); - Q_ASSERT(CalleePropertyIndex == internalClass->find(v4->id_callee()->identifier())); + Q_ASSERT(CalleePropertyIndex == internalClass->find(v4->id_callee()->propertyKey())); setProperty(v4, CalleePropertyIndex, context->d()->function); - Q_ASSERT(LengthPropertyIndex == internalClass->find(v4->id_length()->identifier())); + Q_ASSERT(LengthPropertyIndex == internalClass->find(v4->id_length()->propertyKey())); setProperty(v4, LengthPropertyIndex, Primitive::fromInt32(context->argc())); - Q_ASSERT(SymbolIteratorPropertyIndex == internalClass->find(v4->symbol_iterator()->identifier())); + Q_ASSERT(SymbolIteratorPropertyIndex == internalClass->find(v4->symbol_iterator()->propertyKey())); setProperty(v4, SymbolIteratorPropertyIndex, *v4->arrayProtoValues()); } @@ -78,8 +78,8 @@ void Heap::StrictArgumentsObject::init(QV4::CppStackFrame *frame) Object::init(); - Q_ASSERT(CalleePropertyIndex == internalClass->find(v4->id_callee()->identifier())); - Q_ASSERT(SymbolIteratorPropertyIndex == internalClass->find(v4->symbol_iterator()->identifier())); + Q_ASSERT(CalleePropertyIndex == internalClass->find(v4->id_callee()->propertyKey())); + Q_ASSERT(SymbolIteratorPropertyIndex == internalClass->find(v4->symbol_iterator()->propertyKey())); setProperty(v4, SymbolIteratorPropertyIndex, *v4->arrayProtoValues()); setProperty(v4, CalleePropertyIndex + QV4::Object::GetterOffset, *v4->thrower()); setProperty(v4, CalleePropertyIndex + QV4::Object::SetterOffset, *v4->thrower()); @@ -89,7 +89,7 @@ void Heap::StrictArgumentsObject::init(QV4::CppStackFrame *frame) args->arrayReserve(frame->originalArgumentsCount); args->arrayPut(0, frame->originalArguments, frame->originalArgumentsCount); - Q_ASSERT(LengthPropertyIndex == args->internalClass()->find(v4->id_length()->identifier())); + Q_ASSERT(LengthPropertyIndex == args->internalClass()->find(v4->id_length()->propertyKey())); setProperty(v4, LengthPropertyIndex, Primitive::fromInt32(frame->originalArgumentsCount)); } diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index f01ec33c64..2c4e5f34d4 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -190,8 +190,7 @@ void ExecutionContext::createMutableBinding(String *name, bool deletable) bool ExecutionContext::deleteProperty(String *name) { - name->makeIdentifier(); - PropertyKey id = name->identifier(); + PropertyKey id = name->toPropertyKey(); Heap::ExecutionContext *ctx = d(); for (; ctx; ctx = ctx->outer) { @@ -226,8 +225,7 @@ bool ExecutionContext::deleteProperty(String *name) ExecutionContext::Error ExecutionContext::setProperty(String *name, const Value &value) { - name->makeIdentifier(); - PropertyKey id = name->identifier(); + PropertyKey id = name->toPropertyKey(); QV4::ExecutionEngine *v4 = engine(); Heap::ExecutionContext *ctx = d(); @@ -282,7 +280,7 @@ ExecutionContext::Error ExecutionContext::setProperty(String *name, const Value ReturnedValue ExecutionContext::getProperty(String *name) { - name->makeIdentifier(); + PropertyKey id = name->toPropertyKey(); Heap::ExecutionContext *ctx = d(); for (; ctx; ctx = ctx->outer) { @@ -290,7 +288,6 @@ ReturnedValue ExecutionContext::getProperty(String *name) case Heap::ExecutionContext::Type_BlockContext: case Heap::ExecutionContext::Type_CallContext: { Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx); - PropertyKey id = name->identifier(); uint index = c->internalClass->find(id); if (index < UINT_MAX) @@ -304,7 +301,7 @@ ReturnedValue ExecutionContext::getProperty(String *name) Scope scope(this); ScopedObject activation(scope, ctx->activation); bool hasProperty = false; - ReturnedValue v = activation->get(name, &hasProperty); + ReturnedValue v = activation->get(id, nullptr, &hasProperty); if (hasProperty) return v; } @@ -318,7 +315,7 @@ ReturnedValue ExecutionContext::getProperty(String *name) ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Value *base) { base->setM(nullptr); - name->makeIdentifier(); + PropertyKey id = name->toPropertyKey(); Heap::ExecutionContext *ctx = d(); for (; ctx; ctx = ctx->outer) { @@ -326,8 +323,6 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Value *base) case Heap::ExecutionContext::Type_BlockContext: case Heap::ExecutionContext::Type_CallContext: { Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx); - name->makeIdentifier(); - PropertyKey id = name->identifier(); uint index = c->internalClass->find(id); if (index < UINT_MAX) @@ -350,7 +345,7 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Value *base) Scope scope(this); ScopedObject o(scope, ctx->activation); bool hasProperty = false; - ReturnedValue v = o->get(name, &hasProperty); + ReturnedValue v = o->get(id, nullptr, &hasProperty); if (hasProperty) { base->setM(o->d()); return v; diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp index 5b81d91879..12649c0860 100644 --- a/src/qml/jsruntime/qv4dateobject.cpp +++ b/src/qml/jsruntime/qv4dateobject.cpp @@ -1524,10 +1524,10 @@ ReturnedValue DatePrototype::method_symbolToPrimitive(const FunctionObject *f, c return e->throwTypeError(); String *hint = argv->stringValue(); - PropertyKey id = hint->identifier(); - if (id == e->id_default()->identifier()) + PropertyKey id = hint->toPropertyKey(); + if (id == e->id_default()->propertyKey()) hint = e->id_string(); - else if (id != e->id_string()->identifier() && id != e->id_number()->identifier()) + else if (id != e->id_string()->propertyKey() && id != e->id_number()->propertyKey()) return e->throwTypeError(); return RuntimeHelpers::ordinaryToPrimitive(e, static_cast<const Object *>(thisObject), hint); diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index d5b48afc92..b42633b446 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -295,7 +295,7 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine) ic = newInternalClass(ArrayPrototype::staticVTable(), objectPrototype()); Q_ASSERT(ic->d()->prototype); - ic = ic->addMember(id_length()->identifier(), Attr_NotConfigurable|Attr_NotEnumerable); + ic = ic->addMember(id_length()->propertyKey(), Attr_NotConfigurable|Attr_NotEnumerable); Q_ASSERT(ic->d()->prototype); jsObjects[ArrayProto] = memoryManager->allocObject<ArrayPrototype>(ic->d()); classes[Class_ArrayObject] = ic->changePrototype(arrayPrototype()->d()); @@ -303,22 +303,22 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine) Scoped<InternalClass> argsClass(scope); argsClass = newInternalClass(ArgumentsObject::staticVTable(), objectPrototype()); - argsClass = argsClass->addMember(id_length()->identifier(), Attr_NotEnumerable); - argsClass = argsClass->addMember(symbol_iterator()->identifier(), Attr_Data|Attr_NotEnumerable); - classes[Class_ArgumentsObject] = argsClass->addMember(id_callee()->identifier(), Attr_Data|Attr_NotEnumerable); + argsClass = argsClass->addMember(id_length()->propertyKey(), Attr_NotEnumerable); + argsClass = argsClass->addMember(symbol_iterator()->propertyKey(), Attr_Data|Attr_NotEnumerable); + classes[Class_ArgumentsObject] = argsClass->addMember(id_callee()->propertyKey(), Attr_Data|Attr_NotEnumerable); argsClass = newInternalClass(StrictArgumentsObject::staticVTable(), objectPrototype()); - argsClass = argsClass->addMember(id_length()->identifier(), Attr_NotEnumerable); - argsClass = argsClass->addMember(symbol_iterator()->identifier(), Attr_Data|Attr_NotEnumerable); - classes[Class_StrictArgumentsObject] = argsClass->addMember(id_callee()->identifier(), Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable); + argsClass = argsClass->addMember(id_length()->propertyKey(), Attr_NotEnumerable); + argsClass = argsClass->addMember(symbol_iterator()->propertyKey(), Attr_Data|Attr_NotEnumerable); + classes[Class_StrictArgumentsObject] = argsClass->addMember(id_callee()->propertyKey(), Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable); *static_cast<Value *>(globalObject) = newObject(); Q_ASSERT(globalObject->d()->vtable()); initRootContext(); ic = newInternalClass(QV4::StringObject::staticVTable(), objectPrototype()); - ic = ic->addMember(id_length()->identifier(), Attr_ReadOnly); + ic = ic->addMember(id_length()->propertyKey(), Attr_ReadOnly); classes[Class_StringObject] = ic->changePrototype(stringPrototype()->d()); - Q_ASSERT(classes[Class_StringObject]->find(id_length()->identifier()) == Heap::StringObject::LengthPropertyIndex); + Q_ASSERT(classes[Class_StringObject]->find(id_length()->propertyKey()) == Heap::StringObject::LengthPropertyIndex); classes[Class_SymbolObject] = newInternalClass(QV4::SymbolObject::staticVTable(), symbolPrototype()); @@ -328,17 +328,17 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine) uint index; ic = newInternalClass(QV4::FunctionPrototype::staticVTable(), objectPrototype()); - ic = ic->addMember(id_prototype()->identifier(), Attr_NotEnumerable, &index); + ic = ic->addMember(id_prototype()->propertyKey(), Attr_NotEnumerable, &index); Q_ASSERT(index == Heap::FunctionObject::Index_Prototype); jsObjects[FunctionProto] = memoryManager->allocObject<FunctionPrototype>(ic->d()); ic = newInternalClass(FunctionObject::staticVTable(), functionPrototype()); - ic = ic->addMember(id_prototype()->identifier(), Attr_NotEnumerable|Attr_NotConfigurable, &index); + ic = ic->addMember(id_prototype()->propertyKey(), Attr_NotEnumerable|Attr_NotConfigurable, &index); Q_ASSERT(index == Heap::FunctionObject::Index_Prototype); classes[Class_FunctionObject] = ic->d(); - ic = ic->addMember(id_name()->identifier(), Attr_ReadOnly, &index); + ic = ic->addMember(id_name()->propertyKey(), Attr_ReadOnly, &index); Q_ASSERT(index == Heap::ScriptFunction::Index_Name); ic = ic->changeVTable(ScriptFunction::staticVTable()); - ic = ic->addMember(id_length()->identifier(), Attr_ReadOnly_ButConfigurable, &index); + ic = ic->addMember(id_length()->propertyKey(), Attr_ReadOnly_ButConfigurable, &index); Q_ASSERT(index == Heap::ScriptFunction::Index_Length); classes[Class_ScriptFunction] = ic->d(); ic = ic->changeVTable(ConstructorFunction::staticVTable()); @@ -349,7 +349,7 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine) classes[Class_MemberFunction] = ic->d(); ic = ic->changeVTable(GeneratorFunction::staticVTable()); classes[Class_GeneratorFunction] = ic->d(); - classes[Class_ObjectProto] = classes[Class_Object]->addMember(id_constructor()->identifier(), Attr_NotEnumerable, &index); + classes[Class_ObjectProto] = classes[Class_Object]->addMember(id_constructor()->propertyKey(), Attr_NotEnumerable, &index); Q_ASSERT(index == Heap::FunctionObject::Index_ProtoConstructor); jsObjects[GeneratorProto] = memoryManager->allocObject<GeneratorPrototype>(classes[Class_Object]); @@ -358,40 +358,40 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine) ScopedString str(scope); classes[Class_RegExp] = classes[Class_Empty]->changeVTable(QV4::RegExp::staticVTable()); ic = newInternalClass(QV4::RegExpObject::staticVTable(), objectPrototype()); - ic = ic->addMember(id_lastIndex()->identifier(), Attr_NotEnumerable|Attr_NotConfigurable, &index); + ic = ic->addMember(id_lastIndex()->propertyKey(), Attr_NotEnumerable|Attr_NotConfigurable, &index); Q_ASSERT(index == RegExpObject::Index_LastIndex); - ic = ic->addMember((str = newIdentifier(QStringLiteral("source")))->identifier(), Attr_ReadOnly, &index); + ic = ic->addMember((str = newIdentifier(QStringLiteral("source")))->propertyKey(), Attr_ReadOnly, &index); Q_ASSERT(index == RegExpObject::Index_Source); - ic = ic->addMember((str = newIdentifier(QStringLiteral("global")))->identifier(), Attr_ReadOnly, &index); + ic = ic->addMember((str = newIdentifier(QStringLiteral("global")))->propertyKey(), Attr_ReadOnly, &index); Q_ASSERT(index == RegExpObject::Index_Global); - ic = ic->addMember((str = newIdentifier(QStringLiteral("ignoreCase")))->identifier(), Attr_ReadOnly, &index); + ic = ic->addMember((str = newIdentifier(QStringLiteral("ignoreCase")))->propertyKey(), Attr_ReadOnly, &index); Q_ASSERT(index == RegExpObject::Index_IgnoreCase); - ic = ic->addMember((str = newIdentifier(QStringLiteral("multiline")))->identifier(), Attr_ReadOnly, &index); + ic = ic->addMember((str = newIdentifier(QStringLiteral("multiline")))->propertyKey(), Attr_ReadOnly, &index); Q_ASSERT(index == RegExpObject::Index_Multiline); jsObjects[RegExpProto] = memoryManager->allocObject<RegExpPrototype>(ic->d()); classes[Class_RegExpObject] = ic->changePrototype(regExpPrototype()->d()); - ic = classes[Class_ArrayObject]->addMember(id_index()->identifier(), Attr_Data, &index); + ic = classes[Class_ArrayObject]->addMember(id_index()->propertyKey(), Attr_Data, &index); Q_ASSERT(index == RegExpObject::Index_ArrayIndex); - classes[Class_RegExpExecArray] = ic->addMember(id_input()->identifier(), Attr_Data, &index); + classes[Class_RegExpExecArray] = ic->addMember(id_input()->propertyKey(), Attr_Data, &index); Q_ASSERT(index == RegExpObject::Index_ArrayInput); ic = newInternalClass(ErrorObject::staticVTable(), nullptr); - ic = ic->addMember((str = newIdentifier(QStringLiteral("stack")))->identifier(), Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable, &index); + ic = ic->addMember((str = newIdentifier(QStringLiteral("stack")))->propertyKey(), Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable, &index); Q_ASSERT(index == ErrorObject::Index_Stack); - ic = ic->addMember((str = newIdentifier(QStringLiteral("fileName")))->identifier(), Attr_Data|Attr_NotEnumerable, &index); + ic = ic->addMember((str = newIdentifier(QStringLiteral("fileName")))->propertyKey(), Attr_Data|Attr_NotEnumerable, &index); Q_ASSERT(index == ErrorObject::Index_FileName); - ic = ic->addMember((str = newIdentifier(QStringLiteral("lineNumber")))->identifier(), Attr_Data|Attr_NotEnumerable, &index); + ic = ic->addMember((str = newIdentifier(QStringLiteral("lineNumber")))->propertyKey(), Attr_Data|Attr_NotEnumerable, &index); classes[Class_ErrorObject] = ic->d(); Q_ASSERT(index == ErrorObject::Index_LineNumber); - classes[Class_ErrorObjectWithMessage] = ic->addMember((str = newIdentifier(QStringLiteral("message")))->identifier(), Attr_Data|Attr_NotEnumerable, &index); + classes[Class_ErrorObjectWithMessage] = ic->addMember((str = newIdentifier(QStringLiteral("message")))->propertyKey(), Attr_Data|Attr_NotEnumerable, &index); Q_ASSERT(index == ErrorObject::Index_Message); ic = newInternalClass(ErrorObject::staticVTable(), objectPrototype()); - ic = ic->addMember(id_constructor()->identifier(), Attr_Data|Attr_NotEnumerable, &index); + ic = ic->addMember(id_constructor()->propertyKey(), Attr_Data|Attr_NotEnumerable, &index); Q_ASSERT(index == ErrorPrototype::Index_Constructor); - ic = ic->addMember((str = newIdentifier(QStringLiteral("message")))->identifier(), Attr_Data|Attr_NotEnumerable, &index); + ic = ic->addMember((str = newIdentifier(QStringLiteral("message")))->propertyKey(), Attr_Data|Attr_NotEnumerable, &index); Q_ASSERT(index == ErrorPrototype::Index_Message); - classes[Class_ErrorProto] = ic->addMember(id_name()->identifier(), Attr_Data|Attr_NotEnumerable, &index); + classes[Class_ErrorProto] = ic->addMember(id_name()->propertyKey(), Attr_Data|Attr_NotEnumerable, &index); Q_ASSERT(index == ErrorPrototype::Index_Name); classes[Class_ProxyObject] = classes[Class_Empty]->changeVTable(ProxyObject::staticVTable()); @@ -662,13 +662,15 @@ Heap::Object *ExecutionEngine::newObject(Heap::InternalClass *internalClass) Heap::String *ExecutionEngine::newString(const QString &s) { - Scope scope(this); - return ScopedString(scope, memoryManager->allocWithStringData<String>(s.length() * sizeof(QChar), s))->d(); + return memoryManager->allocWithStringData<String>(s.length() * sizeof(QChar), s); } Heap::String *ExecutionEngine::newIdentifier(const QString &text) { - return identifierTable->insertString(text); + Scope scope(this); + ScopedString s(scope, memoryManager->allocWithStringData<String>(text.length() * sizeof(QChar), text)); + s->toPropertyKey(); + return s->d(); } Heap::Object *ExecutionEngine::newStringObject(const String *string) diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp index 131d3406d2..f5fdc97d4f 100644 --- a/src/qml/jsruntime/qv4function.cpp +++ b/src/qml/jsruntime/qv4function.cpp @@ -120,7 +120,7 @@ void Function::updateInternalClass(ExecutionEngine *engine, const QList<QByteArr ScopedString arg(scope); for (const QString ¶meterName : parameterNames) { arg = engine->newIdentifier(parameterName); - internalClass = internalClass->addMember(arg->identifier(), Attr_NotConfigurable); + internalClass = internalClass->addMember(arg->propertyKey(), Attr_NotConfigurable); } nFormals = parameters.size(); } diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index 772cc22a68..b7b6f83735 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -133,7 +133,7 @@ void Heap::FunctionObject::init() Object::init(); this->scope.set(internalClass->engine, internalClass->engine->rootContext()->d()); - Q_ASSERT(internalClass && internalClass->find(internalClass->engine->id_prototype()->identifier()) == Index_Prototype); + Q_ASSERT(internalClass && internalClass->find(internalClass->engine->id_prototype()->propertyKey()) == Index_Prototype); setProperty(internalClass->engine, Index_Prototype, Primitive::undefinedValue()); } @@ -155,8 +155,8 @@ void FunctionObject::createDefaultPrototypeProperty(uint protoSlot, uint protoCo { Scope s(this); - Q_ASSERT(internalClass() && internalClass()->find(s.engine->id_prototype()->identifier()) == protoSlot); - Q_ASSERT(s.engine->internalClasses(EngineBase::Class_ObjectProto)->find(s.engine->id_constructor()->identifier()) == protoConstructorSlot); + Q_ASSERT(internalClass() && internalClass()->find(s.engine->id_prototype()->propertyKey()) == protoSlot); + Q_ASSERT(s.engine->internalClasses(EngineBase::Class_ObjectProto)->find(s.engine->id_constructor()->propertyKey()) == protoConstructorSlot); ScopedObject proto(s, s.engine->newObject(s.engine->internalClasses(EngineBase::Class_ObjectProto))); proto->setProperty(protoConstructorSlot, d()); @@ -488,7 +488,7 @@ void Heap::ScriptFunction::init(QV4::ExecutionContext *scope, Function *function f->setName(name); f->createDefaultPrototypeProperty(Heap::FunctionObject::Index_Prototype, Heap::FunctionObject::Index_ProtoConstructor); - Q_ASSERT(internalClass && internalClass->find(s.engine->id_length()->identifier()) == Index_Length); + Q_ASSERT(internalClass && internalClass->find(s.engine->id_length()->propertyKey()) == Index_Length); setProperty(s.engine, Index_Length, Primitive::fromInt32(int(function->compiledFunction->length))); } diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp index 58c17b54cc..2e2314cafe 100644 --- a/src/qml/jsruntime/qv4jsonobject.cpp +++ b/src/qml/jsruntime/qv4jsonobject.cpp @@ -261,11 +261,12 @@ bool JsonParser::parseMember(Object *o) if (!parseValue(val)) return false; - ScopedString s(scope, engine->newIdentifier(key)); - uint idx = s->asArrayIndex(); - if (idx < UINT_MAX) { - o->put(idx, val); + ScopedString s(scope, engine->newString(key)); + PropertyKey skey = s->toPropertyKey(); + if (skey.isArrayIndex()) { + o->put(skey.asArrayIndex(), val); } else { + // avoid trouble with properties named __proto__ o->insertMember(s, val); } diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp index 43628ad4f5..446af3f9ef 100644 --- a/src/qml/jsruntime/qv4lookup.cpp +++ b/src/qml/jsruntime/qv4lookup.cpp @@ -466,8 +466,8 @@ bool Lookup::resolveSetter(ExecutionEngine *engine, Object *object, const Value ScopedString name(scope, scope.engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]); Heap::InternalClass *c = object->internalClass(); - name->makeIdentifier(); - uint idx = c->find(name->identifier()); + PropertyKey key = name->toPropertyKey(); + uint idx = c->find(key); if (idx != UINT_MAX) { if (object->isArrayObject() && idx == Heap::ArrayObject::LengthPropertyIndex) { setter = arrayLengthSetter; @@ -485,7 +485,7 @@ bool Lookup::resolveSetter(ExecutionEngine *engine, Object *object, const Value } insertionLookup.protoId = c->protoId; - if (!object->put(name, value)) { + if (!object->put(key, value)) { setter = Lookup::setterFallback; return false; } @@ -495,8 +495,7 @@ bool Lookup::resolveSetter(ExecutionEngine *engine, Object *object, const Value setter = setterFallback; return true; } - name->makeIdentifier(); - idx = object->internalClass()->find(name->identifier()); + idx = object->internalClass()->find(key); if (idx == UINT_MAX) { // ### can this even happen? setter = setterFallback; return false; diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index 0ce5328193..a59d278f7d 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -251,8 +251,8 @@ void Heap::Object::markObjects(Heap::Base *b, MarkStack *stack) void Object::insertMember(StringOrSymbol *s, const Property *p, PropertyAttributes attributes) { uint idx; - s->makeIdentifier(); - Heap::InternalClass::addMember(this, s->identifier(), attributes, &idx); + PropertyKey key = s->toPropertyKey(); + Heap::InternalClass::addMember(this, key, attributes, &idx); if (attributes.isAccessor()) { setProperty(idx + GetterOffset, p->value); @@ -410,10 +410,9 @@ void Object::advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint * // Section 8.12.3 ReturnedValue Object::internalGet(StringOrSymbol *name, const Value *receiver, bool *hasProperty) const { - Q_ASSERT(name->asArrayIndex() == UINT_MAX); + PropertyKey id = name->toPropertyKey(); - name->makeIdentifier(); - PropertyKey id = name->identifier(); + Q_ASSERT(!id.isArrayIndex()); Heap::Object *o = d(); while (o) { @@ -506,7 +505,7 @@ bool Object::internalPut(PropertyKey id, const Value &value, Value *receiver) return false; } else if (!attrs.isWritable()) return false; - else if (isArrayObject() && id == engine->id_length()->identifier()) { + else if (isArrayObject() && id == engine->id_length()->propertyKey()) { bool ok; uint l = value.asArrayLength(&ok); if (!ok) { @@ -672,7 +671,7 @@ bool Object::internalDefineOwnProperty(ExecutionEngine *engine, uint index, Stri current->merge(cattrs, p, attrs); if (member) { - Heap::InternalClass::changeMember(this, member->identifier(), cattrs); + Heap::InternalClass::changeMember(this, member->propertyKey(), cattrs); setProperty(index, current); } else { setArrayAttributes(index, cattrs); @@ -998,9 +997,9 @@ bool ArrayObject::defineOwnProperty(Managed *m, PropertyKey id, const Property * } ExecutionEngine *engine = m->engine(); - if (id == engine->id_length()->identifier()) { + if (id == engine->id_length()->propertyKey()) { Scope scope(engine); - Q_ASSERT(Heap::ArrayObject::LengthPropertyIndex == a->internalClass()->find(engine->id_length()->identifier())); + Q_ASSERT(Heap::ArrayObject::LengthPropertyIndex == a->internalClass()->find(engine->id_length()->propertyKey())); ScopedProperty lp(scope); PropertyAttributes cattrs; a->getProperty(Heap::ArrayObject::LengthPropertyIndex, lp, &cattrs); @@ -1021,7 +1020,7 @@ bool ArrayObject::defineOwnProperty(Managed *m, PropertyKey id, const Property * } if (attrs.hasWritable() && !attrs.isWritable()) { cattrs.setWritable(false); - Heap::InternalClass::changeMember(a, engine->id_length()->identifier(), cattrs); + Heap::InternalClass::changeMember(a, engine->id_length()->propertyKey(), cattrs); } if (!succeeded) return false; diff --git a/src/qml/jsruntime/qv4objectiterator.cpp b/src/qml/jsruntime/qv4objectiterator.cpp index dab8041f0b..73c09a864a 100644 --- a/src/qml/jsruntime/qv4objectiterator.cpp +++ b/src/qml/jsruntime/qv4objectiterator.cpp @@ -104,7 +104,7 @@ void ObjectIterator::next(Value *name, uint *index, Property *pd, PropertyAttrib n = *name; bool shadowed = false; while (o->d() != current->heapObject()) { - PropertyKey id = n ? (n->makeIdentifier(), n->identifier()) : PropertyKey::fromArrayIndex(*index); + PropertyKey id = n ? (n->toPropertyKey()) : PropertyKey::fromArrayIndex(*index); if (id.isValid() && o->getOwnProperty(id) != Attr_Invalid) { shadowed = true; break; diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 1292f4d814..a47bd3731d 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -314,7 +314,7 @@ ReturnedValue QObjectWrapper::getQmlProperty(QQmlContextData *qmlContext, String } } } - return QV4::Object::get(this, name->identifier(), this, hasProperty); + return QV4::Object::get(this, name->propertyKey(), this, hasProperty); } QQmlData *ddata = QQmlData::get(d()->object(), false); diff --git a/src/qml/jsruntime/qv4reflect.cpp b/src/qml/jsruntime/qv4reflect.cpp index 2bfd2bc401..20ea39d4e5 100644 --- a/src/qml/jsruntime/qv4reflect.cpp +++ b/src/qml/jsruntime/qv4reflect.cpp @@ -192,16 +192,11 @@ ReturnedValue Reflect::method_has(const FunctionObject *f, const Value *, const Value undef = Primitive::undefinedValue(); const Value *index = argc > 1 ? &argv[1] : &undef; - bool hasProperty = false; - uint n = index->asArrayIndex(); - if (n < UINT_MAX) { - (void) o->get(n, &hasProperty); - return Encode(hasProperty); - } - ScopedPropertyKey name(scope, index->toPropertyKey(scope.engine)); if (scope.engine->hasException) return false; + + bool hasProperty = false; (void) o->get(name, nullptr, &hasProperty); return Encode(hasProperty); } diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h index bf369c3999..2ff40a18df 100644 --- a/src/qml/jsruntime/qv4regexpobject_p.h +++ b/src/qml/jsruntime/qv4regexpobject_p.h @@ -129,11 +129,11 @@ struct RegExpObject: Object { void initProperties(); int lastIndex() const { - Q_ASSERT(Index_LastIndex == internalClass()->find(engine()->id_lastIndex()->identifier())); + Q_ASSERT(Index_LastIndex == internalClass()->find(engine()->id_lastIndex()->propertyKey())); return propertyData(Index_LastIndex)->toInt32(); } void setLastIndex(int index) { - Q_ASSERT(Index_LastIndex == internalClass()->find(engine()->id_lastIndex()->identifier())); + Q_ASSERT(Index_LastIndex == internalClass()->find(engine()->id_lastIndex()->propertyKey())); return setProperty(Index_LastIndex, Primitive::fromInt32(index)); } diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index 6969dd4eee..8a6b011aa2 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -329,10 +329,6 @@ bool Runtime::method_deleteProperty(ExecutionEngine *engine, const Value &base, return Encode::undefined(); Q_ASSERT(o); - uint n = index.asArrayIndex(); - if (n < UINT_MAX) - return o->deleteProperty(PropertyKey::fromArrayIndex(n)); - ScopedPropertyKey key(scope, index.toPropertyKey(engine)); if (engine->hasException) return false; @@ -451,10 +447,10 @@ ReturnedValue RuntimeHelpers::ordinaryToPrimitive(ExecutionEngine *engine, const String *meth1 = engine->id_toString(); String *meth2 = engine->id_valueOf(); - if (typeHint->identifier() == engine->id_number()->identifier()) { + if (typeHint->propertyKey() == engine->id_number()->propertyKey()) { qSwap(meth1, meth2); } else { - Q_ASSERT(typeHint->identifier() == engine->id_string()->identifier()); + Q_ASSERT(typeHint->propertyKey() == engine->id_string()->propertyKey()); } Scope scope(engine); @@ -1535,7 +1531,8 @@ ReturnedValue Runtime::method_createClass(ExecutionEngine *engine, int classInde return Encode::undefined(); ++computedNames; } else { - propertyName = PropertyKey::fromStringOrSymbol(unit->runtimeStrings[methods[i].name]); + name = unit->runtimeStrings[methods[i].name]; + propertyName = name->toPropertyKey(); } QV4::Function *f = unit->runtimeFunctions[methods[i].function]; Q_ASSERT(f); diff --git a/src/qml/jsruntime/qv4string.cpp b/src/qml/jsruntime/qv4string.cpp index ce5bc7f13e..7c1aef482a 100644 --- a/src/qml/jsruntime/qv4string.cpp +++ b/src/qml/jsruntime/qv4string.cpp @@ -166,7 +166,7 @@ uint String::toUInt(bool *ok) const return UINT_MAX; } -void String::makeIdentifierImpl() const +void String::createPropertyKeyImpl() const { if (!d()->text) d()->simplifyString(); @@ -251,11 +251,10 @@ void Heap::StringOrSymbol::createHashValue() const } PropertyKey StringOrSymbol::toPropertyKey() const { - uint index = asArrayIndex(); - if (index < UINT_MAX) - return PropertyKey::fromArrayIndex(index); - makeIdentifier(); - return identifier(); + if (d()->identifier.isValid()) + return d()->identifier; + createPropertyKey(); + return propertyKey(); } uint String::getLength(const Managed *m) diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h index 81cb54d9cc..65efbe31c2 100644 --- a/src/qml/jsruntime/qv4string_p.h +++ b/src/qml/jsruntime/qv4string_p.h @@ -173,13 +173,13 @@ struct Q_QML_PRIVATE_EXPORT StringOrSymbol : public Managed { IsStringOrSymbol = true }; - inline void makeIdentifier() const; - PropertyKey identifier() const { return d()->identifier; } - - uint asArrayIndex() const; - +private: + inline void createPropertyKey() const; +public: + PropertyKey propertyKey() const { Q_ASSERT(d()->identifier.isValid()); return d()->identifier; } PropertyKey toPropertyKey() const; + inline QString toQString() const { return d()->toQString(); } @@ -217,18 +217,10 @@ struct Q_QML_PRIVATE_EXPORT String : public StringOrSymbol { inline unsigned hashValue() const { return d()->hashValue(); } - uint asArrayIndex() const { - if (subtype() >= Heap::String::StringType_Unknown) - d()->createHashValue(); - Q_ASSERT(d()->subtype < Heap::String::StringType_Complex); - if (subtype() == Heap::String::StringType_ArrayIndex) - return d()->stringHash; - return UINT_MAX; - } uint toUInt(bool *ok) const; // slow path - Q_NEVER_INLINE void makeIdentifierImpl() const; + Q_NEVER_INLINE void createPropertyKeyImpl() const; static uint createHashValue(const QChar *ch, int length, uint *subtype) { @@ -313,18 +305,11 @@ struct ComplexString : String { }; inline -void StringOrSymbol::makeIdentifier() const { +void StringOrSymbol::createPropertyKey() const { if (d()->identifier.isValid()) return; Q_ASSERT(isString()); - static_cast<const String *>(this)->makeIdentifierImpl(); -} - -inline -uint StringOrSymbol::asArrayIndex() const { - if (isString()) - return static_cast<const String *>(this)->asArrayIndex(); - return UINT_MAX; + static_cast<const String *>(this)->createPropertyKeyImpl(); } template<> diff --git a/src/qml/jsruntime/qv4symbol.cpp b/src/qml/jsruntime/qv4symbol.cpp index 1204a716ab..c53cea36c6 100644 --- a/src/qml/jsruntime/qv4symbol.cpp +++ b/src/qml/jsruntime/qv4symbol.cpp @@ -97,7 +97,7 @@ ReturnedValue SymbolCtor::method_keyFor(const FunctionObject *f, const Value *, if (!argc || !argv[0].isSymbol()) return e->throwTypeError(QLatin1String("Symbol.keyFor: Argument is not a symbol.")); const Symbol &arg = static_cast<const Symbol &>(argv[0]); - Heap::Symbol *s = e->identifierTable->symbolForId(arg.identifier()); + Heap::Symbol *s = e->identifierTable->symbolForId(arg.propertyKey()); Q_ASSERT(!s || s == arg.d()); if (s) return e->newString(arg.toQString().mid((1)))->asReturnedValue(); diff --git a/src/qml/jsruntime/qv4value.cpp b/src/qml/jsruntime/qv4value.cpp index 934fb2fbaa..cbc153bb86 100644 --- a/src/qml/jsruntime/qv4value.cpp +++ b/src/qml/jsruntime/qv4value.cpp @@ -237,8 +237,7 @@ QV4::PropertyKey Value::toPropertyKey(ExecutionEngine *e) const if (isStringOrSymbol()) { Scope scope(e); ScopedStringOrSymbol s(scope, this); - s->makeIdentifier(); - return s->identifier(); + return s->toPropertyKey(); } Scope scope(e); ScopedValue v(scope, RuntimeHelpers::toPrimitive(*this, STRING_HINT)); @@ -247,8 +246,7 @@ QV4::PropertyKey Value::toPropertyKey(ExecutionEngine *e) const if (e->hasException) return PropertyKey::invalid(); ScopedStringOrSymbol s(scope, v); - s->makeIdentifier(); - return s->identifier(); + return s->toPropertyKey(); } #endif // V4_BOOTSTRAP diff --git a/src/qml/qml/qqmllistwrapper.cpp b/src/qml/qml/qqmllistwrapper.cpp index a6e0f5cc33..82eb08ddc9 100644 --- a/src/qml/qml/qqmllistwrapper.cpp +++ b/src/qml/qml/qqmllistwrapper.cpp @@ -121,7 +121,7 @@ ReturnedValue QmlListWrapper::get(const Managed *m, PropertyKey id, const Value *hasProperty = false; return Primitive::undefinedValue().asReturnedValue(); } else if (id.isString()) { - if (id == v4->id_length()->identifier() && !w->d()->object.isNull()) { + if (id == v4->id_length()->propertyKey() && !w->d()->object.isNull()) { quint32 count = w->d()->property().count ? w->d()->property().count(&w->d()->property()) : 0; return Primitive::fromUInt32(count).asReturnedValue(); } diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp index 2e5ce29f21..c6f85069c3 100644 --- a/src/qml/qml/qqmlxmlhttprequest.cpp +++ b/src/qml/qml/qqmlxmlhttprequest.cpp @@ -909,7 +909,7 @@ ReturnedValue NamedNodeMap::get(const Managed *m, PropertyKey id, const Value *r if (id.isSymbol()) return Object::get(m, id, receiver, hasProperty); - if (id == v4->id_length()->identifier()) + if (id == v4->id_length()->propertyKey()) return Primitive::fromInt32(r->d()->list().count()).asReturnedValue(); QString str = id.toQString(); @@ -949,7 +949,7 @@ ReturnedValue NodeList::get(const Managed *m, PropertyKey id, const Value *recei return Encode::undefined(); } - if (id == v4->id_length()->identifier()) + if (id == v4->id_length()->propertyKey()) return Primitive::fromInt32(r->d()->d->children.count()).asReturnedValue(); return Object::get(m, id, receiver, hasProperty); } diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp index 7f3b850e4e..3058ac2069 100644 --- a/src/qml/types/qqmldelegatemodel.cpp +++ b/src/qml/types/qqmldelegatemodel.cpp @@ -3413,7 +3413,7 @@ public: Q_ASSERT(m->as<QQmlDelegateModelGroupChangeArray>()); const QQmlDelegateModelGroupChangeArray *array = static_cast<const QQmlDelegateModelGroupChangeArray *>(m); - if (id == array->engine()->id_length()->identifier()) { + if (id == array->engine()->id_length()->propertyKey()) { if (hasProperty) *hasProperty = true; return QV4::Encode(array->count()); diff --git a/tests/auto/qml/ecmascripttests/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations index 144690f5f2..2a54cd1a4f 100644 --- a/tests/auto/qml/ecmascripttests/TestExpectations +++ b/tests/auto/qml/ecmascripttests/TestExpectations @@ -390,15 +390,6 @@ built-ins/Date/UTC/year-offset.js fails built-ins/Date/proto-from-ctor-realm-one.js fails built-ins/Date/proto-from-ctor-realm-two.js fails built-ins/Date/proto-from-ctor-realm-zero.js fails -built-ins/Date/prototype/Symbol.toPrimitive/hint-default-first-invalid.js fails -built-ins/Date/prototype/Symbol.toPrimitive/hint-default-first-non-callable.js fails -built-ins/Date/prototype/Symbol.toPrimitive/hint-default-first-valid.js fails -built-ins/Date/prototype/Symbol.toPrimitive/hint-number-first-invalid.js fails -built-ins/Date/prototype/Symbol.toPrimitive/hint-number-first-non-callable.js fails -built-ins/Date/prototype/Symbol.toPrimitive/hint-number-first-valid.js fails -built-ins/Date/prototype/Symbol.toPrimitive/hint-string-first-invalid.js fails -built-ins/Date/prototype/Symbol.toPrimitive/hint-string-first-non-callable.js fails -built-ins/Date/prototype/Symbol.toPrimitive/hint-string-first-valid.js fails built-ins/Date/prototype/toDateString/format.js fails built-ins/Date/prototype/toDateString/invalid-date.js fails built-ins/Date/prototype/toString/format.js fails |