JavaScript-Embedded

 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 */:



( run in 0.273 second using v1.01-cache-2.11-cpan-4d50c553e7e )