diff --git a/src-input/builtins.yaml b/src-input/builtins.yaml index b9aff659..1df317dc 100644 --- a/src-input/builtins.yaml +++ b/src-input/builtins.yaml @@ -1522,7 +1522,68 @@ objects: type: double bytes: "fff0000000000000" # DBL_NEGATIVE_INFINITY attributes: "" + - key: "EPSILON" + value: + type: double + bytes: "3cb0000000000000" # 3ff0000000000001 - 3ff0000000000000 = 3cb0000000000000 + attributes: "" + es6: true + present_if: DUK_USE_ES6 + - key: "MAX_SAFE_INTEGER" + value: + # >>> struct.pack('>d', 9007199254740991.0).encode('hex') + # '433fffffffffffff' + type: double + bytes: "433fffffffffffff" + attributes: "" + es6: true + present_if: DUK_USE_ES6 + - key: "MIN_SAFE_INTEGER" + value: + # >>> struct.pack('>d', -9007199254740991.0).encode('hex') + # 'c33fffffffffffff' + type: double + bytes: "c33fffffffffffff" + attributes: "" + es6: true + present_if: DUK_USE_ES6 + - key: "isFinite" + value: + type: function + native: duk_bi_number_check_shared + length: 1 + magic: 0 + attributes: "wc" + es6: true + present_if: DUK_USE_ES6 + - key: "isInteger" + value: + type: function + native: duk_bi_number_check_shared + length: 1 + magic: 1 + attributes: "wc" + es6: true + present_if: DUK_USE_ES6 + - key: "isNaN" + value: + type: function + native: duk_bi_number_check_shared + length: 1 + magic: 2 + attributes: "wc" + es6: true + present_if: DUK_USE_ES6 + - key: "isSafeInteger" + value: + type: function + native: duk_bi_number_check_shared + length: 1 + magic: 3 + attributes: "wc" + es6: true + present_if: DUK_USE_ES6 - key: "parseInt" # Must map to the exactly same object as global parseInt() value: type: object diff --git a/src-input/duk_bi_number.c b/src-input/duk_bi_number.c index c687b056..c6788e95 100644 --- a/src-input/duk_bi_number.c +++ b/src-input/duk_bi_number.c @@ -237,4 +237,40 @@ DUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_precision(duk_hthread *thr) { return 1; } +/* + * ES2015 isFinite() etc + */ + +#if defined(DUK_USE_ES6) +DUK_INTERNAL duk_ret_t duk_bi_number_check_shared(duk_hthread *thr) { + duk_int_t magic; + duk_bool_t ret = 0; + + if (duk_is_number(thr, 0)) { + duk_double_t d; + + magic = duk_get_current_magic(thr); + d = duk_get_number(thr, 0); + + switch (magic) { + case 0: /* isFinite() */ + ret = duk_double_is_finite(d); + break; + case 1: /* isInteger() */ + ret = duk_double_is_integer(d); + break; + case 2: /* isNaN() */ + ret = duk_double_is_nan(d); + break; + default: /* isSafeInteger() */ + DUK_ASSERT(magic == 3); + ret = duk_double_is_safe_integer(d); + } + } + + duk_push_boolean(thr, ret); + return 1; +} +#endif /* DUK_USE_ES6 */ + #endif /* DUK_USE_NUMBER_BUILTIN */ diff --git a/src-input/duk_util.h b/src-input/duk_util.h index 8934fe59..2600dcce 100644 --- a/src-input/duk_util.h +++ b/src-input/duk_util.h @@ -560,5 +560,8 @@ DUK_INTERNAL_DECL duk_double_t duk_double_trunc_towards_zero(duk_double_t x); DUK_INTERNAL_DECL duk_bool_t duk_double_same_sign(duk_double_t x, duk_double_t y); DUK_INTERNAL_DECL duk_double_t duk_double_fmin(duk_double_t x, duk_double_t y); DUK_INTERNAL_DECL duk_double_t duk_double_fmax(duk_double_t x, duk_double_t y); +DUK_INTERNAL_DECL duk_bool_t duk_double_is_finite(duk_double_t x); +DUK_INTERNAL_DECL duk_bool_t duk_double_is_integer(duk_double_t x); +DUK_INTERNAL_DECL duk_bool_t duk_double_is_safe_integer(duk_double_t x); #endif /* DUK_UTIL_H_INCLUDED */ diff --git a/src-input/duk_util_misc.c b/src-input/duk_util_misc.c index aea3d009..01c019cf 100644 --- a/src-input/duk_util_misc.c +++ b/src-input/duk_util_misc.c @@ -403,3 +403,22 @@ DUK_INTERNAL duk_double_t duk_double_fmax(duk_double_t x, duk_double_t y) { */ return (x > y ? x : y); } + +DUK_INTERNAL duk_bool_t duk_double_is_finite(duk_double_t x) { + return !duk_double_is_nan_or_inf(x); +} + +DUK_INTERNAL duk_bool_t duk_double_is_integer(duk_double_t x) { + if (duk_double_is_nan_or_inf(x)) { + return 0; + } else { + return duk_js_tointeger_number(x) == x; + } +} + +DUK_INTERNAL duk_bool_t duk_double_is_safe_integer(duk_double_t x) { + /* >>> 2**53-1 + * 9007199254740991 + */ + return duk_double_is_integer(x) && DUK_FABS(x) <= 9007199254740991.0; +}