From 5ecc7e6a1c87ea33976b4c771af672bbe4042e58 Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Tue, 7 Apr 2020 18:06:44 +0100 Subject: LibJS: Add Number.isSafeInteger() --- Libraries/LibJS/Runtime/NumberConstructor.cpp | 20 +++++++++++++++++--- Libraries/LibJS/Runtime/NumberConstructor.h | 2 ++ Libraries/LibJS/Tests/Number.isSafeInteger.js | 26 ++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 Libraries/LibJS/Tests/Number.isSafeInteger.js (limited to 'Libraries/LibJS') diff --git a/Libraries/LibJS/Runtime/NumberConstructor.cpp b/Libraries/LibJS/Runtime/NumberConstructor.cpp index 21b6cc01ee..aeb0282514 100644 --- a/Libraries/LibJS/Runtime/NumberConstructor.cpp +++ b/Libraries/LibJS/Runtime/NumberConstructor.cpp @@ -30,15 +30,21 @@ #include #include +#define EPSILON pow(2, -52) +#define MAX_SAFE_INTEGER pow(2, 53) - 1 +#define MIN_SAFE_INTEGER -(pow(2, 53) - 1) + namespace JS { NumberConstructor::NumberConstructor() { + put_native_function("isSafeInteger", is_safe_integer, 1); + put("prototype", interpreter().number_prototype()); put("length", Value(1)); - put("EPSILON", Value(pow(2, -52))); - put("MAX_SAFE_INTEGER", Value(pow(2, 53) - 1)); - put("MIN_SAFE_INTEGER", Value(-(pow(2, 53) - 1))); + put("EPSILON", Value(EPSILON)); + put("MAX_SAFE_INTEGER", Value(MAX_SAFE_INTEGER)); + put("MIN_SAFE_INTEGER", Value(MIN_SAFE_INTEGER)); put("NEGATIVE_INFINITY", Value(-js_infinity().as_double())); put("POSITIVE_INFINITY", js_infinity()); put("NaN", js_nan()); @@ -65,4 +71,12 @@ Value NumberConstructor::construct(Interpreter& interpreter) return Value(interpreter.heap().allocate(number)); } +Value NumberConstructor::is_safe_integer(Interpreter& interpreter) +{ + if (!interpreter.argument(0).is_number()) + return Value(false); + auto value = interpreter.argument(0).to_number().as_double(); + return Value((int64_t)value == value && value >= MIN_SAFE_INTEGER && value <= MAX_SAFE_INTEGER); +} + } diff --git a/Libraries/LibJS/Runtime/NumberConstructor.h b/Libraries/LibJS/Runtime/NumberConstructor.h index 31bf3052a0..34d7b5d4ed 100644 --- a/Libraries/LibJS/Runtime/NumberConstructor.h +++ b/Libraries/LibJS/Runtime/NumberConstructor.h @@ -41,6 +41,8 @@ public: private: virtual bool has_constructor() const override { return true; } virtual const char* class_name() const override { return "NumberConstructor"; } + + static Value is_safe_integer(Interpreter&); }; } diff --git a/Libraries/LibJS/Tests/Number.isSafeInteger.js b/Libraries/LibJS/Tests/Number.isSafeInteger.js new file mode 100644 index 0000000000..ee7e2308e7 --- /dev/null +++ b/Libraries/LibJS/Tests/Number.isSafeInteger.js @@ -0,0 +1,26 @@ +try { + assert(Number.isSafeInteger.length === 1); + assert(Number.isSafeInteger(0) === true); + assert(Number.isSafeInteger(1) === true); + assert(Number.isSafeInteger(2.0) === true); + assert(Number.isSafeInteger(42) === true); + assert(Number.isSafeInteger(Number.MAX_SAFE_INTEGER) === true); + assert(Number.isSafeInteger(Number.MIN_SAFE_INTEGER) === true); + assert(Number.isSafeInteger() === false); + assert(Number.isSafeInteger("1") === false); + assert(Number.isSafeInteger(2.1) === false); + assert(Number.isSafeInteger(42.42) === false); + assert(Number.isSafeInteger("") === false); + assert(Number.isSafeInteger([]) === false); + assert(Number.isSafeInteger(null) === false); + assert(Number.isSafeInteger(undefined) === false); + assert(Number.isSafeInteger(NaN) === false); + assert(Number.isSafeInteger(Infinity) === false); + assert(Number.isSafeInteger(-Infinity) === false); + assert(Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 1) === false); + assert(Number.isSafeInteger(Number.MIN_SAFE_INTEGER - 1) === false); + + console.log("PASS"); +} catch (e) { + console.log("FAIL: " + e.message); +} -- cgit v1.2.3