JavaScript-Embedded

 view release on metacpan or  search on metacpan

lib/JavaScript/Embedded/C/lib/duktape.c  view on Meta::CPAN

		(u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) 0; \
	} while (0)
#endif /* DUK_USE_64BIT_OPS */

#define DUK_DBLUNION_SET_LOW32(u, v) \
	do { \
		(u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (v); \
	} while (0)

#define DUK_DBLUNION_GET_DOUBLE(u) ((u)->d)
#define DUK_DBLUNION_GET_HIGH32(u) ((u)->ui[DUK_DBL_IDX_UI0])
#define DUK_DBLUNION_GET_LOW32(u)  ((u)->ui[DUK_DBL_IDX_UI1])

#if defined(DUK_USE_64BIT_OPS)
#if defined(DUK_USE_DOUBLE_ME)
#define DUK_DBLUNION_SET_UINT64(u, v) \
	do { \
		(u)->ui[DUK_DBL_IDX_UI0] = (duk_uint32_t) ((v) >> 32); \
		(u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (v); \
	} while (0)
#define DUK_DBLUNION_GET_UINT64(u) ((((duk_uint64_t) (u)->ui[DUK_DBL_IDX_UI0]) << 32) | ((duk_uint64_t) (u)->ui[DUK_DBL_IDX_UI1]))
#else
#define DUK_DBLUNION_SET_UINT64(u, v) \
	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)
#if defined(DUK_USE_DOUBLE_ME)
/* Macros for 64-bit ops + mixed endian doubles. */
#define DUK__DBLUNION_SET_NAN_FULL(u) \
	do { \
		(u)->ull[DUK_DBL_IDX_ULL0] = DUK_U64_CONSTANT(0x000000007ff80000); \
	} while (0)
#define DUK__DBLUNION_IS_NAN_FULL(u) \
	((((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x000000007ff00000)) == DUK_U64_CONSTANT(0x000000007ff00000)) && \
	 ((((u)->ull[DUK_DBL_IDX_ULL0]) & DUK_U64_CONSTANT(0xffffffff000fffff)) != 0))
#define DUK__DBLUNION_IS_NORMALIZED_NAN_FULL(u) ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x000000007ff80000))
#define DUK__DBLUNION_IS_ANYINF(u) \
	(((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0xffffffff7fffffff)) == DUK_U64_CONSTANT(0x000000007ff00000))
#define DUK__DBLUNION_IS_POSINF(u) ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x000000007ff00000))
#define DUK__DBLUNION_IS_NEGINF(u) ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x00000000fff00000))
#define DUK__DBLUNION_IS_ANYZERO(u) \
	(((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0xffffffff7fffffff)) == DUK_U64_CONSTANT(0x0000000000000000))
#define DUK__DBLUNION_IS_POSZERO(u) ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x0000000000000000))
#define DUK__DBLUNION_IS_NEGZERO(u) ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x0000000080000000))
#else
/* Macros for 64-bit ops + big/little endian doubles. */
#define DUK__DBLUNION_SET_NAN_FULL(u) \
	do { \
		(u)->ull[DUK_DBL_IDX_ULL0] = DUK_U64_CONSTANT(0x7ff8000000000000); \
	} while (0)
#define DUK__DBLUNION_IS_NAN_FULL(u) \
	((((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7ff0000000000000)) == DUK_U64_CONSTANT(0x7ff0000000000000)) && \
	 ((((u)->ull[DUK_DBL_IDX_ULL0]) & DUK_U64_CONSTANT(0x000fffffffffffff)) != 0))
#define DUK__DBLUNION_IS_NORMALIZED_NAN_FULL(u) ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x7ff8000000000000))
#define DUK__DBLUNION_IS_ANYINF(u) \
	(((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7fffffffffffffff)) == DUK_U64_CONSTANT(0x7ff0000000000000))
#define DUK__DBLUNION_IS_POSINF(u) ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x7ff0000000000000))
#define DUK__DBLUNION_IS_NEGINF(u) ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0xfff0000000000000))
#define DUK__DBLUNION_IS_ANYZERO(u) \
	(((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7fffffffffffffff)) == DUK_U64_CONSTANT(0x0000000000000000))
#define DUK__DBLUNION_IS_POSZERO(u) ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x0000000000000000))
#define DUK__DBLUNION_IS_NEGZERO(u) ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x8000000000000000))
#endif
#else /* DUK_USE_64BIT_OPS */
/* Macros for no 64-bit ops, any endianness. */
#define DUK__DBLUNION_SET_NAN_FULL(u) \
	do { \
		(u)->ui[DUK_DBL_IDX_UI0] = (duk_uint32_t) 0x7ff80000UL; \
		(u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) 0x00000000UL; \
	} while (0)
#define DUK__DBLUNION_IS_NAN_FULL(u) \
	((((u)->ui[DUK_DBL_IDX_UI0] & 0x7ff00000UL) == 0x7ff00000UL) && \
	 (((u)->ui[DUK_DBL_IDX_UI0] & 0x000fffffUL) != 0 || (u)->ui[DUK_DBL_IDX_UI1] != 0))
#define DUK__DBLUNION_IS_NORMALIZED_NAN_FULL(u) \
	(((u)->ui[DUK_DBL_IDX_UI0] == 0x7ff80000UL) && ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))
#define DUK__DBLUNION_IS_ANYINF(u) \
	((((u)->ui[DUK_DBL_IDX_UI0] & 0x7fffffffUL) == 0x7ff00000UL) && ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))
#define DUK__DBLUNION_IS_POSINF(u) (((u)->ui[DUK_DBL_IDX_UI0] == 0x7ff00000UL) && ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))
#define DUK__DBLUNION_IS_NEGINF(u) (((u)->ui[DUK_DBL_IDX_UI0] == 0xfff00000UL) && ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))
#define DUK__DBLUNION_IS_ANYZERO(u) \
	((((u)->ui[DUK_DBL_IDX_UI0] & 0x7fffffffUL) == 0x00000000UL) && ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))
#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

lib/JavaScript/Embedded/C/lib/duktape.c  view on Meta::CPAN

	} while (0)
#endif /* DUK_USE_ALLOW_UNDEFINED_BEHAVIOR */

DUK_INTERNAL_DECL duk_small_int_t duk_memcmp(const void *s1, const void *s2, duk_size_t len);
DUK_INTERNAL_DECL duk_small_int_t duk_memcmp_unsafe(const void *s1, const void *s2, duk_size_t len);

DUK_INTERNAL_DECL duk_bool_t duk_is_whole_get_int32_nonegzero(duk_double_t x, duk_int32_t *ival);
DUK_INTERNAL_DECL duk_bool_t duk_is_whole_get_int32(duk_double_t x, duk_int32_t *ival);
DUK_INTERNAL_DECL duk_bool_t duk_double_is_anyinf(duk_double_t x);
DUK_INTERNAL_DECL duk_bool_t duk_double_is_posinf(duk_double_t x);
DUK_INTERNAL_DECL duk_bool_t duk_double_is_neginf(duk_double_t x);
DUK_INTERNAL_DECL duk_bool_t duk_double_is_nan(duk_double_t x);
DUK_INTERNAL_DECL duk_bool_t duk_double_is_nan_or_zero(duk_double_t x);
DUK_INTERNAL_DECL duk_bool_t duk_double_is_nan_or_inf(duk_double_t x);
DUK_INTERNAL_DECL duk_bool_t duk_double_is_nan_zero_inf(duk_double_t x);
DUK_INTERNAL_DECL duk_small_uint_t duk_double_signbit(duk_double_t x);
DUK_INTERNAL_DECL duk_double_t duk_double_trunc_towards_zero(duk_double_t x);
DUK_INTERNAL_DECL duk_bool_t duk_double_same_sign(duk_double_t x, duk_double_t y);
DUK_INTERNAL_DECL duk_double_t duk_double_fmin(duk_double_t x, duk_double_t y);
DUK_INTERNAL_DECL duk_double_t duk_double_fmax(duk_double_t x, duk_double_t y);
DUK_INTERNAL_DECL duk_bool_t duk_double_is_finite(duk_double_t x);
DUK_INTERNAL_DECL duk_bool_t duk_double_is_integer(duk_double_t x);
DUK_INTERNAL_DECL duk_bool_t duk_double_is_safe_integer(duk_double_t x);

DUK_INTERNAL_DECL duk_double_t duk_double_div(duk_double_t x, duk_double_t y);
DUK_INTERNAL_DECL duk_int_t duk_double_to_int_t(duk_double_t x);
DUK_INTERNAL_DECL duk_uint_t duk_double_to_uint_t(duk_double_t x);
DUK_INTERNAL_DECL duk_int32_t duk_double_to_int32_t(duk_double_t x);
DUK_INTERNAL_DECL duk_uint32_t duk_double_to_uint32_t(duk_double_t x);
DUK_INTERNAL_DECL duk_float_t duk_double_to_float_t(duk_double_t x);
DUK_INTERNAL_DECL duk_bool_t duk_double_equals(duk_double_t x, duk_double_t y);
DUK_INTERNAL_DECL duk_bool_t duk_float_equals(duk_float_t x, duk_float_t y);

/*
 *  Miscellaneous
 */

/* Example: x     = 0x10 = 0b00010000
 *          x - 1 = 0x0f = 0b00001111
 *          x & (x - 1) == 0
 *
 *          x     = 0x07 = 0b00000111
 *          x - 1 = 0x06 = 0b00000110
 *          x & (x - 1) != 0
 *
 * However, incorrectly true for x == 0 so check for that explicitly.
 */
#define DUK_IS_POWER_OF_TWO(x) ((x) != 0U && ((x) & ((x) -1U)) == 0U)

#endif /* DUK_UTIL_H_INCLUDED */
/* #include duk_strings.h */
#line 1 "duk_strings.h"
/*
 *  Shared string macros.
 *
 *  Using shared macros helps minimize strings data size because it's easy
 *  to check if an existing string could be used.  String constants don't
 *  need to be all defined here; defining a string here makes sense if there's
 *  a high chance the string could be reused.  Also, using macros allows
 *  a call site express the exact string needed, but the macro may map to an
 *  approximate string to reduce unique string count.  Macros can also be
 *  more easily tuned for low memory targets than #if defined()s throughout
 *  the code base.
 *
 *  Because format strings behave differently in the call site (they need to
 *  be followed by format arguments), they use a special prefix DUK_STR_FMT_.
 *
 *  On some compilers using explicit shared strings is preferable; on others
 *  it may be better to use straight literals because the compiler will combine
 *  them anyway, and such strings won't end up unnecessarily in a symbol table.
 */

#if !defined(DUK_ERRMSG_H_INCLUDED)
#define DUK_ERRMSG_H_INCLUDED

/* Mostly API and built-in method related */
#define DUK_STR_INTERNAL_ERROR                  "internal error"
#define DUK_STR_UNSUPPORTED                     "unsupported"
#define DUK_STR_INVALID_COUNT                   "invalid count"
#define DUK_STR_INVALID_ARGS                    "invalid args"
#define DUK_STR_INVALID_STATE                   "invalid state"
#define DUK_STR_INVALID_INPUT                   "invalid input"
#define DUK_STR_INVALID_LENGTH                  "invalid length"
#define DUK_STR_NOT_CONSTRUCTABLE               "not constructable"
#define DUK_STR_CONSTRUCT_ONLY                  "constructor requires 'new'"
#define DUK_STR_NOT_CALLABLE                    "not callable"
#define DUK_STR_NOT_EXTENSIBLE                  "not extensible"
#define DUK_STR_NOT_WRITABLE                    "not writable"
#define DUK_STR_NOT_CONFIGURABLE                "not configurable"
#define DUK_STR_INVALID_CONTEXT                 "invalid context"
#define DUK_STR_INVALID_INDEX                   "invalid args"
#define DUK_STR_PUSH_BEYOND_ALLOC_STACK         "cannot push beyond allocated stack"
#define DUK_STR_NOT_UNDEFINED                   "unexpected type"
#define DUK_STR_NOT_NULL                        "unexpected type"
#define DUK_STR_NOT_BOOLEAN                     "unexpected type"
#define DUK_STR_NOT_NUMBER                      "unexpected type"
#define DUK_STR_NOT_STRING                      "unexpected type"
#define DUK_STR_NOT_OBJECT                      "unexpected type"
#define DUK_STR_NOT_POINTER                     "unexpected type"
#define DUK_STR_NOT_BUFFER                      "not buffer" /* still in use with verbose messages */
#define DUK_STR_UNEXPECTED_TYPE                 "unexpected type"
#define DUK_STR_NOT_THREAD                      "unexpected type"
#define DUK_STR_NOT_COMPFUNC                    "unexpected type"
#define DUK_STR_NOT_NATFUNC                     "unexpected type"
#define DUK_STR_NOT_C_FUNCTION                  "unexpected type"
#define DUK_STR_NOT_FUNCTION                    "unexpected type"
#define DUK_STR_NOT_REGEXP                      "unexpected type"
#define DUK_STR_TOPRIMITIVE_FAILED              "coercion to primitive failed"
#define DUK_STR_NUMBER_OUTSIDE_RANGE            "number outside range"
#define DUK_STR_NOT_OBJECT_COERCIBLE            "not object coercible"
#define DUK_STR_CANNOT_NUMBER_COERCE_SYMBOL     "cannot number coerce Symbol"
#define DUK_STR_CANNOT_STRING_COERCE_SYMBOL     "cannot string coerce Symbol"
#define DUK_STR_STRING_TOO_LONG                 "string too long"
#define DUK_STR_BUFFER_TOO_LONG                 "buffer too long"
#define DUK_STR_ALLOC_FAILED                    "alloc failed"
#define DUK_STR_WRONG_BUFFER_TYPE               "wrong buffer type"
#define DUK_STR_BASE64_ENCODE_FAILED            "base64 encode failed"
#define DUK_STR_SOURCE_DECODE_FAILED            "source decode failed"
#define DUK_STR_UTF8_DECODE_FAILED              "utf-8 decode failed"
#define DUK_STR_BASE64_DECODE_FAILED            "base64 decode failed"
#define DUK_STR_HEX_DECODE_FAILED               "hex decode failed"

lib/JavaScript/Embedded/C/lib/duktape.c  view on Meta::CPAN

 *  OP (8 bits):  opcode (DUK_OP_*), access should be fastest
 *                consecutive opcodes allocated when opcode needs flags
 *   A (8 bits):  typically a target register number
 *   B (8 bits):  typically first source register/constant number
 *   C (8 bits):  typically second source register/constant number
 *
 *  Some instructions combine BC or ABC together for larger parameter values.
 *  Signed integers (e.g. jump offsets) are encoded as unsigned, with an
 *  opcode specific bias.
 *
 *  Some opcodes have flags which are handled by allocating consecutive
 *  opcodes to make space for 1-N flags.  Flags can also be e.g. in the 'A'
 *  field when there's room for the specific opcode.
 *
 *  For example, if three flags were needed, they could be allocated from
 *  the opcode field as follows:
 *
 *  !3!3!2!2!2!2!2!2!2!2!2!2!1!1!1!1!1!1!1!1!1!1! ! ! ! ! ! ! ! ! ! !
 *  !1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!
 *  +-----------------------------------------------+---------------+
 *  !       C       !       B       !       A       !    OP   !Z!Y!X!
 *  +-----------------------------------------------+---------------+
 *
 *  Some opcodes accept a reg/const argument which is handled by allocating
 *  flags in the OP field, see DUK_BC_ISREG() and DUK_BC_ISCONST().  The
 *  following convention is shared by most opcodes, so that the compiler
 *  can handle reg/const flagging without opcode specific code paths:
 *
 *  !3!3!2!2!2!2!2!2!2!2!2!2!1!1!1!1!1!1!1!1!1!1! ! ! ! ! ! ! ! ! ! !
 *  !1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!
 *  +-----------------------------------------------+---------------+
 *  !       C       !       B       !       A       !     OP    !Y!X!
 *  +-----------------------------------------------+---------------+
 *
 *    X  1=B is const, 0=B is reg
 *    Y  1=C is const, 0=C is reg
 *
 *    In effect OP, OP + 1, OP + 2, and OP + 3 are allocated from the
 *    8-bit opcode space for a single logical opcode.  The base opcode
 *    number should be divisible by 4.  If the opcode is called 'FOO'
 *    the following opcode constants would be defined:
 *
 *      DUK_OP_FOO     100       // base opcode number
 *      DUK_OP_FOO_RR  100       // FOO, B=reg, C=reg
 *      DUK_OP_FOO_CR  101       // FOO, B=const, C=reg
 *      DUK_OP_FOO_RC  102       // FOO, B=reg, C=const
 *      DUK_OP_FOO_CC  103       // FOO, B=const, C=const
 *
 *  If only B or C is a reg/const, the unused opcode combinations can be
 *  used for other opcodes (which take no reg/const argument).  However,
 *  such opcode values are initially reserved, at least while opcode space
 *  is available.  For example, if 'BAR' uses B for a register field and
 *  C is a reg/const:
 *
 *      DUK_OP_BAR            116    // base opcode number
 *      DUK_OP_BAR_RR         116    // BAR, B=reg, C=reg
 *      DUK_OP_BAR_CR_UNUSED  117    // unused, could be repurposed
 *      DUK_OP_BAR_RC         118    // BAR, B=reg, C=const
 *      DUK_OP_BAR_CC_UNUSED  119    // unused, could be repurposed
 *
 *  Macro naming is a bit misleading, e.g. "ABC" in macro name but the
 *  field layout is concretely "CBA" in the register.
 */

typedef duk_uint32_t duk_instr_t;

#define DUK_BC_SHIFT_OP  0
#define DUK_BC_SHIFT_A   8
#define DUK_BC_SHIFT_B   16
#define DUK_BC_SHIFT_C   24
#define DUK_BC_SHIFT_BC  DUK_BC_SHIFT_B
#define DUK_BC_SHIFT_ABC DUK_BC_SHIFT_A

#define DUK_BC_UNSHIFTED_MASK_OP  0xffUL
#define DUK_BC_UNSHIFTED_MASK_A   0xffUL
#define DUK_BC_UNSHIFTED_MASK_B   0xffUL
#define DUK_BC_UNSHIFTED_MASK_C   0xffUL
#define DUK_BC_UNSHIFTED_MASK_BC  0xffffUL
#define DUK_BC_UNSHIFTED_MASK_ABC 0xffffffUL

#define DUK_BC_SHIFTED_MASK_OP  (DUK_BC_UNSHIFTED_MASK_OP << DUK_BC_SHIFT_OP)
#define DUK_BC_SHIFTED_MASK_A   (DUK_BC_UNSHIFTED_MASK_A << DUK_BC_SHIFT_A)
#define DUK_BC_SHIFTED_MASK_B   (DUK_BC_UNSHIFTED_MASK_B << DUK_BC_SHIFT_B)
#define DUK_BC_SHIFTED_MASK_C   (DUK_BC_UNSHIFTED_MASK_C << DUK_BC_SHIFT_C)
#define DUK_BC_SHIFTED_MASK_BC  (DUK_BC_UNSHIFTED_MASK_BC << DUK_BC_SHIFT_BC)
#define DUK_BC_SHIFTED_MASK_ABC (DUK_BC_UNSHIFTED_MASK_ABC << DUK_BC_SHIFT_ABC)

#define DUK_DEC_OP(x)  ((x) &0xffUL)
#define DUK_DEC_A(x)   (((x) >> 8) & 0xffUL)
#define DUK_DEC_B(x)   (((x) >> 16) & 0xffUL)
#define DUK_DEC_C(x)   (((x) >> 24) & 0xffUL)
#define DUK_DEC_BC(x)  (((x) >> 16) & 0xffffUL)
#define DUK_DEC_ABC(x) (((x) >> 8) & 0xffffffUL)

#define DUK_ENC_OP(op)          ((duk_instr_t) (op))
#define DUK_ENC_OP_ABC(op, abc) ((duk_instr_t) ((((duk_instr_t) (abc)) << 8) | ((duk_instr_t) (op))))
#define DUK_ENC_OP_A_BC(op, a, bc) \
	((duk_instr_t) ((((duk_instr_t) (bc)) << 16) | (((duk_instr_t) (a)) << 8) | ((duk_instr_t) (op))))
#define DUK_ENC_OP_A_B_C(op, a, b, c) \
	((duk_instr_t) ((((duk_instr_t) (c)) << 24) | (((duk_instr_t) (b)) << 16) | (((duk_instr_t) (a)) << 8) | \
	                ((duk_instr_t) (op))))
#define DUK_ENC_OP_A_B(op, a, b) DUK_ENC_OP_A_B_C((op), (a), (b), 0)
#define DUK_ENC_OP_A(op, a)      DUK_ENC_OP_A_B_C((op), (a), 0, 0)
#define DUK_ENC_OP_BC(op, bc)    DUK_ENC_OP_A_BC((op), 0, (bc))

/* Get opcode base value with B/C reg/const flags cleared. */
#define DUK_BC_NOREGCONST_OP(op) ((op) &0xfc)

/* Constants should be signed so that signed arithmetic involving them
 * won't cause values to be coerced accidentally to unsigned.
 */
#define DUK_BC_OP_MIN  0
#define DUK_BC_OP_MAX  0xffL
#define DUK_BC_A_MIN   0
#define DUK_BC_A_MAX   0xffL
#define DUK_BC_B_MIN   0
#define DUK_BC_B_MAX   0xffL
#define DUK_BC_C_MIN   0
#define DUK_BC_C_MAX   0xffL
#define DUK_BC_BC_MIN  0
#define DUK_BC_BC_MAX  0xffffL

lib/JavaScript/Embedded/C/lib/duktape.c  view on Meta::CPAN

#define DUK_TVAL_INCREF(thr, tv)        DUK_TVAL_INCREF_FAST((thr), (tv))
#define DUK_TVAL_DECREF(thr, tv)        DUK_TVAL_DECREF_FAST((thr), (tv))
#define DUK_TVAL_DECREF_NORZ(thr, tv)   DUK_TVAL_DECREF_NORZ_FAST((thr), (tv))
#define DUK_HEAPHDR_INCREF(thr, h)      DUK_HEAPHDR_INCREF_FAST((thr), (h))
#define DUK_HEAPHDR_DECREF(thr, h)      DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_heaphdr_refzero, duk_heaphdr *)
#define DUK_HEAPHDR_DECREF_NORZ(thr, h) DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_heaphdr_refzero_norz, duk_heaphdr *)
#define DUK_HSTRING_INCREF(thr, h)      DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) (h))
#define DUK_HSTRING_DECREF(thr, h)      DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_hstring_refzero, duk_hstring *)
#define DUK_HSTRING_DECREF_NORZ(thr, h) \
	DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_hstring_refzero, duk_hstring *) /* no 'norz' variant */
#define DUK_HOBJECT_INCREF(thr, h)      DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) (h))
#define DUK_HOBJECT_DECREF(thr, h)      DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_hobject_refzero, duk_hobject *)
#define DUK_HOBJECT_DECREF_NORZ(thr, h) DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_hobject_refzero_norz, duk_hobject *)
#define DUK_HBUFFER_INCREF(thr, h)      DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) (h))
#define DUK_HBUFFER_DECREF(thr, h)      DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_hbuffer_refzero, duk_hbuffer *)
#define DUK_HBUFFER_DECREF_NORZ(thr, h) \
	DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_hbuffer_refzero, duk_hbuffer *) /* no 'norz' variant */
#define DUK_HCOMPFUNC_INCREF(thr, h)      DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) &(h)->obj)
#define DUK_HCOMPFUNC_DECREF(thr, h)      DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_hobject_refzero, duk_hobject *)
#define DUK_HCOMPFUNC_DECREF_NORZ(thr, h) DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_hobject_refzero_norz, duk_hobject *)
#define DUK_HNATFUNC_INCREF(thr, h)       DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) &(h)->obj)
#define DUK_HNATFUNC_DECREF(thr, h)       DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_hobject_refzero, duk_hobject *)
#define DUK_HNATFUNC_DECREF_NORZ(thr, h)  DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_hobject_refzero_norz, duk_hobject *)
#define DUK_HBUFOBJ_INCREF(thr, h)        DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) &(h)->obj)
#define DUK_HBUFOBJ_DECREF(thr, h)        DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_hobject_refzero, duk_hobject *)
#define DUK_HBUFOBJ_DECREF_NORZ(thr, h)   DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_hobject_refzero_norz, duk_hobject *)
#define DUK_HTHREAD_INCREF(thr, h)        DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) &(h)->obj)
#define DUK_HTHREAD_DECREF(thr, h)        DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_hobject_refzero, duk_hobject *)
#define DUK_HTHREAD_DECREF_NORZ(thr, h)   DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_hobject_refzero_norz, duk_hobject *)
#else
#define DUK_TVAL_INCREF(thr, tv)          DUK_TVAL_INCREF_SLOW((thr), (tv))
#define DUK_TVAL_DECREF(thr, tv)          DUK_TVAL_DECREF_SLOW((thr), (tv))
#define DUK_TVAL_DECREF_NORZ(thr, tv)     DUK_TVAL_DECREF_NORZ_SLOW((thr), (tv))
#define DUK_HEAPHDR_INCREF(thr, h)        DUK_HEAPHDR_INCREF_SLOW((thr), (h))
#define DUK_HEAPHDR_DECREF(thr, h)        DUK_HEAPHDR_DECREF_SLOW((thr), (h))
#define DUK_HEAPHDR_DECREF_NORZ(thr, h)   DUK_HEAPHDR_DECREF_NORZ_SLOW((thr), (h))
#define DUK_HSTRING_INCREF(thr, h)        DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) (h))
#define DUK_HSTRING_DECREF(thr, h)        DUK_HSTRING_DECREF_SLOW((thr), (h))
#define DUK_HSTRING_DECREF_NORZ(thr, h)   DUK_HSTRING_DECREF_NORZ_SLOW((thr), (h))
#define DUK_HOBJECT_INCREF(thr, h)        DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) (h))
#define DUK_HOBJECT_DECREF(thr, h)        DUK_HOBJECT_DECREF_SLOW((thr), (h))
#define DUK_HOBJECT_DECREF_NORZ(thr, h)   DUK_HOBJECT_DECREF_NORZ_SLOW((thr), (h))
#define DUK_HBUFFER_INCREF(thr, h)        DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) (h))
#define DUK_HBUFFER_DECREF(thr, h)        DUK_HBUFFER_DECREF_SLOW((thr), (h))
#define DUK_HBUFFER_DECREF_NORZ(thr, h)   DUK_HBUFFER_DECREF_NORZ_SLOW((thr), (h))
#define DUK_HCOMPFUNC_INCREF(thr, h)      DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) &(h)->obj)
#define DUK_HCOMPFUNC_DECREF(thr, h)      DUK_HOBJECT_DECREF_SLOW((thr), (duk_hobject *) &(h)->obj)
#define DUK_HCOMPFUNC_DECREF_NORZ(thr, h) DUK_HOBJECT_DECREF_NORZ_SLOW((thr), (duk_hobject *) &(h)->obj)
#define DUK_HNATFUNC_INCREF(thr, h)       DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) &(h)->obj)
#define DUK_HNATFUNC_DECREF(thr, h)       DUK_HOBJECT_DECREF_SLOW((thr), (duk_hobject *) &(h)->obj)
#define DUK_HNATFUNC_DECREF_NORZ(thr, h)  DUK_HOBJECT_DECREF_NORZ_SLOW((thr), (duk_hobject *) &(h)->obj)
#define DUK_HBUFOBJ_INCREF(thr, h)        DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) &(h)->obj)
#define DUK_HBUFOBJ_DECREF(thr, h)        DUK_HOBJECT_DECREF_SLOW((thr), (duk_hobject *) &(h)->obj)
#define DUK_HBUFOB_DECREF_NORZ(thr, h)    DUK_HOBJECT_DECREF_NORZ_SLOW((thr), (duk_hobject *) &(h)->obj)
#define DUK_HTHREAD_INCREF(thr, h)        DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) &(h)->obj)
#define DUK_HTHREAD_DECREF(thr, h)        DUK_HOBJECT_DECREF_SLOW((thr), (duk_hobject *) &(h)->obj)
#define DUK_HTHREAD_DECREF_NORZ(thr, h)   DUK_HOBJECT_DECREF_NORZ_SLOW((thr), (duk_hobject *) &(h)->obj)
#endif

/* Convenience for some situations; the above macros don't allow NULLs
 * for performance reasons.  Macros cover only actually needed cases.
 */
#define DUK_HEAPHDR_INCREF_ALLOWNULL(thr, h) \
	do { \
		if ((h) != NULL) { \
			DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) (h)); \
		} \
	} while (0)
#define DUK_HEAPHDR_DECREF_ALLOWNULL(thr, h) \
	do { \
		if ((h) != NULL) { \
			DUK_HEAPHDR_DECREF((thr), (duk_heaphdr *) (h)); \
		} \
	} while (0)
#define DUK_HEAPHDR_DECREF_NORZ_ALLOWNULL(thr, h) \
	do { \
		if ((h) != NULL) { \
			DUK_HEAPHDR_DECREF_NORZ((thr), (duk_heaphdr *) (h)); \
		} \
	} while (0)
#define DUK_HOBJECT_INCREF_ALLOWNULL(thr, h) \
	do { \
		if ((h) != NULL) { \
			DUK_HOBJECT_INCREF((thr), (h)); \
		} \
	} while (0)
#define DUK_HOBJECT_DECREF_ALLOWNULL(thr, h) \
	do { \
		if ((h) != NULL) { \
			DUK_HOBJECT_DECREF((thr), (h)); \
		} \
	} while (0)
#define DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, h) \
	do { \
		if ((h) != NULL) { \
			DUK_HOBJECT_DECREF_NORZ((thr), (h)); \
		} \
	} while (0)
#define DUK_HBUFFER_INCREF_ALLOWNULL(thr, h) \
	do { \
		if ((h) != NULL) { \
			DUK_HBUFFER_INCREF((thr), (h)); \
		} \
	} while (0)
#define DUK_HBUFFER_DECREF_ALLOWNULL(thr, h) \
	do { \
		if ((h) != NULL) { \
			DUK_HBUFFER_DECREF((thr), (h)); \
		} \
	} while (0)
