Number: Improve ES6 compatibility

[ChangeLog][QtQml] Number now contains the MAX_SAFE_INTEGER,
MIN_SAFE_INTEGER, isInteger and isSafeInteger properties from the ES6
specification.

All tests for the new functionality pass, except those that require
missing features (like Symbol).

While we're here, also fix up the length attributes of a few methods
(that test262 for ES6 checks).

Remaining failures in Number are now down to:
* Missing binary literal support
* Missing octal literal support
* missing Symbol support

... and there are still some "suspect" failures that may require
behavior changes in:

* toExponential
* toPrecision

Change-Id: I6c9418d2ff94929f5c96d63dde2faa316672e82b
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
Robin Burchell 2017-02-10 10:32:00 +01:00
parent f64fb98a28
commit 11ca664840
2 changed files with 55 additions and 3 deletions

View File

@ -102,6 +102,8 @@ void NumberPrototype::init(ExecutionEngine *engine, Object *ctor)
ctor->defineReadonlyProperty(QStringLiteral("POSITIVE_INFINITY"), Primitive::fromDouble(qInf()));
ctor->defineReadonlyProperty(QStringLiteral("MAX_VALUE"), Primitive::fromDouble(1.7976931348623158e+308));
ctor->defineReadonlyProperty(QStringLiteral("EPSILON"), Primitive::fromDouble(std::numeric_limits<double>::epsilon()));
ctor->defineReadonlyProperty(QStringLiteral("MAX_SAFE_INTEGER"), Primitive::fromDouble(9007199254740991));
ctor->defineReadonlyProperty(QStringLiteral("MIN_SAFE_INTEGER"), Primitive::fromDouble(-9007199254740991));
QT_WARNING_PUSH
QT_WARNING_DISABLE_INTEL(239)
@ -109,15 +111,17 @@ QT_WARNING_DISABLE_INTEL(239)
QT_WARNING_POP
ctor->defineDefaultProperty(QStringLiteral("isFinite"), method_isFinite, 1);
ctor->defineDefaultProperty(QStringLiteral("isInteger"), method_isInteger, 1);
ctor->defineDefaultProperty(QStringLiteral("isSafeInteger"), method_isSafeInteger, 1);
ctor->defineDefaultProperty(QStringLiteral("isNaN"), method_isNaN, 1);
defineDefaultProperty(QStringLiteral("constructor"), (o = ctor));
defineDefaultProperty(engine->id_toString(), method_toString);
defineDefaultProperty(engine->id_toString(), method_toString, 1);
defineDefaultProperty(QStringLiteral("toLocaleString"), method_toLocaleString);
defineDefaultProperty(engine->id_valueOf(), method_valueOf);
defineDefaultProperty(QStringLiteral("toFixed"), method_toFixed, 1);
defineDefaultProperty(QStringLiteral("toExponential"), method_toExponential);
defineDefaultProperty(QStringLiteral("toPrecision"), method_toPrecision);
defineDefaultProperty(QStringLiteral("toExponential"), method_toExponential, 1);
defineDefaultProperty(QStringLiteral("toPrecision"), method_toPrecision, 1);
}
inline ReturnedValue thisNumberValue(Scope &scope, CallData *callData)
@ -155,6 +159,52 @@ void NumberPrototype::method_isFinite(const BuiltinFunction *, Scope &scope, Cal
scope.result = Encode(!std::isnan(v) && !qt_is_inf(v));
}
void NumberPrototype::method_isInteger(const BuiltinFunction *, Scope &scope, CallData *callData)
{
if (!callData->argc) {
scope.result = Encode(false);
return;
}
const Value &v = callData->args[0];
if (!v.isNumber()) {
scope.result = Encode(false);
return;
}
double dv = v.toNumber();
if (std::isnan(dv) || qt_is_inf(dv)) {
scope.result = Encode(false);
return;
}
double iv = v.toInteger();
scope.result = Encode(dv == iv);
}
void NumberPrototype::method_isSafeInteger(const BuiltinFunction *, Scope &scope, CallData *callData)
{
if (!callData->argc) {
scope.result = Encode(false);
return;
}
const Value &v = callData->args[0];
if (!v.isNumber()) {
scope.result = Encode(false);
return;
}
double dv = v.toNumber();
if (std::isnan(dv) || qt_is_inf(dv)) {
scope.result = Encode(false);
return;
}
double iv = v.toInteger();
scope.result = Encode(dv == iv && std::fabs(iv) <= (2^53)-1);
}
void NumberPrototype::method_isNaN(const BuiltinFunction *, Scope &scope, CallData *callData)
{
if (!callData->argc) {

View File

@ -88,6 +88,8 @@ struct NumberPrototype: NumberObject
void init(ExecutionEngine *engine, Object *ctor);
static void method_isFinite(const BuiltinFunction *, Scope &scope, CallData *callData);
static void method_isInteger(const BuiltinFunction *, Scope &scope, CallData *callData);
static void method_isSafeInteger(const BuiltinFunction *, Scope &scope, CallData *callData);
static void method_isNaN(const BuiltinFunction *, Scope &scope, CallData *callData);
static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
static void method_toLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData);