diff options
-rw-r--r-- | src/qml/jsruntime/qv4objectproto.cpp | 8 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 14 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4value.cpp | 11 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4value_p.h | 7 | ||||
-rw-r--r-- | tests/auto/qml/ecmascripttests/TestExpectations | 6 |
5 files changed, 26 insertions, 20 deletions
diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp index 478e2e5915..fa9cae970d 100644 --- a/src/qml/jsruntime/qv4objectproto.cpp +++ b/src/qml/jsruntime/qv4objectproto.cpp @@ -163,7 +163,7 @@ ReturnedValue ObjectPrototype::method_getOwnPropertyDescriptor(const FunctionObj static_cast<ArgumentsObject *>(O.getPointer())->fullyCreate(); ScopedValue v(scope, argc > 1 ? argv[1] : Primitive::undefinedValue()); - ScopedStringOrSymbol name(scope, v->toStringOrSymbol(scope.engine)); + ScopedStringOrSymbol name(scope, v->toPropertyKey(scope.engine)); if (scope.engine->hasException) return QV4::Encode::undefined(); @@ -284,7 +284,7 @@ ReturnedValue ObjectPrototype::method_defineProperty(const FunctionObject *b, co return scope.engine->throwTypeError(); ScopedObject O(scope, argv[0]); - ScopedStringOrSymbol name(scope, (argc > 1 ? argv[1] : Primitive::undefinedValue()).toStringOrSymbol(scope.engine)); + ScopedStringOrSymbol name(scope, (argc > 1 ? argv[1] : Primitive::undefinedValue()).toPropertyKey(scope.engine)); if (scope.engine->hasException) return QV4::Encode::undefined(); @@ -584,7 +584,7 @@ ReturnedValue ObjectPrototype::method_valueOf(const FunctionObject *b, const Val ReturnedValue ObjectPrototype::method_hasOwnProperty(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc) { Scope scope(b); - ScopedStringOrSymbol P(scope, (argc ? argv[0] : Primitive::undefinedValue()).toStringOrSymbol(scope.engine)); + ScopedStringOrSymbol P(scope, (argc ? argv[0] : Primitive::undefinedValue()).toPropertyKey(scope.engine)); if (scope.engine->hasException) return QV4::Encode::undefined(); ScopedObject O(scope, thisObject->toObject(scope.engine)); @@ -618,7 +618,7 @@ ReturnedValue ObjectPrototype::method_isPrototypeOf(const FunctionObject *b, con ReturnedValue ObjectPrototype::method_propertyIsEnumerable(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc) { Scope scope(b); - ScopedStringOrSymbol p(scope, (argc ? argv[0] : Primitive::undefinedValue()).toStringOrSymbol(scope.engine)); + ScopedStringOrSymbol p(scope, (argc ? argv[0] : Primitive::undefinedValue()).toPropertyKey(scope.engine)); if (scope.engine->hasException) return QV4::Encode::undefined(); diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index 477ecb37e9..b712b40897 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -331,7 +331,9 @@ bool Runtime::method_deleteElement(ExecutionEngine *engine, const Value &base, c return o->deleteIndexedProperty(n); } - ScopedStringOrSymbol name(scope, index.toStringOrSymbol(engine)); + ScopedStringOrSymbol name(scope, index.toPropertyKey(engine)); + if (engine->hasException) + return false; return method_deleteMemberString(engine, base, name); } @@ -383,7 +385,7 @@ QV4::ReturnedValue Runtime::method_in(ExecutionEngine *engine, const Value &left if (!ro) return engine->throwTypeError(); Scope scope(engine); - ScopedStringOrSymbol s(scope, left.toStringOrSymbol(engine)); + ScopedStringOrSymbol s(scope, left.toPropertyKey(engine)); if (scope.hasException()) return Encode::undefined(); bool r = ro->hasProperty(s); @@ -647,7 +649,7 @@ static Q_NEVER_INLINE ReturnedValue getElementFallback(ExecutionEngine *engine, Q_ASSERT(!!o); // can't fail as null/undefined is covered above } - ScopedStringOrSymbol name(scope, index.toStringOrSymbol(engine)); + ScopedStringOrSymbol name(scope, index.toPropertyKey(engine)); if (scope.hasException()) return Encode::undefined(); return o->get(name); @@ -701,7 +703,9 @@ static Q_NEVER_INLINE bool setElementFallback(ExecutionEngine *engine, const Val return o->putIndexed(idx, value); } - ScopedStringOrSymbol name(scope, index.toStringOrSymbol(engine)); + ScopedStringOrSymbol name(scope, index.toPropertyKey(engine)); + if (engine->hasException) + return false; return o->put(name, value); } @@ -1213,7 +1217,7 @@ ReturnedValue Runtime::method_callElement(ExecutionEngine *engine, Value *base, ScopedValue thisObject(scope, base->toObject(engine)); base = thisObject; - ScopedStringOrSymbol str(scope, index.toStringOrSymbol(engine)); + ScopedStringOrSymbol str(scope, index.toPropertyKey(engine)); if (engine->hasException) return Encode::undefined(); diff --git a/src/qml/jsruntime/qv4value.cpp b/src/qml/jsruntime/qv4value.cpp index be406db325..9febd41a00 100644 --- a/src/qml/jsruntime/qv4value.cpp +++ b/src/qml/jsruntime/qv4value.cpp @@ -228,6 +228,17 @@ QString Value::toQString() const } } // switch } + +Heap::StringOrSymbol *Value::toPropertyKey(ExecutionEngine *e) const +{ + Scope scope(e); + ScopedValue v(scope, RuntimeHelpers::toPrimitive(*this, STRING_HINT)); + if (!v->isStringOrSymbol()) + v = v->toString(e); + if (e->hasException) + return nullptr; + return static_cast<Heap::StringOrSymbol *>(v->m()); +} #endif // V4_BOOTSTRAP bool Value::sameValue(Value other) const { diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h index af956e84e1..59a8adca8f 100644 --- a/src/qml/jsruntime/qv4value_p.h +++ b/src/qml/jsruntime/qv4value_p.h @@ -415,11 +415,8 @@ public: return reinterpret_cast<Heap::String *>(m()); return toString(e, *this); } - Heap::StringOrSymbol *toStringOrSymbol(ExecutionEngine *e) const { - if (isStringOrSymbol()) - return reinterpret_cast<Heap::StringOrSymbol *>(m()); - return reinterpret_cast<Heap::StringOrSymbol *>(toString(e, *this)); - } + Heap::StringOrSymbol *toPropertyKey(ExecutionEngine *e) const; + static Heap::String *toString(ExecutionEngine *e, Value val); Heap::Object *toObject(ExecutionEngine *e) const { if (isObject()) diff --git a/tests/auto/qml/ecmascripttests/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations index 45d05dcf0c..0c27620fcc 100644 --- a/tests/auto/qml/ecmascripttests/TestExpectations +++ b/tests/auto/qml/ecmascripttests/TestExpectations @@ -707,12 +707,6 @@ built-ins/Object/keys/proxy-keys.js fails built-ins/Object/preventExtensions/15.2.3.10-1-1.js fails built-ins/Object/preventExtensions/15.2.3.10-1-2.js fails built-ins/Object/proto-from-ctor.js fails -built-ins/Object/prototype/hasOwnProperty/symbol_property_toPrimitive.js fails -built-ins/Object/prototype/hasOwnProperty/symbol_property_toString.js fails -built-ins/Object/prototype/hasOwnProperty/symbol_property_valueOf.js fails -built-ins/Object/prototype/propertyIsEnumerable/symbol_property_toPrimitive.js fails -built-ins/Object/prototype/propertyIsEnumerable/symbol_property_toString.js fails -built-ins/Object/prototype/propertyIsEnumerable/symbol_property_valueOf.js fails built-ins/Object/prototype/setPrototypeOf-with-different-values.js fails built-ins/Object/prototype/setPrototypeOf-with-same-value.js fails built-ins/Object/prototype/toLocaleString/primitive_this_value_getter.js strictFails |