#define DUK_HBUFFER_DECREF_NORZ_ALLOWNULL(thr, h) \
	do { \
		if ((h) != NULL) { \
			DUK_HBUFFER_DECREF_NORZ((thr), (h)); \
		} \
	} while (0)
#define DUK_HTHREAD_INCREF_ALLOWNULL(thr, h) \
	do { \
		if ((h) != NULL) { \
			DUK_HTHREAD_INCREF((thr), (h)); \
		} \
	} while (0)
#define DUK_HTHREAD_DECREF_ALLOWNULL(thr, h) \
	do { \
		if ((h) != NULL) { \
			DUK_HTHREAD_DECREF((thr), (h)); \
		} \
	} while (0)
#define DUK_HTHREAD_DECREF_NORZ_ALLOWNULL(thr, h) \
	do { \
		if ((h) != NULL) { \
			DUK_HTHREAD_DECREF_NORZ((thr), (h)); \
		} \
	} while (0)

/* Called after one or more DECREF NORZ calls to handle pending side effects.
 * At present DECREF NORZ does freeing inline but doesn't execute finalizers,
 * so these macros check for pending finalizers and execute them.  The FAST
 * variant is performance critical.
 */
#if defined(DUK_USE_FINALIZER_SUPPORT)
#define DUK_REFZERO_CHECK_FAST(thr) \
	do { \
		duk_refzero_check_fast((thr)); \
	} while (0)
#define DUK_REFZERO_CHECK_SLOW(thr) \
	do { \
		duk_refzero_check_slow((thr)); \
	} while (0)
#else /* DUK_USE_FINALIZER_SUPPORT */
#define DUK_REFZERO_CHECK_FAST(thr) \
	do { \
	} while (0)
#define DUK_REFZERO_CHECK_SLOW(thr) \
	do { \
	} while (0)
#endif /* DUK_USE_FINALIZER_SUPPORT */

/*
 *  Macros to set a duk_tval and update refcount of the target (decref the
 *  old value and incref the new value if necessary).  This is both performance
 *  and footprint critical; any changes made should be measured for size/speed.
 */

#define DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0(thr, tvptr_dst) \
	do { \
		duk_tval *tv__dst; \
		duk_tval tv__tmp; \
		tv__dst = (tvptr_dst); \
		DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \
		DUK_TVAL_SET_UNDEFINED(tv__dst); \
		DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \
	} while (0)

#define DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ_ALT0(thr, tvptr_dst) \
	do { \
		duk_tval *tv__dst; \
		duk_tval tv__tmp; \
		tv__dst = (tvptr_dst); \
		DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \
		DUK_TVAL_SET_UNDEFINED(tv__dst); \
		DUK_TVAL_DECREF_NORZ((thr), &tv__tmp); \
	} while (0)

#define DUK_TVAL_SET_UNUSED_UPDREF_ALT0(thr, tvptr_dst) \
	do { \
		duk_tval *tv__dst; \
		duk_tval tv__tmp; \
		tv__dst = (tvptr_dst); \
		DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \
		DUK_TVAL_SET_UNUSED(tv__dst); \
		DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \
	} while (0)

#define DUK_TVAL_SET_NULL_UPDREF_ALT0(thr, tvptr_dst) \
	do { \
		duk_tval *tv__dst; \
		duk_tval tv__tmp; \
		tv__dst = (tvptr_dst); \
		DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \
		DUK_TVAL_SET_NULL(tv__dst); \
		DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \
	} while (0)

#define DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0(thr, tvptr_dst, newval) \
	do { \
		duk_tval *tv__dst; \
		duk_tval tv__tmp; \
		tv__dst = (tvptr_dst); \
		DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \
		DUK_TVAL_SET_BOOLEAN(tv__dst, (newval)); \
		DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \
	} while (0)

