view release on metacpan or search on metacpan
lib/JavaScript/Embedded/C/lib/duk_config.h view on Meta::CPAN
#endif
#if !defined(DUK_DOUBLE_NAN)
#undef DUK_USE_COMPUTED_NAN
#if defined(NAN)
#define DUK_DOUBLE_NAN NAN
#elif !defined(DUK_F_VBCC) && !defined(DUK_F_MSVC) && !defined(DUK_F_BCC) && \
!defined(DUK_F_OLD_SOLARIS) && !defined(DUK_F_AIX)
#define DUK_DOUBLE_NAN (0.0 / 0.0)
#else
/* In VBCC (0.0 / 0.0) results in a warning and 0.0 instead of NaN.
* In MSVC (VS2010 Express) (0.0 / 0.0) results in a compile error.
* Use a computed NaN (initialized when a heap is created at the
* latest).
*/
#define DUK_USE_COMPUTED_NAN
#define DUK_DOUBLE_NAN duk_computed_nan
#endif
#endif
/* Many platforms are missing fpclassify() and friends, so use replacements
* if necessary. The replacement constants (FP_NAN etc) can be anything but
* match Linux constants now.
lib/JavaScript/Embedded/C/lib/duk_config.h view on Meta::CPAN
* regardless of compiler.
*/
#define DUK_F_USE_REPL_ALL
#elif defined(DUK_F_FREEBSD) && defined(DUK_F_CLANG)
/* Placeholder fix for (detection is wider than necessary):
* http://llvm.org/bugs/show_bug.cgi?id=17788
*/
#define DUK_F_USE_REPL_ALL
#elif defined(DUK_F_UCLIBC)
/* At least some uclibc versions have broken floating point math. For
* example, fpclassify() can incorrectly classify certain NaN formats.
* To be safe, use replacements.
*/
#define DUK_F_USE_REPL_ALL
#elif defined(DUK_F_AIX)
/* Older versions may be missing isnan(), etc. */
#define DUK_F_USE_REPL_ALL
#endif
#if defined(DUK_F_USE_REPL_ALL)
#define DUK_USE_REPL_FPCLASSIFY
lib/JavaScript/Embedded/C/lib/duk_config.h view on Meta::CPAN
#endif
/* Similar workarounds for atan2() semantics issues. MinGW issues are
* documented in test-bug-mingw-math-issues.js.
*/
#undef DUK_USE_ATAN2_WORKAROUNDS
#if defined(DUK_F_MINGW)
#define DUK_USE_ATAN2_WORKAROUNDS
#endif
/* Rely as little as possible on compiler behavior for NaN comparison,
* signed zero handling, etc. Currently never activated but may be needed
* for broken compilers.
*/
#undef DUK_USE_PARANOID_MATH
/* There was a curious bug where test-bi-date-canceling.js would fail e.g.
* on 64-bit Ubuntu, gcc-4.8.1, -m32, and no -std=c99. Some date computations
* using doubles would be optimized which then broke some corner case tests.
* The problem goes away by adding 'volatile' to the datetime computations.
* Not sure what the actual triggering conditions are, but using this on
lib/JavaScript/Embedded/C/lib/duk_source_meta.json view on Meta::CPAN
"plain": "object",
"base64": "b2JqZWN0",
"define": "DUK_STRIDX_LC_OBJECT"
},
{
"plain": "undefined",
"base64": "dW5kZWZpbmVk",
"define": "DUK_STRIDX_LC_UNDEFINED"
},
{
"plain": "NaN",
"base64": "TmFO",
"define": "DUK_STRIDX_NAN"
},
{
"plain": "Infinity",
"base64": "SW5maW5pdHk=",
"define": "DUK_STRIDX_INFINITY"
},
{
"plain": "-Infinity",
lib/JavaScript/Embedded/C/lib/duk_source_meta.json view on Meta::CPAN
"index",
"prototype",
"constructor",
"message",
"boolean",
"number",
"string",
"symbol",
"object",
"undefined",
"NaN",
"Infinity",
"-Infinity",
"-0",
",",
"\n ",
"[...]",
"Invalid Date",
"arguments",
"callee",
"caller",
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
*
* seeeeeee eeeeffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
* A B C D E F G H
*
* s sign bit
* eee... exponent field
* fff... fraction
*
* See http://en.wikipedia.org/wiki/Double_precision_floating-point_format.
*
* NaNs are represented as exponent 0x7ff and mantissa != 0. The NaN is a
* signaling NaN when the highest bit of the mantissa is zero, and a quiet
* NaN when the highest bit is set.
*
* At least three memory layouts are relevant here:
*
* A B C D E F G H Big endian (e.g. 68k) DUK_USE_DOUBLE_BE
* H G F E D C B A Little endian (e.g. x86) DUK_USE_DOUBLE_LE
* D C B A H G F E Mixed endian (e.g. ARM FPA) DUK_USE_DOUBLE_ME
*
* Legacy ARM (FPA) is a special case: ARM double values are in mixed
* endian format while ARM duk_uint64_t values are in standard little endian
* format (H G F E D C B A). When a double is read as a duk_uint64_t
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
* See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0056d/Bcfhgcgd.html.
*
* Indexes of various types (8-bit, 16-bit, 32-bit) in memory relative to
* the logical (big endian) order:
*
* byte order duk_uint8_t duk_uint16_t duk_uint32_t
* BE 01234567 0123 01
* LE 76543210 3210 10
* ME (ARM) 32107654 1032 01
*
* Some processors may alter NaN values in a floating point load+store.
* For instance, on X86 a FLD + FSTP may convert a signaling NaN to a
* quiet one. This is catastrophic when NaN space is used in packed
* duk_tval values. See: misc/clang_aliasing.c.
*/
#if !defined(DUK_DBLUNION_H_INCLUDED)
#define DUK_DBLUNION_H_INCLUDED
/*
* Union for accessing double parts, also serves as packed duk_tval
*/
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
do { \
(u)->ull[DUK_DBL_IDX_ULL0] = (duk_uint64_t) (v); \
} while (0)
#define DUK_DBLUNION_GET_UINT64(u) ((u)->ull[DUK_DBL_IDX_ULL0])
#endif
#define DUK_DBLUNION_SET_INT64(u, v) DUK_DBLUNION_SET_UINT64((u), (duk_uint64_t) (v))
#define DUK_DBLUNION_GET_INT64(u) ((duk_int64_t) DUK_DBLUNION_GET_UINT64((u)))
#endif /* DUK_USE_64BIT_OPS */
/*
* Double NaN manipulation macros related to NaN normalization needed when
* using the packed duk_tval representation. NaN normalization is necessary
* to keep double values compatible with the duk_tval format.
*
* When packed duk_tval is used, the NaN space is used to store pointers
* and other tagged values in addition to NaNs. Actual NaNs are normalized
* to a specific quiet NaN. The macros below are used by the implementation
* to check and normalize NaN values when they might be created. The macros
* are essentially NOPs when the non-packed duk_tval representation is used.
*
* A FULL check is exact and checks all bits. A NOTFULL check is used by
* the packed duk_tval and works correctly for all NaNs except those that
* begin with 0x7ff0. Since the 'normalized NaN' values used with packed
* duk_tval begin with 0x7ff8, the partial check is reliable when packed
* duk_tval is used. The 0x7ff8 prefix means the normalized NaN will be a
* quiet NaN regardless of its remaining lower bits.
*
* The ME variant below is specifically for ARM byte order, which has the
* feature that while doubles have a mixed byte order (32107654), unsigned
* long long values has a little endian byte order (76543210). When writing
* a logical double value through a ULL pointer, the 32-bit words need to be
* swapped; hence the #if defined()s below for ULL writes with DUK_USE_DOUBLE_ME.
* This is not full ARM support but suffices for some environments.
*/
#if defined(DUK_USE_64BIT_OPS)
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
#define DUK__DBLUNION_IS_POSZERO(u) (((u)->ui[DUK_DBL_IDX_UI0] == 0x00000000UL) && ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))
#define DUK__DBLUNION_IS_NEGZERO(u) (((u)->ui[DUK_DBL_IDX_UI0] == 0x80000000UL) && ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))
#endif /* DUK_USE_64BIT_OPS */
#define DUK__DBLUNION_SET_NAN_NOTFULL(u) \
do { \
(u)->us[DUK_DBL_IDX_US0] = 0x7ff8UL; \
} while (0)
#define DUK__DBLUNION_IS_NAN_NOTFULL(u) \
/* E == 0x7ff, topmost four bits of F != 0 => assume NaN */ \
((((u)->us[DUK_DBL_IDX_US0] & 0x7ff0UL) == 0x7ff0UL) && (((u)->us[DUK_DBL_IDX_US0] & 0x000fUL) != 0x0000UL))
#define DUK__DBLUNION_IS_NORMALIZED_NAN_NOTFULL(u) \
/* E == 0x7ff, F == 8 => normalized NaN */ \
((u)->us[DUK_DBL_IDX_US0] == 0x7ff8UL)
#define DUK__DBLUNION_NORMALIZE_NAN_CHECK_FULL(u) \
do { \
if (DUK__DBLUNION_IS_NAN_FULL((u))) { \
DUK__DBLUNION_SET_NAN_FULL((u)); \
} \
} while (0)
#define DUK__DBLUNION_NORMALIZE_NAN_CHECK_NOTFULL(u) \
do { \
/* Check must be full. */ \
if (DUK__DBLUNION_IS_NAN_FULL((u))) { \
DUK__DBLUNION_SET_NAN_NOTFULL((u)); \
} \
} while (0)
/* Concrete macros for NaN handling used by the implementation internals.
* Chosen so that they match the duk_tval representation: with a packed
* duk_tval, ensure NaNs are properly normalized; with a non-packed duk_tval
* these are essentially NOPs.
*/
#if defined(DUK_USE_PACKED_TVAL)
#define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u) DUK__DBLUNION_NORMALIZE_NAN_CHECK_FULL((u))
#define DUK_DBLUNION_IS_NAN(u) DUK__DBLUNION_IS_NAN_FULL((u))
#define DUK_DBLUNION_IS_NORMALIZED_NAN(u) DUK__DBLUNION_IS_NORMALIZED_NAN_FULL((u))
#define DUK_DBLUNION_SET_NAN(d) DUK__DBLUNION_SET_NAN_FULL((d))
#if 0
#define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u) DUK__DBLUNION_NORMALIZE_NAN_CHECK_NOTFULL((u))
#define DUK_DBLUNION_IS_NAN(u) DUK__DBLUNION_IS_NAN_NOTFULL((u))
#define DUK_DBLUNION_IS_NORMALIZED_NAN(u) DUK__DBLUNION_IS_NORMALIZED_NAN_NOTFULL((u))
#define DUK_DBLUNION_SET_NAN(d) DUK__DBLUNION_SET_NAN_NOTFULL((d))
#endif
#define DUK_DBLUNION_IS_NORMALIZED(u) \
(!DUK_DBLUNION_IS_NAN((u)) || /* either not a NaN */ \
DUK_DBLUNION_IS_NORMALIZED_NAN((u))) /* or is a normalized NaN */
#else /* DUK_USE_PACKED_TVAL */
#define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u) /* nop: no need to normalize */
#define DUK_DBLUNION_IS_NAN(u) DUK__DBLUNION_IS_NAN_FULL((u)) /* (DUK_ISNAN((u)->d)) */
#define DUK_DBLUNION_IS_NORMALIZED_NAN(u) DUK__DBLUNION_IS_NAN_FULL((u)) /* (DUK_ISNAN((u)->d)) */
#define DUK_DBLUNION_IS_NORMALIZED(u) 1 /* all doubles are considered normalized */
#define DUK_DBLUNION_SET_NAN(u) \
do { \
/* in non-packed representation we don't care about which NaN is used */ \
(u)->d = DUK_DOUBLE_NAN; \
} while (0)
#endif /* DUK_USE_PACKED_TVAL */
#define DUK_DBLUNION_IS_ANYINF(u) DUK__DBLUNION_IS_ANYINF((u))
#define DUK_DBLUNION_IS_POSINF(u) DUK__DBLUNION_IS_POSINF((u))
#define DUK_DBLUNION_IS_NEGINF(u) DUK__DBLUNION_IS_NEGINF((u))
#define DUK_DBLUNION_IS_ANYZERO(u) DUK__DBLUNION_IS_ANYZERO((u))
#define DUK_DBLUNION_IS_POSZERO(u) DUK__DBLUNION_IS_POSZERO((u))
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
/* use duk_double_union as duk_tval directly */
typedef union duk_double_union duk_tval;
typedef struct {
duk_uint16_t a;
duk_uint16_t b;
duk_uint16_t c;
duk_uint16_t d;
} duk_tval_unused;
/* tags */
#define DUK_TAG_NORMALIZED_NAN 0x7ff8UL /* the NaN variant we use */
/* avoid tag 0xfff0, no risk of confusion with negative infinity */
#define DUK_TAG_MIN 0xfff1UL
#if defined(DUK_USE_FASTINT)
#define DUK_TAG_FASTINT 0xfff1UL /* embed: integer value */
#endif
#define DUK_TAG_UNUSED 0xfff2UL /* marker; not actual tagged value */
#define DUK_TAG_UNDEFINED 0xfff3UL /* embed: nothing */
#define DUK_TAG_NULL 0xfff4UL /* embed: nothing */
#define DUK_TAG_BOOLEAN 0xfff5UL /* embed: 0 or 1 (false or true) */
/* DUK_TAG_NUMBER would logically go here, but it has multiple 'tags' */
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
#define DUK_TVAL_SET_NULL(tv) \
do { \
(tv)->us[DUK_DBL_IDX_US0] = (duk_uint16_t) DUK_TAG_NULL; \
} while (0)
#define DUK_TVAL_SET_BOOLEAN(tv, val) \
DUK_DBLUNION_SET_HIGH32((tv), (((duk_uint32_t) DUK_TAG_BOOLEAN) << 16) | ((duk_uint32_t) (val)))
#define DUK_TVAL_SET_NAN(tv) DUK_DBLUNION_SET_NAN_FULL((tv))
/* Assumes that caller has normalized NaNs, otherwise trouble ahead. */
#if defined(DUK_USE_FASTINT)
#define DUK_TVAL_SET_DOUBLE(tv, d) \
do { \
duk_double_t duk__dblval; \
duk__dblval = (d); \
DUK_ASSERT_DOUBLE_IS_NORMALIZED(duk__dblval); \
DUK_DBLUNION_SET_DOUBLE((tv), duk__dblval); \
} while (0)
#define DUK_TVAL_SET_I48(tv, i) DUK__TVAL_SET_I48((tv), (i))
#define DUK_TVAL_SET_I32(tv, i) DUK__TVAL_SET_I32((tv), (i))
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
#define DUK_TVAL_SET_BUFFER(tv, hptr) \
do { \
duk_tval *duk__tv; \
duk__tv = (tv); \
duk__tv->t = DUK_TAG_BUFFER; \
duk__tv->v.hbuffer = (hptr); \
} while (0)
#define DUK_TVAL_SET_NAN(tv) \
do { \
/* in non-packed representation we don't care about which NaN is used */ \
duk_tval *duk__tv; \
duk__tv = (tv); \
duk__tv->t = DUK_TAG_NUMBER; \
duk__tv->v.d = DUK_DOUBLE_NAN; \
} while (0)
#define DUK_TVAL_SET_TVAL(tv, x) \
do { \
*(tv) = *(x); \
} while (0)
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
#define DUK_HTHREAD_STRING_LC_STRING(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_STRING)
#define DUK_STRIDX_LC_SYMBOL 56 /* 'symbol' */
#define DUK_HEAP_STRING_LC_SYMBOL(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_SYMBOL)
#define DUK_HTHREAD_STRING_LC_SYMBOL(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_SYMBOL)
#define DUK_STRIDX_LC_OBJECT 57 /* 'object' */
#define DUK_HEAP_STRING_LC_OBJECT(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_OBJECT)
#define DUK_HTHREAD_STRING_LC_OBJECT(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_OBJECT)
#define DUK_STRIDX_LC_UNDEFINED 58 /* 'undefined' */
#define DUK_HEAP_STRING_LC_UNDEFINED(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_UNDEFINED)
#define DUK_HTHREAD_STRING_LC_UNDEFINED(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_UNDEFINED)
#define DUK_STRIDX_NAN 59 /* 'NaN' */
#define DUK_HEAP_STRING_NAN(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_NAN)
#define DUK_HTHREAD_STRING_NAN(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_NAN)
#define DUK_STRIDX_INFINITY 60 /* 'Infinity' */
#define DUK_HEAP_STRING_INFINITY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INFINITY)
#define DUK_HTHREAD_STRING_INFINITY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INFINITY)
#define DUK_STRIDX_MINUS_INFINITY 61 /* '-Infinity' */
#define DUK_HEAP_STRING_MINUS_INFINITY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_MINUS_INFINITY)
#define DUK_HTHREAD_STRING_MINUS_INFINITY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_MINUS_INFINITY)
#define DUK_STRIDX_MINUS_ZERO 62 /* '-0' */
#define DUK_HEAP_STRING_MINUS_ZERO(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_MINUS_ZERO)
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
/* .buffer reference to an ArrayBuffer, may be NULL. */
duk_hobject *buf_prop;
/* Slice and accessor information.
*
* Because the underlying buffer may be dynamic, these may be
* invalidated by the buffer being modified so that both offset
* and length should be validated before every access. Behavior
* when the underlying buffer has changed doesn't need to be clean:
* virtual 'length' doesn't need to be affected, reads can return
* zero/NaN, and writes can be ignored.
*
* Note that a data pointer cannot be precomputed because 'buf' may
* be dynamic and its pointer unstable.
*/
duk_uint_t offset; /* byte offset to buf */
duk_uint_t length; /* byte index limit for element access, exclusive */
duk_uint8_t shift; /* element size shift:
* 0 = u8/i8
* 1 = u16/i16
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
DUK_LOCAL duk_int_t duk__api_coerce_d2i(duk_hthread *thr, duk_idx_t idx, duk_int_t def_value, duk_bool_t require) {
duk_tval *tv;
duk_small_int_t c;
duk_double_t d;
tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
/*
* Special cases like NaN and +/- Infinity are handled explicitly
* because a plain C coercion from double to int handles these cases
* in undesirable ways. For instance, NaN may coerce to INT_MIN
* (not zero), and INT_MAX + 1 may coerce to INT_MIN (not INT_MAX).
*
* This double-to-int coercion differs from ToInteger() because it
* has a finite range (ToInteger() allows e.g. +/- Infinity). It
* also differs from ToInt32() because the INT_MIN/INT_MAX clamping
* depends on the size of the int type on the platform. In particular,
* on platforms with a 64-bit int type, the full range is allowed.
*/
#if defined(DUK_USE_FASTINT)
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
DUK_CTX_ASSERT_VALID(thr);
tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
#if defined(DUK_USE_FASTINT)
if (DUK_TVAL_IS_FASTINT(tv)) {
ret.d = (duk_double_t) DUK_TVAL_GET_FASTINT(tv); /* XXX: cast trick */
} else
#endif
if (DUK_TVAL_IS_DOUBLE(tv)) {
/* When using packed duk_tval, number must be in NaN-normalized form
* for it to be a duk_tval, so no need to normalize. NOP for unpacked
* duk_tval.
*/
ret.d = DUK_TVAL_GET_DOUBLE(tv);
DUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&ret));
} else {
ret.d = def_value;
/* Default value (including NaN) may not be normalized. */
}
return ret.d;
}
DUK_EXTERNAL duk_double_t duk_get_number(duk_hthread *thr, duk_idx_t idx) {
DUK_ASSERT_API_ENTRY(thr);
return duk__get_number_raw(thr, idx, DUK_DOUBLE_NAN); /* default: NaN */
}
DUK_EXTERNAL duk_double_t duk_get_number_default(duk_hthread *thr, duk_idx_t idx, duk_double_t def_value) {
DUK_ASSERT_API_ENTRY(thr);
return duk__get_number_raw(thr, idx, def_value);
}
DUK_EXTERNAL duk_double_t duk_require_number(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
duk_double_union ret;
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
if (DUK_UNLIKELY(!DUK_TVAL_IS_NUMBER(tv))) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "number", DUK_STR_NOT_NUMBER);
DUK_WO_NORETURN(return 0.0;);
}
ret.d = DUK_TVAL_GET_NUMBER(tv);
/* When using packed duk_tval, number must be in NaN-normalized form
* for it to be a duk_tval, so no need to normalize. NOP for unpacked
* duk_tval.
*/
DUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&ret));
return ret.d;
}
DUK_EXTERNAL duk_double_t duk_opt_number(duk_hthread *thr, duk_idx_t idx, duk_double_t def_value) {
DUK_ASSERT_API_ENTRY(thr);
if (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {
/* User provided default is not NaN normalized. */
return def_value;
}
return duk_require_number(thr, idx);
}
DUK_EXTERNAL duk_int_t duk_get_int(duk_hthread *thr, duk_idx_t idx) {
DUK_ASSERT_API_ENTRY(thr);
return (duk_int_t) duk__api_coerce_d2i(thr, idx, 0 /*def_value*/, 0 /*require*/);
}
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
* a shorter and faster algorithm by inspecting IEEE representation
* directly.
*/
d = duk_to_number(thr, idx);
if (d <= 0.0) {
return 0;
} else if (d >= 255) {
return 255;
} else if (DUK_ISNAN(d)) {
/* Avoid NaN-to-integer coercion as it is compiler specific. */
return 0;
}
t = d - DUK_FLOOR(d);
if (duk_double_equals(t, 0.5)) {
/* Exact halfway, round to even. */
ret = (duk_uint8_t) d;
ret = (ret + 1) & 0xfe; /* Example: d=3.5, t=0.5 -> ret = (3 + 1) & 0xfe = 4 & 0xfe = 4
* Example: d=4.5, t=0.5 -> ret = (4 + 1) & 0xfe = 5 & 0xfe = 4
*/
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
/* XXX: shorter version for unpacked representation? */
tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
return DUK_TVAL_IS_NUMBER(tv);
}
DUK_EXTERNAL duk_bool_t duk_is_nan(duk_hthread *thr, duk_idx_t idx) {
/* XXX: This will now return false for non-numbers, even though they would
* coerce to NaN (as a general rule). In particular, duk_get_number()
* returns a NaN for non-numbers, so should this function also return
* true for non-numbers?
*/
duk_tval *tv;
DUK_ASSERT_API_ENTRY(thr);
tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
DUK_EXTERNAL void duk_push_false(duk_hthread *thr) {
duk_tval *tv_slot;
DUK_ASSERT_API_ENTRY(thr);
DUK__CHECK_SPACE();
tv_slot = thr->valstack_top++;
DUK_TVAL_SET_BOOLEAN_FALSE(tv_slot);
}
/* normalize NaN which may not match our canonical internal NaN */
DUK_EXTERNAL void duk_push_number(duk_hthread *thr, duk_double_t val) {
duk_tval *tv_slot;
duk_double_union du;
DUK_ASSERT_API_ENTRY(thr);
DUK__CHECK_SPACE();
du.d = val;
DUK_DBLUNION_NORMALIZE_NAN_CHECK(&du);
tv_slot = thr->valstack_top++;
DUK_TVAL_SET_NUMBER(tv_slot, du.d);
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
* not a number. ES2015 provides a concrete description:
* http://www.ecma-international.org/ecma-262/6.0/#sec-sortcompare.
*/
d = duk_to_number_m1(thr);
if (d < 0.0) {
ret = -1;
} else if (d > 0.0) {
ret = 1;
} else {
/* Because NaN compares to false, NaN is handled here
* without an explicit check above.
*/
ret = 0;
}
duk_pop_nodecref_unsafe(thr);
DUK_DDD(DUK_DDDPRINT("-> result %ld (from comparefn, after coercion)", (long) ret));
return ret;
}
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
}
}
return 1;
fail_neutered:
fail_field_length:
fail_bounds:
if (no_assert) {
/* Node.js return value for noAssert out-of-bounds reads is
* usually (but not always) NaN. Return NaN consistently.
*/
duk_push_nan(thr);
return 1;
}
DUK_DCERROR_RANGE_INVALID_ARGS(thr);
}
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
/* XXX: split into separate functions for each field type? */
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
i_step = -1;
i_end = 0;
} else {
/* Write in little endian */
i = -1; /* one i_step added at top of loop */
i_step = 1;
i_end = field_bytelen - 1;
}
/* XXX: The duk_to_number() cast followed by integer coercion
* is platform specific so NaN, +/- Infinity, and out-of-bounds
* values result in platform specific output now.
* See: test-bi-nodejs-buffer-proto-varint-special.js
*/
#if defined(DUK_USE_64BIT_OPS)
tmp = (duk_int64_t) duk_to_number(thr, 0);
p = (duk_uint8_t *) (buf + offset);
do {
i += i_step;
DUK_ASSERT(i >= 0 && i < field_bytelen);
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
use_float = duk_double_equals((duk_double_t) d_float, d);
if (use_float) {
p = enc_ctx->ptr;
*p++ = 0xfaU;
DUK_RAW_WRITEINC_FLOAT_BE(p, d_float);
enc_ctx->ptr = p;
return;
}
}
/* Special handling for NaN and Inf which we want to encode as
* half-floats. They share the same (maximum) exponent.
*/
if (expt == 1024) {
DUK_ASSERT(DUK_ISNAN(d) || DUK_ISINF(d));
p = enc_ctx->ptr;
*p++ = 0xf9U;
if (DUK_ISNAN(d)) {
/* Shortest NaN encoding is using a half-float. Lose the
* exact NaN bits in the process. IEEE double would be
* 7ff8 0000 0000 0000, i.e. a quiet NaN in most architectures
* (https://en.wikipedia.org/wiki/NaN#Encoding). The
* equivalent half float is 7e00.
*/
*p++ = 0x7eU;
} else {
/* Shortest +/- Infinity encoding is using a half-float. */
if (DUK_SIGNBIT(d)) {
*p++ = 0xfcU;
} else {
*p++ = 0x7cU;
}
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
DUK_RAW_WRITEINC_DOUBLE_BE(p, d);
enc_ctx->ptr = p;
}
DUK_LOCAL void duk__cbor_encode_double(duk_cbor_encode_context *enc_ctx, double d) {
duk_uint8_t *p;
double d_floor;
/* Integers and floating point values of all types are conceptually
* equivalent in CBOR. Try to always choose the shortest encoding
* which is not always immediately obvious. For example, NaN and Inf
* can be most compactly represented as a half-float (assuming NaN
* bits are not preserved), and 0x1'0000'0000 as a single precision
* float. Shortest forms in preference order (prefer integer over
* float when equal length):
*
* uint 1 byte [0,23] (not -0)
* sint 1 byte [-24,-1]
* uint+1 2 bytes [24,255]
* sint+1 2 bytes [-256,-25]
* uint+2 3 bytes [256,65535]
* sint+2 3 bytes [-65536,-257]
* half-float 3 bytes -0, NaN, +/- Infinity, range [-65504,65504]
* uint+4 5 bytes [65536,4294967295]
* sint+4 5 bytes [-4294967296,-258]
* float 5 bytes range [-(1 - 2^(-24)) * 2^128, (1 - 2^(-24)) * 2^128]
* uint+8 9 bytes [4294967296,18446744073709551615]
* sint+8 9 bytes [-18446744073709551616,-4294967297]
* double 9 bytes
*
* For whole numbers (compatible with integers):
* - 1-byte or 2-byte uint/sint representation is preferred for
* [-256,255].
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
* preferred encoding is always an integer uint/sint.
* - For integers above 32 bits the situation is more complicated.
* Half-floats are never useful for them because of their limited
* range, but IEEE single precision floats (5 bytes encoded) can
* represent some integers between the 32-bit and 64-bit ranges
* which require 9 bytes as a uint/sint.
*
* For floating point values not compatible with integers, the
* preferred encoding is quite clear:
* - For +Inf/-Inf use half-float.
* - For NaN use a half-float, assuming NaN bits ("payload") is
* not worth preserving. Duktape doesn't in general guarantee
* preservation of the NaN payload so using a half-float seems
* consistent with that.
* - For remaining values, prefer the shortest form which doesn't
* lose any precision. For normal half-floats and single precision
* floats this is simple: just check exponent and mantissa bits
* using a fixed mask. For denormal half-floats and single
* precision floats the check is a bit more complicated: a normal
* IEEE double can sometimes be represented as a denormal
* half-float or single precision float.
*
* https://en.wikipedia.org/wiki/Half-precision_floating-point_format#IEEE_754_half-precision_binary_floating-point_format:_binary16
*/
/* Caller must ensure space. */
DUK_ASSERT(duk__cbor_get_reserve(enc_ctx) >= 1 + 8);
/* Most important path is integers. The floor() test will be true
* for Inf too (but not NaN).
*/
d_floor = DUK_FLOOR(d); /* identity if d is +/- 0.0, NaN, or +/- Infinity */
if (DUK_LIKELY(duk_double_equals(d_floor, d) != 0)) {
DUK_ASSERT(!DUK_ISNAN(d)); /* NaN == NaN compares false. */
if (DUK_SIGNBIT(d)) {
if (d >= -4294967296.0) {
d = -1.0 - d;
if (d >= 0.0) {
DUK_ASSERT(d >= 0.0);
duk__cbor_encode_uint32(enc_ctx, duk__cbor_double_to_uint32(d), 0x20U);
return;
}
/* Input was negative zero, d == -1.0 < 0.0.
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
u.uc[5] = (duk_uint8_t) ((u16 << 2) & 0xffU); /* Mask is really 0xfcU */
duk_dblunion_little_to_host(&u);
res = u.d - 0.00006103515625; /* 2^(-14) */
if (u16 & 0x8000U) {
res = -res;
}
return res;
}
} else if (expt == 16) {
/* +/- Inf or NaN. */
if ((u16 & 0x03ffU) == 0) {
u.uc[7] = (inp[0] & 0x80U) + 0x7fU;
u.uc[6] = 0xf0U;
} else {
/* Create a 'quiet NaN' with highest
* bit set (there are some platforms
* where the NaN payload convention is
* the opposite). Keep sign.
*/
u.uc[7] = (inp[0] & 0x80U) + 0x7fU;
u.uc[6] = 0xf8U;
}
} else {
/* Normal. */
tmp = (inp[0] & 0x80U) ? 0x80000000UL : 0UL;
tmp += (duk_uint_t) (expt + 1023) << 20;
tmp += (duk_uint_t) (inp[0] & 0x03U) << 18;
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
/* Given a (year, month, day-within-month) triple, compute day number.
* The input triple is un-normalized and may contain non-finite values.
*/
DUK_LOCAL duk_double_t duk__make_day(duk_double_t year, duk_double_t month, duk_double_t day) {
duk_int_t day_num;
duk_bool_t is_leap;
duk_small_int_t i, n;
/* Assume that year, month, day are all coerced to whole numbers.
* They may also be NaN or infinity, in which case this function
* must return NaN or infinity to ensure time value becomes NaN.
* If 'day' is NaN, the final return will end up returning a NaN,
* so it doesn't need to be checked here.
*/
if (!DUK_ISFINITE(year) || !DUK_ISFINITE(month)) {
return DUK_DOUBLE_NAN;
}
year += DUK_FLOOR(month / 12.0);
month = DUK_FMOD(month, 12.0);
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
month += 12.0;
}
/* The algorithm in E5.1 Section 15.9.1.12 normalizes month, but
* does not normalize the day-of-month (nor check whether or not
* it is finite) because it's not necessary for finding the day
* number which matches the (year,month) pair.
*
* We assume that duk__day_from_year() is exact here.
*
* Without an explicit infinity / NaN check in the beginning,
* day_num would be a bogus integer here.
*
* It's possible for 'year' to be out of integer range here.
* If so, we need to return NaN without integer overflow.
* This fixes test-bug-setyear-overflow.js.
*/
if (!duk_bi_date_year_in_valid_range(year)) {
DUK_DD(DUK_DDPRINT("year not in ecmascript valid range, avoid integer overflow: %lf", (double) year));
return DUK_DOUBLE_NAN;
}
day_num = duk__day_from_year((duk_int_t) year);
is_leap = duk_bi_date_is_leap_year((duk_int_t) year);
n = (duk_small_int_t) month;
for (i = 0; i < n; i++) {
day_num += duk__days_in_month[i];
if (i == 1 && is_leap) {
day_num++;
}
}
/* If 'day' is NaN, returns NaN. */
return (duk_double_t) day_num + day;
}
/* Split time value into parts. The time value may contain fractions (it may
* come from duk_time_to_components() API call) which are truncated. Possible
* local time adjustment has already been applied when reading the time value.
*/
DUK_INTERNAL void duk_bi_date_timeval_to_parts(duk_double_t d, duk_int_t *parts, duk_double_t *dparts, duk_small_uint_t flags) {
duk_double_t d1, d2;
duk_int_t t1, t2;
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
duk_double_t tmp_time;
duk_double_t tmp_day;
duk_double_t d;
#endif
duk_small_uint_t i;
duk_int_t tzoff, tzoffprev1, tzoffprev2;
/* Expects 'this' at top of stack on entry. */
/* Coerce all finite parts with ToInteger(). ToInteger() must not
* be called for NaN/Infinity because it will convert e.g. NaN to
* zero. If ToInteger() has already been called, this has no side
* effects and is idempotent.
*
* Don't read dparts[DUK_DATE_IDX_WEEKDAY]; it will cause Valgrind
* issues if the value is uninitialized.
*/
for (i = 0; i <= DUK_DATE_IDX_MILLISECOND; i++) {
/* SCANBUILD: scan-build complains here about assigned value
* being garbage or undefined. This is correct but operating
* on undefined values has no ill effect and is ignored by the
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
* have 'd' which is a time value computed from local parts, so
* it is off by the UTC-to-local time offset which we don't know
* yet. The current solution for computing the UTC-to-local
* time offset is to iterate a few times and detect a fixed
* point or a two-cycle loop (or a sanity iteration limit),
* see test-bi-date-local-parts.js and test-bi-date-tzoffset-basic-fi.js.
*
* E5.1 Section 15.9.1.9:
* UTC(t) = t - LocalTZA - DaylightSavingTA(t - LocalTZA)
*
* For NaN/inf, DUK_USE_DATE_GET_LOCAL_TZOFFSET() returns 0.
*/
#if 0
/* Old solution: don't iterate, incorrect */
tzoff = DUK_USE_DATE_GET_LOCAL_TZOFFSET(d);
DUK_DDD(DUK_DDDPRINT("tzoffset w/o iteration, tzoff=%ld", (long) tzoff));
d -= tzoff * 1000L;
DUK_UNREF(tzoffprev1);
DUK_UNREF(tzoffprev2);
#endif
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
if (tzoffprev1 > tzoff) {
tzoff = tzoffprev1;
}
break;
}
}
DUK_DDD(DUK_DDDPRINT("tzoffset iteration, tzoff=%ld", (long) tzoff));
d -= tzoff * 1000L;
}
/* TimeClip(), which also handles Infinity -> NaN conversion */
d = duk__timeclip(d);
return d;
}
/*
* API oriented helpers
*/
/* Push 'this' binding, check that it is a Date object; then push the
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
if (DUK_ISNAN(d)) {
if (flags & DUK_DATE_FLAG_NAN_TO_ZERO) {
d = 0.0;
}
if (flags & DUK_DATE_FLAG_NAN_TO_RANGE_ERROR) {
DUK_ERROR_RANGE(thr, "Invalid Date");
DUK_WO_NORETURN(return 0.0;);
}
}
/* if no NaN handling flag, may still be NaN here, but not Inf */
DUK_ASSERT(!DUK_ISINF(d));
if (flags & DUK_DATE_FLAG_LOCALTIME) {
/* Note: DST adjustment is determined using UTC time.
* If 'd' is NaN, tzoffset will be 0.
*/
tzoffset = DUK_USE_DATE_GET_LOCAL_TZOFFSET(d); /* seconds */
d += tzoffset * 1000L;
}
if (out_tzoffset) {
*out_tzoffset = tzoffset;
}
/* [ ... this ] */
return d;
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
duk_small_uint_t idx_first, idx;
duk_small_uint_t i;
nargs = duk_get_top(thr);
d = duk__push_this_get_timeval(thr, flags_and_maxnargs);
DUK_ASSERT(DUK_ISFINITE(d) || DUK_ISNAN(d));
if (DUK_ISFINITE(d)) {
duk_bi_date_timeval_to_parts(d, parts, dparts, flags_and_maxnargs);
} else {
/* NaN timevalue: we need to coerce the arguments, but
* the resulting internal timestamp needs to remain NaN.
* This works but is not pretty: parts and dparts will
* be partially uninitialized, but we only write to them.
*/
}
/*
* Determining which datetime components to overwrite based on
* stack arguments is a bit complicated, but important to factor
* out from setters themselves for compactness.
*
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
dparts[idx] -= 1.0;
}
}
/* Leaves new timevalue on stack top and returns 1, which is correct
* for part setters.
*/
if (DUK_ISFINITE(d)) {
return duk__set_this_timeval_from_dparts(thr, dparts, flags_and_maxnargs);
} else {
/* Internal timevalue is already NaN, so don't touch it. */
duk_push_nan(thr);
return 1;
}
}
/* Apply ToNumber() to specified index; if ToInteger(val) in [0,99], add
* 1900 and replace value at idx_val.
*/
DUK_LOCAL void duk__twodigit_year_fixup(duk_hthread *thr, duk_idx_t idx_val) {
duk_double_t d;
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
/* called as a normal function: return new Date().toString() */
duk_to_string(thr, -1);
}
return 1;
} else if (nargs == 1) {
const char *str;
duk_to_primitive(thr, 0, DUK_HINT_NONE);
str = duk_get_string_notsymbol(thr, 0);
if (str) {
duk__parse_string(thr, str);
duk_replace(thr, 0); /* may be NaN */
}
d = duk__timeclip(duk_to_number(thr, 0)); /* symbols fail here */
duk_push_number(thr, d);
duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W);
return 1;
}
duk__set_parts_from_args(thr, dparts, nargs);
/* Parts are in local time, convert when setting. */
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
DUK_INTERNAL duk_ret_t duk_bi_date_constructor_parse(duk_hthread *thr) {
return duk__parse_string(thr, duk_to_string(thr, 0));
}
DUK_INTERNAL duk_ret_t duk_bi_date_constructor_utc(duk_hthread *thr) {
duk_idx_t nargs = duk_get_top(thr);
duk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];
duk_double_t d;
/* Behavior for nargs < 2 is implementation dependent: currently we'll
* set a NaN time value (matching V8 behavior) in this case.
*/
if (nargs < 2) {
duk_push_nan(thr);
} else {
duk__set_parts_from_args(thr, dparts, nargs);
d = duk_bi_date_get_timeval_from_dparts(dparts, 0 /*flags*/);
duk_push_number(thr, d);
}
return 1;
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_TO_ISO_STRING);
duk_dup_m2(thr); /* -> [ O toIsoString O ] */
duk_call_method(thr, 0);
return 1;
}
/*
* Getters.
*
* Implementing getters is quite easy. The internal time value is either
* NaN, or represents milliseconds (without fractions) from Jan 1, 1970.
* The internal time value can be converted to integer parts, and each
* part will be normalized and will fit into a 32-bit signed integer.
*
* A shared native helper to provide all getters. Magic value contains
* a set of flags and also packs the date component index argument. The
* helper provides:
*
* getFullYear()
* getUTCFullYear()
* getMonth()
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
* setUTCDate()
* setMonth()
* setUTCMonth()
* setFullYear()
* setUTCFullYear()
* setYear()
*
* Notes:
*
* - Date.prototype.setYear() (Section B addition): special year check
* is omitted. NaN / Infinity will just flow through and ultimately
* result in a NaN internal time value.
*
* - Date.prototype.setYear() does not have optional arguments for
* setting month and day-in-month (like setFullYear()), but we indicate
* 'maxnargs' to be 3 to get the year written to the correct component
* index in duk__set_part_helper(). The function has nargs == 1, so only
* the year will be set regardless of actual argument count.
*/
DUK_INTERNAL duk_ret_t duk_bi_date_prototype_set_shared(duk_hthread *thr) {
duk_small_uint_t flags_and_maxnargs = duk__date_get_indirect_magic(thr);
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
/* Get local time offset (in seconds) for a certain (UTC) instant 'd'. */
DUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_gmtime(duk_double_t d) {
time_t t, t1, t2;
duk_int_t parts[DUK_DATE_IDX_NUM_PARTS];
duk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];
struct tm tms[2];
#if defined(DUK_USE_DATE_TZO_GMTIME)
struct tm *tm_ptr;
#endif
/* For NaN/inf, the return value doesn't matter. */
if (!DUK_ISFINITE(d)) {
return 0;
}
/* If not within ECMAScript range, some integer time calculations
* won't work correctly (and some asserts will fail), so bail out
* if so. This fixes test-bug-date-insane-setyear.js. There is
* a +/- 24h leeway in this range check to avoid a test262 corner
* case documented in test-bug-date-timeval-edges.js.
*/
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
/* [ ... buf ] */
return;
syntax_error:
duk__json_dec_syntax_error(js_ctx);
DUK_UNREACHABLE();
}
#endif /* DUK_USE_JX */
/* Parse a number, other than NaN or +/- Infinity */
DUK_LOCAL void duk__json_dec_number(duk_json_dec_ctx *js_ctx) {
duk_hthread *thr = js_ctx->thr;
const duk_uint8_t *p_start;
const duk_uint8_t *p;
duk_uint8_t x;
duk_small_uint_t s2n_flags;
DUK_DDD(DUK_DDDPRINT("parse_number"));
p_start = js_ctx->p;
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));
DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));
/* XXX: Stack discipline is annoying, could be changed in numconv. */
duk_push_tval(js_ctx->thr, tv);
duk__json_enc_double(js_ctx);
duk_pop(js_ctx->thr);
#if 0
/* Could also rely on native sprintf(), but it will handle
* values like NaN, Infinity, -0, exponent notation etc in
* a JSON-incompatible way.
*/
duk_double_t d;
char buf[64];
DUK_ASSERT(DUK_TVAL_IS_DOUBLE(tv));
d = DUK_TVAL_GET_DOUBLE(tv);
DUK_SPRINTF(buf, "%lg", d);
DUK__EMIT_CSTR(js_ctx, buf);
#endif
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
}
if (duk_is_number(thr, idx_space)) {
duk_small_int_t nspace;
/* spaces[] must be static to allow initializer with old compilers like BCC */
static const char spaces[10] = {
DUK_ASC_SPACE, DUK_ASC_SPACE, DUK_ASC_SPACE, DUK_ASC_SPACE, DUK_ASC_SPACE,
DUK_ASC_SPACE, DUK_ASC_SPACE, DUK_ASC_SPACE, DUK_ASC_SPACE, DUK_ASC_SPACE
}; /* XXX: helper */
/* ToInteger() coercion; NaN -> 0, infinities are clamped to 0 and 10 */
nspace = (duk_small_int_t) duk_to_int_clamped(thr, idx_space, 0 /*minval*/, 10 /*maxval*/);
DUK_ASSERT(nspace >= 0 && nspace <= 10);
duk_push_lstring(thr, spaces, (duk_size_t) nspace);
js_ctx->h_gap = duk_known_hstring(thr, -1);
DUK_ASSERT(js_ctx->h_gap != NULL);
} else if (duk_is_string_notsymbol(thr, idx_space)) {
duk_dup(thr, idx_space);
duk_substring(thr, -1, 0, 10); /* clamp to 10 chars */
js_ctx->h_gap = duk_known_hstring(thr, -1);
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
typedef double (*duk__two_arg_func)(double, double);
DUK_LOCAL duk_ret_t duk__math_minmax(duk_hthread *thr, duk_double_t initial, duk__two_arg_func min_max) {
duk_idx_t n = duk_get_top(thr);
duk_idx_t i;
duk_double_t res = initial;
duk_double_t t;
/*
* Note: fmax() does not match the E5 semantics. E5 requires
* that if -any- input to Math.max() is a NaN, the result is a
* NaN. fmax() will return a NaN only if -both- inputs are NaN.
* Same applies to fmin().
*
* Note: every input value must be coerced with ToNumber(), even
* if we know the result will be a NaN anyway: ToNumber() may have
* side effects for which even order of evaluation matters.
*/
for (i = 0; i < n; i++) {
t = duk_to_number(thr, i);
if (DUK_FPCLASSIFY(t) == DUK_FP_NAN || DUK_FPCLASSIFY(res) == DUK_FP_NAN) {
/* Note: not normalized, but duk_push_number() will normalize */
res = (duk_double_t) DUK_DOUBLE_NAN;
} else {
res = (duk_double_t) min_max(res, (double) t);
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
}
#if defined(DUK_USE_ES6)
DUK_INTERNAL duk_ret_t duk_bi_math_object_hypot(duk_hthread *thr) {
/*
* E6 Section 20.2.2.18: Math.hypot
*
* - If no arguments are passed, the result is +0.
* - If any argument is +inf, the result is +inf.
* - If any argument is -inf, the result is +inf.
* - If no argument is +inf or -inf, and any argument is NaN, the result is
* NaN.
* - If all arguments are either +0 or -0, the result is +0.
*/
duk_idx_t nargs;
duk_idx_t i;
duk_bool_t found_nan;
duk_double_t max;
duk_double_t sum, summand;
duk_double_t comp, prelim;
duk_double_t t;
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
}
#endif /* DUK_USE_ES6 */
#if defined(DUK_USE_ES6)
DUK_INTERNAL duk_ret_t duk_bi_math_object_sign(duk_hthread *thr) {
duk_double_t d;
d = duk_to_number(thr, 0);
if (duk_double_is_nan(d)) {
DUK_ASSERT(duk_is_nan(thr, -1));
return 1; /* NaN input -> return NaN */
}
if (duk_double_equals(d, 0.0)) {
/* Zero sign kept, i.e. -0 -> -0, +0 -> +0. */
return 1;
}
duk_push_int(thr, (d > 0.0 ? 1 : -1));
return 1;
}
#endif /* DUK_USE_ES6 */
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
done:
return duk_get_number(thr, -1);
}
DUK_INTERNAL duk_ret_t duk_bi_number_constructor(duk_hthread *thr) {
duk_idx_t nargs;
duk_hobject *h_this;
/*
* The Number constructor uses ToNumber(arg) for number coercion
* (coercing an undefined argument to NaN). However, if the
* argument is not given at all, +0 must be used instead. To do
* this, a vararg function is used.
*/
nargs = duk_get_top(thr);
if (nargs == 0) {
duk_push_int(thr, 0);
}
duk_to_number(thr, 0);
duk_set_top(thr, 1);
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
/*
* E5 Section 15.7.2.1 requires that the constructed object
* must have the original Number.prototype as its internal
* prototype. However, since Number.prototype is non-writable
* and non-configurable, this doesn't have to be enforced here:
* The default object (bound to 'this') is OK, though we have
* to change its class.
*
* Internal value set to ToNumber(arg) or +0; if no arg given,
* ToNumber(undefined) = NaN, so special treatment is needed
* (above). String internal value is immutable.
*/
/* XXX: helper */
duk_push_this(thr);
h_this = duk_known_hobject(thr, -1);
DUK_HOBJECT_SET_CLASS_NUMBER(h_this, DUK_HOBJECT_CLASS_NUMBER);
DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_this) == thr->builtins[DUK_BIDX_NUMBER_PROTOTYPE]);
DUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(h_this) == DUK_HOBJECT_CLASS_NUMBER);
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
}
prec = (duk_small_int_t) duk_to_int_check_range(thr, 0, 1, 21);
n2s_flags = DUK_N2S_FLAG_FIXED_FORMAT | DUK_N2S_FLAG_NO_ZERO_PAD;
duk_numconv_stringify(thr, 10 /*radix*/, prec /*digits*/, n2s_flags /*flags*/);
return 1;
use_to_string:
/* Used when precision is undefined; also used for NaN (-> "NaN"),
* and +/- infinity (-> "Infinity", "-Infinity").
*/
DUK_ASSERT_TOP(thr, 2);
duk_to_string(thr, -1);
return 1;
}
/*
* ES2015 isFinite() etc
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
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;
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
0 /*min(incl)*/,
(duk_int_t) DUK_HSTRING_GET_CHARLEN(h) - 1 /*max(incl)*/,
&clamped /*out_clamped*/);
#if defined(DUK_USE_ES6)
magic = duk_get_current_magic(thr);
#else
DUK_ASSERT(duk_get_current_magic(thr) == 0);
magic = 0;
#endif
if (clamped) {
/* For out-of-bounds indices .charCodeAt() returns NaN and
* .codePointAt() returns undefined.
*/
if (magic != 0) {
return 0;
}
duk_push_nan(thr);
} else {
DUK_ASSERT(pos >= 0);
cp = (duk_uint32_t) duk_hstring_char_code_at_raw(thr, h, (duk_uint_t) pos, (duk_bool_t) magic /*surrogate_aware*/);
duk_push_u32(thr, cp);
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
h_this = duk_push_this_coercible_to_string(thr);
DUK_ASSERT(h_this != NULL);
clen_this = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h_this);
h_search = duk_to_hstring(thr, 0);
DUK_ASSERT(h_search != NULL);
duk_to_number(thr, 1);
if (duk_is_nan(thr, 1) && is_lastindexof) {
/* indexOf: NaN should cause pos to be zero.
* lastIndexOf: NaN should cause pos to be +Infinity
* (and later be clamped to len).
*/
cpos = clen_this;
} else {
cpos = duk_to_int_clamped(thr, 1, 0, clen_this);
}
cpos = duk__str_search_shared(thr, h_this, h_search, cpos, is_lastindexof /*backwards*/);
duk_push_int(thr, cpos);
return 1;
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
}
#endif /* DUK_USE_EXEC_REGCONST_OPTIMIZE */
/*
* Computed values (e.g. INFINITY)
*/
#if defined(DUK_USE_COMPUTED_NAN)
do {
/* Workaround for some exotic platforms where NAN is missing
* and the expression (0.0 / 0.0) does NOT result in a NaN.
* Such platforms use the global 'duk_computed_nan' which must
* be initialized at runtime. Use 'volatile' to ensure that
* the compiler will actually do the computation and not try
* to do constant folding which might result in the original
* problem.
*/
volatile double dbl1 = 0.0;
volatile double dbl2 = 0.0;
duk_computed_nan = dbl1 / dbl2;
} while (0);
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
duk_double_union du;
duk_small_uint_t i;
for (i = 0; i < 8; i++) {
/* Encoding endianness must match target memory layout,
* build scripts and genbuiltins.py must ensure this.
*/
du.uc[i] = (duk_uint8_t) duk_bd_decode(bd, 8);
}
duk_push_number(thr, du.d); /* push operation normalizes NaNs */
}
DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
duk_bitdecoder_ctx bd_ctx;
duk_bitdecoder_ctx *bd = &bd_ctx; /* convenience */
duk_hobject *h;
duk_small_uint_t i, j;
DUK_D(DUK_DPRINT("INITBUILTINS BEGIN: DUK_NUM_BUILTINS=%d, DUK_NUM_BUILTINS_ALL=%d",
(int) DUK_NUM_BUILTINS,
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
* - test-bug-mingw-math-issues.js
*/
if (DUK_ISINF(d2)) {
if (DUK_ISINF(d1)) {
return DUK_DOUBLE_NAN;
} else {
return d1;
}
} else if (duk_double_equals(d1, 0.0)) {
/* d1 +/-0 is returned as is (preserving sign) except when
* d2 is zero or NaN.
*/
if (duk_double_equals(d2, 0.0) || DUK_ISNAN(d2)) {
return DUK_DOUBLE_NAN;
} else {
return d1;
}
}
#else
/* Some ISO C assumptions. */
DUK_ASSERT(duk_double_equals(DUK_FMOD(1.0, DUK_DOUBLE_INFINITY), 1.0));
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
#endif
return (duk_double_t) DUK_FMOD((double) d1, (double) d2);
}
/* Shared helper for Math.pow() and exponentiation operator. */
DUK_INTERNAL double duk_js_arith_pow(double x, double y) {
/* The ANSI C pow() semantics differ from ECMAScript.
*
* E.g. when x==1 and y is +/- infinite, the ECMAScript required
* result is NaN, while at least Linux pow() returns 1.
*/
duk_small_int_t cx, cy, sx;
DUK_UNREF(cx);
DUK_UNREF(sx);
cy = (duk_small_int_t) DUK_FPCLASSIFY(y);
if (cy == DUK_FP_NAN) {
goto ret_nan;
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
/* Math.pow(-0,y) where y<0 should be:
* - -Infinity if y<0 and an odd integer
* - Infinity if y<0 but not an odd integer
* NetBSD pow() returns -Infinity for all finite y<0. The
* if-clause also catches y == -Infinity (which works even
* without the fix).
*/
/* fmod() return value has same sign as input (negative) so
* the result here will be in the range ]-2,0], -1 indicates
* odd. If x is -Infinity, NaN is returned and the odd check
* always concludes "not odd" which results in desired outcome.
*/
double tmp = DUK_FMOD(y, 2);
if (tmp == -1.0) {
return -DUK_DOUBLE_INFINITY;
} else {
/* Not odd, or y == -Infinity */
return DUK_DOUBLE_INFINITY;
}
}
} else if (cx == DUK_FP_NAN) {
if (duk_double_equals(y, 0.0)) {
/* NaN ** +/- 0 should always be 1, but is NaN on
* at least some Cygwin/MinGW versions.
*/
return 1.0;
}
}
#else
/* Some ISO C assumptions. */
DUK_ASSERT(duk_double_equals(DUK_POW(DUK_DOUBLE_NAN, 0.0), 1.0));
DUK_ASSERT(DUK_ISINF(DUK_POW(0.0, -1.0)) && DUK_SIGNBIT(DUK_POW(0.0, -1.0)) == 0);
DUK_ASSERT(DUK_ISINF(DUK_POW(-0.0, -2.0)) && DUK_SIGNBIT(DUK_POW(-0.0, -2.0)) == 0);
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
}
#endif /* DUK_USE_FASTINT */
if (DUK_TVAL_IS_NUMBER(tv_x) && DUK_TVAL_IS_NUMBER(tv_y)) {
#if !defined(DUK_USE_EXEC_PREFER_SIZE)
duk_tval *tv_z;
#endif
du.d = DUK_TVAL_GET_NUMBER(tv_x) + DUK_TVAL_GET_NUMBER(tv_y);
#if defined(DUK_USE_EXEC_PREFER_SIZE)
duk_push_number(thr, du.d); /* will NaN normalize result */
duk_replace(thr, (duk_idx_t) idx_z);
#else /* DUK_USE_EXEC_PREFER_SIZE */
DUK_DBLUNION_NORMALIZE_NAN_CHECK(&du);
DUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));
tv_z = thr->valstack_bottom + idx_z;
DUK_TVAL_SET_NUMBER_UPDREF(thr, tv_z, du.d); /* side effects */
#endif /* DUK_USE_EXEC_PREFER_SIZE */
return;
}
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
d1 = duk_to_number_m2(thr);
d2 = duk_to_number_m1(thr);
DUK_ASSERT(duk_is_number(thr, -2));
DUK_ASSERT(duk_is_number(thr, -1));
DUK_ASSERT_DOUBLE_IS_NORMALIZED(d1);
DUK_ASSERT_DOUBLE_IS_NORMALIZED(d2);
du.d = d1 + d2;
duk_pop_2_unsafe(thr);
duk_push_number(thr, du.d); /* will NaN normalize result */
}
duk_replace(thr, (duk_idx_t) idx_z); /* side effects */
}
DUK_LOCAL DUK_EXEC_ALWAYS_INLINE_PERF void duk__vm_arith_binary_op(duk_hthread *thr,
duk_tval *tv_x,
duk_tval *tv_y,
duk_uint_fast_t idx_z,
duk_small_uint_fast_t opcode) {
/*
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
}
#endif
default: {
DUK_UNREACHABLE();
du.d = DUK_DOUBLE_NAN; /* should not happen */
break;
}
}
#if defined(DUK_USE_EXEC_PREFER_SIZE)
duk_push_number(thr, du.d); /* will NaN normalize result */
duk_replace(thr, (duk_idx_t) idx_z);
#else /* DUK_USE_EXEC_PREFER_SIZE */
/* important to use normalized NaN with 8-byte tagged types */
DUK_DBLUNION_NORMALIZE_NAN_CHECK(&du);
DUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));
tv_z = thr->valstack_bottom + idx_z;
DUK_TVAL_SET_NUMBER_UPDREF(thr, tv_z, du.d); /* side effects */
#endif /* DUK_USE_EXEC_PREFER_SIZE */
}
DUK_LOCAL DUK_EXEC_ALWAYS_INLINE_PERF void duk__vm_bitwise_binary_op(duk_hthread *thr,
duk_tval *tv_x,
duk_tval *tv_y,
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
*/
fi3 = (duk_int64_t) i3;
fastint_result_set:
tv_z = thr->valstack_bottom + idx_z;
DUK_TVAL_SET_FASTINT_UPDREF(thr, tv_z, fi3); /* side effects */
#else /* DUK_USE_FASTINT */
d3 = (duk_double_t) i3;
result_set:
DUK_ASSERT(!DUK_ISNAN(d3)); /* 'd3' is never NaN, so no need to normalize */
DUK_ASSERT_DOUBLE_IS_NORMALIZED(d3); /* always normalized */
#if defined(DUK_USE_EXEC_PREFER_SIZE)
duk_push_number(thr, d3); /* would NaN normalize result, but unnecessary */
duk_replace(thr, (duk_idx_t) idx_z);
#else /* DUK_USE_EXEC_PREFER_SIZE */
tv_z = thr->valstack_bottom + idx_z;
DUK_TVAL_SET_NUMBER_UPDREF(thr, tv_z, d3); /* side effects */
#endif /* DUK_USE_EXEC_PREFER_SIZE */
#endif /* DUK_USE_FASTINT */
}
/* In-place unary operation. */
DUK_LOCAL DUK_EXEC_ALWAYS_INLINE_PERF void duk__vm_arith_unary_op(duk_hthread *thr,
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
du.d = d1;
DUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));
#if defined(DUK_USE_FASTINT)
tv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);
DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF(thr, tv, du.d); /* always 'fast', i.e. inlined */
return;
#endif
} else {
DUK_ASSERT(opcode == DUK_OP_UNM);
du.d = -d1;
DUK_DBLUNION_NORMALIZE_NAN_CHECK(&du); /* mandatory if du.d is a NaN */
DUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));
}
/* XXX: size optimize: push+replace? */
tv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);
DUK_TVAL_SET_NUMBER_UPDREF(thr, tv, du.d);
}
DUK_LOCAL DUK_EXEC_ALWAYS_INLINE_PERF void duk__vm_bitwise_not(duk_hthread *thr, duk_uint_fast_t idx_src, duk_uint_fast_t idx_dst) {
/*
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
* the grammar allows leading and trailing white space.
*
* - Quick reject based on string length is difficult even after
* accounting for white space; there may be arbitrarily many
* decimal digits.
*
* - Standard grammar allows decimal values ("123"), hex values
* ("0x123") and infinities
*
* - Unlike source code literals, ToNumber() coerces empty strings
* and strings with only whitespace to zero (not NaN). However,
* while '' coerces to 0, '+' and '-' coerce to NaN.
*/
/* E5 Section 9.3.1 */
DUK_LOCAL duk_double_t duk__tonumber_string_raw(duk_hthread *thr) {
duk_small_uint_t s2n_flags;
duk_double_t d;
DUK_ASSERT(duk_is_string(thr, -1));
/* Quite lenient, e.g. allow empty as zero, but don't allow trailing
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
return d;
}
DUK_INTERNAL duk_double_t duk_js_tonumber(duk_hthread *thr, duk_tval *tv) {
DUK_ASSERT(thr != NULL);
DUK_ASSERT(tv != NULL);
switch (DUK_TVAL_GET_TAG(tv)) {
case DUK_TAG_UNDEFINED: {
/* return a specific NaN (although not strictly necessary) */
duk_double_union du;
DUK_DBLUNION_SET_NAN(&du);
DUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));
return du.d;
}
case DUK_TAG_NULL: {
/* +0.0 */
return 0.0;
}
case DUK_TAG_BOOLEAN: {
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
duk_pop_unsafe(thr);
return d;
}
case DUK_TAG_POINTER: {
/* Coerce like boolean */
void *p = DUK_TVAL_GET_POINTER(tv);
return (p != NULL ? 1.0 : 0.0);
}
case DUK_TAG_LIGHTFUNC: {
/* +(function(){}) -> NaN */
return DUK_DOUBLE_NAN;
}
#if defined(DUK_USE_FASTINT)
case DUK_TAG_FASTINT:
return (duk_double_t) DUK_TVAL_GET_FASTINT(tv);
#endif
default: {
/* number */
DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));
DUK_ASSERT(DUK_TVAL_IS_DOUBLE(tv));
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
return 0.0;
} else if (DUK_UNLIKELY(c == DUK_FP_INFINITE)) {
return x;
} else {
/* Finite, including neg/pos zero. Neg zero sign must be
* preserved.
*/
return duk_double_trunc_towards_zero(x);
}
#else /* DUK_USE_PREFER_SIZE */
/* NaN and Infinity have the same exponent so it's a cheap
* initial check for the rare path.
*/
if (DUK_UNLIKELY(duk_double_is_nan_or_inf(x) != 0U)) {
if (duk_double_is_nan(x)) {
return 0.0;
} else {
return x;
}
} else {
return duk_double_trunc_towards_zero(x);
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
if (cx == DUK_FP_ZERO && cy == DUK_FP_ZERO) {
return 1;
}
if (x == y) {
return 1;
}
return 0;
#else /* DUK_USE_PARANOID_MATH */
/* Better equivalent algorithm. If the compiler is compliant, C and
* ECMAScript semantics are identical for this particular comparison.
* In particular, NaNs must never compare equal and zeroes must compare
* equal regardless of sign. Could also use a macro, but this inlines
* already nicely (no difference on gcc, for instance).
*/
if (duk_double_equals(x, y)) {
/* IEEE requires that NaNs compare false */
DUK_ASSERT(DUK_FPCLASSIFY(x) != DUK_FP_NAN);
DUK_ASSERT(DUK_FPCLASSIFY(y) != DUK_FP_NAN);
return 1;
} else {
/* IEEE requires that zeros compare the same regardless
* of their signed, so if both x and y are zeroes, they
* are caught above.
*/
DUK_ASSERT(!(DUK_FPCLASSIFY(x) == DUK_FP_ZERO && DUK_FPCLASSIFY(y) == DUK_FP_ZERO));
return 0;
}
#endif /* DUK_USE_PARANOID_MATH */
}
DUK_LOCAL duk_bool_t duk__js_samevalue_number(duk_double_t x, duk_double_t y) {
#if defined(DUK_USE_PARANOID_MATH)
duk_small_int_t cx = (duk_small_int_t) DUK_FPCLASSIFY(x);
duk_small_int_t cy = (duk_small_int_t) DUK_FPCLASSIFY(y);
if (cx == DUK_FP_NAN && cy == DUK_FP_NAN) {
/* SameValue(NaN, NaN) = true, regardless of NaN sign or extra bits */
return 1;
}
if (cx == DUK_FP_ZERO && cy == DUK_FP_ZERO) {
/* Note: cannot assume that a non-zero return value of signbit() would
* always be the same -- hence cannot (portably) use something like:
*
* signbit(x) == signbit(y)
*/
duk_small_int_t sx = DUK_SIGNBIT(x) ? 1 : 0;
duk_small_int_t sy = DUK_SIGNBIT(y) ? 1 : 0;
return (sx == sy);
}
/* normal comparison; known:
* - both x and y are not NaNs (but one of them can be)
* - both x and y are not zero (but one of them can be)
* - x and y may be denormal or infinite
*/
return (x == y);
#else /* DUK_USE_PARANOID_MATH */
duk_small_int_t cx = (duk_small_int_t) DUK_FPCLASSIFY(x);
duk_small_int_t cy = (duk_small_int_t) DUK_FPCLASSIFY(y);
if (duk_double_equals(x, y)) {
/* IEEE requires that NaNs compare false */
DUK_ASSERT(DUK_FPCLASSIFY(x) != DUK_FP_NAN);
DUK_ASSERT(DUK_FPCLASSIFY(y) != DUK_FP_NAN);
/* Using classification has smaller footprint than direct comparison. */
if (DUK_UNLIKELY(cx == DUK_FP_ZERO && cy == DUK_FP_ZERO)) {
/* Note: cannot assume that a non-zero return value of signbit() would
* always be the same -- hence cannot (portably) use something like:
*
* signbit(x) == signbit(y)
*/
return duk_double_same_sign(x, y);
}
return 1;
} else {
/* IEEE requires that zeros compare the same regardless
* of their sign, so if both x and y are zeroes, they
* are caught above.
*/
DUK_ASSERT(!(DUK_FPCLASSIFY(x) == DUK_FP_ZERO && DUK_FPCLASSIFY(y) == DUK_FP_ZERO));
/* Difference to non-strict/strict comparison is that NaNs compare
* equal and signed zero signs matter.
*/
if (DUK_UNLIKELY(cx == DUK_FP_NAN && cy == DUK_FP_NAN)) {
/* SameValue(NaN, NaN) = true, regardless of NaN sign or extra bits */
return 1;
}
return 0;
}
#endif /* DUK_USE_PARANOID_MATH */
}
DUK_INTERNAL duk_bool_t duk_js_equals_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_t flags) {
duk_uint_t type_mask_x;
duk_uint_t type_mask_y;
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
if (d1 < d2) {
return retval ^ 1; /* true */
}
return retval; /* false */
}
#else /* DUK_USE_PARANOID_MATH */
DUK_LOCAL duk_bool_t duk__compare_number(duk_bool_t retval, duk_double_t d1, duk_double_t d2) {
/* This comparison tree relies doesn't match the exact steps in
* E5 Section 11.8.5 but should produce the same results. The
* steps rely on exact IEEE semantics for NaNs, etc.
*/
DUK_ASSERT(retval == 0 || retval == 1);
if (d1 < d2) {
/* In no case should both (d1 < d2) and (d2 < d1) be true.
* It's possible that neither is true though, and that's
* handled below.
*/
DUK_ASSERT(!(d2 < d1));
/* - d1 < d2, both d1/d2 are normals (not Infinity, not NaN)
* - d2 is +Infinity, d1 != +Infinity and NaN
* - d1 is -Infinity, d2 != -Infinity and NaN
*/
return retval ^ 1;
} else {
if (d2 < d1) {
/* - !(d1 < d2), both d1/d2 are normals (not Infinity, not NaN)
* - d1 is +Infinity, d2 != +Infinity and NaN
* - d2 is -Infinity, d1 != -Infinity and NaN
*/
return retval;
} else {
/* - d1 and/or d2 is NaN
* - d1 and d2 are both +/- 0
* - d1 == d2 (including infinities)
*/
if (duk_double_is_nan(d1) || duk_double_is_nan(d2)) {
/* Note: undefined from Section 11.8.5 always
* results in false return (see e.g. Section
* 11.8.3) - hence special treatment here.
*/
return 0; /* zero regardless of negation */
} else {
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
duk_small_int_t c;
duk_small_int_t neg;
duk_uint32_t uval;
duk__numconv_stringify_ctx nc_ctx_alloc; /* large context; around 2kB now */
duk__numconv_stringify_ctx *nc_ctx = &nc_ctx_alloc;
x = (duk_double_t) duk_require_number(thr, -1);
duk_pop(thr);
/*
* Handle special cases (NaN, infinity, zero).
*/
c = (duk_small_int_t) DUK_FPCLASSIFY(x);
if (DUK_SIGNBIT((double) x)) {
x = -x;
neg = 1;
} else {
neg = 0;
}
/* NaN sign bit is platform specific with unpacked, un-normalized NaNs */
DUK_ASSERT(c == DUK_FP_NAN || DUK_SIGNBIT((double) x) == 0);
if (c == DUK_FP_NAN) {
duk_push_hstring_stridx(thr, DUK_STRIDX_NAN);
return;
} else if (c == DUK_FP_INFINITE) {
if (neg) {
/* -Infinity */
duk_push_hstring_stridx(thr, DUK_STRIDX_MINUS_INFINITY);
} else {
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
duk_native_stack_check(thr);
duk__numconv_stringify_raw(thr, radix, digits, flags);
}
/*
* Exposed string-to-number API
*
* Input: [ string ]
* Output: [ number ]
*
* If number parsing fails, a NaN is pushed as the result. If number parsing
* fails due to an internal error, an InternalError is thrown.
*/
DUK_LOCAL DUK_NOINLINE void duk__numconv_parse_raw(duk_hthread *thr, duk_small_int_t radix, duk_small_uint_t flags) {
duk__numconv_stringify_ctx nc_ctx_alloc; /* large context; around 2kB now */
duk__numconv_stringify_ctx *nc_ctx = &nc_ctx_alloc;
duk_double_t res;
duk_hstring *h_str;
duk_int_t expt;
duk_bool_t expt_neg;
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
DUK_ASSERT(radix >= 2 && radix <= 36);
DUK_ASSERT(radix - 2 < (duk_small_int_t) sizeof(duk__str2num_digits_for_radix));
/*
* Preliminaries: trim, sign, Infinity check
*
* We rely on the interned string having a NUL terminator, which will
* cause a parse failure wherever it is encountered. As a result, we
* don't need separate pointer checks.
*
* There is no special parsing for 'NaN' in the specification although
* 'Infinity' (with an optional sign) is allowed in some contexts.
* Some contexts allow plus/minus sign, while others only allow the
* minus sign (like JSON.parse()).
*
* Automatic hex number detection (leading '0x' or '0X') and octal
* number detection (leading '0' followed by at least one octal digit)
* is done here too.
*
* Symbols are not explicitly rejected here (that's up to the caller).
* If a symbol were passed here, it should ultimately safely fail
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
#if 0
} else if ((flags & DUK_S2N_FLAG_ALLOW_AUTO_LEGACY_OCT_INT) &&
(ch >= (duk_small_int_t) '0' && ch <= (duk_small_int_t) '9')) {
DUK_DDD(DUK_DDDPRINT("detected 0n oct prefix, changing radix and preventing fractions and exponent"));
detect_radix = 8;
/* NOTE: if this legacy octal case is added back, it has
* different flags and 'p' advance so this needs to be
* reworked.
*/
flags |= DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO; /* interpret e.g. '09' as '0', not NaN */
p += 1;
#endif
} else if ((flags & DUK_S2N_FLAG_ALLOW_AUTO_OCT_INT) && ch == DUK_ASC_LC_O) {
DUK_DDD(DUK_DDDPRINT("detected 0o oct prefix, changing radix and preventing fractions and exponent"));
detect_radix = 8;
} else if ((flags & DUK_S2N_FLAG_ALLOW_AUTO_BIN_INT) && ch == DUK_ASC_LC_B) {
DUK_DDD(DUK_DDDPRINT("detected 0b bin prefix, changing radix and preventing fractions and exponent"));
detect_radix = 2;
}
if (detect_radix > 0) {
radix = detect_radix;
/* Clear empty as zero flag: interpret e.g. '0x' and '0xg' as a NaN (= parse error) */
flags &= ~(DUK_S2N_FLAG_ALLOW_EXP | DUK_S2N_FLAG_ALLOW_EMPTY_FRAC | DUK_S2N_FLAG_ALLOW_FRAC |
DUK_S2N_FLAG_ALLOW_NAKED_FRAC | DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO);
flags |= DUK_S2N_FLAG_ALLOW_LEADING_ZERO; /* allow e.g. '0x0009' and '0b00010001' */
p += 2;
}
}
/*
* Scan number and setup for Dragon4.
*
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
* dig_frac and dig_expt are -1 if not present
* dig_lzero is only computed for whole number part
*
* Parsing state
*
* Parsing whole part dig_frac < 0 AND dig_expt < 0
* Parsing fraction part dig_frac >= 0 AND dig_expt < 0
* Parsing exponent part dig_expt >= 0 (dig_frac may be < 0 or >= 0)
*
* Note: in case we hit an implementation limit (like exponent range),
* we should throw an error, NOT return NaN or Infinity. Even with
* very large exponent (or significand) values the final result may be
* finite, so NaN/Infinity would be incorrect.
*/
duk__bi_set_small(&nc_ctx->f, 0);
dig_prec = 0;
dig_lzero = 0;
dig_whole = 0;
dig_frac = -1;
dig_expt = -1;
expt = 0;
expt_adj = 0; /* essentially tracks digit position of lowest 'f' digit */
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
/* ".123" */
if ((flags & DUK_S2N_FLAG_ALLOW_NAKED_FRAC) == 0) {
DUK_DDD(DUK_DDDPRINT("parse failed: fraction part not allowed without "
"leading integer digit(s)"));
goto parse_fail;
}
} else {
/* Empty ("") is allowed in some formats (e.g. Number(''), as zero,
* but it must not have a leading +/- sign (GH-2019). Note that
* for Number(), h_str is already trimmed so we can check for zero
* length and still get Number(' + ') == NaN.
*/
if ((flags & DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO) == 0) {
DUK_DDD(DUK_DDDPRINT("parse failed: empty string not allowed (as zero)"));
goto parse_fail;
} else if (DUK_HSTRING_GET_BYTELEN(h_str) != 0) {
DUK_DDD(DUK_DDDPRINT("parse failed: no digits, but not empty (had a +/- sign)"));
goto parse_fail;
}
}
} else {
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
* as an integer, but pre-check it to be inside the 32-bit range before the loop.
* If not, the check in E5 Section 15.10.6.2, step 9.a applies.
*/
/* XXX: lastIndex handling produces a lot of asm */
/* [ ... re_obj input bc saved_buf ] */
duk_get_prop_stridx_short(thr, -4, DUK_STRIDX_LAST_INDEX); /* -> [ ... re_obj input bc saved_buf lastIndex ] */
(void) duk_to_int(thr, -1); /* ToInteger(lastIndex) */
d = duk_get_number(thr, -1); /* integer, but may be +/- Infinite, +/- zero (not NaN, though) */
duk_pop_nodecref_unsafe(thr);
if (global) {
if (d < 0.0 || d > (double) DUK_HSTRING_GET_CHARLEN(h_input)) {
/* match fail */
char_offset = 0; /* not really necessary */
DUK_ASSERT(match == 0);
goto match_over;
}
char_offset = (duk_uint32_t) d;
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
DUK_LOCAL duk_uint_t duk__selftest_double_aliasing(void) {
/* This testcase fails when Emscripten-generated code runs on Firefox.
* It's not an issue because the failure should only affect packed
* duk_tval representation, which is not used with Emscripten.
*/
#if defined(DUK_USE_PACKED_TVAL)
duk_uint_t error_count = 0;
duk__test_double_union a, b;
/* Test signaling NaN and alias assignment in all endianness combinations.
*/
/* little endian */
a.x[0] = 0x11;
a.x[1] = 0x22;
a.x[2] = 0x33;
a.x[3] = 0x44;
a.x[4] = 0x00;
a.x[5] = 0x00;
a.x[6] = 0xf1;
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
* Provide explicit cast helpers which try to avoid implementation defined
* or undefined behavior. These helpers can then be simplified in the vast
* majority of cases where the implementation defined or undefined behavior
* is not problematic.
*/
/* #include duk_internal.h -> already included */
/* Portable double-to-integer cast which avoids undefined behavior and avoids
* relying on fmin(), fmax(), or other intrinsics. Out-of-range results are
* not assumed by caller, but here value is clamped, NaN converts to minval.
*/
#define DUK__DOUBLE_INT_CAST1(tname, minval, maxval) \
do { \
if (DUK_LIKELY(x >= (duk_double_t) (minval))) { \
DUK_ASSERT(!DUK_ISNAN(x)); \
if (DUK_LIKELY(x <= (duk_double_t) (maxval))) { \
return (tname) x; \
} else { \
return (tname) (maxval); \
} \
} else { \
/* NaN or below minval. Since we don't care about the result \
* for out-of-range values, just return the minimum value for \
* both. \
*/ \
return (tname) (minval); \
} \
} while (0)
/* Rely on specific NaN behavior for duk_double_{fmin,fmax}(): if either
* argument is a NaN, return the second argument. This avoids a
* NaN-to-integer cast which is undefined behavior.
*/
#define DUK__DOUBLE_INT_CAST2(tname, minval, maxval) \
do { \
return (tname) duk_double_fmin(duk_double_fmax(x, (duk_double_t) (minval)), (duk_double_t) (maxval)); \
} while (0)
/* Another solution which doesn't need C99+ behavior for fmin() and fmax(). */
#define DUK__DOUBLE_INT_CAST3(tname, minval, maxval) \
do { \
if (DUK_ISNAN(x)) { \
/* 0 or any other value is fine. */ \
return (tname) 0; \
} else \
return (tname) DUK_FMIN(DUK_FMAX(x, (duk_double_t) (minval)), (duk_double_t) (maxval)); \
} \
} \
while (0)
/* C99+ solution: relies on specific fmin() and fmax() behavior in C99: if
* one argument is NaN but the other isn't, the non-NaN argument is returned.
* Because the limits are non-NaN values, explicit NaN check is not needed.
* This may not work on all legacy platforms, and also doesn't seem to inline
* the fmin() and fmax() calls (unless one uses -ffast-math which we don't
* support).
*/
#define DUK__DOUBLE_INT_CAST4(tname, minval, maxval) \
do { \
return (tname) DUK_FMIN(DUK_FMAX(x, (duk_double_t) (minval)), (duk_double_t) (maxval)); \
} while (0)
DUK_INTERNAL duk_int_t duk_double_to_int_t(duk_double_t x) {
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
return (duk_float_t) x;
} else if (t <= DUK__FLOAT_ROUND_LIMIT) {
/* Out-of-range, but rounds to min/max float. */
DUK_ASSERT(!DUK_ISNAN(x));
if (x < 0.0) {
return (duk_float_t) -DUK__FLOAT_MAX;
} else {
return (duk_float_t) DUK__FLOAT_MAX;
}
} else if (DUK_ISNAN(x)) {
/* Assumes double NaN -> float NaN considered "in range". */
DUK_ASSERT(DUK_ISNAN(x));
return (duk_float_t) x;
} else {
/* Out-of-range, rounds to +/- Infinity. */
if (x < 0.0) {
return (duk_float_t) -DUK_DOUBLE_INFINITY;
} else {
return (duk_float_t) DUK_DOUBLE_INFINITY;
}
}
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
DUK_INTERNAL duk_bool_t duk_double_is_neginf(duk_double_t x) {
duk_double_union du;
du.d = x;
return DUK_DBLUNION_IS_NEGINF(&du);
}
DUK_INTERNAL duk_bool_t duk_double_is_nan(duk_double_t x) {
duk_double_union du;
du.d = x;
/* Assumes we're dealing with a Duktape internal NaN which is
* NaN normalized if duk_tval requires it.
*/
DUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));
return DUK_DBLUNION_IS_NAN(&du);
}
DUK_INTERNAL duk_bool_t duk_double_is_nan_or_zero(duk_double_t x) {
duk_double_union du;
du.d = x;
/* Assumes we're dealing with a Duktape internal NaN which is
* NaN normalized if duk_tval requires it.
*/
DUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));
return DUK_DBLUNION_IS_NAN(&du) || DUK_DBLUNION_IS_ANYZERO(&du);
}
DUK_INTERNAL duk_bool_t duk_double_is_nan_or_inf(duk_double_t x) {
duk_double_union du;
du.d = x;
/* If exponent is 0x7FF the argument is either a NaN or an
* infinity. We don't need to check any other fields.
*/
#if defined(DUK_USE_64BIT_OPS)
#if defined(DUK_USE_DOUBLE_ME)
return (du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x000000007ff00000)) == DUK_U64_CONSTANT(0x000000007ff00000);
#else
return (du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7ff0000000000000)) == DUK_U64_CONSTANT(0x7ff0000000000000);
#endif
#else
return (du.ui[DUK_DBL_IDX_UI0] & 0x7ff00000UL) == 0x7ff00000UL;
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
duk_double_union du1;
duk_double_union du2;
du1.d = x;
du2.d = y;
return (((du1.ui[DUK_DBL_IDX_UI0] ^ du2.ui[DUK_DBL_IDX_UI0]) & 0x80000000UL) == 0);
}
DUK_INTERNAL duk_double_t duk_double_fmin(duk_double_t x, duk_double_t y) {
/* Doesn't replicate fmin() behavior exactly: for fmin() if one
* argument is a NaN, the other argument should be returned.
* Duktape doesn't rely on this behavior so the replacement can
* be simplified.
*/
return (x < y ? x : y);
}
DUK_INTERNAL duk_double_t duk_double_fmax(duk_double_t x, duk_double_t y) {
/* Doesn't replicate fmax() behavior exactly: for fmax() if one
* argument is a NaN, the other argument should be returned.
* Duktape doesn't rely on this behavior so the replacement can
* be simplified.
*/
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);
}
lib/JavaScript/Embedded/C/lib/duktape.c view on Meta::CPAN
} else {
return DUK_DOUBLE_INFINITY;
}
} else if (x < 0.0) {
if (DUK_SIGNBIT(y)) {
return DUK_DOUBLE_INFINITY;
} else {
return -DUK_DOUBLE_INFINITY;
}
} else {
/* +/- 0, NaN */
return DUK_DOUBLE_NAN;
}
}
#endif
return x / y;
}
/* Double and float byteorder changes. */
lib/JavaScript/Embedded/C/lib/duktape.h view on Meta::CPAN
* to helpers (duk__get_part_helper() and duk__set_part_helper()).
*
* Must be in-sync with genbuiltins.py.
*/
/* NOTE: when writing a Date provider you only need a few specific
* flags from here, the rest are internal. Avoid using anything you
* don't need.
*/
#define DUK_DATE_FLAG_NAN_TO_ZERO (1 << 0) /* timeval breakdown: internal time value NaN -> zero */
#define DUK_DATE_FLAG_NAN_TO_RANGE_ERROR (1 << 1) /* timeval breakdown: internal time value NaN -> RangeError (toISOString) */
#define DUK_DATE_FLAG_ONEBASED (1 << 2) /* timeval breakdown: convert month and day-of-month parts to one-based (default is zero-based) */
#define DUK_DATE_FLAG_EQUIVYEAR (1 << 3) /* timeval breakdown: replace year with equivalent year in the [1971,2037] range for DST calculations */
#define DUK_DATE_FLAG_LOCALTIME (1 << 4) /* convert time value to local time */
#define DUK_DATE_FLAG_SUB1900 (1 << 5) /* getter: subtract 1900 from year when getting year part */
#define DUK_DATE_FLAG_TOSTRING_DATE (1 << 6) /* include date part in string conversion result */
#define DUK_DATE_FLAG_TOSTRING_TIME (1 << 7) /* include time part in string conversion result */
#define DUK_DATE_FLAG_TOSTRING_LOCALE (1 << 8) /* use locale specific formatting if available */
#define DUK_DATE_FLAG_TIMESETTER (1 << 9) /* setter: call is a time setter (affects hour, min, sec, ms); otherwise date setter (affects year, month, day-in-month) */
#define DUK_DATE_FLAG_YEAR_FIXUP (1 << 10) /* setter: perform 2-digit year fixup (00...99 -> 1900...1999) */
#define DUK_DATE_FLAG_SEP_T (1 << 11) /* string conversion: use 'T' instead of ' ' as a separator */
lib/JavaScript/Embedded/C/ppport.h view on Meta::CPAN
s++; if (s == send || (*s != 'F' && *s != 'f')) return 0;
s++; if (s < send && (*s == 'I' || *s == 'i')) {
s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
s++; if (s == send || (*s != 'I' && *s != 'i')) return 0;
s++; if (s == send || (*s != 'T' && *s != 't')) return 0;
s++; if (s == send || (*s != 'Y' && *s != 'y')) return 0;
s++;
}
sawinf = 1;
} else if (*s == 'N' || *s == 'n') {
/* XXX TODO: There are signaling NaNs and quiet NaNs. */
s++; if (s == send || (*s != 'A' && *s != 'a')) return 0;
s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
s++;
sawnan = 1;
} else
return 0;
if (sawinf) {
numtype &= IS_NUMBER_NEG; /* Keep track of sign */
numtype |= IS_NUMBER_INFINITY | IS_NUMBER_NOT_INT;
t/data/typescript.js view on Meta::CPAN
Cannot_find_global_value_0: { code: 2468, category: ts.DiagnosticCategory.Error, key: "Cannot_find_global_value_0_2468", message: "Cannot find global value '{0}'." },
The_0_operator_cannot_be_applied_to_type_symbol: { code: 2469, category: ts.DiagnosticCategory.Error, key: "The_0_operator_cannot_be_applied_to_type_symbol_2469", message: "The '{0}' operator cannot be applied to type 'symbol'." },
Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object: { code: 2470, category: ts.DiagnosticCategory.Error, key: "Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object_2470", message: "'Symbol' reference do...
A_computed_property_name_of_the_form_0_must_be_of_type_symbol: { code: 2471, category: ts.DiagnosticCategory.Error, key: "A_computed_property_name_of_the_form_0_must_be_of_type_symbol_2471", message: "A computed property name of the form '{0}...
Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher: { code: 2472, category: ts.DiagnosticCategory.Error, key: "Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_highe...
Enum_declarations_must_all_be_const_or_non_const: { code: 2473, category: ts.DiagnosticCategory.Error, key: "Enum_declarations_must_all_be_const_or_non_const_2473", message: "Enum declarations must all be const or non-const." },
In_const_enum_declarations_member_initializer_must_be_constant_expression: { code: 2474, category: ts.DiagnosticCategory.Error, key: "In_const_enum_declarations_member_initializer_must_be_constant_expression_2474", message: "In 'const' enum d...
const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment: { code: 2475, category: ts.DiagnosticCategory.Error, key: "const_enums_can_only_be_used_in_property_or_...
A_const_enum_member_can_only_be_accessed_using_a_string_literal: { code: 2476, category: ts.DiagnosticCategory.Error, key: "A_const_enum_member_can_only_be_accessed_using_a_string_literal_2476", message: "A const enum member can only be acces...
const_enum_member_initializer_was_evaluated_to_a_non_finite_value: { code: 2477, category: ts.DiagnosticCategory.Error, key: "const_enum_member_initializer_was_evaluated_to_a_non_finite_value_2477", message: "'const' enum member initializer w...
const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN: { code: 2478, category: ts.DiagnosticCategory.Error, key: "const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN_2478", message: "'const' enum member initializ...
Property_0_does_not_exist_on_const_enum_1: { code: 2479, category: ts.DiagnosticCategory.Error, key: "Property_0_does_not_exist_on_const_enum_1_2479", message: "Property '{0}' does not exist on 'const' enum '{1}'." },
let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations: { code: 2480, category: ts.DiagnosticCategory.Error, key: "let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations_2480", message: "'let' is not allowed to be ...
Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1: { code: 2481, category: ts.DiagnosticCategory.Error, key: "Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1_24...
The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation: { code: 2483, category: ts.DiagnosticCategory.Error, key: "The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation_2483", message: "The left-hand side of a '...
Export_declaration_conflicts_with_exported_declaration_of_0: { code: 2484, category: ts.DiagnosticCategory.Error, key: "Export_declaration_conflicts_with_exported_declaration_of_0_2484", message: "Export declaration conflicts with exported de...
The_left_hand_side_of_a_for_of_statement_cannot_be_a_previously_defined_constant: { code: 2485, category: ts.DiagnosticCategory.Error, key: "The_left_hand_side_of_a_for_of_statement_cannot_be_a_previously_defined_constant_2485", message: "The...
The_left_hand_side_of_a_for_in_statement_cannot_be_a_previously_defined_constant: { code: 2486, category: ts.DiagnosticCategory.Error, key: "The_left_hand_side_of_a_for_in_statement_cannot_be_a_previously_defined_constant_2486", message: "The...
Invalid_left_hand_side_in_for_of_statement: { code: 2487, category: ts.DiagnosticCategory.Error, key: "Invalid_left_hand_side_in_for_of_statement_2487", message: "Invalid left-hand side in 'for...of' statement." },
Type_must_have_a_Symbol_iterator_method_that_returns_an_iterator: { code: 2488, category: ts.DiagnosticCategory.Error, key: "Type_must_have_a_Symbol_iterator_method_that_returns_an_iterator_2488", message: "Type must have a '[Symbol.iterator]...
An_iterator_must_have_a_next_method: { code: 2489, category: ts.DiagnosticCategory.Error, key: "An_iterator_must_have_a_next_method_2489", message: "An iterator must have a 'next()' method." },
t/data/typescript.js view on Meta::CPAN
// Only if its the beginning can we have #! trivia
return pos === 0;
default:
return ch > 127 /* maxAsciiCharacter */;
}
}
ts.couldStartTrivia = couldStartTrivia;
/* @internal */
function skipTrivia(text, pos, stopAfterLineBreak) {
// Using ! with a greater than test is a fast way of testing the following conditions:
// pos === undefined || pos === null || isNaN(pos) || pos < 0;
if (!(pos >= 0)) {
return pos;
}
// Keep in sync with couldStartTrivia
while (true) {
var ch = text.charCodeAt(pos);
switch (ch) {
case 13 /* carriageReturn */:
if (text.charCodeAt(pos + 1) === 10 /* lineFeed */) {
pos++;
t/data/typescript.js view on Meta::CPAN
// Consider the property name '"0xF00D"'. When one indexes with '0xF00D', they are actually indexing with the value of 'ToString(0xF00D)'
// according to the ECMAScript specification, so it is actually as if the user indexed with the string '"61453"'.
// Thus, the text of all numeric literals equivalent to '61543' such as '0xF00D', '0xf00D', '0170015', etc. are not valid numeric names
// because their 'ToString' representation is not equal to their original text.
// This is motivated by ECMA-262 sections 9.3.1, 9.8.1, 11.1.5, and 11.2.1.
//
// Here, we test whether 'ToString(ToNumber(name))' is exactly equal to 'name'.
// The '+' prefix operator is equivalent here to applying the abstract ToNumber operation.
// Applying the 'toString()' method on a number gives us the abstract ToString operation on a number.
//
// Note that this accepts the values 'Infinity', '-Infinity', and 'NaN', and that this is intentional.
// This is desired behavior, because when indexing with them as numeric entities, you are indexing
// with the strings '"Infinity"', '"-Infinity"', and '"NaN"' respectively.
return (+name).toString() === name;
}
function checkComputedPropertyName(node) {
var links = getNodeLinks(node.expression);
if (!links.resolvedType) {
links.resolvedType = checkExpression(node.expression);
// This will allow types number, string, symbol or any. It will also allow enums, the unknown
// type, and any union of these types (like string | number).
if (!isTypeAnyOrAllConstituentTypesHaveKind(links.resolvedType, 132 /* NumberLike */ | 258 /* StringLike */ | 16777216 /* ESSymbol */)) {
error(node, ts.Diagnostics.A_computed_property_name_must_be_of_type_string_number_symbol_or_any);
t/data/typescript.js view on Meta::CPAN
}
else if (ambient) {
error(initializer, ts.Diagnostics.In_ambient_enum_declarations_member_initializer_must_be_constant_expression);
}
else {
// Only here do we need to check that the initializer is assignable to the enum type.
checkTypeAssignableTo(checkExpression(initializer), enumType, initializer, /*headMessage*/ undefined);
}
}
else if (enumIsConst) {
if (isNaN(value)) {
error(initializer, ts.Diagnostics.const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN);
}
else if (!isFinite(value)) {
error(initializer, ts.Diagnostics.const_enum_member_initializer_was_evaluated_to_a_non_finite_value);
}
}
}
return value;
function evalConstant(e) {
switch (e.kind) {
case 182 /* PrefixUnaryExpression */: