diff options
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 |