#define DUK_TVAL_SET_NUMBER_UPDREF_ALT0(thr, tvptr_dst, newval) \
	do { \
		duk_tval *tv__dst; \
		duk_tval tv__tmp; \
		tv__dst = (tvptr_dst); \
		DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \

lib/JavaScript/Embedded/C/lib/duktape.c  view on Meta::CPAN

 *       (dense) range of [0,N[ array indexed entries with default attributes
 *       (writable, enumerable, configurable).  If the array part would become
 *       sparse or non-default attributes are required, the array part is
 *       abandoned and moved to the 'entry part'.
 *
 *    3. An optional 'hash part' is used to optimize lookups of the entry
 *       part; it is used only for objects with sufficiently many properties
 *       and can be abandoned without loss of information.
 *
 *  These three conceptual parts are stored in a single memory allocated area.
 *  This minimizes memory allocation overhead but also means that all three
 *  parts are resized together, and makes property access a bit complicated.
 */

#if !defined(DUK_HOBJECT_H_INCLUDED)
#define DUK_HOBJECT_H_INCLUDED

/* Object flags.  Make sure this stays in sync with debugger object
 * inspection code.
 */

/* XXX: some flags are object subtype specific (e.g. common to all function
 * subtypes, duk_harray, etc) and could be reused for different subtypes.
 */
#define DUK_HOBJECT_FLAG_EXTENSIBLE    DUK_HEAPHDR_USER_FLAG(0) /* object is extensible */
#define DUK_HOBJECT_FLAG_CONSTRUCTABLE DUK_HEAPHDR_USER_FLAG(1) /* object is constructable */
#define DUK_HOBJECT_FLAG_CALLABLE      DUK_HEAPHDR_USER_FLAG(2) /* object is callable */
#define DUK_HOBJECT_FLAG_BOUNDFUNC     DUK_HEAPHDR_USER_FLAG(3) /* object established using Function.prototype.bind() */
#define DUK_HOBJECT_FLAG_COMPFUNC      DUK_HEAPHDR_USER_FLAG(4) /* object is a compiled function (duk_hcompfunc) */
#define DUK_HOBJECT_FLAG_NATFUNC       DUK_HEAPHDR_USER_FLAG(5) /* object is a native function (duk_hnatfunc) */
#define DUK_HOBJECT_FLAG_BUFOBJ        DUK_HEAPHDR_USER_FLAG(6) /* object is a buffer object (duk_hbufobj) (always exotic) */
#define DUK_HOBJECT_FLAG_FASTREFS \
	DUK_HEAPHDR_USER_FLAG(7) /* object has no fields needing DECREF/marking beyond base duk_hobject header */
#define DUK_HOBJECT_FLAG_ARRAY_PART DUK_HEAPHDR_USER_FLAG(8) /* object has an array part (a_size may still be 0) */
#define DUK_HOBJECT_FLAG_STRICT     DUK_HEAPHDR_USER_FLAG(9) /* function: function object is strict */
#define DUK_HOBJECT_FLAG_NOTAIL     DUK_HEAPHDR_USER_FLAG(10) /* function: function must not be tail called */
#define DUK_HOBJECT_FLAG_NEWENV     DUK_HEAPHDR_USER_FLAG(11) /* function: create new environment when called (see duk_hcompfunc) */
#define DUK_HOBJECT_FLAG_NAMEBINDING \
	DUK_HEAPHDR_USER_FLAG( \
	    12) /* function: create binding for func name (function templates only, used for named function expressions) */
#define DUK_HOBJECT_FLAG_CREATEARGS       DUK_HEAPHDR_USER_FLAG(13) /* function: create an arguments object on function call */
#define DUK_HOBJECT_FLAG_HAVE_FINALIZER   DUK_HEAPHDR_USER_FLAG(14) /* object has a callable (own) finalizer property */
#define DUK_HOBJECT_FLAG_EXOTIC_ARRAY     DUK_HEAPHDR_USER_FLAG(15) /* 'Array' object, array length and index exotic behavior */
#define DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ DUK_HEAPHDR_USER_FLAG(16) /* 'String' object, array index exotic behavior */
#define DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS \
	DUK_HEAPHDR_USER_FLAG(17) /* 'Arguments' object and has arguments exotic behavior (non-strict callee) */
#define DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ DUK_HEAPHDR_USER_FLAG(18) /* 'Proxy' object */
#define DUK_HOBJECT_FLAG_SPECIAL_CALL    DUK_HEAPHDR_USER_FLAG(19) /* special casing in call behavior, for .call(), .apply(), etc. */

#define DUK_HOBJECT_FLAG_CLASS_BASE DUK_HEAPHDR_USER_FLAG_NUMBER(20)
#define DUK_HOBJECT_FLAG_CLASS_BITS 5

#define DUK_HOBJECT_GET_CLASS_NUMBER(h) \
	DUK_HEAPHDR_GET_FLAG_RANGE(&(h)->hdr, DUK_HOBJECT_FLAG_CLASS_BASE, DUK_HOBJECT_FLAG_CLASS_BITS)
#define DUK_HOBJECT_SET_CLASS_NUMBER(h, v) \
	DUK_HEAPHDR_SET_FLAG_RANGE(&(h)->hdr, DUK_HOBJECT_FLAG_CLASS_BASE, DUK_HOBJECT_FLAG_CLASS_BITS, (v))

#define DUK_HOBJECT_GET_CLASS_MASK(h) \
	(1UL << DUK_HEAPHDR_GET_FLAG_RANGE(&(h)->hdr, DUK_HOBJECT_FLAG_CLASS_BASE, DUK_HOBJECT_FLAG_CLASS_BITS))

/* Macro for creating flag initializer from a class number.
 * Unsigned type cast is needed to avoid warnings about coercing
 * a signed integer to an unsigned one; the largest class values
 * have the highest bit (bit 31) set which causes this.
 */
#define DUK_HOBJECT_CLASS_AS_FLAGS(v) (((duk_uint_t) (v)) << DUK_HOBJECT_FLAG_CLASS_BASE)

/* E5 Section 8.6.2 + custom classes */
#define DUK_HOBJECT_CLASS_NONE              0
#define DUK_HOBJECT_CLASS_OBJECT            1
#define DUK_HOBJECT_CLASS_ARRAY             2
#define DUK_HOBJECT_CLASS_FUNCTION          3
#define DUK_HOBJECT_CLASS_ARGUMENTS         4
#define DUK_HOBJECT_CLASS_BOOLEAN           5
#define DUK_HOBJECT_CLASS_DATE              6
#define DUK_HOBJECT_CLASS_ERROR             7
#define DUK_HOBJECT_CLASS_JSON              8
#define DUK_HOBJECT_CLASS_MATH              9
#define DUK_HOBJECT_CLASS_NUMBER            10
#define DUK_HOBJECT_CLASS_REGEXP            11
#define DUK_HOBJECT_CLASS_STRING            12
#define DUK_HOBJECT_CLASS_GLOBAL            13
#define DUK_HOBJECT_CLASS_SYMBOL            14
#define DUK_HOBJECT_CLASS_OBJENV            15 /* custom */
#define DUK_HOBJECT_CLASS_DECENV            16 /* custom */
#define DUK_HOBJECT_CLASS_POINTER           17 /* custom */
#define DUK_HOBJECT_CLASS_THREAD            18 /* custom; implies DUK_HOBJECT_IS_THREAD */
#define DUK_HOBJECT_CLASS_BUFOBJ_MIN        19
#define DUK_HOBJECT_CLASS_ARRAYBUFFER       19 /* implies DUK_HOBJECT_IS_BUFOBJ */
#define DUK_HOBJECT_CLASS_DATAVIEW          20
#define DUK_HOBJECT_CLASS_INT8ARRAY         21
#define DUK_HOBJECT_CLASS_UINT8ARRAY        22
#define DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY 23
#define DUK_HOBJECT_CLASS_INT16ARRAY        24
#define DUK_HOBJECT_CLASS_UINT16ARRAY       25
#define DUK_HOBJECT_CLASS_INT32ARRAY        26
#define DUK_HOBJECT_CLASS_UINT32ARRAY       27
#define DUK_HOBJECT_CLASS_FLOAT32ARRAY      28
#define DUK_HOBJECT_CLASS_FLOAT64ARRAY      29
#define DUK_HOBJECT_CLASS_BUFOBJ_MAX        29
#define DUK_HOBJECT_CLASS_MAX               29

/* Class masks. */
#define DUK_HOBJECT_CMASK_ALL               ((1UL << (DUK_HOBJECT_CLASS_MAX + 1)) - 1UL)
#define DUK_HOBJECT_CMASK_NONE              (1UL << DUK_HOBJECT_CLASS_NONE)
#define DUK_HOBJECT_CMASK_ARGUMENTS         (1UL << DUK_HOBJECT_CLASS_ARGUMENTS)
#define DUK_HOBJECT_CMASK_ARRAY             (1UL << DUK_HOBJECT_CLASS_ARRAY)
#define DUK_HOBJECT_CMASK_BOOLEAN           (1UL << DUK_HOBJECT_CLASS_BOOLEAN)
#define DUK_HOBJECT_CMASK_DATE              (1UL << DUK_HOBJECT_CLASS_DATE)
#define DUK_HOBJECT_CMASK_ERROR             (1UL << DUK_HOBJECT_CLASS_ERROR)
#define DUK_HOBJECT_CMASK_FUNCTION          (1UL << DUK_HOBJECT_CLASS_FUNCTION)
#define DUK_HOBJECT_CMASK_JSON              (1UL << DUK_HOBJECT_CLASS_JSON)
#define DUK_HOBJECT_CMASK_MATH              (1UL << DUK_HOBJECT_CLASS_MATH)
#define DUK_HOBJECT_CMASK_NUMBER            (1UL << DUK_HOBJECT_CLASS_NUMBER)
#define DUK_HOBJECT_CMASK_OBJECT            (1UL << DUK_HOBJECT_CLASS_OBJECT)
#define DUK_HOBJECT_CMASK_REGEXP            (1UL << DUK_HOBJECT_CLASS_REGEXP)
#define DUK_HOBJECT_CMASK_STRING            (1UL << DUK_HOBJECT_CLASS_STRING)
#define DUK_HOBJECT_CMASK_GLOBAL            (1UL << DUK_HOBJECT_CLASS_GLOBAL)
#define DUK_HOBJECT_CMASK_SYMBOL            (1UL << DUK_HOBJECT_CLASS_SYMBOL)
#define DUK_HOBJECT_CMASK_OBJENV            (1UL << DUK_HOBJECT_CLASS_OBJENV)
#define DUK_HOBJECT_CMASK_DECENV            (1UL << DUK_HOBJECT_CLASS_DECENV)

lib/JavaScript/Embedded/C/lib/duktape.c  view on Meta::CPAN

#endif
#define DUK_HOBJECT_CLEAR_FASTREFS(h)         DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_FASTREFS)
#define DUK_HOBJECT_CLEAR_ARRAY_PART(h)       DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ARRAY_PART)
#define DUK_HOBJECT_CLEAR_STRICT(h)           DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_STRICT)
#define DUK_HOBJECT_CLEAR_NOTAIL(h)           DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NOTAIL)
#define DUK_HOBJECT_CLEAR_NEWENV(h)           DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NEWENV)
#define DUK_HOBJECT_CLEAR_NAMEBINDING(h)      DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NAMEBINDING)
#define DUK_HOBJECT_CLEAR_CREATEARGS(h)       DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CREATEARGS)
#define DUK_HOBJECT_CLEAR_HAVE_FINALIZER(h)   DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_HAVE_FINALIZER)
#define DUK_HOBJECT_CLEAR_EXOTIC_ARRAY(h)     DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARRAY)
#define DUK_HOBJECT_CLEAR_EXOTIC_STRINGOBJ(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ)
#define DUK_HOBJECT_CLEAR_EXOTIC_ARGUMENTS(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS)
#if defined(DUK_USE_ES6_PROXY)
#define DUK_HOBJECT_CLEAR_EXOTIC_PROXYOBJ(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)
#endif
#define DUK_HOBJECT_CLEAR_SPECIAL_CALL(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_SPECIAL_CALL)

/* Object can/cannot use FASTREFS, i.e. has no strong reference fields beyond
 * duk_hobject base header.  This is used just for asserts so doesn't need to
 * be optimized.
 */
#define DUK_HOBJECT_PROHIBITS_FASTREFS(h) \
	(DUK_HOBJECT_IS_COMPFUNC((h)) || DUK_HOBJECT_IS_DECENV((h)) || DUK_HOBJECT_IS_OBJENV((h)) || DUK_HOBJECT_IS_BUFOBJ((h)) || \
	 DUK_HOBJECT_IS_THREAD((h)) || DUK_HOBJECT_IS_PROXY((h)) || DUK_HOBJECT_IS_BOUNDFUNC((h)))
#define DUK_HOBJECT_ALLOWS_FASTREFS(h) (!DUK_HOBJECT_PROHIBITS_FASTREFS((h)))

/* Flags used for property attributes in duk_propdesc and packed flags.
 * Must fit into 8 bits.
 */
#define DUK_PROPDESC_FLAG_WRITABLE     (1U << 0) /* E5 Section 8.6.1 */
#define DUK_PROPDESC_FLAG_ENUMERABLE   (1U << 1) /* E5 Section 8.6.1 */
#define DUK_PROPDESC_FLAG_CONFIGURABLE (1U << 2) /* E5 Section 8.6.1 */
#define DUK_PROPDESC_FLAG_ACCESSOR     (1U << 3) /* accessor */
#define DUK_PROPDESC_FLAG_VIRTUAL \
	(1U << 4) /* property is virtual: used in duk_propdesc, never stored \
	           * (used by e.g. buffer virtual properties) \
	           */
#define DUK_PROPDESC_FLAGS_MASK \
	(DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_ENUMERABLE | DUK_PROPDESC_FLAG_CONFIGURABLE | DUK_PROPDESC_FLAG_ACCESSOR)

/* Additional flags which are passed in the same flags argument as property
 * flags but are not stored in object properties.
 */
#define DUK_PROPDESC_FLAG_NO_OVERWRITE (1U << 4) /* internal define property: skip write silently if exists */

/* Convenience defines for property attributes. */
#define DUK_PROPDESC_FLAGS_NONE 0
#define DUK_PROPDESC_FLAGS_W    (DUK_PROPDESC_FLAG_WRITABLE)
#define DUK_PROPDESC_FLAGS_E    (DUK_PROPDESC_FLAG_ENUMERABLE)
#define DUK_PROPDESC_FLAGS_C    (DUK_PROPDESC_FLAG_CONFIGURABLE)
#define DUK_PROPDESC_FLAGS_WE   (DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_ENUMERABLE)
#define DUK_PROPDESC_FLAGS_WC   (DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_CONFIGURABLE)
#define DUK_PROPDESC_FLAGS_EC   (DUK_PROPDESC_FLAG_ENUMERABLE | DUK_PROPDESC_FLAG_CONFIGURABLE)
#define DUK_PROPDESC_FLAGS_WEC  (DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_ENUMERABLE | DUK_PROPDESC_FLAG_CONFIGURABLE)

/* Flags for duk_hobject_get_own_propdesc() and variants. */
#define DUK_GETDESC_FLAG_PUSH_VALUE       (1U << 0) /* push value to stack */
#define DUK_GETDESC_FLAG_IGNORE_PROTOLOOP (1U << 1) /* don't throw for prototype loop */

/*
 *  Macro for object validity check
 *
 *  Assert for currently guaranteed relations between flags, for instance.
 */

#if defined(DUK_USE_ASSERTIONS)
DUK_INTERNAL_DECL void duk_hobject_assert_valid(duk_hobject *h);
#define DUK_HOBJECT_ASSERT_VALID(h) \
	do { \
		duk_hobject_assert_valid((h)); \
	} while (0)
#else
#define DUK_HOBJECT_ASSERT_VALID(h) \
	do { \
	} while (0)
#endif

/*
 *  Macros to access the 'props' allocation.
 */

#if defined(DUK_USE_HEAPPTR16)
#define DUK_HOBJECT_GET_PROPS(heap, h) ((duk_uint8_t *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, ((duk_heaphdr *) (h))->h_extra16))
#define DUK_HOBJECT_SET_PROPS(heap, h, x) \
	do { \
		((duk_heaphdr *) (h))->h_extra16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (x)); \
	} while (0)
#else
#define DUK_HOBJECT_GET_PROPS(heap, h) ((h)->props)
#define DUK_HOBJECT_SET_PROPS(heap, h, x) \
	do { \
		(h)->props = (duk_uint8_t *) (x); \
	} while (0)
#endif

#if defined(DUK_USE_HOBJECT_LAYOUT_1)
/* LAYOUT 1 */
#define DUK_HOBJECT_E_GET_KEY_BASE(heap, h) ((duk_hstring **) (void *) (DUK_HOBJECT_GET_PROPS((heap), (h))))
#define DUK_HOBJECT_E_GET_VALUE_BASE(heap, h) \
	((duk_propvalue *) (void *) (DUK_HOBJECT_GET_PROPS((heap), (h)) + DUK_HOBJECT_GET_ESIZE((h)) * sizeof(duk_hstring *)))
#define DUK_HOBJECT_E_GET_FLAGS_BASE(heap, h) \
	((duk_uint8_t *) (void *) (DUK_HOBJECT_GET_PROPS((heap), (h)) + \
	                           DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue))))
