Add some ECMAScript 6 Number and Math methods and properties
This adds the Number.EPSILON property, the Number.isFinite, Number.isNaN, and Math.sign methods introduced in ECMAScript 6. Change-Id: Ib16408a63c202a4ef30a14334f65ac3a1a13cfaf Reviewed-by: Michael Brasser <michael.brasser@live.com> Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
This commit is contained in:
parent
9e44c5594f
commit
7a0f3269b1
|
@ -231,6 +231,15 @@
|
|||
\li \l {Number::toLocaleString}{toLocaleString(locale, format, precision)}
|
||||
\endlist
|
||||
|
||||
\section2 The Number Object
|
||||
|
||||
\section3 Function Properties
|
||||
|
||||
\list
|
||||
\li isFinite(x) // ECMAScript 6: Added in Qt 5.8
|
||||
\li isNaN(x) // ECMAScript 6: Added in Qt 5.8
|
||||
\endlist
|
||||
|
||||
\section1 The Math Object
|
||||
|
||||
\section2 Value Properties
|
||||
|
@ -264,6 +273,7 @@
|
|||
\li pow(x, y)
|
||||
\li random()
|
||||
\li round(x)
|
||||
\li sign(x) // ECMAScript 6: Added in Qt 5.8
|
||||
\li sin(x)
|
||||
\li sqrt(x)
|
||||
\li tan(x)
|
||||
|
|
|
@ -80,6 +80,7 @@ Heap::MathObject::MathObject()
|
|||
m->defineDefaultProperty(QStringLiteral("pow"), QV4::MathObject::method_pow, 2);
|
||||
m->defineDefaultProperty(QStringLiteral("random"), QV4::MathObject::method_random, 0);
|
||||
m->defineDefaultProperty(QStringLiteral("round"), QV4::MathObject::method_round, 1);
|
||||
m->defineDefaultProperty(QStringLiteral("sign"), QV4::MathObject::method_sign, 1);
|
||||
m->defineDefaultProperty(QStringLiteral("sin"), QV4::MathObject::method_sin, 1);
|
||||
m->defineDefaultProperty(QStringLiteral("sqrt"), QV4::MathObject::method_sqrt, 1);
|
||||
m->defineDefaultProperty(QStringLiteral("tan"), QV4::MathObject::method_tan, 1);
|
||||
|
@ -299,6 +300,19 @@ ReturnedValue MathObject::method_round(CallContext *context)
|
|||
return Encode(v);
|
||||
}
|
||||
|
||||
ReturnedValue MathObject::method_sign(CallContext *context)
|
||||
{
|
||||
double v = context->argc() ? context->args()[0].toNumber() : qt_qnan();
|
||||
|
||||
if (std::isnan(v))
|
||||
return Encode(qt_qnan());
|
||||
|
||||
if (qIsNull(v))
|
||||
return v;
|
||||
|
||||
return Encode(std::signbit(v) ? -1 : 1);
|
||||
}
|
||||
|
||||
ReturnedValue MathObject::method_sin(CallContext *context)
|
||||
{
|
||||
double v = context->argc() ? context->args()[0].toNumber() : qt_qnan();
|
||||
|
|
|
@ -84,6 +84,7 @@ struct MathObject: Object
|
|||
static ReturnedValue method_pow(CallContext *context);
|
||||
static ReturnedValue method_random(CallContext *context);
|
||||
static ReturnedValue method_round(CallContext *context);
|
||||
static ReturnedValue method_sign(CallContext *context);
|
||||
static ReturnedValue method_sin(CallContext *context);
|
||||
static ReturnedValue method_sqrt(CallContext *context);
|
||||
static ReturnedValue method_tan(CallContext *context);
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include <QtCore/qmath.h>
|
||||
#include <QtCore/QDebug>
|
||||
#include <cassert>
|
||||
#include <limits>
|
||||
|
||||
using namespace QV4;
|
||||
|
||||
|
@ -99,12 +100,16 @@ void NumberPrototype::init(ExecutionEngine *engine, Object *ctor)
|
|||
ctor->defineReadonlyProperty(QStringLiteral("NEGATIVE_INFINITY"), Primitive::fromDouble(-qInf()));
|
||||
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()));
|
||||
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_INTEL(239)
|
||||
ctor->defineReadonlyProperty(QStringLiteral("MIN_VALUE"), Primitive::fromDouble(5e-324));
|
||||
QT_WARNING_POP
|
||||
|
||||
ctor->defineDefaultProperty(QStringLiteral("isFinite"), method_isFinite, 1);
|
||||
ctor->defineDefaultProperty(QStringLiteral("isNaN"), method_isNaN, 1);
|
||||
|
||||
defineDefaultProperty(QStringLiteral("constructor"), (o = ctor));
|
||||
defineDefaultProperty(engine->id_toString(), method_toString);
|
||||
defineDefaultProperty(QStringLiteral("toLocaleString"), method_toLocaleString);
|
||||
|
@ -134,6 +139,24 @@ inline double thisNumber(ExecutionContext *ctx)
|
|||
return n->value();
|
||||
}
|
||||
|
||||
ReturnedValue NumberPrototype::method_isFinite(CallContext *ctx)
|
||||
{
|
||||
if (!ctx->argc())
|
||||
return Encode(false);
|
||||
|
||||
double v = ctx->args()[0].toNumber();
|
||||
return Encode(!std::isnan(v) && !qt_is_inf(v));
|
||||
}
|
||||
|
||||
ReturnedValue NumberPrototype::method_isNaN(CallContext *ctx)
|
||||
{
|
||||
if (!ctx->argc())
|
||||
return Encode(false);
|
||||
|
||||
double v = ctx->args()[0].toNumber();
|
||||
return Encode(std::isnan(v));
|
||||
}
|
||||
|
||||
ReturnedValue NumberPrototype::method_toString(CallContext *ctx)
|
||||
{
|
||||
Scope scope(ctx);
|
||||
|
|
|
@ -87,6 +87,8 @@ struct NumberPrototype: NumberObject
|
|||
{
|
||||
void init(ExecutionEngine *engine, Object *ctor);
|
||||
|
||||
static ReturnedValue method_isFinite(CallContext *ctx);
|
||||
static ReturnedValue method_isNaN(CallContext *ctx);
|
||||
static ReturnedValue method_toString(CallContext *ctx);
|
||||
static ReturnedValue method_toLocaleString(CallContext *ctx);
|
||||
static ReturnedValue method_valueOf(CallContext *ctx);
|
||||
|
|
|
@ -1024,11 +1024,14 @@ void tst_QJSEngine::builtinFunctionNames_data()
|
|||
QTest::newRow("Math.pow") << QString("Math.pow") << QString("pow");
|
||||
QTest::newRow("Math.random") << QString("Math.random") << QString("random");
|
||||
QTest::newRow("Math.round") << QString("Math.round") << QString("round");
|
||||
QTest::newRow("Math.sign") << QString("Math.sign") << QString("sign");
|
||||
QTest::newRow("Math.sin") << QString("Math.sin") << QString("sin");
|
||||
QTest::newRow("Math.sqrt") << QString("Math.sqrt") << QString("sqrt");
|
||||
QTest::newRow("Math.tan") << QString("Math.tan") << QString("tan");
|
||||
|
||||
QTest::newRow("Number") << QString("Number") << QString("Number");
|
||||
QTest::newRow("Number.isFinite") << QString("Number.isFinite") << QString("isFinite");
|
||||
QTest::newRow("Number.isNaN") << QString("Number.isNaN") << QString("isNaN");
|
||||
QTest::newRow("Number.prototype.toString") << QString("Number.prototype.toString") << QString("toString");
|
||||
QTest::newRow("Number.prototype.toLocaleString") << QString("Number.prototype.toLocaleString") << QString("toLocaleString");
|
||||
QTest::newRow("Number.prototype.valueOf") << QString("Number.prototype.valueOf") << QString("valueOf");
|
||||
|
@ -1920,6 +1923,7 @@ void tst_QJSEngine::jsNumberClass()
|
|||
QVERIFY(ctor.property("NaN").isNumber());
|
||||
QVERIFY(ctor.property("NEGATIVE_INFINITY").isNumber());
|
||||
QVERIFY(ctor.property("POSITIVE_INFINITY").isNumber());
|
||||
QVERIFY(ctor.property("EPSILON").isNumber());
|
||||
}
|
||||
QCOMPARE(proto.toNumber(), qreal(0));
|
||||
QVERIFY(proto.property("constructor").strictlyEquals(ctor));
|
||||
|
@ -1958,6 +1962,50 @@ void tst_QJSEngine::jsNumberClass()
|
|||
QCOMPARE(ret.toNumber(), qreal(456));
|
||||
}
|
||||
|
||||
QVERIFY(ctor.property("isFinite").isCallable());
|
||||
{
|
||||
QJSValue ret = eng.evaluate("Number.isFinite()");
|
||||
QVERIFY(ret.isBool());
|
||||
QCOMPARE(ret.toBool(), false);
|
||||
}
|
||||
{
|
||||
QJSValue ret = eng.evaluate("Number.isFinite(NaN)");
|
||||
QVERIFY(ret.isBool());
|
||||
QCOMPARE(ret.toBool(), false);
|
||||
}
|
||||
{
|
||||
QJSValue ret = eng.evaluate("Number.isFinite(Infinity)");
|
||||
QVERIFY(ret.isBool());
|
||||
QCOMPARE(ret.toBool(), false);
|
||||
}
|
||||
{
|
||||
QJSValue ret = eng.evaluate("Number.isFinite(-Infinity)");
|
||||
QVERIFY(ret.isBool());
|
||||
QCOMPARE(ret.toBool(), false);
|
||||
}
|
||||
{
|
||||
QJSValue ret = eng.evaluate("Number.isFinite(123)");
|
||||
QVERIFY(ret.isBool());
|
||||
QCOMPARE(ret.toBool(), true);
|
||||
}
|
||||
|
||||
QVERIFY(ctor.property("isNaN").isCallable());
|
||||
{
|
||||
QJSValue ret = eng.evaluate("Number.isNaN()");
|
||||
QVERIFY(ret.isBool());
|
||||
QCOMPARE(ret.toBool(), false);
|
||||
}
|
||||
{
|
||||
QJSValue ret = eng.evaluate("Number.isNaN(NaN)");
|
||||
QVERIFY(ret.isBool());
|
||||
QCOMPARE(ret.toBool(), true);
|
||||
}
|
||||
{
|
||||
QJSValue ret = eng.evaluate("Number.isNaN(123)");
|
||||
QVERIFY(ret.isBool());
|
||||
QCOMPARE(ret.toBool(), false);
|
||||
}
|
||||
|
||||
QVERIFY(proto.property("toString").isCallable());
|
||||
{
|
||||
QJSValue ret = eng.evaluate("new Number(123).toString()");
|
||||
|
|
Loading…
Reference in New Issue