aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/jsruntime/qv4dateobject.cpp18
-rw-r--r--src/qml/jsruntime/qv4dateobject_p.h1
-rw-r--r--src/qml/jsruntime/qv4engine.cpp1
-rw-r--r--src/qml/jsruntime/qv4engine_p.h2
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp49
-rw-r--r--src/qml/jsruntime/qv4runtime_p.h1
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp10
-rw-r--r--tests/auto/qml/ecmascripttests/TestExpectations33
8 files changed, 68 insertions, 47 deletions
diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp
index e9a2056a61..092c36e52a 100644
--- a/src/qml/jsruntime/qv4dateobject.cpp
+++ b/src/qml/jsruntime/qv4dateobject.cpp
@@ -44,6 +44,7 @@
#include "qv4runtime_p.h"
#include "qv4string_p.h"
#include "qv4jscall_p.h"
+#include "qv4symbol_p.h"
#include <QtCore/QDebug>
#include <QtCore/QDateTime>
@@ -859,6 +860,7 @@ void DatePrototype::init(ExecutionEngine *engine, Object *ctor)
defineDefaultProperty(QStringLiteral("toISOString"), method_toISOString, 0);
defineDefaultProperty(QStringLiteral("toJSON"), method_toJSON, 1);
+ defineDefaultProperty(engine->symbol_toPrimitive(), method_symbolToPrimitive, 1, Attr_ReadOnly_ButConfigurable);
}
double DatePrototype::getThisDate(ExecutionEngine *v4, const Value *thisObject)
@@ -1515,6 +1517,22 @@ ReturnedValue DatePrototype::method_toJSON(const FunctionObject *b, const Value
return toIso->call(O, nullptr, 0);
}
+ReturnedValue DatePrototype::method_symbolToPrimitive(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
+{
+ ExecutionEngine *e = f->engine();
+ if (!thisObject->isObject() || !argc || !argv->isString())
+ return e->throwTypeError();
+
+ String *hint = argv->stringValue();
+ Identifier id = hint->identifier();
+ if (id == e->id_default()->identifier())
+ hint = e->id_string();
+ else if (id != e->id_string()->identifier() && id != e->id_number()->identifier())
+ return e->throwTypeError();
+
+ return RuntimeHelpers::ordinaryToPrimitive(e, static_cast<const Object *>(thisObject), hint);
+}
+
void DatePrototype::timezoneUpdated(ExecutionEngine *e)
{
e->localTZA = getLocalTZA();
diff --git a/src/qml/jsruntime/qv4dateobject_p.h b/src/qml/jsruntime/qv4dateobject_p.h
index 1ee514f599..0a5a3954d1 100644
--- a/src/qml/jsruntime/qv4dateobject_p.h
+++ b/src/qml/jsruntime/qv4dateobject_p.h
@@ -169,6 +169,7 @@ struct DatePrototype: Object
static ReturnedValue method_toUTCString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_toISOString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_toJSON(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_symbolToPrimitive(const FunctionObject *f, const Value *thisObject, const Value *, int);
static void timezoneUpdated(ExecutionEngine *e);
};
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index fbe9db7075..87132f64bb 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -240,6 +240,7 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine)
jsStrings[String_boolean] = newIdentifier(QStringLiteral("boolean"));
jsStrings[String_number] = newIdentifier(QStringLiteral("number"));
jsStrings[String_string] = newIdentifier(QStringLiteral("string"));
+ jsStrings[String_default] = newIdentifier(QStringLiteral("default"));
jsStrings[String_symbol] = newIdentifier(QStringLiteral("symbol"));
jsStrings[String_object] = newIdentifier(QStringLiteral("object"));
jsStrings[String_function] = newIdentifier(QStringLiteral("function"));
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index 9206fdc0bb..155383c55d 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -304,6 +304,7 @@ public:
String_boolean,
String_number,
String_string,
+ String_default,
String_symbol,
String_object,
String_function,
@@ -365,6 +366,7 @@ public:
String *id_boolean() const { return reinterpret_cast<String *>(jsStrings + String_boolean); }
String *id_number() const { return reinterpret_cast<String *>(jsStrings + String_number); }
String *id_string() const { return reinterpret_cast<String *>(jsStrings + String_string); }
+ String *id_default() const { return reinterpret_cast<String *>(jsStrings + String_default); }
String *id_symbol() const { return reinterpret_cast<String *>(jsStrings + String_symbol); }
String *id_object() const { return reinterpret_cast<String *>(jsStrings + String_object); }
String *id_function() const { return reinterpret_cast<String *>(jsStrings + String_function); }
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 6eff9c50db..3cc1943427 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -420,27 +420,59 @@ Heap::String *RuntimeHelpers::stringFromNumber(ExecutionEngine *engine, double n
ReturnedValue RuntimeHelpers::objectDefaultValue(const Object *object, int typeHint)
{
- if (typeHint == PREFERREDTYPE_HINT) {
- if (object->as<DateObject>())
- typeHint = STRING_HINT;
- else
- typeHint = NUMBER_HINT;
+ ExecutionEngine *engine = object->internalClass()->engine;
+ if (engine->hasException)
+ return Encode::undefined();
+
+ String *hint;
+ switch (typeHint) {
+ case STRING_HINT:
+ hint = engine->id_string();
+ break;
+ case NUMBER_HINT:
+ hint = engine->id_number();
+ break;
+ default:
+ hint = engine->id_default();
+ break;
}
- ExecutionEngine *engine = object->internalClass()->engine;
+ Scope scope(engine);
+ ScopedFunctionObject toPrimitive(scope, object->get(engine->symbol_toPrimitive()));
if (engine->hasException)
return Encode::undefined();
+ if (toPrimitive) {
+ ScopedValue result(scope, toPrimitive->call(object, hint, 1));
+ if (engine->hasException)
+ return Encode::undefined();
+ if (!result->isPrimitive())
+ return engine->throwTypeError();
+ return result->asReturnedValue();
+ }
+
+ if (hint == engine->id_default())
+ hint = engine->id_number();
+ return ordinaryToPrimitive(engine, object, hint);
+}
+
+
+ReturnedValue RuntimeHelpers::ordinaryToPrimitive(ExecutionEngine *engine, const Object *object, String *typeHint)
+{
+ Q_ASSERT(!engine->hasException);
String *meth1 = engine->id_toString();
String *meth2 = engine->id_valueOf();
- if (typeHint == NUMBER_HINT)
+ if (typeHint->identifier() == engine->id_number()->identifier()) {
qSwap(meth1, meth2);
+ } else {
+ Q_ASSERT(typeHint->identifier() == engine->id_string()->identifier());
+ }
Scope scope(engine);
ScopedValue result(scope);
- ScopedValue conv(scope, object->get(meth1));
+ ScopedValue conv(scope, object->get(meth1));
if (FunctionObject *o = conv->as<FunctionObject>()) {
result = o->call(object, nullptr, 0);
if (result->isPrimitive())
@@ -461,7 +493,6 @@ ReturnedValue RuntimeHelpers::objectDefaultValue(const Object *object, int typeH
}
-
Heap::Object *RuntimeHelpers::convertToObject(ExecutionEngine *engine, const Value &value)
{
Q_ASSERT(!value.isObject());
diff --git a/src/qml/jsruntime/qv4runtime_p.h b/src/qml/jsruntime/qv4runtime_p.h
index 3a26c23990..72af90d1dc 100644
--- a/src/qml/jsruntime/qv4runtime_p.h
+++ b/src/qml/jsruntime/qv4runtime_p.h
@@ -100,6 +100,7 @@ enum TypeHint {
struct Q_QML_PRIVATE_EXPORT RuntimeHelpers {
static ReturnedValue objectDefaultValue(const Object *object, int typeHint);
static ReturnedValue toPrimitive(const Value &value, TypeHint typeHint);
+ static ReturnedValue ordinaryToPrimitive(ExecutionEngine *engine, const Object *object, String *typeHint);
static double stringToNumber(const QString &s);
static Heap::String *stringFromNumber(ExecutionEngine *engine, double number);
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index d89d314942..bf07faca2a 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -398,13 +398,13 @@ static bool compareEqual(QV4::Value lhs, QV4::Value rhs)
Heap::Base *r = rhs.m();
Q_ASSERT(l);
Q_ASSERT(r);
- if (l->internalClass->vtable->isString == r->internalClass->vtable->isString)
+ if (l->internalClass->vtable->isStringOrSymbol == r->internalClass->vtable->isStringOrSymbol)
return static_cast<QV4::Managed &>(lhs).isEqualTo(&static_cast<QV4::Managed &>(rhs));
- if (l->internalClass->vtable->isString) {
+ if (l->internalClass->vtable->isStringOrSymbol) {
rhs = Primitive::fromReturnedValue(RuntimeHelpers::objectDefaultValue(&static_cast<QV4::Object &>(rhs), PREFERREDTYPE_HINT));
break;
} else {
- Q_ASSERT(r->internalClass->vtable->isString);
+ Q_ASSERT(r->internalClass->vtable->isStringOrSymbol);
lhs = Primitive::fromReturnedValue(RuntimeHelpers::objectDefaultValue(&static_cast<QV4::Object &>(lhs), PREFERREDTYPE_HINT));
break;
}
@@ -419,8 +419,8 @@ static bool compareEqual(QV4::Value lhs, QV4::Value rhs)
rhs = Primitive::fromDouble(rhs.int_32());
// fall through
default: // double
- if (lhs.m()->internalClass->vtable->isString)
- return RuntimeHelpers::toNumber(lhs) == rhs.doubleValue();
+ if (lhs.m()->internalClass->vtable->isStringOrSymbol)
+ return lhs.m()->internalClass->vtable->isString ? (RuntimeHelpers::toNumber(lhs) == rhs.doubleValue()) : false;
else
lhs = Primitive::fromReturnedValue(RuntimeHelpers::objectDefaultValue(&static_cast<QV4::Object &>(lhs), PREFERREDTYPE_HINT));
}
diff --git a/tests/auto/qml/ecmascripttests/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations
index 6724b90663..f5dbf20864 100644
--- a/tests/auto/qml/ecmascripttests/TestExpectations
+++ b/tests/auto/qml/ecmascripttests/TestExpectations
@@ -477,17 +477,12 @@ 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-invalid.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/Symbol.toPrimitive/length.js fails
-built-ins/Date/prototype/Symbol.toPrimitive/name.js fails
-built-ins/Date/prototype/Symbol.toPrimitive/prop-desc.js fails
-built-ins/Date/prototype/Symbol.toPrimitive/this-val-non-obj.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
@@ -497,13 +492,6 @@ built-ins/Date/prototype/toUTCString/day-names.js fails
built-ins/Date/prototype/toUTCString/format.js fails
built-ins/Date/prototype/toUTCString/month-names.js fails
built-ins/Date/subclassing.js fails
-built-ins/Date/value-symbol-to-prim-invocation.js fails
-built-ins/Date/value-symbol-to-prim-return-obj.js fails
-built-ins/Date/value-symbol-to-prim-return-prim.js fails
-built-ins/Date/value-to-primitive-call.js fails
-built-ins/Date/value-to-primitive-result-faulty.js fails
-built-ins/Date/value-to-primitive-result-non-string-prim.js fails
-built-ins/Date/value-to-primitive-result-string.js fails
built-ins/Error/proto-from-ctor-realm.js fails
built-ins/Error/prototype/S15.11.4_A2.js fails
built-ins/Function/call-bind-this-realm-undef.js fails
@@ -1974,13 +1962,9 @@ built-ins/SharedArrayBuffer/zero-length.js fails
built-ins/String/proto-from-ctor-realm.js fails
built-ins/String/prototype/endsWith/return-abrupt-from-searchstring-regexp-test.js fails
built-ins/String/prototype/includes/return-abrupt-from-searchstring-regexp-test.js fails
-built-ins/String/prototype/indexOf/position-tointeger-errors.js fails
built-ins/String/prototype/indexOf/position-tointeger-toprimitive.js fails
-built-ins/String/prototype/indexOf/position-tointeger-wrapped-values.js fails
built-ins/String/prototype/indexOf/position-tointeger.js fails
-built-ins/String/prototype/indexOf/searchstring-tostring-errors.js fails
built-ins/String/prototype/indexOf/searchstring-tostring-toprimitive.js fails
-built-ins/String/prototype/indexOf/searchstring-tostring-wrapped-values.js fails
built-ins/String/prototype/match/cstm-matcher-invocation.js fails
built-ins/String/prototype/replace/cstm-replace-invocation.js fails
built-ins/String/prototype/replace/this-value-not-obj-coercible.js fails
@@ -2479,8 +2463,6 @@ built-ins/TypedArrays/ctors/object-arg/as-generator-iterable-returns.js fails
built-ins/TypedArrays/ctors/object-arg/custom-proto-access-throws.js fails
built-ins/TypedArrays/ctors/object-arg/iterator-not-callable-throws.js fails
built-ins/TypedArrays/ctors/object-arg/proto-from-ctor-realm.js fails
-built-ins/TypedArrays/ctors/object-arg/throws-setting-obj-to-primitive-typeerror.js fails
-built-ins/TypedArrays/ctors/object-arg/throws-setting-obj-to-primitive.js fails
built-ins/TypedArrays/ctors/object-arg/use-custom-proto-if-object.js fails
built-ins/TypedArrays/ctors/object-arg/use-default-proto-if-custom-proto-is-not-object.js fails
built-ins/TypedArrays/ctors/typedarray-arg/custom-proto-access-throws.js fails
@@ -2764,13 +2746,7 @@ built-ins/eval/length-non-configurable.js fails
built-ins/global/global-object.js fails
built-ins/global/property-descriptor.js fails
built-ins/isFinite/toprimitive-not-callable-throws.js fails
-built-ins/isFinite/toprimitive-result-is-object-throws.js fails
-built-ins/isFinite/toprimitive-result-is-symbol-throws.js fails
-built-ins/isFinite/toprimitive-valid-result.js fails
built-ins/isNaN/toprimitive-not-callable-throws.js fails
-built-ins/isNaN/toprimitive-result-is-object-throws.js fails
-built-ins/isNaN/toprimitive-result-is-symbol-throws.js fails
-built-ins/isNaN/toprimitive-valid-result.js fails
language/arguments-object/cls-decl-gen-meth-args-trailing-comma-multiple.js fails
language/arguments-object/cls-decl-gen-meth-args-trailing-comma-null.js fails
language/arguments-object/cls-decl-gen-meth-args-trailing-comma-single-args.js fails
@@ -2901,11 +2877,6 @@ language/eval-code/indirect/var-env-global-lex-non-strict.js fails
language/eval-code/indirect/var-env-var-init-global-exstng.js strictFails
language/eval-code/indirect/var-env-var-init-global-new.js strictFails
language/eval-code/indirect/var-env-var-non-strict.js strictFails
-language/expressions/addition/coerce-symbol-to-prim-err.js fails
-language/expressions/addition/coerce-symbol-to-prim-invocation.js fails
-language/expressions/addition/coerce-symbol-to-prim-return-obj.js fails
-language/expressions/addition/coerce-symbol-to-prim-return-prim.js fails
-language/expressions/addition/get-symbol-to-prim-err.js fails
language/expressions/array/spread-err-mult-err-expr-throws.js fails
language/expressions/array/spread-err-mult-err-iter-get-value.js fails
language/expressions/array/spread-err-mult-err-itr-get-call.js fails
@@ -3996,10 +3967,6 @@ language/expressions/conditional/tco-cond.js strictFails
language/expressions/conditional/tco-pos.js strictFails
language/expressions/delete/11.4.1-5-a-28-s.js strictFails
language/expressions/delete/super-property.js fails
-language/expressions/equals/coerce-symbol-to-prim-invocation.js fails
-language/expressions/equals/coerce-symbol-to-prim-return-obj.js fails
-language/expressions/equals/coerce-symbol-to-prim-return-prim.js fails
-language/expressions/equals/to-prim-hint.js fails
language/expressions/exponentiation/applying-the-exp-operator_A7.js fails
language/expressions/exponentiation/applying-the-exp-operator_A8.js fails
language/expressions/function/arguments-with-arguments-fn.js sloppyFails