#define DUK_HOBJECT_A_GET_BASE(heap, h) \
	((duk_tval *) (void *) (DUK_HOBJECT_GET_PROPS((heap), (h)) + \
	                        DUK_HOBJECT_GET_ESIZE((h)) * \
	                            (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t))))
#define DUK_HOBJECT_H_GET_BASE(heap, h) \
	((duk_uint32_t *) (void *) (DUK_HOBJECT_GET_PROPS((heap), (h)) + \
	                            DUK_HOBJECT_GET_ESIZE((h)) * \
	                                (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \
	                            DUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval)))
#define DUK_HOBJECT_P_COMPUTE_SIZE(n_ent, n_arr, n_hash) \
	((n_ent) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + (n_arr) * sizeof(duk_tval) + \
	 (n_hash) * sizeof(duk_uint32_t))
#define DUK_HOBJECT_P_SET_REALLOC_PTRS(p_base, set_e_k, set_e_pv, set_e_f, set_a, set_h, n_ent, n_arr, n_hash) \
	do { \
		(set_e_k) = (duk_hstring **) (void *) (p_base); \
		(set_e_pv) = (duk_propvalue *) (void *) ((set_e_k) + (n_ent)); \
		(set_e_f) = (duk_uint8_t *) (void *) ((set_e_pv) + (n_ent)); \
		(set_a) = (duk_tval *) (void *) ((set_e_f) + (n_ent)); \
		(set_h) = (duk_uint32_t *) (void *) ((set_a) + (n_arr)); \
	} while (0)
#elif defined(DUK_USE_HOBJECT_LAYOUT_2)
/* LAYOUT 2 */
#if (DUK_USE_ALIGN_BY == 4)
#define DUK_HOBJECT_E_FLAG_PADDING(e_sz) ((4 - (e_sz)) & 0x03)
#elif (DUK_USE_ALIGN_BY == 8)
#define DUK_HOBJECT_E_FLAG_PADDING(e_sz) ((8 - (e_sz)) & 0x07)
#elif (DUK_USE_ALIGN_BY == 1)
#define DUK_HOBJECT_E_FLAG_PADDING(e_sz) 0
#else
#error invalid DUK_USE_ALIGN_BY
#endif
#define DUK_HOBJECT_E_GET_KEY_BASE(heap, h) \
	((duk_hstring **) (void *) (DUK_HOBJECT_GET_PROPS((heap), (h)) + DUK_HOBJECT_GET_ESIZE((h)) * sizeof(duk_propvalue)))
#define DUK_HOBJECT_E_GET_VALUE_BASE(heap, h) ((duk_propvalue *) (void *) (DUK_HOBJECT_GET_PROPS((heap), (h))))
#define DUK_HOBJECT_E_GET_FLAGS_BASE(heap, h) \
	((duk_uint8_t *) (void *) (DUK_HOBJECT_GET_PROPS((heap), (h)) + \

lib/JavaScript/Embedded/C/lib/duktape.c  view on Meta::CPAN

	do { \
		DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.get = (v); \
	} while (0)
#define DUK_HOBJECT_E_SET_VALUE_SETTER(heap, h, i, v) \
	do { \
		DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.set = (v); \
	} while (0)
#define DUK_HOBJECT_E_SET_FLAGS(heap, h, i, f) \
	do { \
		DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) = (duk_uint8_t) (f); \
	} while (0)
#define DUK_HOBJECT_A_SET_VALUE(heap, h, i, v) \
	do { \
		DUK_HOBJECT_A_GET_VALUE((heap), (h), (i)) = (v); \
	} while (0)
#define DUK_HOBJECT_A_SET_VALUE_TVAL(heap, h, i, v) DUK_HOBJECT_A_SET_VALUE((heap), (h), (i), (v)) /* alias for above */
#define DUK_HOBJECT_H_SET_INDEX(heap, h, i, v) \
	do { \
		DUK_HOBJECT_H_GET_INDEX((heap), (h), (i)) = (v); \
	} while (0)

#define DUK_HOBJECT_E_SET_FLAG_BITS(heap, h, i, mask) \
	do { \
		DUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)] |= (mask); \
	} while (0)

#define DUK_HOBJECT_E_CLEAR_FLAG_BITS(heap, h, i, mask) \
	do { \
		DUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)] &= ~(mask); \
	} while (0)

#define DUK_HOBJECT_E_SLOT_IS_WRITABLE(heap, h, i) ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_WRITABLE) != 0)
#define DUK_HOBJECT_E_SLOT_IS_ENUMERABLE(heap, h, i) \
	((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_ENUMERABLE) != 0)
#define DUK_HOBJECT_E_SLOT_IS_CONFIGURABLE(heap, h, i) \
	((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_CONFIGURABLE) != 0)
#define DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, h, i) ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_ACCESSOR) != 0)

#define DUK_HOBJECT_E_SLOT_SET_WRITABLE(heap, h, i)   DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i), DUK_PROPDESC_FLAG_WRITABLE)
#define DUK_HOBJECT_E_SLOT_SET_ENUMERABLE(heap, h, i) DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i), DUK_PROPDESC_FLAG_ENUMERABLE)
#define DUK_HOBJECT_E_SLOT_SET_CONFIGURABLE(heap, h, i) \
	DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i), DUK_PROPDESC_FLAG_CONFIGURABLE)
#define DUK_HOBJECT_E_SLOT_SET_ACCESSOR(heap, h, i) DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i), DUK_PROPDESC_FLAG_ACCESSOR)

#define DUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(heap, h, i) DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i), DUK_PROPDESC_FLAG_WRITABLE)
#define DUK_HOBJECT_E_SLOT_CLEAR_ENUMERABLE(heap, h, i) \
	DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i), DUK_PROPDESC_FLAG_ENUMERABLE)
#define DUK_HOBJECT_E_SLOT_CLEAR_CONFIGURABLE(heap, h, i) \
	DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i), DUK_PROPDESC_FLAG_CONFIGURABLE)
#define DUK_HOBJECT_E_SLOT_CLEAR_ACCESSOR(heap, h, i) DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i), DUK_PROPDESC_FLAG_ACCESSOR)

#define DUK_PROPDESC_IS_WRITABLE(p)     (((p)->flags & DUK_PROPDESC_FLAG_WRITABLE) != 0)
#define DUK_PROPDESC_IS_ENUMERABLE(p)   (((p)->flags & DUK_PROPDESC_FLAG_ENUMERABLE) != 0)
#define DUK_PROPDESC_IS_CONFIGURABLE(p) (((p)->flags & DUK_PROPDESC_FLAG_CONFIGURABLE) != 0)
#define DUK_PROPDESC_IS_ACCESSOR(p)     (((p)->flags & DUK_PROPDESC_FLAG_ACCESSOR) != 0)

#define DUK_HOBJECT_HASHIDX_UNUSED  0xffffffffUL
#define DUK_HOBJECT_HASHIDX_DELETED 0xfffffffeUL

/*
 *  Macros for accessing size fields
 */

#if defined(DUK_USE_OBJSIZES16)
#define DUK_HOBJECT_GET_ESIZE(h) ((h)->e_size16)
#define DUK_HOBJECT_SET_ESIZE(h, v) \
	do { \
		(h)->e_size16 = (v); \
	} while (0)
#define DUK_HOBJECT_GET_ENEXT(h) ((h)->e_next16)
#define DUK_HOBJECT_SET_ENEXT(h, v) \
	do { \
		(h)->e_next16 = (v); \
	} while (0)
#define DUK_HOBJECT_POSTINC_ENEXT(h) ((h)->e_next16++)
#define DUK_HOBJECT_GET_ASIZE(h)     ((h)->a_size16)
#define DUK_HOBJECT_SET_ASIZE(h, v) \
	do { \
		(h)->a_size16 = (v); \
	} while (0)
#if defined(DUK_USE_HOBJECT_HASH_PART)
#define DUK_HOBJECT_GET_HSIZE(h) ((h)->h_size16)
#define DUK_HOBJECT_SET_HSIZE(h, v) \
	do { \
		(h)->h_size16 = (v); \
	} while (0)
#else
#define DUK_HOBJECT_GET_HSIZE(h) 0
#define DUK_HOBJECT_SET_HSIZE(h, v) \
	do { \
		DUK_ASSERT((v) == 0); \
	} while (0)
#endif
#else
#define DUK_HOBJECT_GET_ESIZE(h) ((h)->e_size)
#define DUK_HOBJECT_SET_ESIZE(h, v) \
	do { \
		(h)->e_size = (v); \
	} while (0)
#define DUK_HOBJECT_GET_ENEXT(h) ((h)->e_next)
#define DUK_HOBJECT_SET_ENEXT(h, v) \
	do { \
		(h)->e_next = (v); \
	} while (0)
#define DUK_HOBJECT_POSTINC_ENEXT(h) ((h)->e_next++)
#define DUK_HOBJECT_GET_ASIZE(h)     ((h)->a_size)
#define DUK_HOBJECT_SET_ASIZE(h, v) \
	do { \
		(h)->a_size = (v); \
	} while (0)
#if defined(DUK_USE_HOBJECT_HASH_PART)
#define DUK_HOBJECT_GET_HSIZE(h) ((h)->h_size)
#define DUK_HOBJECT_SET_HSIZE(h, v) \
	do { \
		(h)->h_size = (v); \
	} while (0)
#else
#define DUK_HOBJECT_GET_HSIZE(h) 0
#define DUK_HOBJECT_SET_HSIZE(h, v) \
	do { \
		DUK_ASSERT((v) == 0); \
	} while (0)
#endif
#endif

/*
 *  Misc
 */

/* Maximum prototype traversal depth.  Sanity limit which handles e.g.
 * prototype loops (even complex ones like 1->2->3->4->2->3->4->2->3->4).
 */
#define DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY 10000L

/*
 *  ECMAScript [[Class]]
 */

/* range check not necessary because all 4-bit values are mapped */
#define DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(n) duk_class_number_to_stridx[(n)]

#define DUK_HOBJECT_GET_CLASS_STRING(heap, h) \
	DUK_HEAP_GET_STRING((heap), DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(DUK_HOBJECT_GET_CLASS_NUMBER((h))))

/*
 *  Macros for property handling
 */

#if defined(DUK_USE_HEAPPTR16)
#define DUK_HOBJECT_GET_PROTOTYPE(heap, h) ((duk_hobject *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->prototype16))
#define DUK_HOBJECT_SET_PROTOTYPE(heap, h, x) \
	do { \
		(h)->prototype16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (x)); \
	} while (0)
#else
#define DUK_HOBJECT_GET_PROTOTYPE(heap, h) ((h)->prototype)
#define DUK_HOBJECT_SET_PROTOTYPE(heap, h, x) \
	do { \
		(h)->prototype = (x); \
	} while (0)
#endif

/* Set prototype, DECREF earlier value, INCREF new value (tolerating NULLs). */
#define DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h, p) duk_hobject_set_prototype_updref((thr), (h), (p))

/* Set initial prototype, assume NULL previous prototype, INCREF new value,
 * tolerate NULL.
 */
#define DUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, h, proto) \
	do { \
		duk_hthread *duk__thr = (thr); \
		duk_hobject *duk__obj = (h); \
		duk_hobject *duk__proto = (proto); \
		DUK_UNREF(duk__thr); \
		DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(duk__thr->heap, duk__obj) == NULL); \
		DUK_HOBJECT_SET_PROTOTYPE(duk__thr->heap, duk__obj, duk__proto); \
		DUK_HOBJECT_INCREF_ALLOWNULL(duk__thr, duk__proto); \
	} while (0)

/*
 *  Finalizer check
 */

#if defined(DUK_USE_HEAPPTR16)
#define DUK_HOBJECT_HAS_FINALIZER_FAST(heap, h) duk_hobject_has_finalizer_fast_raw((heap), (h))
#else
#define DUK_HOBJECT_HAS_FINALIZER_FAST(heap, h) duk_hobject_has_finalizer_fast_raw((h))
#endif

/*
 *  Resizing and hash behavior
 */

/* Sanity limit on max number of properties (allocated, not necessarily used).
 * This is somewhat arbitrary, but if we're close to 2**32 properties some
 * algorithms will fail (e.g. hash size selection, next prime selection).
 * Also, we use negative array/entry table indices to indicate 'not found',
 * so anything above 0x80000000 will cause trouble now.
 */
#if defined(DUK_USE_OBJSIZES16)
#define DUK_HOBJECT_MAX_PROPERTIES 0x0000ffffUL
#else
#define DUK_HOBJECT_MAX_PROPERTIES 0x3fffffffUL /* 2**30-1 ~= 1G properties */
#endif

/* internal align target for props allocation, must be 2*n for some n */

lib/JavaScript/Embedded/C/lib/duktape.c  view on Meta::CPAN

#endif /* DUK_USE_REGEXP_CANON_WORKAROUND */
}

/*
 *  E5 Section 15.10.2.6 "IsWordChar" abstract operation.  Assume
 *  x < 0 for characters read outside the string.
 */

DUK_INTERNAL duk_small_int_t duk_unicode_re_is_wordchar(duk_codepoint_t x) {
	/*
	 *  Note: the description in E5 Section 15.10.2.6 has a typo, it
	 *  contains 'A' twice and lacks 'a'; the intent is [0-9a-zA-Z_].
	 */
	if ((x >= '0' && x <= '9') || (x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z') || (x == '_')) {
		return 1;
	}
	return 0;
}

/*
 *  Regexp range tables
 */

/* exposed because lexer needs these too */
DUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_digit[2] = {
	(duk_uint16_t) 0x0030UL,
	(duk_uint16_t) 0x0039UL,
};
DUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_white[22] = {
	(duk_uint16_t) 0x0009UL, (duk_uint16_t) 0x000DUL, (duk_uint16_t) 0x0020UL, (duk_uint16_t) 0x0020UL, (duk_uint16_t) 0x00A0UL,
	(duk_uint16_t) 0x00A0UL, (duk_uint16_t) 0x1680UL, (duk_uint16_t) 0x1680UL, (duk_uint16_t) 0x180EUL, (duk_uint16_t) 0x180EUL,
	(duk_uint16_t) 0x2000UL, (duk_uint16_t) 0x200AUL, (duk_uint16_t) 0x2028UL, (duk_uint16_t) 0x2029UL, (duk_uint16_t) 0x202FUL,
	(duk_uint16_t) 0x202FUL, (duk_uint16_t) 0x205FUL, (duk_uint16_t) 0x205FUL, (duk_uint16_t) 0x3000UL, (duk_uint16_t) 0x3000UL,
	(duk_uint16_t) 0xFEFFUL, (duk_uint16_t) 0xFEFFUL,
};
DUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_wordchar[8] = {
	(duk_uint16_t) 0x0030UL, (duk_uint16_t) 0x0039UL, (duk_uint16_t) 0x0041UL, (duk_uint16_t) 0x005AUL,
	(duk_uint16_t) 0x005FUL, (duk_uint16_t) 0x005FUL, (duk_uint16_t) 0x0061UL, (duk_uint16_t) 0x007AUL,
};
DUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_not_digit[4] = {
	(duk_uint16_t) 0x0000UL,
	(duk_uint16_t) 0x002FUL,
	(duk_uint16_t) 0x003AUL,
	(duk_uint16_t) 0xFFFFUL,
};
DUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_not_white[24] = {
	(duk_uint16_t) 0x0000UL, (duk_uint16_t) 0x0008UL, (duk_uint16_t) 0x000EUL, (duk_uint16_t) 0x001FUL, (duk_uint16_t) 0x0021UL,
	(duk_uint16_t) 0x009FUL, (duk_uint16_t) 0x00A1UL, (duk_uint16_t) 0x167FUL, (duk_uint16_t) 0x1681UL, (duk_uint16_t) 0x180DUL,
	(duk_uint16_t) 0x180FUL, (duk_uint16_t) 0x1FFFUL, (duk_uint16_t) 0x200BUL, (duk_uint16_t) 0x2027UL, (duk_uint16_t) 0x202AUL,
	(duk_uint16_t) 0x202EUL, (duk_uint16_t) 0x2030UL, (duk_uint16_t) 0x205EUL, (duk_uint16_t) 0x2060UL, (duk_uint16_t) 0x2FFFUL,
	(duk_uint16_t) 0x3001UL, (duk_uint16_t) 0xFEFEUL, (duk_uint16_t) 0xFF00UL, (duk_uint16_t) 0xFFFFUL,
};
DUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_not_wordchar[10] = {
	(duk_uint16_t) 0x0000UL, (duk_uint16_t) 0x002FUL, (duk_uint16_t) 0x003AUL, (duk_uint16_t) 0x0040UL, (duk_uint16_t) 0x005BUL,
	(duk_uint16_t) 0x005EUL, (duk_uint16_t) 0x0060UL, (duk_uint16_t) 0x0060UL, (duk_uint16_t) 0x007BUL, (duk_uint16_t) 0xFFFFUL,
};

#endif /* DUK_USE_REGEXP_SUPPORT */
#line 1 "duk_util_memrw.c"
/*
 *  Macro support functions for reading/writing raw data.
 *
 *  These are done using memcpy to ensure they're valid even for unaligned
 *  reads/writes on platforms where alignment counts.  On x86 at least gcc
 *  is able to compile these into a bswap+mov.  "Always inline" is used to
 *  ensure these macros compile to minimal code.
 */

/* #include duk_internal.h -> already included */

union duk__u16_union {
	duk_uint8_t b[2];
	duk_uint16_t x;
};
typedef union duk__u16_union duk__u16_union;

union duk__u32_union {
	duk_uint8_t b[4];
	duk_uint32_t x;
};
typedef union duk__u32_union duk__u32_union;

#if defined(DUK_USE_64BIT_OPS)
union duk__u64_union {
	duk_uint8_t b[8];
	duk_uint64_t x;
};
typedef union duk__u64_union duk__u64_union;
#endif

DUK_INTERNAL DUK_ALWAYS_INLINE duk_uint16_t duk_raw_read_u16_be(const duk_uint8_t *p) {
	duk__u16_union u;
	duk_memcpy((void *) u.b, (const void *) p, (size_t) 2);
	u.x = DUK_NTOH16(u.x);
	return u.x;
}

DUK_INTERNAL DUK_ALWAYS_INLINE duk_uint32_t duk_raw_read_u32_be(const duk_uint8_t *p) {
	duk__u32_union u;
	duk_memcpy((void *) u.b, (const void *) p, (size_t) 4);
	u.x = DUK_NTOH32(u.x);
	return u.x;
}

DUK_INTERNAL DUK_ALWAYS_INLINE duk_float_t duk_raw_read_float_be(const duk_uint8_t *p) {
	duk_float_union fu;
	duk_memcpy((void *) fu.uc, (const void *) p, (size_t) 4);
	duk_fltunion_big_to_host(&fu);
	return fu.f;
}

DUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_raw_read_double_be(const duk_uint8_t *p) {
	duk_double_union du;
	duk_memcpy((void *) du.uc, (const void *) p, (size_t) 8);
	duk_dblunion_big_to_host(&du);
	return du.d;
}

DUK_INTERNAL DUK_ALWAYS_INLINE duk_uint16_t duk_raw_readinc_u16_be(const duk_uint8_t **p) {
	duk_uint16_t res = duk_raw_read_u16_be(*p);
	*p += 2;

lib/JavaScript/Embedded/C/lib/duktape.c  view on Meta::CPAN


fail_type:
	DUK_DCERROR_TYPE_INVALID_ARGS(thr);
}

/* %NativeFunctionPrototype% .name getter. */
DUK_INTERNAL duk_ret_t duk_bi_native_function_name(duk_hthread *thr) {
	duk_tval *tv;
	duk_hnatfunc *h;

	tv = duk_get_borrowed_this_tval(thr);
	DUK_ASSERT(tv != NULL);

	if (DUK_TVAL_IS_OBJECT(tv)) {
		h = (duk_hnatfunc *) DUK_TVAL_GET_OBJECT(tv);
		DUK_ASSERT(h != NULL);
		if (!DUK_HOBJECT_IS_NATFUNC((duk_hobject *) h)) {
			goto fail_type;
		}
#if 0
		duk_push_hnatfunc_name(thr, h);
#endif
		duk_push_hstring_empty(thr);
	} else if (DUK_TVAL_IS_LIGHTFUNC(tv)) {
		duk_push_lightfunc_name(thr, tv);
	} else {
		goto fail_type;
	}
	return 1;

fail_type:
	DUK_DCERROR_TYPE_INVALID_ARGS(thr);
}

#if defined(DUK_USE_SYMBOL_BUILTIN)
DUK_INTERNAL duk_ret_t duk_bi_function_prototype_hasinstance(duk_hthread *thr) {
	/* This binding: RHS, stack index 0: LHS. */
	duk_bool_t ret;

	ret = duk_js_instanceof_ordinary(thr, DUK_GET_TVAL_POSIDX(thr, 0), DUK_GET_THIS_TVAL_PTR(thr));
	duk_push_boolean(thr, ret);
	return 1;
}
#endif /* DUK_USE_SYMBOL_BUILTIN */
#line 1 "duk_bi_global.c"
/*
 *  Global object built-ins
 */

/* #include duk_internal.h -> already included */

/*
 *  Encoding/decoding helpers
 */

/* XXX: Could add fast path (for each transform callback) with direct byte
 * lookups (no shifting) and no explicit check for x < 0x80 before table
 * lookup.
 */

/* Macros for creating and checking bitmasks for character encoding.
 * Bit number is a bit counterintuitive, but minimizes code size.
 */
#define DUK__MKBITS(a, b, c, d, e, f, g, h) \
	((duk_uint8_t) (((a) << 0) | ((b) << 1) | ((c) << 2) | ((d) << 3) | ((e) << 4) | ((f) << 5) | ((g) << 6) | ((h) << 7)))
#define DUK__CHECK_BITMASK(table, cp) ((table)[(cp) >> 3] & (1 << ((cp) &0x07)))

/* E5.1 Section 15.1.3.3: uriReserved + uriUnescaped + '#' */
DUK_LOCAL const duk_uint8_t duk__encode_uriunescaped_table[16] = {
	DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x00-0x0f */
	DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x10-0x1f */
	DUK__MKBITS(0, 1, 0, 1, 1, 0, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), /* 0x20-0x2f */
	DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 0, 1, 0, 1), /* 0x30-0x3f */
	DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), /* 0x40-0x4f */
	DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 0, 0, 0, 0, 1), /* 0x50-0x5f */
	DUK__MKBITS(0, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), /* 0x60-0x6f */
	DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 0, 0, 0, 1, 0), /* 0x70-0x7f */
};

/* E5.1 Section 15.1.3.4: uriUnescaped */
DUK_LOCAL const duk_uint8_t duk__encode_uricomponent_unescaped_table[16] = {
	DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x00-0x0f */
	DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x10-0x1f */
	DUK__MKBITS(0, 1, 0, 0, 0, 0, 0, 1), DUK__MKBITS(1, 1, 1, 0, 0, 1, 1, 0), /* 0x20-0x2f */
	DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 0, 0, 0, 0, 0, 0), /* 0x30-0x3f */
	DUK__MKBITS(0, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), /* 0x40-0x4f */
	DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 0, 0, 0, 0, 1), /* 0x50-0x5f */
	DUK__MKBITS(0, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), /* 0x60-0x6f */
	DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 0, 0, 0, 1, 0), /* 0x70-0x7f */
};

/* E5.1 Section 15.1.3.1: uriReserved + '#' */
DUK_LOCAL const duk_uint8_t duk__decode_uri_reserved_table[16] = {
	DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x00-0x0f */
	DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x10-0x1f */
	DUK__MKBITS(0, 0, 0, 1, 1, 0, 1, 0), DUK__MKBITS(0, 0, 0, 1, 1, 0, 0, 1), /* 0x20-0x2f */
	DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 1, 1, 0, 1, 0, 1), /* 0x30-0x3f */
	DUK__MKBITS(1, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x40-0x4f */
	DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x50-0x5f */
	DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x60-0x6f */
	DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x70-0x7f */
};

/* E5.1 Section 15.1.3.2: empty */
DUK_LOCAL const duk_uint8_t duk__decode_uri_component_reserved_table[16] = {
	DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x00-0x0f */
	DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x10-0x1f */
	DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x20-0x2f */
	DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x30-0x3f */
	DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x40-0x4f */
	DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x50-0x5f */
	DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x60-0x6f */
	DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x70-0x7f */
};

#if defined(DUK_USE_SECTION_B)
/* E5.1 Section B.2.2, step 7. */
DUK_LOCAL const duk_uint8_t duk__escape_unescaped_table[16] = {
	DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x00-0x0f */
	DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x10-0x1f */
	DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 1, 1, 0, 1, 1, 1), /* 0x20-0x2f */

lib/JavaScript/Embedded/C/lib/duktape.c  view on Meta::CPAN

#undef DUK__BITPACK_LOOKUP2
#undef DUK__BITPACK_SWITCH
#undef DUK__BITPACK_SWITCH1
#undef DUK__BITPACK_UNUSED1
#line 1 "duk_util_bitencoder.c"
/*
 *  Bitstream encoder.
 */

/* #include duk_internal.h -> already included */

DUK_INTERNAL void duk_be_encode(duk_bitencoder_ctx *ctx, duk_uint32_t data, duk_small_int_t bits) {
	duk_uint8_t tmp;

	DUK_ASSERT(ctx != NULL);
	DUK_ASSERT(ctx->currbits < 8);

	/* This limitation would be fixable but adds unnecessary complexity. */
	DUK_ASSERT(bits >= 1 && bits <= 24);

	ctx->currval = (ctx->currval << bits) | data;
	ctx->currbits += bits;

	while (ctx->currbits >= 8) {
		if (ctx->offset < ctx->length) {
			tmp = (duk_uint8_t) ((ctx->currval >> (ctx->currbits - 8)) & 0xff);
			ctx->data[ctx->offset++] = tmp;
		} else {
			/* If buffer has been exhausted, truncate bitstream */
			ctx->truncated = 1;
		}

		ctx->currbits -= 8;
	}
}

DUK_INTERNAL void duk_be_finish(duk_bitencoder_ctx *ctx) {
	duk_small_int_t npad;

	DUK_ASSERT(ctx != NULL);
	DUK_ASSERT(ctx->currbits < 8);

	npad = (duk_small_int_t) (8 - ctx->currbits);
	if (npad > 0) {
		duk_be_encode(ctx, 0, npad);
	}
	DUK_ASSERT(ctx->currbits == 0);
}
#line 1 "duk_util_bufwriter.c"
/*
 *  Fast buffer writer with slack management.
 */

/* #include duk_internal.h -> already included */

/* XXX: Avoid duk_{memcmp,memmove}_unsafe() by imposing a minimum length of
 * >0 for the underlying dynamic buffer.
 */

/*
 *  Macro support functions (use only macros in calling code)
 */

DUK_LOCAL void duk__bw_update_ptrs(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_size_t curr_offset, duk_size_t new_length) {
	duk_uint8_t *p;

	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(bw_ctx != NULL);
	DUK_UNREF(thr);

	/* 'p' might be NULL when the underlying buffer is zero size.  If so,
	 * the resulting pointers are not used unsafely.
	 */
	p = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, bw_ctx->buf);
	DUK_ASSERT(p != NULL || (DUK_HBUFFER_DYNAMIC_GET_SIZE(bw_ctx->buf) == 0 && curr_offset == 0 && new_length == 0));
	bw_ctx->p = p + curr_offset;
	bw_ctx->p_base = p;
	bw_ctx->p_limit = p + new_length;
}

DUK_INTERNAL void duk_bw_init(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_hbuffer_dynamic *h_buf) {
	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(bw_ctx != NULL);
	DUK_ASSERT(h_buf != NULL);

	bw_ctx->buf = h_buf;
	duk__bw_update_ptrs(thr, bw_ctx, 0, DUK_HBUFFER_DYNAMIC_GET_SIZE(h_buf));
}

DUK_INTERNAL void duk_bw_init_pushbuf(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_size_t buf_size) {
	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(bw_ctx != NULL);

	(void) duk_push_dynamic_buffer(thr, buf_size);
	bw_ctx->buf = (duk_hbuffer_dynamic *) duk_known_hbuffer(thr, -1);
	DUK_ASSERT(bw_ctx->buf != NULL);
	duk__bw_update_ptrs(thr, bw_ctx, 0, buf_size);
}

/* Resize target buffer for requested size.  Called by the macro only when the
 * fast path test (= there is space) fails.
 */
DUK_INTERNAL duk_uint8_t *duk_bw_resize(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_size_t sz) {
	duk_size_t curr_off;
	duk_size_t add_sz;
	duk_size_t new_sz;

	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(bw_ctx != NULL);

	/* We could do this operation without caller updating bw_ctx->ptr,
	 * but by writing it back here we can share code better.
	 */

	curr_off = (duk_size_t) (bw_ctx->p - bw_ctx->p_base);
	add_sz = (curr_off >> DUK_BW_SLACK_SHIFT) + DUK_BW_SLACK_ADD;
	new_sz = curr_off + sz + add_sz;
	if (DUK_UNLIKELY(new_sz < curr_off)) {
		/* overflow */
		DUK_ERROR_RANGE(thr, DUK_STR_BUFFER_TOO_LONG);
		DUK_WO_NORETURN(return NULL;);



( run in 1.526 second using v1.01-cache-2.11-cpan-8644d7adfcd )