diff options
Diffstat (limited to 'content/handlers/javascript/duktape/duktape.c')
-rw-r--r-- | content/handlers/javascript/duktape/duktape.c | 43605 |
1 files changed, 24116 insertions, 19489 deletions
diff --git a/content/handlers/javascript/duktape/duktape.c b/content/handlers/javascript/duktape/duktape.c index b64383b11..4e5662188 100644 --- a/content/handlers/javascript/duktape/duktape.c +++ b/content/handlers/javascript/duktape/duktape.c @@ -1,10 +1,10 @@ /* Omit from static analysis. */ #ifndef __clang_analyzer__ /* - * Single source autogenerated distributable for Duktape 1.6.0. + * Single source autogenerated distributable for Duktape 2.0.2. * - * Git commit 17e3d86cf8b4788bd0d37658f833ab440ce43a1c (v1.6.0). - * Git branch HEAD. + * Git commit external (external). + * Git branch external. * * See Duktape AUTHORS.rst and LICENSE.txt for copyright and * licensing information. @@ -18,7 +18,7 @@ * * (http://opensource.org/licenses/MIT) * -* Copyright (c) 2013-2016 by Duktape authors (see AUTHORS.rst) +* Copyright (c) 2013-2017 by Duktape authors (see AUTHORS.rst) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -38,6 +38,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + /* AUTHORS.rst */ /* * =============== @@ -71,6 +72,18 @@ * * Ren\u00e9 Hollander <rene@rene8888.at> * * Julien Hamaide (https://github.com/crazyjul) * * Sebastian G\u00f6tte (https://github.com/jaseg) +* * Tomasz Magulski (https://github.com/magul) +* * \D. Bohdan (https://github.com/dbohdan) +* * Ond\u0159ej Jirman (https://github.com/megous) +* * Sa\u00fal Ibarra Corretg\u00e9 <saghul@gmail.com> +* * Jeremy HU <huxingyi@msn.com> +* * Ole Andr\u00e9 Vadla Ravn\u00e5s (https://github.com/oleavr) +* * Harold Brenes (https://github.com/harold-b) +* * Oliver Crow (https://github.com/ocrow) +* * Jakub Ch\u0142api\u0144ski (https://github.com/jchlapinski) +* * Brett Vickers (https://github.com/beevik) +* * Dominik Okwieka (https://github.com/okitec) +* * Remko Tron\u00e7on (https://el-tramo.be) * * Other contributions * =================== @@ -108,12 +121,21 @@ * * Michael Drake (https://github.com/tlsa) * * https://github.com/chris-y * * Laurent Zubiaur (https://github.com/lzubiaur) -* * Ole Andr\u00e9 Vadla Ravn\u00e5s (https://github.com/oleavr) +* * Neil Kolban (https://github.com/nkolban) * * If you are accidentally missing from this list, send me an e-mail * (``sami.vaarala@iki.fi``) and I'll fix the omission. */ -#line 1 "duk_internal.h" + +/* + * Replacements for missing platform functions. + * + * Unlike the originals, fpclassify() and signbit() replacements don't + * work on any floating point types, only doubles. The C typing here + * mimics the standard prototypes. + */ + +/* #include duk_internal.h */ /* * Top-level include file to be used for all (internal) source files. * @@ -121,7 +143,7 @@ * have not been designed to be individually included. */ -#ifndef DUK_INTERNAL_H_INCLUDED +#if !defined(DUK_INTERNAL_H_INCLUDED) #define DUK_INTERNAL_H_INCLUDED /* @@ -143,9 +165,7 @@ /* * User declarations, e.g. prototypes for user functions used by Duktape - * macros. Concretely, if DUK_USE_PANIC_HANDLER is used and the macro - * value calls a user function, it needs to be declared for Duktape - * compilation to avoid warnings. + * macros. */ DUK_USE_USER_DECLARE() @@ -159,8 +179,8 @@ DUK_USE_USER_DECLARE() * dependencies. */ -#line 1 "duk_replacements.h" -#ifndef DUK_REPLACEMENTS_H_INCLUDED +/* #include duk_replacements.h */ +#if !defined(DUK_REPLACEMENTS_H_INCLUDED) #define DUK_REPLACEMENTS_H_INCLUDED #if !defined(DUK_SINGLE_FILE) @@ -170,6 +190,8 @@ DUK_INTERNAL_DECL double duk_computed_infinity; #if defined(DUK_USE_COMPUTED_NAN) DUK_INTERNAL_DECL double duk_computed_nan; #endif +#endif /* !DUK_SINGLE_FILE */ + #if defined(DUK_USE_REPL_FPCLASSIFY) DUK_INTERNAL_DECL int duk_repl_fpclassify(double x); #endif @@ -185,10 +207,9 @@ DUK_INTERNAL_DECL int duk_repl_isnan(double x); #if defined(DUK_USE_REPL_ISINF) DUK_INTERNAL_DECL int duk_repl_isinf(double x); #endif -#endif /* !DUK_SINGLE_FILE */ #endif /* DUK_REPLACEMENTS_H_INCLUDED */ -#line 1 "duk_jmpbuf.h" +/* #include duk_jmpbuf.h */ /* * Wrapper for jmp_buf. * @@ -199,7 +220,7 @@ DUK_INTERNAL_DECL int duk_repl_isinf(double x); * http://en.wikipedia.org/wiki/Setjmp.h#Member_types */ -#ifndef DUK_JMPBUF_H_INCLUDED +#if !defined(DUK_JMPBUF_H_INCLUDED) #define DUK_JMPBUF_H_INCLUDED #if defined(DUK_USE_CPP_EXCEPTIONS) @@ -213,7 +234,7 @@ struct duk_jmpbuf { #endif #endif /* DUK_JMPBUF_H_INCLUDED */ -#line 1 "duk_exception.h" +/* #include duk_exception.h */ /* * Exception for Duktape internal throws when C++ exceptions are used * for long control transfers. @@ -222,7 +243,7 @@ struct duk_jmpbuf { * that user code would accidentally catch this exception. */ -#ifndef DUK_EXCEPTION_H_INCLUDED +#if !defined(DUK_EXCEPTION_H_INCLUDED) #define DUK_EXCEPTION_H_INCLUDED #if defined(DUK_USE_CPP_EXCEPTIONS) @@ -232,12 +253,12 @@ class duk_internal_exception { #endif #endif /* DUK_EXCEPTION_H_INCLUDED */ -#line 1 "duk_forwdecl.h" +/* #include duk_forwdecl.h */ /* * Forward declarations for all Duktape structures. */ -#ifndef DUK_FORWDECL_H_INCLUDED +#if !defined(DUK_FORWDECL_H_INCLUDED) #define DUK_FORWDECL_H_INCLUDED /* @@ -253,13 +274,14 @@ struct duk_jmpbuf; /* duk_tval intentionally skipped */ struct duk_heaphdr; struct duk_heaphdr_string; +struct duk_harray; struct duk_hstring; struct duk_hstring_external; struct duk_hobject; -struct duk_hcompiledfunction; -struct duk_hnativefunction; +struct duk_hcompfunc; +struct duk_hnatfunc; struct duk_hthread; -struct duk_hbufferobject; +struct duk_hbufobj; struct duk_hbuffer; struct duk_hbuffer_fixed; struct duk_hbuffer_dynamic; @@ -278,7 +300,7 @@ struct duk_strcache; struct duk_ljstate; struct duk_strtab_entry; -#ifdef DUK_USE_DEBUG +#if defined(DUK_USE_DEBUG) struct duk_fixedbuffer; #endif @@ -308,12 +330,13 @@ typedef struct duk_jmpbuf duk_jmpbuf; /* duk_tval intentionally skipped */ typedef struct duk_heaphdr duk_heaphdr; typedef struct duk_heaphdr_string duk_heaphdr_string; +typedef struct duk_harray duk_harray; typedef struct duk_hstring duk_hstring; typedef struct duk_hstring_external duk_hstring_external; typedef struct duk_hobject duk_hobject; -typedef struct duk_hcompiledfunction duk_hcompiledfunction; -typedef struct duk_hnativefunction duk_hnativefunction; -typedef struct duk_hbufferobject duk_hbufferobject; +typedef struct duk_hcompfunc duk_hcompfunc; +typedef struct duk_hnatfunc duk_hnatfunc; +typedef struct duk_hbufobj duk_hbufobj; typedef struct duk_hthread duk_hthread; typedef struct duk_hbuffer duk_hbuffer; typedef struct duk_hbuffer_fixed duk_hbuffer_fixed; @@ -333,7 +356,7 @@ typedef struct duk_strcache duk_strcache; typedef struct duk_ljstate duk_ljstate; typedef struct duk_strtab_entry duk_strtab_entry; -#ifdef DUK_USE_DEBUG +#if defined(DUK_USE_DEBUG) typedef struct duk_fixedbuffer duk_fixedbuffer; #endif @@ -355,7 +378,7 @@ typedef struct duk_re_matcher_ctx duk_re_matcher_ctx; typedef struct duk_re_compiler_ctx duk_re_compiler_ctx; #endif /* DUK_FORWDECL_H_INCLUDED */ -#line 1 "duk_tval.h" +/* #include duk_tval.h */ /* * Tagged type definition (duk_tval) and accessor macros. * @@ -368,15 +391,13 @@ typedef struct duk_re_compiler_ctx duk_re_compiler_ctx; * 64-bit environments (it usually pads to 16 bytes per value). * * Selecting the tagged type format involves many trade-offs (memory - * use, size and performance of generated code, portability, etc), - * see doc/types.rst for a detailed discussion (especially of how the - * IEEE double format is used to pack tagged values). + * use, size and performance of generated code, portability, etc). * * NB: because macro arguments are often expressions, macros should * avoid evaluating their argument more than once. */ -#ifndef DUK_TVAL_H_INCLUDED +#if !defined(DUK_TVAL_H_INCLUDED) #define DUK_TVAL_H_INCLUDED /* sanity */ @@ -393,10 +414,17 @@ typedef struct duk_re_compiler_ctx duk_re_compiler_ctx; /* 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 @@ -410,195 +438,226 @@ typedef union duk_double_union duk_tval; #define DUK_TAG_STRING 0xfff8UL /* embed: duk_hstring ptr */ #define DUK_TAG_OBJECT 0xfff9UL /* embed: duk_hobject ptr */ #define DUK_TAG_BUFFER 0xfffaUL /* embed: duk_hbuffer ptr */ +#define DUK_TAG_MAX 0xfffaUL /* for convenience */ #define DUK_XTAG_BOOLEAN_FALSE 0xfff50000UL #define DUK_XTAG_BOOLEAN_TRUE 0xfff50001UL +#define DUK_TVAL_IS_VALID_TAG(tv) \ + (DUK_TVAL_GET_TAG((tv)) - DUK_TAG_MIN <= DUK_TAG_MAX - DUK_TAG_MIN) + +/* DUK_TVAL_UNUSED initializer for duk_tval_unused, works for any endianness. */ +#define DUK_TVAL_UNUSED_INITIALIZER() \ + { DUK_TAG_UNUSED, DUK_TAG_UNUSED, DUK_TAG_UNUSED, DUK_TAG_UNUSED } + /* two casts to avoid gcc warning: "warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]" */ #if defined(DUK_USE_64BIT_OPS) #if defined(DUK_USE_DOUBLE_ME) -#define DUK__TVAL_SET_TAGGEDPOINTER(v,h,tag) do { \ - (v)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) (tag)) << 16) | (((duk_uint64_t) (duk_uint32_t) (h)) << 32); \ +#define DUK__TVAL_SET_TAGGEDPOINTER(tv,h,tag) do { \ + (tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) (tag)) << 16) | (((duk_uint64_t) (duk_uint32_t) (h)) << 32); \ } while (0) #else -#define DUK__TVAL_SET_TAGGEDPOINTER(v,h,tag) do { \ - (v)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) (tag)) << 48) | ((duk_uint64_t) (duk_uint32_t) (h)); \ +#define DUK__TVAL_SET_TAGGEDPOINTER(tv,h,tag) do { \ + (tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) (tag)) << 48) | ((duk_uint64_t) (duk_uint32_t) (h)); \ } while (0) #endif #else /* DUK_USE_64BIT_OPS */ -#define DUK__TVAL_SET_TAGGEDPOINTER(v,h,tag) do { \ - (v)->ui[DUK_DBL_IDX_UI0] = ((duk_uint32_t) (tag)) << 16; \ - (v)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (h); \ +#define DUK__TVAL_SET_TAGGEDPOINTER(tv,h,tag) do { \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->ui[DUK_DBL_IDX_UI0] = ((duk_uint32_t) (tag)) << 16; \ + duk__tv->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (h); \ } while (0) #endif /* DUK_USE_64BIT_OPS */ #if defined(DUK_USE_64BIT_OPS) /* Double casting for pointer to avoid gcc warning (cast from pointer to integer of different size) */ #if defined(DUK_USE_DOUBLE_ME) -#define DUK__TVAL_SET_LIGHTFUNC(v,fp,flags) do { \ - (v)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_LIGHTFUNC) << 16) | \ - ((duk_uint64_t) (flags)) | \ - (((duk_uint64_t) (duk_uint32_t) (fp)) << 32); \ +#define DUK__TVAL_SET_LIGHTFUNC(tv,fp,flags) do { \ + (tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_LIGHTFUNC) << 16) | \ + ((duk_uint64_t) (flags)) | \ + (((duk_uint64_t) (duk_uint32_t) (fp)) << 32); \ } while (0) #else -#define DUK__TVAL_SET_LIGHTFUNC(v,fp,flags) do { \ - (v)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_LIGHTFUNC) << 48) | \ - (((duk_uint64_t) (flags)) << 32) | \ - ((duk_uint64_t) (duk_uint32_t) (fp)); \ +#define DUK__TVAL_SET_LIGHTFUNC(tv,fp,flags) do { \ + (tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_LIGHTFUNC) << 48) | \ + (((duk_uint64_t) (flags)) << 32) | \ + ((duk_uint64_t) (duk_uint32_t) (fp)); \ } while (0) #endif #else /* DUK_USE_64BIT_OPS */ -#define DUK__TVAL_SET_LIGHTFUNC(v,fp,flags) do { \ - (v)->ui[DUK_DBL_IDX_UI0] = (((duk_uint32_t) DUK_TAG_LIGHTFUNC) << 16) | ((duk_uint32_t) (flags)); \ - (v)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (fp); \ +#define DUK__TVAL_SET_LIGHTFUNC(tv,fp,flags) do { \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->ui[DUK_DBL_IDX_UI0] = (((duk_uint32_t) DUK_TAG_LIGHTFUNC) << 16) | ((duk_uint32_t) (flags)); \ + duk__tv->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (fp); \ } while (0) #endif /* DUK_USE_64BIT_OPS */ #if defined(DUK_USE_FASTINT) /* Note: masking is done for 'i' to deal with negative numbers correctly */ #if defined(DUK_USE_DOUBLE_ME) -#define DUK__TVAL_SET_FASTINT(v,i) do { \ - (v)->ui[DUK_DBL_IDX_UI0] = ((duk_uint32_t) DUK_TAG_FASTINT) << 16 | (((duk_uint32_t) ((i) >> 32)) & 0x0000ffffUL); \ - (v)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (i); \ +#define DUK__TVAL_SET_I48(tv,i) do { \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->ui[DUK_DBL_IDX_UI0] = ((duk_uint32_t) DUK_TAG_FASTINT) << 16 | (((duk_uint32_t) ((i) >> 32)) & 0x0000ffffUL); \ + duk__tv->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (i); \ } while (0) -#define DUK__TVAL_SET_FASTINT_U32(v,i) do { \ - (v)->ui[DUK_DBL_IDX_UI0] = ((duk_uint32_t) DUK_TAG_FASTINT) << 16; \ - (v)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (i); \ +#define DUK__TVAL_SET_U32(tv,i) do { \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->ui[DUK_DBL_IDX_UI0] = ((duk_uint32_t) DUK_TAG_FASTINT) << 16; \ + duk__tv->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (i); \ } while (0) #else -#define DUK__TVAL_SET_FASTINT(v,i) do { \ - (v)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_FASTINT) << 48) | (((duk_uint64_t) (i)) & 0x0000ffffffffffffULL); \ +#define DUK__TVAL_SET_I48(tv,i) do { \ + (tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_FASTINT) << 48) | (((duk_uint64_t) (i)) & 0x0000ffffffffffffULL); \ } while (0) -#define DUK__TVAL_SET_FASTINT_U32(v,i) do { \ - (v)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_FASTINT) << 48) | (duk_uint64_t) (i); \ +#define DUK__TVAL_SET_U32(tv,i) do { \ + (tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_FASTINT) << 48) | (duk_uint64_t) (i); \ } while (0) #endif -#define DUK__TVAL_SET_FASTINT_I32(v,i) do { \ +/* This needs to go through a cast because sign extension is needed. */ +#define DUK__TVAL_SET_I32(tv,i) do { \ duk_int64_t duk__tmp = (duk_int64_t) (i); \ - DUK_TVAL_SET_FASTINT((v), duk__tmp); \ + DUK_TVAL_SET_I48((tv), duk__tmp); \ } while (0) -/* XXX: clumsy sign extend and masking of 16 topmost bits */ +/* XXX: Clumsy sign extend and masking of 16 topmost bits. */ #if defined(DUK_USE_DOUBLE_ME) -#define DUK__TVAL_GET_FASTINT(v) (((duk_int64_t) ((((duk_uint64_t) (v)->ui[DUK_DBL_IDX_UI0]) << 32) | ((duk_uint64_t) (v)->ui[DUK_DBL_IDX_UI1]))) << 16 >> 16) +#define DUK__TVAL_GET_FASTINT(tv) (((duk_int64_t) ((((duk_uint64_t) (tv)->ui[DUK_DBL_IDX_UI0]) << 32) | ((duk_uint64_t) (tv)->ui[DUK_DBL_IDX_UI1]))) << 16 >> 16) #else -#define DUK__TVAL_GET_FASTINT(v) ((((duk_int64_t) (v)->ull[DUK_DBL_IDX_ULL0]) << 16) >> 16) +#define DUK__TVAL_GET_FASTINT(tv) ((((duk_int64_t) (tv)->ull[DUK_DBL_IDX_ULL0]) << 16) >> 16) #endif -#define DUK__TVAL_GET_FASTINT_U32(v) ((v)->ui[DUK_DBL_IDX_UI1]) -#define DUK__TVAL_GET_FASTINT_I32(v) ((duk_int32_t) (v)->ui[DUK_DBL_IDX_UI1]) +#define DUK__TVAL_GET_FASTINT_U32(tv) ((tv)->ui[DUK_DBL_IDX_UI1]) +#define DUK__TVAL_GET_FASTINT_I32(tv) ((duk_int32_t) (tv)->ui[DUK_DBL_IDX_UI1]) #endif /* DUK_USE_FASTINT */ -#define DUK_TVAL_SET_UNDEFINED(v) do { \ - (v)->us[DUK_DBL_IDX_US0] = (duk_uint16_t) DUK_TAG_UNDEFINED; \ +#define DUK_TVAL_SET_UNDEFINED(tv) do { \ + (tv)->us[DUK_DBL_IDX_US0] = (duk_uint16_t) DUK_TAG_UNDEFINED; \ } while (0) -#define DUK_TVAL_SET_UNUSED(v) do { \ - (v)->us[DUK_DBL_IDX_US0] = (duk_uint16_t) DUK_TAG_UNUSED; \ +#define DUK_TVAL_SET_UNUSED(tv) do { \ + (tv)->us[DUK_DBL_IDX_US0] = (duk_uint16_t) DUK_TAG_UNUSED; \ } while (0) -#define DUK_TVAL_SET_NULL(v) do { \ - (v)->us[DUK_DBL_IDX_US0] = (duk_uint16_t) DUK_TAG_NULL; \ +#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(v,val) DUK_DBLUNION_SET_HIGH32((v), (((duk_uint32_t) DUK_TAG_BOOLEAN) << 16) | ((duk_uint32_t) (val))) +#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(v) DUK_DBLUNION_SET_NAN_FULL((v)) +#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(v,d) do { \ +#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((v), duk__dblval); \ + DUK_DBLUNION_SET_DOUBLE((tv), duk__dblval); \ } while (0) -#define DUK_TVAL_SET_FASTINT(v,i) DUK__TVAL_SET_FASTINT((v), (i)) -#define DUK_TVAL_SET_FASTINT_I32(v,i) DUK__TVAL_SET_FASTINT_I32((v), (i)) -#define DUK_TVAL_SET_FASTINT_U32(v,i) DUK__TVAL_SET_FASTINT_U32((v), (i)) -#define DUK_TVAL_SET_NUMBER_CHKFAST(v,d) duk_tval_set_number_chkfast((v), (d)) -#define DUK_TVAL_SET_NUMBER(v,d) DUK_TVAL_SET_DOUBLE((v), (d)) -#define DUK_TVAL_CHKFAST_INPLACE(v) do { \ +#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)) +#define DUK_TVAL_SET_U32(tv,i) DUK__TVAL_SET_U32((tv), (i)) +#define DUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv,d) duk_tval_set_number_chkfast_fast((tv), (d)) +#define DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv,d) duk_tval_set_number_chkfast_slow((tv), (d)) +#define DUK_TVAL_SET_NUMBER(tv,d) DUK_TVAL_SET_DOUBLE((tv), (d)) +#define DUK_TVAL_CHKFAST_INPLACE_FAST(tv) do { \ duk_tval *duk__tv; \ duk_double_t duk__d; \ - duk__tv = (v); \ + duk__tv = (tv); \ if (DUK_TVAL_IS_DOUBLE(duk__tv)) { \ duk__d = DUK_TVAL_GET_DOUBLE(duk__tv); \ - DUK_TVAL_SET_NUMBER_CHKFAST(duk__tv, duk__d); \ + DUK_TVAL_SET_NUMBER_CHKFAST_FAST(duk__tv, duk__d); \ } \ } while (0) -#else -#define DUK_TVAL_SET_DOUBLE(v,d) do { \ +#define DUK_TVAL_CHKFAST_INPLACE_SLOW(tv) do { \ + duk_tval *duk__tv; \ + duk_double_t duk__d; \ + duk__tv = (tv); \ + if (DUK_TVAL_IS_DOUBLE(duk__tv)) { \ + duk__d = DUK_TVAL_GET_DOUBLE(duk__tv); \ + DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(duk__tv, duk__d); \ + } \ + } while (0) +#else /* 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((v), duk__dblval); \ + DUK_DBLUNION_SET_DOUBLE((tv), duk__dblval); \ } while (0) -#define DUK_TVAL_SET_FASTINT(v,i) DUK_TVAL_SET_DOUBLE((v), (duk_double_t) (i)) /* XXX: fast int-to-double */ -#define DUK_TVAL_SET_FASTINT_I32(v,i) DUK_TVAL_SET_DOUBLE((v), (duk_double_t) (i)) -#define DUK_TVAL_SET_FASTINT_U32(v,i) DUK_TVAL_SET_DOUBLE((v), (duk_double_t) (i)) -#define DUK_TVAL_SET_NUMBER_CHKFAST(v,d) DUK_TVAL_SET_DOUBLE((v), (d)) -#define DUK_TVAL_SET_NUMBER(v,d) DUK_TVAL_SET_DOUBLE((v), (d)) -#define DUK_TVAL_CHKFAST_INPLACE(v) do { } while (0) -#endif +#define DUK_TVAL_SET_I48(tv,i) DUK_TVAL_SET_DOUBLE((tv), (duk_double_t) (i)) /* XXX: fast int-to-double */ +#define DUK_TVAL_SET_I32(tv,i) DUK_TVAL_SET_DOUBLE((tv), (duk_double_t) (i)) +#define DUK_TVAL_SET_U32(tv,i) DUK_TVAL_SET_DOUBLE((tv), (duk_double_t) (i)) +#define DUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv,d) DUK_TVAL_SET_DOUBLE((tv), (d)) +#define DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv,d) DUK_TVAL_SET_DOUBLE((tv), (d)) +#define DUK_TVAL_SET_NUMBER(tv,d) DUK_TVAL_SET_DOUBLE((tv), (d)) +#define DUK_TVAL_CHKFAST_INPLACE_FAST(tv) do { } while (0) +#define DUK_TVAL_CHKFAST_INPLACE_SLOW(tv) do { } while (0) +#endif /* DUK_USE_FASTINT */ -#define DUK_TVAL_SET_LIGHTFUNC(v,fp,flags) DUK__TVAL_SET_LIGHTFUNC((v), (fp), (flags)) -#define DUK_TVAL_SET_STRING(v,h) DUK__TVAL_SET_TAGGEDPOINTER((v), (h), DUK_TAG_STRING) -#define DUK_TVAL_SET_OBJECT(v,h) DUK__TVAL_SET_TAGGEDPOINTER((v), (h), DUK_TAG_OBJECT) -#define DUK_TVAL_SET_BUFFER(v,h) DUK__TVAL_SET_TAGGEDPOINTER((v), (h), DUK_TAG_BUFFER) -#define DUK_TVAL_SET_POINTER(v,p) DUK__TVAL_SET_TAGGEDPOINTER((v), (p), DUK_TAG_POINTER) +#define DUK_TVAL_SET_FASTINT(tv,i) DUK_TVAL_SET_I48((tv), (i)) /* alias */ -#define DUK_TVAL_SET_TVAL(v,x) do { *(v) = *(x); } while (0) +#define DUK_TVAL_SET_LIGHTFUNC(tv,fp,flags) DUK__TVAL_SET_LIGHTFUNC((tv), (fp), (flags)) +#define DUK_TVAL_SET_STRING(tv,h) DUK__TVAL_SET_TAGGEDPOINTER((tv), (h), DUK_TAG_STRING) +#define DUK_TVAL_SET_OBJECT(tv,h) DUK__TVAL_SET_TAGGEDPOINTER((tv), (h), DUK_TAG_OBJECT) +#define DUK_TVAL_SET_BUFFER(tv,h) DUK__TVAL_SET_TAGGEDPOINTER((tv), (h), DUK_TAG_BUFFER) +#define DUK_TVAL_SET_POINTER(tv,p) DUK__TVAL_SET_TAGGEDPOINTER((tv), (p), DUK_TAG_POINTER) + +#define DUK_TVAL_SET_TVAL(tv,x) do { *(tv) = *(x); } while (0) /* getters */ -#define DUK_TVAL_GET_BOOLEAN(v) ((int) (v)->us[DUK_DBL_IDX_US1]) +#define DUK_TVAL_GET_BOOLEAN(tv) ((duk_small_int_t) (tv)->us[DUK_DBL_IDX_US1]) #if defined(DUK_USE_FASTINT) -#define DUK_TVAL_GET_DOUBLE(v) ((v)->d) -#define DUK_TVAL_GET_FASTINT(v) DUK__TVAL_GET_FASTINT((v)) -#define DUK_TVAL_GET_FASTINT_U32(v) DUK__TVAL_GET_FASTINT_U32((v)) -#define DUK_TVAL_GET_FASTINT_I32(v) DUK__TVAL_GET_FASTINT_I32((v)) -#define DUK_TVAL_GET_NUMBER(v) duk_tval_get_number_packed((v)) +#define DUK_TVAL_GET_DOUBLE(tv) ((tv)->d) +#define DUK_TVAL_GET_FASTINT(tv) DUK__TVAL_GET_FASTINT((tv)) +#define DUK_TVAL_GET_FASTINT_U32(tv) DUK__TVAL_GET_FASTINT_U32((tv)) +#define DUK_TVAL_GET_FASTINT_I32(tv) DUK__TVAL_GET_FASTINT_I32((tv)) +#define DUK_TVAL_GET_NUMBER(tv) duk_tval_get_number_packed((tv)) #else -#define DUK_TVAL_GET_NUMBER(v) ((v)->d) -#define DUK_TVAL_GET_DOUBLE(v) ((v)->d) +#define DUK_TVAL_GET_NUMBER(tv) ((tv)->d) +#define DUK_TVAL_GET_DOUBLE(tv) ((tv)->d) #endif -#define DUK_TVAL_GET_LIGHTFUNC(v,out_fp,out_flags) do { \ - (out_flags) = (v)->ui[DUK_DBL_IDX_UI0] & 0xffffUL; \ - (out_fp) = (duk_c_function) (v)->ui[DUK_DBL_IDX_UI1]; \ +#define DUK_TVAL_GET_LIGHTFUNC(tv,out_fp,out_flags) do { \ + (out_flags) = (tv)->ui[DUK_DBL_IDX_UI0] & 0xffffUL; \ + (out_fp) = (duk_c_function) (tv)->ui[DUK_DBL_IDX_UI1]; \ } while (0) -#define DUK_TVAL_GET_LIGHTFUNC_FUNCPTR(v) ((duk_c_function) ((v)->ui[DUK_DBL_IDX_UI1])) -#define DUK_TVAL_GET_LIGHTFUNC_FLAGS(v) (((int) (v)->ui[DUK_DBL_IDX_UI0]) & 0xffffUL) -#define DUK_TVAL_GET_STRING(v) ((duk_hstring *) (v)->vp[DUK_DBL_IDX_VP1]) -#define DUK_TVAL_GET_OBJECT(v) ((duk_hobject *) (v)->vp[DUK_DBL_IDX_VP1]) -#define DUK_TVAL_GET_BUFFER(v) ((duk_hbuffer *) (v)->vp[DUK_DBL_IDX_VP1]) -#define DUK_TVAL_GET_POINTER(v) ((void *) (v)->vp[DUK_DBL_IDX_VP1]) -#define DUK_TVAL_GET_HEAPHDR(v) ((duk_heaphdr *) (v)->vp[DUK_DBL_IDX_VP1]) +#define DUK_TVAL_GET_LIGHTFUNC_FUNCPTR(tv) ((duk_c_function) ((tv)->ui[DUK_DBL_IDX_UI1])) +#define DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv) (((duk_small_int_t) (tv)->ui[DUK_DBL_IDX_UI0]) & 0xffffUL) +#define DUK_TVAL_GET_STRING(tv) ((duk_hstring *) (tv)->vp[DUK_DBL_IDX_VP1]) +#define DUK_TVAL_GET_OBJECT(tv) ((duk_hobject *) (tv)->vp[DUK_DBL_IDX_VP1]) +#define DUK_TVAL_GET_BUFFER(tv) ((duk_hbuffer *) (tv)->vp[DUK_DBL_IDX_VP1]) +#define DUK_TVAL_GET_POINTER(tv) ((void *) (tv)->vp[DUK_DBL_IDX_VP1]) +#define DUK_TVAL_GET_HEAPHDR(tv) ((duk_heaphdr *) (tv)->vp[DUK_DBL_IDX_VP1]) /* decoding */ -#define DUK_TVAL_GET_TAG(v) ((duk_small_uint_t) (v)->us[DUK_DBL_IDX_US0]) - -#define DUK_TVAL_IS_UNDEFINED(v) (DUK_TVAL_GET_TAG((v)) == DUK_TAG_UNDEFINED) -#define DUK_TVAL_IS_UNUSED(v) (DUK_TVAL_GET_TAG((v)) == DUK_TAG_UNUSED) -#define DUK_TVAL_IS_NULL(v) (DUK_TVAL_GET_TAG((v)) == DUK_TAG_NULL) -#define DUK_TVAL_IS_BOOLEAN(v) (DUK_TVAL_GET_TAG((v)) == DUK_TAG_BOOLEAN) -#define DUK_TVAL_IS_BOOLEAN_TRUE(v) ((v)->ui[DUK_DBL_IDX_UI0] == DUK_XTAG_BOOLEAN_TRUE) -#define DUK_TVAL_IS_BOOLEAN_FALSE(v) ((v)->ui[DUK_DBL_IDX_UI0] == DUK_XTAG_BOOLEAN_FALSE) -#define DUK_TVAL_IS_LIGHTFUNC(v) (DUK_TVAL_GET_TAG((v)) == DUK_TAG_LIGHTFUNC) -#define DUK_TVAL_IS_STRING(v) (DUK_TVAL_GET_TAG((v)) == DUK_TAG_STRING) -#define DUK_TVAL_IS_OBJECT(v) (DUK_TVAL_GET_TAG((v)) == DUK_TAG_OBJECT) -#define DUK_TVAL_IS_BUFFER(v) (DUK_TVAL_GET_TAG((v)) == DUK_TAG_BUFFER) -#define DUK_TVAL_IS_POINTER(v) (DUK_TVAL_GET_TAG((v)) == DUK_TAG_POINTER) +#define DUK_TVAL_GET_TAG(tv) ((duk_small_uint_t) (tv)->us[DUK_DBL_IDX_US0]) + +#define DUK_TVAL_IS_UNDEFINED(tv) (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_UNDEFINED) +#define DUK_TVAL_IS_UNUSED(tv) (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_UNUSED) +#define DUK_TVAL_IS_NULL(tv) (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_NULL) +#define DUK_TVAL_IS_BOOLEAN(tv) (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_BOOLEAN) +#define DUK_TVAL_IS_BOOLEAN_TRUE(tv) ((tv)->ui[DUK_DBL_IDX_UI0] == DUK_XTAG_BOOLEAN_TRUE) +#define DUK_TVAL_IS_BOOLEAN_FALSE(tv) ((tv)->ui[DUK_DBL_IDX_UI0] == DUK_XTAG_BOOLEAN_FALSE) +#define DUK_TVAL_IS_LIGHTFUNC(tv) (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_LIGHTFUNC) +#define DUK_TVAL_IS_STRING(tv) (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_STRING) +#define DUK_TVAL_IS_OBJECT(tv) (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_OBJECT) +#define DUK_TVAL_IS_BUFFER(tv) (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_BUFFER) +#define DUK_TVAL_IS_POINTER(tv) (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_POINTER) #if defined(DUK_USE_FASTINT) /* 0xfff0 is -Infinity */ -#define DUK_TVAL_IS_DOUBLE(v) (DUK_TVAL_GET_TAG((v)) <= 0xfff0UL) -#define DUK_TVAL_IS_FASTINT(v) (DUK_TVAL_GET_TAG((v)) == DUK_TAG_FASTINT) -#define DUK_TVAL_IS_NUMBER(v) (DUK_TVAL_GET_TAG((v)) <= 0xfff1UL) +#define DUK_TVAL_IS_DOUBLE(tv) (DUK_TVAL_GET_TAG((tv)) <= 0xfff0UL) +#define DUK_TVAL_IS_FASTINT(tv) (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_FASTINT) +#define DUK_TVAL_IS_NUMBER(tv) (DUK_TVAL_GET_TAG((tv)) <= 0xfff1UL) #else -#define DUK_TVAL_IS_NUMBER(v) (DUK_TVAL_GET_TAG((v)) <= 0xfff0UL) -#define DUK_TVAL_IS_DOUBLE(v) DUK_TVAL_IS_NUMBER((v)) +#define DUK_TVAL_IS_NUMBER(tv) (DUK_TVAL_GET_TAG((tv)) <= 0xfff0UL) +#define DUK_TVAL_IS_DOUBLE(tv) DUK_TVAL_IS_NUMBER((tv)) #endif /* This is performance critical because it appears in every DECREF. */ -#define DUK_TVAL_IS_HEAP_ALLOCATED(v) (DUK_TVAL_GET_TAG((v)) >= DUK_TAG_STRING) +#define DUK_TVAL_IS_HEAP_ALLOCATED(tv) (DUK_TVAL_GET_TAG((tv)) >= DUK_TAG_STRING) #if defined(DUK_USE_FASTINT) DUK_INTERNAL_DECL duk_double_t duk_tval_get_number_packed(duk_tval *tv); @@ -633,8 +692,8 @@ struct duk_tval_struct { void *voidptr; duk_hstring *hstring; duk_hobject *hobject; - duk_hcompiledfunction *hcompiledfunction; - duk_hnativefunction *hnativefunction; + duk_hcompfunc *hcompfunc; + duk_hnatfunc *hnatfunc; duk_hthread *hthread; duk_hbuffer *hbuffer; duk_heaphdr *heaphdr; @@ -642,7 +701,22 @@ struct duk_tval_struct { } v; }; -#define DUK__TAG_NUMBER 0 /* not exposed */ +typedef struct { + duk_small_uint_t t; + duk_small_uint_t v_extra; + /* The rest of the fields don't matter except for debug dumps and such + * for which a partial initializer may trigger out-ot-bounds memory + * reads. Include a double field which is usually as large or larger + * than pointers (not always however). + */ + duk_double_t d; +} duk_tval_unused; + +#define DUK_TVAL_UNUSED_INITIALIZER() \ + { DUK_TAG_UNUSED, 0, 0.0 } + +#define DUK_TAG_MIN 0 +#define DUK_TAG_NUMBER 0 /* DUK_TAG_NUMBER only defined for non-packed duk_tval */ #if defined(DUK_USE_FASTINT) #define DUK_TAG_FASTINT 1 #endif @@ -655,8 +729,12 @@ struct duk_tval_struct { #define DUK_TAG_STRING 8 /* first heap allocated, match bit boundary */ #define DUK_TAG_OBJECT 9 #define DUK_TAG_BUFFER 10 +#define DUK_TAG_MAX 10 -/* DUK__TAG_NUMBER is intentionally first, as it is the default clause in code +#define DUK_TVAL_IS_VALID_TAG(tv) \ + (DUK_TVAL_GET_TAG((tv)) - DUK_TAG_MIN <= DUK_TAG_MAX - DUK_TAG_MIN) + +/* DUK_TAG_NUMBER is intentionally first, as it is the default clause in code * to support the 8-byte representation. Further, it is a non-heap-allocated * type so it should come before DUK_TAG_STRING. Finally, it should not break * the tag value ranges covered by case-clauses in a switch-case. @@ -664,103 +742,156 @@ struct duk_tval_struct { /* setters */ #define DUK_TVAL_SET_UNDEFINED(tv) do { \ - (tv)->t = DUK_TAG_UNDEFINED; \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->t = DUK_TAG_UNDEFINED; \ } while (0) #define DUK_TVAL_SET_UNUSED(tv) do { \ - (tv)->t = DUK_TAG_UNUSED; \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->t = DUK_TAG_UNUSED; \ } while (0) #define DUK_TVAL_SET_NULL(tv) do { \ - (tv)->t = DUK_TAG_NULL; \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->t = DUK_TAG_NULL; \ } while (0) #define DUK_TVAL_SET_BOOLEAN(tv,val) do { \ - (tv)->t = DUK_TAG_BOOLEAN; \ - (tv)->v.i = (val); \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->t = DUK_TAG_BOOLEAN; \ + duk__tv->v.i = (val); \ } while (0) #if defined(DUK_USE_FASTINT) #define DUK_TVAL_SET_DOUBLE(tv,val) do { \ - (tv)->t = DUK__TAG_NUMBER; \ - (tv)->v.d = (val); \ + duk_tval *duk__tv; \ + duk_double_t duk__dblval; \ + duk__dblval = (val); \ + DUK_ASSERT_DOUBLE_IS_NORMALIZED(duk__dblval); /* nop for unpacked duk_tval */ \ + duk__tv = (tv); \ + duk__tv->t = DUK_TAG_NUMBER; \ + duk__tv->v.d = duk__dblval; \ } while (0) -#define DUK_TVAL_SET_FASTINT(tv,val) do { \ - (tv)->t = DUK_TAG_FASTINT; \ - (tv)->v.fi = (val); \ +#define DUK_TVAL_SET_I48(tv,val) do { \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->t = DUK_TAG_FASTINT; \ + duk__tv->v.fi = (val); \ } while (0) -#define DUK_TVAL_SET_FASTINT_U32(tv,val) do { \ - (tv)->t = DUK_TAG_FASTINT; \ - (tv)->v.fi = (duk_int64_t) (val); \ +#define DUK_TVAL_SET_U32(tv,val) do { \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->t = DUK_TAG_FASTINT; \ + duk__tv->v.fi = (duk_int64_t) (val); \ } while (0) -#define DUK_TVAL_SET_FASTINT_I32(tv,val) do { \ - (tv)->t = DUK_TAG_FASTINT; \ - (tv)->v.fi = (duk_int64_t) (val); \ +#define DUK_TVAL_SET_I32(tv,val) do { \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->t = DUK_TAG_FASTINT; \ + duk__tv->v.fi = (duk_int64_t) (val); \ } while (0) -#define DUK_TVAL_SET_NUMBER_CHKFAST(tv,d) \ - duk_tval_set_number_chkfast((tv), (d)) +#define DUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv,d) \ + duk_tval_set_number_chkfast_fast((tv), (d)) +#define DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv,d) \ + duk_tval_set_number_chkfast_slow((tv), (d)) #define DUK_TVAL_SET_NUMBER(tv,val) \ DUK_TVAL_SET_DOUBLE((tv), (val)) -#define DUK_TVAL_CHKFAST_INPLACE(v) do { \ +#define DUK_TVAL_CHKFAST_INPLACE_FAST(tv) do { \ duk_tval *duk__tv; \ duk_double_t duk__d; \ - duk__tv = (v); \ + duk__tv = (tv); \ if (DUK_TVAL_IS_DOUBLE(duk__tv)) { \ duk__d = DUK_TVAL_GET_DOUBLE(duk__tv); \ - DUK_TVAL_SET_NUMBER_CHKFAST(duk__tv, duk__d); \ + DUK_TVAL_SET_NUMBER_CHKFAST_FAST(duk__tv, duk__d); \ } \ } while (0) -#else +#define DUK_TVAL_CHKFAST_INPLACE_SLOW(tv) do { \ + duk_tval *duk__tv; \ + duk_double_t duk__d; \ + duk__tv = (tv); \ + if (DUK_TVAL_IS_DOUBLE(duk__tv)) { \ + duk__d = DUK_TVAL_GET_DOUBLE(duk__tv); \ + DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(duk__tv, duk__d); \ + } \ + } while (0) +#else /* DUK_USE_FASTINT */ #define DUK_TVAL_SET_DOUBLE(tv,d) \ DUK_TVAL_SET_NUMBER((tv), (d)) -#define DUK_TVAL_SET_FASTINT(tv,val) \ +#define DUK_TVAL_SET_I48(tv,val) \ DUK_TVAL_SET_NUMBER((tv), (duk_double_t) (val)) /* XXX: fast int-to-double */ -#define DUK_TVAL_SET_FASTINT_U32(tv,val) \ +#define DUK_TVAL_SET_U32(tv,val) \ DUK_TVAL_SET_NUMBER((tv), (duk_double_t) (val)) -#define DUK_TVAL_SET_FASTINT_I32(tv,val) \ +#define DUK_TVAL_SET_I32(tv,val) \ DUK_TVAL_SET_NUMBER((tv), (duk_double_t) (val)) #define DUK_TVAL_SET_NUMBER(tv,val) do { \ - (tv)->t = DUK__TAG_NUMBER; \ - (tv)->v.d = (val); \ + duk_tval *duk__tv; \ + duk_double_t duk__dblval; \ + duk__dblval = (val); \ + DUK_ASSERT_DOUBLE_IS_NORMALIZED(duk__dblval); /* nop for unpacked duk_tval */ \ + duk__tv = (tv); \ + duk__tv->t = DUK_TAG_NUMBER; \ + duk__tv->v.d = duk__dblval; \ } while (0) -#define DUK_TVAL_SET_NUMBER_CHKFAST(tv,d) \ +#define DUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv,d) \ + DUK_TVAL_SET_NUMBER((tv), (d)) +#define DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv,d) \ DUK_TVAL_SET_NUMBER((tv), (d)) -#define DUK_TVAL_CHKFAST_INPLACE(v) do { } while (0) +#define DUK_TVAL_CHKFAST_INPLACE_FAST(tv) do { } while (0) +#define DUK_TVAL_CHKFAST_INPLACE_SLOW(tv) do { } while (0) #endif /* DUK_USE_FASTINT */ +#define DUK_TVAL_SET_FASTINT(tv,i) \ + DUK_TVAL_SET_I48((tv), (i)) /* alias */ + #define DUK_TVAL_SET_POINTER(tv,hptr) do { \ - (tv)->t = DUK_TAG_POINTER; \ - (tv)->v.voidptr = (hptr); \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->t = DUK_TAG_POINTER; \ + duk__tv->v.voidptr = (hptr); \ } while (0) #define DUK_TVAL_SET_LIGHTFUNC(tv,fp,flags) do { \ - (tv)->t = DUK_TAG_LIGHTFUNC; \ - (tv)->v_extra = (flags); \ - (tv)->v.lightfunc = (duk_c_function) (fp); \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->t = DUK_TAG_LIGHTFUNC; \ + duk__tv->v_extra = (flags); \ + duk__tv->v.lightfunc = (duk_c_function) (fp); \ } while (0) #define DUK_TVAL_SET_STRING(tv,hptr) do { \ - (tv)->t = DUK_TAG_STRING; \ - (tv)->v.hstring = (hptr); \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->t = DUK_TAG_STRING; \ + duk__tv->v.hstring = (hptr); \ } while (0) #define DUK_TVAL_SET_OBJECT(tv,hptr) do { \ - (tv)->t = DUK_TAG_OBJECT; \ - (tv)->v.hobject = (hptr); \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->t = DUK_TAG_OBJECT; \ + duk__tv->v.hobject = (hptr); \ } while (0) #define DUK_TVAL_SET_BUFFER(tv,hptr) do { \ - (tv)->t = DUK_TAG_BUFFER; \ - (tv)->v.hbuffer = (hptr); \ + 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 */ \ - (tv)->t = DUK__TAG_NUMBER; \ - (tv)->v.d = DUK_DOUBLE_NAN; \ + 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(v,x) do { *(v) = *(x); } while (0) +#define DUK_TVAL_SET_TVAL(tv,x) do { *(tv) = *(x); } while (0) /* getters */ #define DUK_TVAL_GET_BOOLEAN(tv) ((tv)->v.i) @@ -805,13 +936,13 @@ struct duk_tval_struct { #define DUK_TVAL_IS_BOOLEAN_TRUE(tv) (((tv)->t == DUK_TAG_BOOLEAN) && ((tv)->v.i != 0)) #define DUK_TVAL_IS_BOOLEAN_FALSE(tv) (((tv)->t == DUK_TAG_BOOLEAN) && ((tv)->v.i == 0)) #if defined(DUK_USE_FASTINT) -#define DUK_TVAL_IS_DOUBLE(tv) ((tv)->t == DUK__TAG_NUMBER) +#define DUK_TVAL_IS_DOUBLE(tv) ((tv)->t == DUK_TAG_NUMBER) #define DUK_TVAL_IS_FASTINT(tv) ((tv)->t == DUK_TAG_FASTINT) -#define DUK_TVAL_IS_NUMBER(tv) ((tv)->t == DUK__TAG_NUMBER || \ +#define DUK_TVAL_IS_NUMBER(tv) ((tv)->t == DUK_TAG_NUMBER || \ (tv)->t == DUK_TAG_FASTINT) #else -#define DUK_TVAL_IS_NUMBER(tv) ((tv)->t == DUK__TAG_NUMBER) -#define DUK_TVAL_IS_DOUBLE(v) DUK_TVAL_IS_NUMBER((v)) +#define DUK_TVAL_IS_NUMBER(tv) ((tv)->t == DUK_TAG_NUMBER) +#define DUK_TVAL_IS_DOUBLE(tv) DUK_TVAL_IS_NUMBER((tv)) #endif /* DUK_USE_FASTINT */ #define DUK_TVAL_IS_POINTER(tv) ((tv)->t == DUK_TAG_POINTER) #define DUK_TVAL_IS_LIGHTFUNC(tv) ((tv)->t == DUK_TAG_LIGHTFUNC) @@ -842,13 +973,18 @@ DUK_INTERNAL_DECL duk_double_t duk_tval_get_number_unpacked_fastint(duk_tval *tv * Convenience (independent of representation) */ -#define DUK_TVAL_SET_BOOLEAN_TRUE(v) DUK_TVAL_SET_BOOLEAN(v, 1) -#define DUK_TVAL_SET_BOOLEAN_FALSE(v) DUK_TVAL_SET_BOOLEAN(v, 0) +#define DUK_TVAL_SET_BOOLEAN_TRUE(tv) DUK_TVAL_SET_BOOLEAN((tv), 1) +#define DUK_TVAL_SET_BOOLEAN_FALSE(tv) DUK_TVAL_SET_BOOLEAN((tv), 0) + +#define DUK_TVAL_STRING_IS_SYMBOL(tv) \ + DUK_HSTRING_HAS_SYMBOL(DUK_TVAL_GET_STRING((tv))) /* Lightfunc flags packing and unpacking. */ -/* Sign extend: 0x0000##00 -> 0x##000000 -> sign extend to 0xssssss## */ +/* Sign extend: 0x0000##00 -> 0x##000000 -> sign extend to 0xssssss##. + * Avoid signed shifts due to portability limitations. + */ #define DUK_LFUNC_FLAGS_GET_MAGIC(lf_flags) \ - ((((duk_int32_t) (lf_flags)) << 16) >> 24) + ((duk_int32_t) (duk_int8_t) (((duk_uint16_t) (lf_flags)) >> 8)) #define DUK_LFUNC_FLAGS_GET_LENGTH(lf_flags) \ (((lf_flags) >> 4) & 0x0f) #define DUK_LFUNC_FLAGS_GET_NARGS(lf_flags) \ @@ -870,20 +1006,21 @@ DUK_INTERNAL_DECL duk_double_t duk_tval_get_number_unpacked_fastint(duk_tval *tv #define DUK_FASTINT_MAX 0x7fffffffffffLL #define DUK_FASTINT_BITS 48 -DUK_INTERNAL_DECL void duk_tval_set_number_chkfast(duk_tval *tv, duk_double_t x); +DUK_INTERNAL_DECL void duk_tval_set_number_chkfast_fast(duk_tval *tv, duk_double_t x); +DUK_INTERNAL_DECL void duk_tval_set_number_chkfast_slow(duk_tval *tv, duk_double_t x); #endif #endif /* DUK_TVAL_H_INCLUDED */ -#line 1 "duk_builtins.h" +/* #include duk_builtins.h */ /* * Automatically generated by genbuiltins.py, do not edit! */ -#ifndef DUK_BUILTINS_H_INCLUDED +#if !defined(DUK_BUILTINS_H_INCLUDED) #define DUK_BUILTINS_H_INCLUDED #if defined(DUK_USE_ROM_STRINGS) -#error ROM support not enabled, rerun make_dist.py with --rom-support +#error ROM support not enabled, rerun configure.py with --rom-support #else /* DUK_USE_ROM_STRINGS */ #define DUK_STRIDX_UC_UNDEFINED 0 /* 'Undefined' */ #define DUK_HEAP_STRING_UC_UNDEFINED(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_UNDEFINED) @@ -891,102 +1028,102 @@ DUK_INTERNAL_DECL void duk_tval_set_number_chkfast(duk_tval *tv, duk_double_t x) #define DUK_STRIDX_UC_NULL 1 /* 'Null' */ #define DUK_HEAP_STRING_UC_NULL(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_NULL) #define DUK_HTHREAD_STRING_UC_NULL(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_NULL) -#define DUK_STRIDX_UC_ARGUMENTS 2 /* 'Arguments' */ +#define DUK_STRIDX_UC_SYMBOL 2 /* 'Symbol' */ +#define DUK_HEAP_STRING_UC_SYMBOL(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_SYMBOL) +#define DUK_HTHREAD_STRING_UC_SYMBOL(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_SYMBOL) +#define DUK_STRIDX_UC_ARGUMENTS 3 /* 'Arguments' */ #define DUK_HEAP_STRING_UC_ARGUMENTS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_ARGUMENTS) #define DUK_HTHREAD_STRING_UC_ARGUMENTS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_ARGUMENTS) -#define DUK_STRIDX_UC_OBJECT 3 /* 'Object' */ +#define DUK_STRIDX_UC_OBJECT 4 /* 'Object' */ #define DUK_HEAP_STRING_UC_OBJECT(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_OBJECT) #define DUK_HTHREAD_STRING_UC_OBJECT(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_OBJECT) -#define DUK_STRIDX_UC_FUNCTION 4 /* 'Function' */ +#define DUK_STRIDX_UC_FUNCTION 5 /* 'Function' */ #define DUK_HEAP_STRING_UC_FUNCTION(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_FUNCTION) #define DUK_HTHREAD_STRING_UC_FUNCTION(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_FUNCTION) -#define DUK_STRIDX_ARRAY 5 /* 'Array' */ +#define DUK_STRIDX_ARRAY 6 /* 'Array' */ #define DUK_HEAP_STRING_ARRAY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ARRAY) #define DUK_HTHREAD_STRING_ARRAY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ARRAY) -#define DUK_STRIDX_UC_STRING 6 /* 'String' */ +#define DUK_STRIDX_UC_STRING 7 /* 'String' */ #define DUK_HEAP_STRING_UC_STRING(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_STRING) #define DUK_HTHREAD_STRING_UC_STRING(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_STRING) -#define DUK_STRIDX_UC_BOOLEAN 7 /* 'Boolean' */ +#define DUK_STRIDX_UC_BOOLEAN 8 /* 'Boolean' */ #define DUK_HEAP_STRING_UC_BOOLEAN(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_BOOLEAN) #define DUK_HTHREAD_STRING_UC_BOOLEAN(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_BOOLEAN) -#define DUK_STRIDX_UC_NUMBER 8 /* 'Number' */ +#define DUK_STRIDX_UC_NUMBER 9 /* 'Number' */ #define DUK_HEAP_STRING_UC_NUMBER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_NUMBER) #define DUK_HTHREAD_STRING_UC_NUMBER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_NUMBER) -#define DUK_STRIDX_DATE 9 /* 'Date' */ +#define DUK_STRIDX_DATE 10 /* 'Date' */ #define DUK_HEAP_STRING_DATE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DATE) #define DUK_HTHREAD_STRING_DATE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DATE) -#define DUK_STRIDX_REG_EXP 10 /* 'RegExp' */ +#define DUK_STRIDX_REG_EXP 11 /* 'RegExp' */ #define DUK_HEAP_STRING_REG_EXP(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_REG_EXP) #define DUK_HTHREAD_STRING_REG_EXP(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_REG_EXP) -#define DUK_STRIDX_UC_ERROR 11 /* 'Error' */ +#define DUK_STRIDX_UC_ERROR 12 /* 'Error' */ #define DUK_HEAP_STRING_UC_ERROR(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_ERROR) #define DUK_HTHREAD_STRING_UC_ERROR(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_ERROR) -#define DUK_STRIDX_MATH 12 /* 'Math' */ +#define DUK_STRIDX_MATH 13 /* 'Math' */ #define DUK_HEAP_STRING_MATH(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_MATH) #define DUK_HTHREAD_STRING_MATH(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_MATH) -#define DUK_STRIDX_JSON 13 /* 'JSON' */ +#define DUK_STRIDX_JSON 14 /* 'JSON' */ #define DUK_HEAP_STRING_JSON(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON) #define DUK_HTHREAD_STRING_JSON(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON) -#define DUK_STRIDX_EMPTY_STRING 14 /* '' */ +#define DUK_STRIDX_EMPTY_STRING 15 /* '' */ #define DUK_HEAP_STRING_EMPTY_STRING(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_EMPTY_STRING) #define DUK_HTHREAD_STRING_EMPTY_STRING(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_EMPTY_STRING) -#define DUK_STRIDX_ARRAY_BUFFER 15 /* 'ArrayBuffer' */ +#define DUK_STRIDX_ARRAY_BUFFER 16 /* 'ArrayBuffer' */ #define DUK_HEAP_STRING_ARRAY_BUFFER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ARRAY_BUFFER) #define DUK_HTHREAD_STRING_ARRAY_BUFFER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ARRAY_BUFFER) -#define DUK_STRIDX_DATA_VIEW 16 /* 'DataView' */ +#define DUK_STRIDX_DATA_VIEW 17 /* 'DataView' */ #define DUK_HEAP_STRING_DATA_VIEW(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DATA_VIEW) #define DUK_HTHREAD_STRING_DATA_VIEW(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DATA_VIEW) -#define DUK_STRIDX_INT8_ARRAY 17 /* 'Int8Array' */ +#define DUK_STRIDX_INT8_ARRAY 18 /* 'Int8Array' */ #define DUK_HEAP_STRING_INT8_ARRAY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT8_ARRAY) #define DUK_HTHREAD_STRING_INT8_ARRAY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT8_ARRAY) -#define DUK_STRIDX_UINT8_ARRAY 18 /* 'Uint8Array' */ +#define DUK_STRIDX_UINT8_ARRAY 19 /* 'Uint8Array' */ #define DUK_HEAP_STRING_UINT8_ARRAY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UINT8_ARRAY) #define DUK_HTHREAD_STRING_UINT8_ARRAY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UINT8_ARRAY) -#define DUK_STRIDX_UINT8_CLAMPED_ARRAY 19 /* 'Uint8ClampedArray' */ +#define DUK_STRIDX_UINT8_CLAMPED_ARRAY 20 /* 'Uint8ClampedArray' */ #define DUK_HEAP_STRING_UINT8_CLAMPED_ARRAY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UINT8_CLAMPED_ARRAY) #define DUK_HTHREAD_STRING_UINT8_CLAMPED_ARRAY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UINT8_CLAMPED_ARRAY) -#define DUK_STRIDX_INT16_ARRAY 20 /* 'Int16Array' */ +#define DUK_STRIDX_INT16_ARRAY 21 /* 'Int16Array' */ #define DUK_HEAP_STRING_INT16_ARRAY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT16_ARRAY) #define DUK_HTHREAD_STRING_INT16_ARRAY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT16_ARRAY) -#define DUK_STRIDX_UINT16_ARRAY 21 /* 'Uint16Array' */ +#define DUK_STRIDX_UINT16_ARRAY 22 /* 'Uint16Array' */ #define DUK_HEAP_STRING_UINT16_ARRAY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UINT16_ARRAY) #define DUK_HTHREAD_STRING_UINT16_ARRAY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UINT16_ARRAY) -#define DUK_STRIDX_INT32_ARRAY 22 /* 'Int32Array' */ +#define DUK_STRIDX_INT32_ARRAY 23 /* 'Int32Array' */ #define DUK_HEAP_STRING_INT32_ARRAY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT32_ARRAY) #define DUK_HTHREAD_STRING_INT32_ARRAY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT32_ARRAY) -#define DUK_STRIDX_UINT32_ARRAY 23 /* 'Uint32Array' */ +#define DUK_STRIDX_UINT32_ARRAY 24 /* 'Uint32Array' */ #define DUK_HEAP_STRING_UINT32_ARRAY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UINT32_ARRAY) #define DUK_HTHREAD_STRING_UINT32_ARRAY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UINT32_ARRAY) -#define DUK_STRIDX_FLOAT32_ARRAY 24 /* 'Float32Array' */ +#define DUK_STRIDX_FLOAT32_ARRAY 25 /* 'Float32Array' */ #define DUK_HEAP_STRING_FLOAT32_ARRAY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FLOAT32_ARRAY) #define DUK_HTHREAD_STRING_FLOAT32_ARRAY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FLOAT32_ARRAY) -#define DUK_STRIDX_FLOAT64_ARRAY 25 /* 'Float64Array' */ +#define DUK_STRIDX_FLOAT64_ARRAY 26 /* 'Float64Array' */ #define DUK_HEAP_STRING_FLOAT64_ARRAY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FLOAT64_ARRAY) #define DUK_HTHREAD_STRING_FLOAT64_ARRAY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FLOAT64_ARRAY) -#define DUK_STRIDX_GLOBAL 26 /* 'global' */ +#define DUK_STRIDX_GLOBAL 27 /* 'global' */ #define DUK_HEAP_STRING_GLOBAL(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_GLOBAL) #define DUK_HTHREAD_STRING_GLOBAL(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_GLOBAL) -#define DUK_STRIDX_OBJ_ENV 27 /* 'ObjEnv' */ +#define DUK_STRIDX_OBJ_ENV 28 /* 'ObjEnv' */ #define DUK_HEAP_STRING_OBJ_ENV(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_OBJ_ENV) #define DUK_HTHREAD_STRING_OBJ_ENV(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_OBJ_ENV) -#define DUK_STRIDX_DEC_ENV 28 /* 'DecEnv' */ +#define DUK_STRIDX_DEC_ENV 29 /* 'DecEnv' */ #define DUK_HEAP_STRING_DEC_ENV(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DEC_ENV) #define DUK_HTHREAD_STRING_DEC_ENV(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DEC_ENV) -#define DUK_STRIDX_UC_BUFFER 29 /* 'Buffer' */ +#define DUK_STRIDX_UC_BUFFER 30 /* 'Buffer' */ #define DUK_HEAP_STRING_UC_BUFFER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_BUFFER) #define DUK_HTHREAD_STRING_UC_BUFFER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_BUFFER) -#define DUK_STRIDX_UC_POINTER 30 /* 'Pointer' */ +#define DUK_STRIDX_UC_POINTER 31 /* 'Pointer' */ #define DUK_HEAP_STRING_UC_POINTER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_POINTER) #define DUK_HTHREAD_STRING_UC_POINTER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_POINTER) -#define DUK_STRIDX_UC_THREAD 31 /* 'Thread' */ +#define DUK_STRIDX_UC_THREAD 32 /* 'Thread' */ #define DUK_HEAP_STRING_UC_THREAD(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_THREAD) #define DUK_HTHREAD_STRING_UC_THREAD(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_THREAD) -#define DUK_STRIDX_EVAL 32 /* 'eval' */ +#define DUK_STRIDX_EVAL 33 /* 'eval' */ #define DUK_HEAP_STRING_EVAL(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_EVAL) #define DUK_HTHREAD_STRING_EVAL(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_EVAL) -#define DUK_STRIDX_DEFINE_PROPERTY 33 /* 'defineProperty' */ -#define DUK_HEAP_STRING_DEFINE_PROPERTY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DEFINE_PROPERTY) -#define DUK_HTHREAD_STRING_DEFINE_PROPERTY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DEFINE_PROPERTY) #define DUK_STRIDX_VALUE 34 /* 'value' */ #define DUK_HEAP_STRING_VALUE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_VALUE) #define DUK_HTHREAD_STRING_VALUE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_VALUE) @@ -1029,9 +1166,9 @@ DUK_INTERNAL_DECL void duk_tval_set_number_chkfast(duk_tval *tv, duk_double_t x) #define DUK_STRIDX_LAST_INDEX 47 /* 'lastIndex' */ #define DUK_HEAP_STRING_LAST_INDEX(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LAST_INDEX) #define DUK_HTHREAD_STRING_LAST_INDEX(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LAST_INDEX) -#define DUK_STRIDX_ESCAPED_EMPTY_REGEXP 48 /* '(?:)' */ -#define DUK_HEAP_STRING_ESCAPED_EMPTY_REGEXP(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ESCAPED_EMPTY_REGEXP) -#define DUK_HTHREAD_STRING_ESCAPED_EMPTY_REGEXP(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ESCAPED_EMPTY_REGEXP) +#define DUK_STRIDX_FLAGS 48 /* 'flags' */ +#define DUK_HEAP_STRING_FLAGS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FLAGS) +#define DUK_HTHREAD_STRING_FLAGS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FLAGS) #define DUK_STRIDX_INDEX 49 /* 'index' */ #define DUK_HEAP_STRING_INDEX(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INDEX) #define DUK_HTHREAD_STRING_INDEX(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INDEX) @@ -1053,30 +1190,30 @@ DUK_INTERNAL_DECL void duk_tval_set_number_chkfast(duk_tval *tv, duk_double_t x) #define DUK_STRIDX_LC_STRING 55 /* 'string' */ #define DUK_HEAP_STRING_LC_STRING(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_STRING) #define DUK_HTHREAD_STRING_LC_STRING(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_STRING) -#define DUK_STRIDX_LC_OBJECT 56 /* 'object' */ +#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 57 /* 'undefined' */ +#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 58 /* 'NaN' */ +#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 59 /* 'Infinity' */ +#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 60 /* '-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 61 /* '-0' */ +#define DUK_STRIDX_MINUS_ZERO 62 /* '-0' */ #define DUK_HEAP_STRING_MINUS_ZERO(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_MINUS_ZERO) #define DUK_HTHREAD_STRING_MINUS_ZERO(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_MINUS_ZERO) -#define DUK_STRIDX_COMMA 62 /* ',' */ +#define DUK_STRIDX_COMMA 63 /* ',' */ #define DUK_HEAP_STRING_COMMA(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_COMMA) #define DUK_HTHREAD_STRING_COMMA(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_COMMA) -#define DUK_STRIDX_SPACE 63 /* ' ' */ -#define DUK_HEAP_STRING_SPACE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_SPACE) -#define DUK_HTHREAD_STRING_SPACE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_SPACE) #define DUK_STRIDX_NEWLINE_4SPACE 64 /* '\n ' */ #define DUK_HEAP_STRING_NEWLINE_4SPACE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_NEWLINE_4SPACE) #define DUK_HTHREAD_STRING_NEWLINE_4SPACE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_NEWLINE_4SPACE) @@ -1095,388 +1232,316 @@ DUK_INTERNAL_DECL void duk_tval_set_number_chkfast(duk_tval *tv, duk_double_t x) #define DUK_STRIDX_CALLER 69 /* 'caller' */ #define DUK_HEAP_STRING_CALLER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CALLER) #define DUK_HTHREAD_STRING_CALLER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CALLER) -#define DUK_STRIDX_HAS 70 /* 'has' */ -#define DUK_HEAP_STRING_HAS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_HAS) -#define DUK_HTHREAD_STRING_HAS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_HAS) +#define DUK_STRIDX_DELETE_PROPERTY 70 /* 'deleteProperty' */ +#define DUK_HEAP_STRING_DELETE_PROPERTY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DELETE_PROPERTY) +#define DUK_HTHREAD_STRING_DELETE_PROPERTY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DELETE_PROPERTY) #define DUK_STRIDX_GET 71 /* 'get' */ #define DUK_HEAP_STRING_GET(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_GET) #define DUK_HTHREAD_STRING_GET(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_GET) -#define DUK_STRIDX_DELETE_PROPERTY 72 /* 'deleteProperty' */ -#define DUK_HEAP_STRING_DELETE_PROPERTY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DELETE_PROPERTY) -#define DUK_HTHREAD_STRING_DELETE_PROPERTY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DELETE_PROPERTY) -#define DUK_STRIDX_ENUMERATE 73 /* 'enumerate' */ -#define DUK_HEAP_STRING_ENUMERATE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ENUMERATE) -#define DUK_HTHREAD_STRING_ENUMERATE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ENUMERATE) -#define DUK_STRIDX_OWN_KEYS 74 /* 'ownKeys' */ +#define DUK_STRIDX_HAS 72 /* 'has' */ +#define DUK_HEAP_STRING_HAS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_HAS) +#define DUK_HTHREAD_STRING_HAS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_HAS) +#define DUK_STRIDX_OWN_KEYS 73 /* 'ownKeys' */ #define DUK_HEAP_STRING_OWN_KEYS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_OWN_KEYS) #define DUK_HTHREAD_STRING_OWN_KEYS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_OWN_KEYS) -#define DUK_STRIDX_SET_PROTOTYPE_OF 75 /* 'setPrototypeOf' */ +#define DUK_STRIDX_SET_PROTOTYPE_OF 74 /* 'setPrototypeOf' */ #define DUK_HEAP_STRING_SET_PROTOTYPE_OF(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_SET_PROTOTYPE_OF) #define DUK_HTHREAD_STRING_SET_PROTOTYPE_OF(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_SET_PROTOTYPE_OF) -#define DUK_STRIDX___PROTO__ 76 /* '__proto__' */ +#define DUK_STRIDX___PROTO__ 75 /* '__proto__' */ #define DUK_HEAP_STRING___PROTO__(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX___PROTO__) #define DUK_HTHREAD_STRING___PROTO__(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX___PROTO__) -#define DUK_STRIDX_REQUIRE 77 /* 'require' */ -#define DUK_HEAP_STRING_REQUIRE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_REQUIRE) -#define DUK_HTHREAD_STRING_REQUIRE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_REQUIRE) -#define DUK_STRIDX_ID 78 /* 'id' */ -#define DUK_HEAP_STRING_ID(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ID) -#define DUK_HTHREAD_STRING_ID(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ID) -#define DUK_STRIDX_EXPORTS 79 /* 'exports' */ -#define DUK_HEAP_STRING_EXPORTS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_EXPORTS) -#define DUK_HTHREAD_STRING_EXPORTS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_EXPORTS) -#define DUK_STRIDX_FILENAME 80 /* 'filename' */ -#define DUK_HEAP_STRING_FILENAME(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FILENAME) -#define DUK_HTHREAD_STRING_FILENAME(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FILENAME) -#define DUK_STRIDX_TO_STRING 81 /* 'toString' */ +#define DUK_STRIDX_TO_STRING 76 /* 'toString' */ #define DUK_HEAP_STRING_TO_STRING(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TO_STRING) #define DUK_HTHREAD_STRING_TO_STRING(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TO_STRING) -#define DUK_STRIDX_TO_JSON 82 /* 'toJSON' */ +#define DUK_STRIDX_TO_JSON 77 /* 'toJSON' */ #define DUK_HEAP_STRING_TO_JSON(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TO_JSON) #define DUK_HTHREAD_STRING_TO_JSON(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TO_JSON) -#define DUK_STRIDX_TYPE 83 /* 'type' */ +#define DUK_STRIDX_TYPE 78 /* 'type' */ #define DUK_HEAP_STRING_TYPE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TYPE) #define DUK_HTHREAD_STRING_TYPE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TYPE) -#define DUK_STRIDX_DATA 84 /* 'data' */ +#define DUK_STRIDX_DATA 79 /* 'data' */ #define DUK_HEAP_STRING_DATA(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DATA) #define DUK_HTHREAD_STRING_DATA(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DATA) -#define DUK_STRIDX_LENGTH 85 /* 'length' */ +#define DUK_STRIDX_LENGTH 80 /* 'length' */ #define DUK_HEAP_STRING_LENGTH(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LENGTH) #define DUK_HTHREAD_STRING_LENGTH(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LENGTH) -#define DUK_STRIDX_BYTE_LENGTH 86 /* 'byteLength' */ -#define DUK_HEAP_STRING_BYTE_LENGTH(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_BYTE_LENGTH) -#define DUK_HTHREAD_STRING_BYTE_LENGTH(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_BYTE_LENGTH) -#define DUK_STRIDX_BYTE_OFFSET 87 /* 'byteOffset' */ -#define DUK_HEAP_STRING_BYTE_OFFSET(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_BYTE_OFFSET) -#define DUK_HTHREAD_STRING_BYTE_OFFSET(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_BYTE_OFFSET) -#define DUK_STRIDX_BYTES_PER_ELEMENT 88 /* 'BYTES_PER_ELEMENT' */ -#define DUK_HEAP_STRING_BYTES_PER_ELEMENT(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_BYTES_PER_ELEMENT) -#define DUK_HTHREAD_STRING_BYTES_PER_ELEMENT(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_BYTES_PER_ELEMENT) -#define DUK_STRIDX_SET 89 /* 'set' */ +#define DUK_STRIDX_SET 81 /* 'set' */ #define DUK_HEAP_STRING_SET(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_SET) #define DUK_HTHREAD_STRING_SET(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_SET) -#define DUK_STRIDX_STACK 90 /* 'stack' */ +#define DUK_STRIDX_STACK 82 /* 'stack' */ #define DUK_HEAP_STRING_STACK(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_STACK) #define DUK_HTHREAD_STRING_STACK(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_STACK) -#define DUK_STRIDX_PC 91 /* 'pc' */ +#define DUK_STRIDX_PC 83 /* 'pc' */ #define DUK_HEAP_STRING_PC(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PC) #define DUK_HTHREAD_STRING_PC(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PC) -#define DUK_STRIDX_LINE_NUMBER 92 /* 'lineNumber' */ +#define DUK_STRIDX_LINE_NUMBER 84 /* 'lineNumber' */ #define DUK_HEAP_STRING_LINE_NUMBER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LINE_NUMBER) #define DUK_HTHREAD_STRING_LINE_NUMBER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LINE_NUMBER) -#define DUK_STRIDX_INT_TRACEDATA 93 /* '\xffTracedata' */ +#define DUK_STRIDX_INT_TRACEDATA 85 /* '\xffTracedata' */ #define DUK_HEAP_STRING_INT_TRACEDATA(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_TRACEDATA) #define DUK_HTHREAD_STRING_INT_TRACEDATA(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_TRACEDATA) -#define DUK_STRIDX_NAME 94 /* 'name' */ +#define DUK_STRIDX_NAME 86 /* 'name' */ #define DUK_HEAP_STRING_NAME(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_NAME) #define DUK_HTHREAD_STRING_NAME(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_NAME) -#define DUK_STRIDX_FILE_NAME 95 /* 'fileName' */ +#define DUK_STRIDX_FILE_NAME 87 /* 'fileName' */ #define DUK_HEAP_STRING_FILE_NAME(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FILE_NAME) #define DUK_HTHREAD_STRING_FILE_NAME(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FILE_NAME) -#define DUK_STRIDX_LC_BUFFER 96 /* 'buffer' */ -#define DUK_HEAP_STRING_LC_BUFFER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_BUFFER) -#define DUK_HTHREAD_STRING_LC_BUFFER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_BUFFER) -#define DUK_STRIDX_LC_POINTER 97 /* 'pointer' */ +#define DUK_STRIDX_LC_POINTER 88 /* 'pointer' */ #define DUK_HEAP_STRING_LC_POINTER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_POINTER) #define DUK_HTHREAD_STRING_LC_POINTER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_POINTER) -#define DUK_STRIDX_INT_VALUE 98 /* '\xffValue' */ +#define DUK_STRIDX_INT_VALUE 89 /* '\xffValue' */ #define DUK_HEAP_STRING_INT_VALUE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_VALUE) #define DUK_HTHREAD_STRING_INT_VALUE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_VALUE) -#define DUK_STRIDX_INT_NEXT 99 /* '\xffNext' */ +#define DUK_STRIDX_INT_NEXT 90 /* '\xffNext' */ #define DUK_HEAP_STRING_INT_NEXT(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_NEXT) #define DUK_HTHREAD_STRING_INT_NEXT(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_NEXT) -#define DUK_STRIDX_INT_BYTECODE 100 /* '\xffBytecode' */ +#define DUK_STRIDX_INT_BYTECODE 91 /* '\xffBytecode' */ #define DUK_HEAP_STRING_INT_BYTECODE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_BYTECODE) #define DUK_HTHREAD_STRING_INT_BYTECODE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_BYTECODE) -#define DUK_STRIDX_INT_FORMALS 101 /* '\xffFormals' */ +#define DUK_STRIDX_INT_FORMALS 92 /* '\xffFormals' */ #define DUK_HEAP_STRING_INT_FORMALS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_FORMALS) #define DUK_HTHREAD_STRING_INT_FORMALS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_FORMALS) -#define DUK_STRIDX_INT_VARMAP 102 /* '\xffVarmap' */ +#define DUK_STRIDX_INT_VARMAP 93 /* '\xffVarmap' */ #define DUK_HEAP_STRING_INT_VARMAP(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_VARMAP) #define DUK_HTHREAD_STRING_INT_VARMAP(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_VARMAP) -#define DUK_STRIDX_INT_LEXENV 103 /* '\xffLexenv' */ -#define DUK_HEAP_STRING_INT_LEXENV(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_LEXENV) -#define DUK_HTHREAD_STRING_INT_LEXENV(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_LEXENV) -#define DUK_STRIDX_INT_VARENV 104 /* '\xffVarenv' */ -#define DUK_HEAP_STRING_INT_VARENV(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_VARENV) -#define DUK_HTHREAD_STRING_INT_VARENV(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_VARENV) -#define DUK_STRIDX_INT_SOURCE 105 /* '\xffSource' */ +#define DUK_STRIDX_INT_SOURCE 94 /* '\xffSource' */ #define DUK_HEAP_STRING_INT_SOURCE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_SOURCE) #define DUK_HTHREAD_STRING_INT_SOURCE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_SOURCE) -#define DUK_STRIDX_INT_PC2LINE 106 /* '\xffPc2line' */ +#define DUK_STRIDX_INT_PC2LINE 95 /* '\xffPc2line' */ #define DUK_HEAP_STRING_INT_PC2LINE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_PC2LINE) #define DUK_HTHREAD_STRING_INT_PC2LINE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_PC2LINE) -#define DUK_STRIDX_INT_ARGS 107 /* '\xffArgs' */ +#define DUK_STRIDX_INT_ARGS 96 /* '\xffArgs' */ #define DUK_HEAP_STRING_INT_ARGS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_ARGS) #define DUK_HTHREAD_STRING_INT_ARGS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_ARGS) -#define DUK_STRIDX_INT_MAP 108 /* '\xffMap' */ +#define DUK_STRIDX_INT_MAP 97 /* '\xffMap' */ #define DUK_HEAP_STRING_INT_MAP(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_MAP) #define DUK_HTHREAD_STRING_INT_MAP(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_MAP) -#define DUK_STRIDX_INT_FINALIZER 109 /* '\xffFinalizer' */ +#define DUK_STRIDX_INT_VARENV 98 /* '\xffVarenv' */ +#define DUK_HEAP_STRING_INT_VARENV(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_VARENV) +#define DUK_HTHREAD_STRING_INT_VARENV(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_VARENV) +#define DUK_STRIDX_INT_FINALIZER 99 /* '\xffFinalizer' */ #define DUK_HEAP_STRING_INT_FINALIZER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_FINALIZER) #define DUK_HTHREAD_STRING_INT_FINALIZER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_FINALIZER) -#define DUK_STRIDX_INT_HANDLER 110 /* '\xffHandler' */ +#define DUK_STRIDX_INT_HANDLER 100 /* '\xffHandler' */ #define DUK_HEAP_STRING_INT_HANDLER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_HANDLER) #define DUK_HTHREAD_STRING_INT_HANDLER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_HANDLER) -#define DUK_STRIDX_INT_CALLEE 111 /* '\xffCallee' */ +#define DUK_STRIDX_INT_CALLEE 101 /* '\xffCallee' */ #define DUK_HEAP_STRING_INT_CALLEE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_CALLEE) #define DUK_HTHREAD_STRING_INT_CALLEE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_CALLEE) -#define DUK_STRIDX_INT_THREAD 112 /* '\xffThread' */ +#define DUK_STRIDX_INT_THREAD 102 /* '\xffThread' */ #define DUK_HEAP_STRING_INT_THREAD(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_THREAD) #define DUK_HTHREAD_STRING_INT_THREAD(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_THREAD) -#define DUK_STRIDX_INT_REGBASE 113 /* '\xffRegbase' */ +#define DUK_STRIDX_INT_REGBASE 103 /* '\xffRegbase' */ #define DUK_HEAP_STRING_INT_REGBASE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_REGBASE) #define DUK_HTHREAD_STRING_INT_REGBASE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_REGBASE) -#define DUK_STRIDX_INT_TARGET 114 /* '\xffTarget' */ +#define DUK_STRIDX_INT_TARGET 104 /* '\xffTarget' */ #define DUK_HEAP_STRING_INT_TARGET(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_TARGET) #define DUK_HTHREAD_STRING_INT_TARGET(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_TARGET) -#define DUK_STRIDX_INT_THIS 115 /* '\xffThis' */ +#define DUK_STRIDX_INT_THIS 105 /* '\xffThis' */ #define DUK_HEAP_STRING_INT_THIS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_THIS) #define DUK_HTHREAD_STRING_INT_THIS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_THIS) -#define DUK_STRIDX_COMPILE 116 /* 'compile' */ +#define DUK_STRIDX_COMPILE 106 /* 'compile' */ #define DUK_HEAP_STRING_COMPILE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_COMPILE) #define DUK_HTHREAD_STRING_COMPILE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_COMPILE) -#define DUK_STRIDX_INPUT 117 /* 'input' */ +#define DUK_STRIDX_INPUT 107 /* 'input' */ #define DUK_HEAP_STRING_INPUT(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INPUT) #define DUK_HTHREAD_STRING_INPUT(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INPUT) -#define DUK_STRIDX_ERR_CREATE 118 /* 'errCreate' */ +#define DUK_STRIDX_ERR_CREATE 108 /* 'errCreate' */ #define DUK_HEAP_STRING_ERR_CREATE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ERR_CREATE) #define DUK_HTHREAD_STRING_ERR_CREATE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ERR_CREATE) -#define DUK_STRIDX_ERR_THROW 119 /* 'errThrow' */ +#define DUK_STRIDX_ERR_THROW 109 /* 'errThrow' */ #define DUK_HEAP_STRING_ERR_THROW(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ERR_THROW) #define DUK_HTHREAD_STRING_ERR_THROW(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ERR_THROW) -#define DUK_STRIDX_MOD_SEARCH 120 /* 'modSearch' */ -#define DUK_HEAP_STRING_MOD_SEARCH(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_MOD_SEARCH) -#define DUK_HTHREAD_STRING_MOD_SEARCH(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_MOD_SEARCH) -#define DUK_STRIDX_MOD_LOADED 121 /* 'modLoaded' */ -#define DUK_HEAP_STRING_MOD_LOADED(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_MOD_LOADED) -#define DUK_HTHREAD_STRING_MOD_LOADED(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_MOD_LOADED) -#define DUK_STRIDX_ENV 122 /* 'env' */ +#define DUK_STRIDX_ENV 110 /* 'env' */ #define DUK_HEAP_STRING_ENV(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ENV) #define DUK_HTHREAD_STRING_ENV(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ENV) -#define DUK_STRIDX_HEX 123 /* 'hex' */ +#define DUK_STRIDX_HEX 111 /* 'hex' */ #define DUK_HEAP_STRING_HEX(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_HEX) #define DUK_HTHREAD_STRING_HEX(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_HEX) -#define DUK_STRIDX_BASE64 124 /* 'base64' */ +#define DUK_STRIDX_BASE64 112 /* 'base64' */ #define DUK_HEAP_STRING_BASE64(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_BASE64) #define DUK_HTHREAD_STRING_BASE64(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_BASE64) -#define DUK_STRIDX_JX 125 /* 'jx' */ +#define DUK_STRIDX_JX 113 /* 'jx' */ #define DUK_HEAP_STRING_JX(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JX) #define DUK_HTHREAD_STRING_JX(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JX) -#define DUK_STRIDX_JC 126 /* 'jc' */ +#define DUK_STRIDX_JC 114 /* 'jc' */ #define DUK_HEAP_STRING_JC(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JC) #define DUK_HTHREAD_STRING_JC(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JC) -#define DUK_STRIDX_RESUME 127 /* 'resume' */ +#define DUK_STRIDX_RESUME 115 /* 'resume' */ #define DUK_HEAP_STRING_RESUME(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_RESUME) #define DUK_HTHREAD_STRING_RESUME(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_RESUME) -#define DUK_STRIDX_FMT 128 /* 'fmt' */ -#define DUK_HEAP_STRING_FMT(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FMT) -#define DUK_HTHREAD_STRING_FMT(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FMT) -#define DUK_STRIDX_RAW 129 /* 'raw' */ -#define DUK_HEAP_STRING_RAW(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_RAW) -#define DUK_HTHREAD_STRING_RAW(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_RAW) -#define DUK_STRIDX_LC_TRACE 130 /* 'trace' */ -#define DUK_HEAP_STRING_LC_TRACE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_TRACE) -#define DUK_HTHREAD_STRING_LC_TRACE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_TRACE) -#define DUK_STRIDX_LC_DEBUG 131 /* 'debug' */ -#define DUK_HEAP_STRING_LC_DEBUG(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_DEBUG) -#define DUK_HTHREAD_STRING_LC_DEBUG(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_DEBUG) -#define DUK_STRIDX_LC_INFO 132 /* 'info' */ -#define DUK_HEAP_STRING_LC_INFO(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_INFO) -#define DUK_HTHREAD_STRING_LC_INFO(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_INFO) -#define DUK_STRIDX_LC_WARN 133 /* 'warn' */ -#define DUK_HEAP_STRING_LC_WARN(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_WARN) -#define DUK_HTHREAD_STRING_LC_WARN(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_WARN) -#define DUK_STRIDX_LC_ERROR 134 /* 'error' */ -#define DUK_HEAP_STRING_LC_ERROR(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_ERROR) -#define DUK_HTHREAD_STRING_LC_ERROR(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_ERROR) -#define DUK_STRIDX_LC_FATAL 135 /* 'fatal' */ -#define DUK_HEAP_STRING_LC_FATAL(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_FATAL) -#define DUK_HTHREAD_STRING_LC_FATAL(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_FATAL) -#define DUK_STRIDX_LC_N 136 /* 'n' */ -#define DUK_HEAP_STRING_LC_N(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_N) -#define DUK_HTHREAD_STRING_LC_N(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_N) -#define DUK_STRIDX_LC_L 137 /* 'l' */ -#define DUK_HEAP_STRING_LC_L(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_L) -#define DUK_HTHREAD_STRING_LC_L(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_L) -#define DUK_STRIDX_CLOG 138 /* 'clog' */ -#define DUK_HEAP_STRING_CLOG(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CLOG) -#define DUK_HTHREAD_STRING_CLOG(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CLOG) -#define DUK_STRIDX_TO_LOG_STRING 139 /* 'toLogString' */ -#define DUK_HEAP_STRING_TO_LOG_STRING(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TO_LOG_STRING) -#define DUK_HTHREAD_STRING_TO_LOG_STRING(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TO_LOG_STRING) -#define DUK_STRIDX_JSON_EXT_UNDEFINED 140 /* '{"_undef":true}' */ +#define DUK_STRIDX_JSON_EXT_UNDEFINED 116 /* '{"_undef":true}' */ #define DUK_HEAP_STRING_JSON_EXT_UNDEFINED(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_UNDEFINED) #define DUK_HTHREAD_STRING_JSON_EXT_UNDEFINED(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_UNDEFINED) -#define DUK_STRIDX_JSON_EXT_NAN 141 /* '{"_nan":true}' */ +#define DUK_STRIDX_JSON_EXT_NAN 117 /* '{"_nan":true}' */ #define DUK_HEAP_STRING_JSON_EXT_NAN(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_NAN) #define DUK_HTHREAD_STRING_JSON_EXT_NAN(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_NAN) -#define DUK_STRIDX_JSON_EXT_POSINF 142 /* '{"_inf":true}' */ +#define DUK_STRIDX_JSON_EXT_POSINF 118 /* '{"_inf":true}' */ #define DUK_HEAP_STRING_JSON_EXT_POSINF(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_POSINF) #define DUK_HTHREAD_STRING_JSON_EXT_POSINF(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_POSINF) -#define DUK_STRIDX_JSON_EXT_NEGINF 143 /* '{"_ninf":true}' */ +#define DUK_STRIDX_JSON_EXT_NEGINF 119 /* '{"_ninf":true}' */ #define DUK_HEAP_STRING_JSON_EXT_NEGINF(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_NEGINF) #define DUK_HTHREAD_STRING_JSON_EXT_NEGINF(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_NEGINF) -#define DUK_STRIDX_JSON_EXT_FUNCTION1 144 /* '{"_func":true}' */ +#define DUK_STRIDX_JSON_EXT_FUNCTION1 120 /* '{"_func":true}' */ #define DUK_HEAP_STRING_JSON_EXT_FUNCTION1(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_FUNCTION1) #define DUK_HTHREAD_STRING_JSON_EXT_FUNCTION1(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_FUNCTION1) -#define DUK_STRIDX_JSON_EXT_FUNCTION2 145 /* '{_func:true}' */ +#define DUK_STRIDX_JSON_EXT_FUNCTION2 121 /* '{_func:true}' */ #define DUK_HEAP_STRING_JSON_EXT_FUNCTION2(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_FUNCTION2) #define DUK_HTHREAD_STRING_JSON_EXT_FUNCTION2(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_FUNCTION2) -#define DUK_STRIDX_BREAK 146 /* 'break' */ +#define DUK_STRIDX_BREAK 122 /* 'break' */ #define DUK_HEAP_STRING_BREAK(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_BREAK) #define DUK_HTHREAD_STRING_BREAK(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_BREAK) -#define DUK_STRIDX_CASE 147 /* 'case' */ +#define DUK_STRIDX_CASE 123 /* 'case' */ #define DUK_HEAP_STRING_CASE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CASE) #define DUK_HTHREAD_STRING_CASE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CASE) -#define DUK_STRIDX_CATCH 148 /* 'catch' */ +#define DUK_STRIDX_CATCH 124 /* 'catch' */ #define DUK_HEAP_STRING_CATCH(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CATCH) #define DUK_HTHREAD_STRING_CATCH(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CATCH) -#define DUK_STRIDX_CONTINUE 149 /* 'continue' */ +#define DUK_STRIDX_CONTINUE 125 /* 'continue' */ #define DUK_HEAP_STRING_CONTINUE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CONTINUE) #define DUK_HTHREAD_STRING_CONTINUE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CONTINUE) -#define DUK_STRIDX_DEBUGGER 150 /* 'debugger' */ +#define DUK_STRIDX_DEBUGGER 126 /* 'debugger' */ #define DUK_HEAP_STRING_DEBUGGER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DEBUGGER) #define DUK_HTHREAD_STRING_DEBUGGER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DEBUGGER) -#define DUK_STRIDX_DEFAULT 151 /* 'default' */ +#define DUK_STRIDX_DEFAULT 127 /* 'default' */ #define DUK_HEAP_STRING_DEFAULT(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DEFAULT) #define DUK_HTHREAD_STRING_DEFAULT(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DEFAULT) -#define DUK_STRIDX_DELETE 152 /* 'delete' */ +#define DUK_STRIDX_DELETE 128 /* 'delete' */ #define DUK_HEAP_STRING_DELETE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DELETE) #define DUK_HTHREAD_STRING_DELETE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DELETE) -#define DUK_STRIDX_DO 153 /* 'do' */ +#define DUK_STRIDX_DO 129 /* 'do' */ #define DUK_HEAP_STRING_DO(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DO) #define DUK_HTHREAD_STRING_DO(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DO) -#define DUK_STRIDX_ELSE 154 /* 'else' */ +#define DUK_STRIDX_ELSE 130 /* 'else' */ #define DUK_HEAP_STRING_ELSE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ELSE) #define DUK_HTHREAD_STRING_ELSE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ELSE) -#define DUK_STRIDX_FINALLY 155 /* 'finally' */ +#define DUK_STRIDX_FINALLY 131 /* 'finally' */ #define DUK_HEAP_STRING_FINALLY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FINALLY) #define DUK_HTHREAD_STRING_FINALLY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FINALLY) -#define DUK_STRIDX_FOR 156 /* 'for' */ +#define DUK_STRIDX_FOR 132 /* 'for' */ #define DUK_HEAP_STRING_FOR(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FOR) #define DUK_HTHREAD_STRING_FOR(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FOR) -#define DUK_STRIDX_LC_FUNCTION 157 /* 'function' */ +#define DUK_STRIDX_LC_FUNCTION 133 /* 'function' */ #define DUK_HEAP_STRING_LC_FUNCTION(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_FUNCTION) #define DUK_HTHREAD_STRING_LC_FUNCTION(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_FUNCTION) -#define DUK_STRIDX_IF 158 /* 'if' */ +#define DUK_STRIDX_IF 134 /* 'if' */ #define DUK_HEAP_STRING_IF(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_IF) #define DUK_HTHREAD_STRING_IF(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_IF) -#define DUK_STRIDX_IN 159 /* 'in' */ +#define DUK_STRIDX_IN 135 /* 'in' */ #define DUK_HEAP_STRING_IN(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_IN) #define DUK_HTHREAD_STRING_IN(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_IN) -#define DUK_STRIDX_INSTANCEOF 160 /* 'instanceof' */ +#define DUK_STRIDX_INSTANCEOF 136 /* 'instanceof' */ #define DUK_HEAP_STRING_INSTANCEOF(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INSTANCEOF) #define DUK_HTHREAD_STRING_INSTANCEOF(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INSTANCEOF) -#define DUK_STRIDX_NEW 161 /* 'new' */ +#define DUK_STRIDX_NEW 137 /* 'new' */ #define DUK_HEAP_STRING_NEW(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_NEW) #define DUK_HTHREAD_STRING_NEW(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_NEW) -#define DUK_STRIDX_RETURN 162 /* 'return' */ +#define DUK_STRIDX_RETURN 138 /* 'return' */ #define DUK_HEAP_STRING_RETURN(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_RETURN) #define DUK_HTHREAD_STRING_RETURN(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_RETURN) -#define DUK_STRIDX_SWITCH 163 /* 'switch' */ +#define DUK_STRIDX_SWITCH 139 /* 'switch' */ #define DUK_HEAP_STRING_SWITCH(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_SWITCH) #define DUK_HTHREAD_STRING_SWITCH(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_SWITCH) -#define DUK_STRIDX_THIS 164 /* 'this' */ +#define DUK_STRIDX_THIS 140 /* 'this' */ #define DUK_HEAP_STRING_THIS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_THIS) #define DUK_HTHREAD_STRING_THIS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_THIS) -#define DUK_STRIDX_THROW 165 /* 'throw' */ +#define DUK_STRIDX_THROW 141 /* 'throw' */ #define DUK_HEAP_STRING_THROW(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_THROW) #define DUK_HTHREAD_STRING_THROW(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_THROW) -#define DUK_STRIDX_TRY 166 /* 'try' */ +#define DUK_STRIDX_TRY 142 /* 'try' */ #define DUK_HEAP_STRING_TRY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TRY) #define DUK_HTHREAD_STRING_TRY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TRY) -#define DUK_STRIDX_TYPEOF 167 /* 'typeof' */ +#define DUK_STRIDX_TYPEOF 143 /* 'typeof' */ #define DUK_HEAP_STRING_TYPEOF(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TYPEOF) #define DUK_HTHREAD_STRING_TYPEOF(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TYPEOF) -#define DUK_STRIDX_VAR 168 /* 'var' */ +#define DUK_STRIDX_VAR 144 /* 'var' */ #define DUK_HEAP_STRING_VAR(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_VAR) #define DUK_HTHREAD_STRING_VAR(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_VAR) -#define DUK_STRIDX_CONST 169 /* 'const' */ +#define DUK_STRIDX_CONST 145 /* 'const' */ #define DUK_HEAP_STRING_CONST(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CONST) #define DUK_HTHREAD_STRING_CONST(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CONST) -#define DUK_STRIDX_VOID 170 /* 'void' */ +#define DUK_STRIDX_VOID 146 /* 'void' */ #define DUK_HEAP_STRING_VOID(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_VOID) #define DUK_HTHREAD_STRING_VOID(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_VOID) -#define DUK_STRIDX_WHILE 171 /* 'while' */ +#define DUK_STRIDX_WHILE 147 /* 'while' */ #define DUK_HEAP_STRING_WHILE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WHILE) #define DUK_HTHREAD_STRING_WHILE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WHILE) -#define DUK_STRIDX_WITH 172 /* 'with' */ +#define DUK_STRIDX_WITH 148 /* 'with' */ #define DUK_HEAP_STRING_WITH(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WITH) #define DUK_HTHREAD_STRING_WITH(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WITH) -#define DUK_STRIDX_CLASS 173 /* 'class' */ +#define DUK_STRIDX_CLASS 149 /* 'class' */ #define DUK_HEAP_STRING_CLASS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CLASS) #define DUK_HTHREAD_STRING_CLASS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CLASS) -#define DUK_STRIDX_ENUM 174 /* 'enum' */ +#define DUK_STRIDX_ENUM 150 /* 'enum' */ #define DUK_HEAP_STRING_ENUM(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ENUM) #define DUK_HTHREAD_STRING_ENUM(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ENUM) -#define DUK_STRIDX_EXPORT 175 /* 'export' */ +#define DUK_STRIDX_EXPORT 151 /* 'export' */ #define DUK_HEAP_STRING_EXPORT(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_EXPORT) #define DUK_HTHREAD_STRING_EXPORT(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_EXPORT) -#define DUK_STRIDX_EXTENDS 176 /* 'extends' */ +#define DUK_STRIDX_EXTENDS 152 /* 'extends' */ #define DUK_HEAP_STRING_EXTENDS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_EXTENDS) #define DUK_HTHREAD_STRING_EXTENDS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_EXTENDS) -#define DUK_STRIDX_IMPORT 177 /* 'import' */ +#define DUK_STRIDX_IMPORT 153 /* 'import' */ #define DUK_HEAP_STRING_IMPORT(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_IMPORT) #define DUK_HTHREAD_STRING_IMPORT(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_IMPORT) -#define DUK_STRIDX_SUPER 178 /* 'super' */ +#define DUK_STRIDX_SUPER 154 /* 'super' */ #define DUK_HEAP_STRING_SUPER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_SUPER) #define DUK_HTHREAD_STRING_SUPER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_SUPER) -#define DUK_STRIDX_LC_NULL 179 /* 'null' */ +#define DUK_STRIDX_LC_NULL 155 /* 'null' */ #define DUK_HEAP_STRING_LC_NULL(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_NULL) #define DUK_HTHREAD_STRING_LC_NULL(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_NULL) -#define DUK_STRIDX_TRUE 180 /* 'true' */ +#define DUK_STRIDX_TRUE 156 /* 'true' */ #define DUK_HEAP_STRING_TRUE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TRUE) #define DUK_HTHREAD_STRING_TRUE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TRUE) -#define DUK_STRIDX_FALSE 181 /* 'false' */ +#define DUK_STRIDX_FALSE 157 /* 'false' */ #define DUK_HEAP_STRING_FALSE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FALSE) #define DUK_HTHREAD_STRING_FALSE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FALSE) -#define DUK_STRIDX_IMPLEMENTS 182 /* 'implements' */ +#define DUK_STRIDX_IMPLEMENTS 158 /* 'implements' */ #define DUK_HEAP_STRING_IMPLEMENTS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_IMPLEMENTS) #define DUK_HTHREAD_STRING_IMPLEMENTS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_IMPLEMENTS) -#define DUK_STRIDX_INTERFACE 183 /* 'interface' */ +#define DUK_STRIDX_INTERFACE 159 /* 'interface' */ #define DUK_HEAP_STRING_INTERFACE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INTERFACE) #define DUK_HTHREAD_STRING_INTERFACE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INTERFACE) -#define DUK_STRIDX_LET 184 /* 'let' */ +#define DUK_STRIDX_LET 160 /* 'let' */ #define DUK_HEAP_STRING_LET(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LET) #define DUK_HTHREAD_STRING_LET(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LET) -#define DUK_STRIDX_PACKAGE 185 /* 'package' */ +#define DUK_STRIDX_PACKAGE 161 /* 'package' */ #define DUK_HEAP_STRING_PACKAGE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PACKAGE) #define DUK_HTHREAD_STRING_PACKAGE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PACKAGE) -#define DUK_STRIDX_PRIVATE 186 /* 'private' */ +#define DUK_STRIDX_PRIVATE 162 /* 'private' */ #define DUK_HEAP_STRING_PRIVATE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PRIVATE) #define DUK_HTHREAD_STRING_PRIVATE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PRIVATE) -#define DUK_STRIDX_PROTECTED 187 /* 'protected' */ +#define DUK_STRIDX_PROTECTED 163 /* 'protected' */ #define DUK_HEAP_STRING_PROTECTED(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PROTECTED) #define DUK_HTHREAD_STRING_PROTECTED(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PROTECTED) -#define DUK_STRIDX_PUBLIC 188 /* 'public' */ +#define DUK_STRIDX_PUBLIC 164 /* 'public' */ #define DUK_HEAP_STRING_PUBLIC(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PUBLIC) #define DUK_HTHREAD_STRING_PUBLIC(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PUBLIC) -#define DUK_STRIDX_STATIC 189 /* 'static' */ +#define DUK_STRIDX_STATIC 165 /* 'static' */ #define DUK_HEAP_STRING_STATIC(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_STATIC) #define DUK_HTHREAD_STRING_STATIC(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_STATIC) -#define DUK_STRIDX_YIELD 190 /* 'yield' */ +#define DUK_STRIDX_YIELD 166 /* 'yield' */ #define DUK_HEAP_STRING_YIELD(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_YIELD) #define DUK_HTHREAD_STRING_YIELD(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_YIELD) -#define DUK_HEAP_NUM_STRINGS 191 -#define DUK_STRIDX_START_RESERVED 146 -#define DUK_STRIDX_START_STRICT_RESERVED 182 -#define DUK_STRIDX_END_RESERVED 191 /* exclusive endpoint */ +#define DUK_HEAP_NUM_STRINGS 167 +#define DUK_STRIDX_START_RESERVED 122 +#define DUK_STRIDX_START_STRICT_RESERVED 158 +#define DUK_STRIDX_END_RESERVED 167 /* exclusive endpoint */ /* To convert a heap stridx to a token number, subtract * DUK_STRIDX_START_RESERVED and add DUK_TOK_START_RESERVED. */ #if !defined(DUK_SINGLE_FILE) -DUK_INTERNAL_DECL const duk_uint8_t duk_strings_data[1049]; +DUK_INTERNAL_DECL const duk_uint8_t duk_strings_data[921]; #endif /* !DUK_SINGLE_FILE */ #define DUK_STRDATA_MAX_STRLEN 17 -#define DUK_STRDATA_DATA_LENGTH 1049 +#define DUK_STRDATA_DATA_LENGTH 921 #endif /* DUK_USE_ROM_STRINGS */ #if defined(DUK_USE_ROM_OBJECTS) -#error ROM support not enabled, rerun make_dist.py with --rom-support -#else +#error RAM support not enabled, rerun configure.py with --ram-support +#else /* DUK_USE_ROM_OBJECTS */ DUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_function_constructor(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype(duk_context *ctx); @@ -1488,15 +1553,15 @@ DUK_INTERNAL_DECL duk_ret_t duk_bi_date_constructor(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_constructor(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_error_constructor_shared(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_type_error_thrower(duk_context *ctx); -DUK_INTERNAL_DECL duk_ret_t duk_bi_proxy_constructor(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_thread_constructor(duk_context *ctx); -DUK_INTERNAL_DECL duk_ret_t duk_bi_buffer_constructor(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_pointer_constructor(duk_context *ctx); -DUK_INTERNAL_DECL duk_ret_t duk_bi_logger_constructor(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_proxy_constructor(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_arraybuffer_constructor(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_dataview_constructor(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_typedarray_constructor(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_constructor(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_textencoder_constructor(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_textdecoder_constructor(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_eval(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_parse_int(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_parse_float(duk_context *ctx); @@ -1508,12 +1573,11 @@ DUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_encode_uri(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_encode_uri_component(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_escape(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_unescape(duk_context *ctx); -DUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_print_helper(duk_context *ctx); -DUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_require(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_object_getprototype_shared(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_object_setprototype_shared(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_get_own_property_descriptor(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_keys_shared(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_assign(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_create(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_define_property(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_define_properties(duk_context *ctx); @@ -1521,6 +1585,7 @@ DUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_seal_freeze_shared(duk_con DUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_prevent_extensions(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_is_sealed_frozen_shared(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_is_extensible(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_is(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_to_string(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_to_locale_string(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_value_of(duk_context *ctx); @@ -1547,6 +1612,7 @@ DUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_indexof_shared(duk_context *c DUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_iter_shared(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_reduce_shared(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_string_constructor_from_char_code(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_string_constructor_from_code_point(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_to_string(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_char_at(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_char_code_at(duk_context *ctx); @@ -1561,6 +1627,7 @@ DUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_split(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_substring(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_caseconv_shared(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_trim(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_repeat(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_substr(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_boolean_prototype_tostring_shared(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_number_prototype_to_string(duk_context *ctx); @@ -1581,7 +1648,9 @@ DUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_set_time(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_set_shared(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_prototype_exec(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_prototype_test(duk_context *ctx); -DUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_prototype_to_string(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_prototype_tostring(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_prototype_flags(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_prototype_shared_getter(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_stack_getter(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_stack_setter(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_filename_getter(duk_context *ctx); @@ -1591,6 +1660,7 @@ DUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_linenumber_setter(duk_context DUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_to_string(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_onearg_shared(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_twoarg_shared(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_hypot(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_max(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_min(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_random(duk_context *ctx); @@ -1606,16 +1676,21 @@ DUK_INTERNAL_DECL duk_ret_t duk_bi_duktape_object_compact(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_thread_yield(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_thread_resume(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_thread_current(duk_context *ctx); -DUK_INTERNAL_DECL duk_ret_t duk_bi_buffer_prototype_tostring_shared(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_pointer_prototype_tostring_shared(duk_context *ctx); -DUK_INTERNAL_DECL duk_ret_t duk_bi_logger_prototype_fmt(duk_context *ctx); -DUK_INTERNAL_DECL duk_ret_t duk_bi_logger_prototype_raw(duk_context *ctx); -DUK_INTERNAL_DECL duk_ret_t duk_bi_logger_prototype_log_shared(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_object_delete_property(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_object_get(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_object_has(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_object_set(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_arraybuffer_isview(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_typedarray_bytelength_getter(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_buffer_slice_shared(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_typedarray_byteoffset_getter(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_typedarray_buffer_getter(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_buffer_readfield(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_buffer_writefield(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_typedarray_set(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_uint8array_allocplain(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_uint8array_plainof(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_concat(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_is_encoding(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_is_buffer(duk_context *ctx); @@ -1626,15 +1701,13 @@ DUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_tojson(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_fill(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_copy(duk_context *ctx); DUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_write(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_textencoder_prototype_encoding_getter(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_textencoder_prototype_encode(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_textdecoder_prototype_shared_getter(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_textdecoder_prototype_decode(duk_context *ctx); #if !defined(DUK_SINGLE_FILE) -DUK_INTERNAL_DECL const duk_c_function duk_bi_native_functions[149]; -#endif /* !DUK_SINGLE_FILE */ -#if defined(DUK_USE_BUILTIN_INITJS) -#if !defined(DUK_SINGLE_FILE) -DUK_INTERNAL_DECL const duk_uint8_t duk_initjs_data[204]; +DUK_INTERNAL_DECL const duk_c_function duk_bi_native_functions[164]; #endif /* !DUK_SINGLE_FILE */ -#define DUK_BUILTIN_INITJS_DATA_LENGTH 204 -#endif /* DUK_USE_BUILTIN_INITJS */ #define DUK_BIDX_GLOBAL 0 #define DUK_BIDX_GLOBAL_ENV 1 #define DUK_BIDX_OBJECT_CONSTRUCTOR 2 @@ -1670,79 +1743,96 @@ DUK_INTERNAL_DECL const duk_uint8_t duk_initjs_data[204]; #define DUK_BIDX_MATH 32 #define DUK_BIDX_JSON 33 #define DUK_BIDX_TYPE_ERROR_THROWER 34 -#define DUK_BIDX_PROXY_CONSTRUCTOR 35 -#define DUK_BIDX_DUKTAPE 36 -#define DUK_BIDX_THREAD_CONSTRUCTOR 37 -#define DUK_BIDX_THREAD_PROTOTYPE 38 -#define DUK_BIDX_BUFFER_CONSTRUCTOR 39 -#define DUK_BIDX_BUFFER_PROTOTYPE 40 -#define DUK_BIDX_POINTER_CONSTRUCTOR 41 -#define DUK_BIDX_POINTER_PROTOTYPE 42 -#define DUK_BIDX_LOGGER_CONSTRUCTOR 43 -#define DUK_BIDX_LOGGER_PROTOTYPE 44 -#define DUK_BIDX_DOUBLE_ERROR 45 -#define DUK_BIDX_ARRAYBUFFER_CONSTRUCTOR 46 -#define DUK_BIDX_ARRAYBUFFER_PROTOTYPE 47 -#define DUK_BIDX_DATAVIEW_CONSTRUCTOR 48 -#define DUK_BIDX_DATAVIEW_PROTOTYPE 49 -#define DUK_BIDX_TYPEDARRAY_PROTOTYPE 50 -#define DUK_BIDX_INT8ARRAY_CONSTRUCTOR 51 -#define DUK_BIDX_INT8ARRAY_PROTOTYPE 52 -#define DUK_BIDX_UINT8ARRAY_CONSTRUCTOR 53 -#define DUK_BIDX_UINT8ARRAY_PROTOTYPE 54 -#define DUK_BIDX_UINT8CLAMPEDARRAY_CONSTRUCTOR 55 -#define DUK_BIDX_UINT8CLAMPEDARRAY_PROTOTYPE 56 -#define DUK_BIDX_INT16ARRAY_CONSTRUCTOR 57 -#define DUK_BIDX_INT16ARRAY_PROTOTYPE 58 -#define DUK_BIDX_UINT16ARRAY_CONSTRUCTOR 59 -#define DUK_BIDX_UINT16ARRAY_PROTOTYPE 60 -#define DUK_BIDX_INT32ARRAY_CONSTRUCTOR 61 -#define DUK_BIDX_INT32ARRAY_PROTOTYPE 62 -#define DUK_BIDX_UINT32ARRAY_CONSTRUCTOR 63 -#define DUK_BIDX_UINT32ARRAY_PROTOTYPE 64 -#define DUK_BIDX_FLOAT32ARRAY_CONSTRUCTOR 65 -#define DUK_BIDX_FLOAT32ARRAY_PROTOTYPE 66 -#define DUK_BIDX_FLOAT64ARRAY_CONSTRUCTOR 67 -#define DUK_BIDX_FLOAT64ARRAY_PROTOTYPE 68 -#define DUK_BIDX_NODEJS_BUFFER_CONSTRUCTOR 69 -#define DUK_BIDX_NODEJS_BUFFER_PROTOTYPE 70 -#define DUK_NUM_BUILTINS 71 -#define DUK_NUM_BIDX_BUILTINS 71 -#define DUK_NUM_ALL_BUILTINS 71 +#define DUK_BIDX_DUKTAPE 35 +#define DUK_BIDX_THREAD_CONSTRUCTOR 36 +#define DUK_BIDX_THREAD_PROTOTYPE 37 +#define DUK_BIDX_POINTER_CONSTRUCTOR 38 +#define DUK_BIDX_POINTER_PROTOTYPE 39 +#define DUK_BIDX_DOUBLE_ERROR 40 +#define DUK_BIDX_PROXY_CONSTRUCTOR 41 +#define DUK_BIDX_REFLECT 42 +#define DUK_BIDX_SYMBOL_PROTOTYPE 43 +#define DUK_BIDX_ARRAYBUFFER_CONSTRUCTOR 44 +#define DUK_BIDX_ARRAYBUFFER_PROTOTYPE 45 +#define DUK_BIDX_DATAVIEW_CONSTRUCTOR 46 +#define DUK_BIDX_DATAVIEW_PROTOTYPE 47 +#define DUK_BIDX_TYPEDARRAY_CONSTRUCTOR 48 +#define DUK_BIDX_TYPEDARRAY_PROTOTYPE 49 +#define DUK_BIDX_INT8ARRAY_CONSTRUCTOR 50 +#define DUK_BIDX_INT8ARRAY_PROTOTYPE 51 +#define DUK_BIDX_UINT8ARRAY_CONSTRUCTOR 52 +#define DUK_BIDX_UINT8ARRAY_PROTOTYPE 53 +#define DUK_BIDX_UINT8CLAMPEDARRAY_CONSTRUCTOR 54 +#define DUK_BIDX_UINT8CLAMPEDARRAY_PROTOTYPE 55 +#define DUK_BIDX_INT16ARRAY_CONSTRUCTOR 56 +#define DUK_BIDX_INT16ARRAY_PROTOTYPE 57 +#define DUK_BIDX_UINT16ARRAY_CONSTRUCTOR 58 +#define DUK_BIDX_UINT16ARRAY_PROTOTYPE 59 +#define DUK_BIDX_INT32ARRAY_CONSTRUCTOR 60 +#define DUK_BIDX_INT32ARRAY_PROTOTYPE 61 +#define DUK_BIDX_UINT32ARRAY_CONSTRUCTOR 62 +#define DUK_BIDX_UINT32ARRAY_PROTOTYPE 63 +#define DUK_BIDX_FLOAT32ARRAY_CONSTRUCTOR 64 +#define DUK_BIDX_FLOAT32ARRAY_PROTOTYPE 65 +#define DUK_BIDX_FLOAT64ARRAY_CONSTRUCTOR 66 +#define DUK_BIDX_FLOAT64ARRAY_PROTOTYPE 67 +#define DUK_BIDX_NODEJS_BUFFER_CONSTRUCTOR 68 +#define DUK_BIDX_NODEJS_BUFFER_PROTOTYPE 69 +#define DUK_BIDX_TEXTENCODER_CONSTRUCTOR 70 +#define DUK_BIDX_TEXTENCODER_PROTOTYPE 71 +#define DUK_BIDX_TEXTDECODER_CONSTRUCTOR 72 +#define DUK_BIDX_TEXTDECODER_PROTOTYPE 73 +#define DUK_NUM_BUILTINS 74 +#define DUK_NUM_BIDX_BUILTINS 74 +#define DUK_NUM_ALL_BUILTINS 74 #if defined(DUK_USE_DOUBLE_LE) #if !defined(DUK_SINGLE_FILE) -DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[3833]; +DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[3790]; #endif /* !DUK_SINGLE_FILE */ -#define DUK_BUILTINS_DATA_LENGTH 3833 +#define DUK_BUILTINS_DATA_LENGTH 3790 #elif defined(DUK_USE_DOUBLE_BE) #if !defined(DUK_SINGLE_FILE) -DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[3833]; +DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[3790]; #endif /* !DUK_SINGLE_FILE */ -#define DUK_BUILTINS_DATA_LENGTH 3833 +#define DUK_BUILTINS_DATA_LENGTH 3790 #elif defined(DUK_USE_DOUBLE_ME) #if !defined(DUK_SINGLE_FILE) -DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[3833]; +DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[3790]; #endif /* !DUK_SINGLE_FILE */ -#define DUK_BUILTINS_DATA_LENGTH 3833 +#define DUK_BUILTINS_DATA_LENGTH 3790 #else #error invalid endianness defines #endif #endif /* DUK_USE_ROM_OBJECTS */ #endif /* DUK_BUILTINS_H_INCLUDED */ -#line 52 "duk_internal.h" -#line 1 "duk_util.h" +/* #include duk_util.h */ /* * Utilities */ -#ifndef DUK_UTIL_H_INCLUDED +#if !defined(DUK_UTIL_H_INCLUDED) #define DUK_UTIL_H_INCLUDED #define DUK_UTIL_MIN_HASH_PRIME 17 /* must match genhashsizes.py */ #define DUK_UTIL_GET_HASH_PROBE_STEP(hash) (duk_util_probe_steps[(hash) & 0x1f]) +#if defined(DUK_USE_GET_RANDOM_DOUBLE) +#define DUK_UTIL_GET_RANDOM_DOUBLE(thr) DUK_USE_GET_RANDOM_DOUBLE((thr)->heap_udata) +#else +#define DUK_UTIL_GET_RANDOM_DOUBLE(thr) duk_util_tinyrandom_get_double(thr) +#endif + +/* + * Some useful constants + */ + +#define DUK_DOUBLE_2TO32 4294967296.0 +#define DUK_DOUBLE_2TO31 2147483648.0 +#define DUK_DOUBLE_LOG2E 1.4426950408889634 +#define DUK_DOUBLE_LOG10E 0.4342944819032518 + /* * Endian conversion */ @@ -1773,6 +1863,8 @@ struct duk_bitdecoder_ctx { duk_small_int_t currbits; }; +#define DUK_BD_BITPACKED_STRING_MAXLEN 256 + /* * Bitstream encoder */ @@ -2225,15 +2317,19 @@ DUK_INTERNAL_DECL duk_uint32_t duk_util_hashbytes(const duk_uint8_t *data, duk_s DUK_INTERNAL_DECL duk_uint32_t duk_util_get_hash_prime(duk_uint32_t size); #endif -DUK_INTERNAL_DECL duk_int32_t duk_bd_decode(duk_bitdecoder_ctx *ctx, duk_small_int_t bits); -DUK_INTERNAL_DECL duk_small_int_t duk_bd_decode_flag(duk_bitdecoder_ctx *ctx); -DUK_INTERNAL_DECL duk_int32_t duk_bd_decode_flagged(duk_bitdecoder_ctx *ctx, duk_small_int_t bits, duk_int32_t def_value); +DUK_INTERNAL_DECL duk_uint32_t duk_bd_decode(duk_bitdecoder_ctx *ctx, duk_small_int_t bits); +DUK_INTERNAL_DECL duk_small_uint_t duk_bd_decode_flag(duk_bitdecoder_ctx *ctx); +DUK_INTERNAL_DECL duk_uint32_t duk_bd_decode_flagged(duk_bitdecoder_ctx *ctx, duk_small_int_t bits, duk_uint32_t def_value); +DUK_INTERNAL_DECL duk_uint32_t duk_bd_decode_varuint(duk_bitdecoder_ctx *ctx); +DUK_INTERNAL_DECL duk_small_uint_t duk_bd_decode_bitpacked_string(duk_bitdecoder_ctx *bd, duk_uint8_t *out); DUK_INTERNAL_DECL void duk_be_encode(duk_bitencoder_ctx *ctx, duk_uint32_t data, duk_small_int_t bits); DUK_INTERNAL_DECL void duk_be_finish(duk_bitencoder_ctx *ctx); -DUK_INTERNAL_DECL duk_uint32_t duk_util_tinyrandom_get_bits(duk_hthread *thr, duk_small_int_t n); +#if !defined(DUK_USE_GET_RANDOM_DOUBLE) DUK_INTERNAL_DECL duk_double_t duk_util_tinyrandom_get_double(duk_hthread *thr); +DUK_INTERNAL_DECL void duk_util_tinyrandom_prepare_seed(duk_hthread *thr); +#endif DUK_INTERNAL_DECL void duk_bw_init(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_hbuffer_dynamic *h_buf); DUK_INTERNAL_DECL void duk_bw_init_pushbuf(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_size_t buf_size); @@ -2250,483 +2346,672 @@ DUK_INTERNAL_DECL duk_uint8_t *duk_bw_insert_ensure_area(duk_hthread *thr, duk_b DUK_INTERNAL_DECL void duk_bw_remove_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len); /* No duk_bw_remove_ensure_slice(), functionality would be identical. */ -DUK_INTERNAL_DECL DUK_INLINE duk_uint16_t duk_raw_read_u16_be(duk_uint8_t **p); -DUK_INTERNAL_DECL DUK_INLINE duk_uint32_t duk_raw_read_u32_be(duk_uint8_t **p); -DUK_INTERNAL_DECL DUK_INLINE duk_double_t duk_raw_read_double_be(duk_uint8_t **p); -DUK_INTERNAL_DECL DUK_INLINE void duk_raw_write_u16_be(duk_uint8_t **p, duk_uint16_t val); -DUK_INTERNAL_DECL DUK_INLINE void duk_raw_write_u32_be(duk_uint8_t **p, duk_uint32_t val); -DUK_INTERNAL_DECL DUK_INLINE void duk_raw_write_double_be(duk_uint8_t **p, duk_double_t val); +DUK_INTERNAL_DECL duk_uint16_t duk_raw_read_u16_be(duk_uint8_t **p); +DUK_INTERNAL_DECL duk_uint32_t duk_raw_read_u32_be(duk_uint8_t **p); +DUK_INTERNAL_DECL duk_double_t duk_raw_read_double_be(duk_uint8_t **p); +DUK_INTERNAL_DECL void duk_raw_write_u16_be(duk_uint8_t **p, duk_uint16_t val); +DUK_INTERNAL_DECL void duk_raw_write_u32_be(duk_uint8_t **p, duk_uint32_t val); +DUK_INTERNAL_DECL void duk_raw_write_double_be(duk_uint8_t **p, duk_double_t val); #if defined(DUK_USE_DEBUGGER_SUPPORT) /* For now only needed by the debugger. */ -DUK_INTERNAL void duk_byteswap_bytes(duk_uint8_t *p, duk_small_uint_t len); -#endif +DUK_INTERNAL_DECL void duk_byteswap_bytes(duk_uint8_t *p, duk_small_uint_t len); +#endif + +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); #endif /* DUK_UTIL_H_INCLUDED */ -#line 1 "duk_strings.h" +/* #include duk_strings.h */ /* - * Shared error messages: declarations and macros + * Shared string macros. * - * Error messages are accessed through macros with fine-grained, explicit - * error message distinctions. Concrete error messages are selected by the - * macros and multiple macros can map to the same concrete string to save - * on code footprint. This allows flexible footprint/verbosity tuning with - * minimal code impact. There are a few limitations to this approach: - * (1) switching between plain messages and format strings doesn't work - * conveniently, and (2) conditional strings are a bit awkward to handle. + * 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 have a special prefix (DUK_STR_FMT_ - * and duk_str_fmt_). + * 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. */ -#ifndef DUK_ERRMSG_H_INCLUDED +#if !defined(DUK_ERRMSG_H_INCLUDED) #define DUK_ERRMSG_H_INCLUDED -#define DUK_STR_INTERNAL_ERROR duk_str_internal_error -#define DUK_STR_INVALID_COUNT duk_str_invalid_count -#define DUK_STR_INVALID_CALL_ARGS duk_str_invalid_call_args -#define DUK_STR_NOT_CONSTRUCTABLE duk_str_not_constructable -#define DUK_STR_NOT_CALLABLE duk_str_not_callable -#define DUK_STR_NOT_EXTENSIBLE duk_str_not_extensible -#define DUK_STR_NOT_WRITABLE duk_str_not_writable -#define DUK_STR_NOT_CONFIGURABLE duk_str_not_configurable - -#if !defined(DUK_SINGLE_FILE) -DUK_INTERNAL_DECL const char *duk_str_internal_error; -DUK_INTERNAL_DECL const char *duk_str_invalid_count; -DUK_INTERNAL_DECL const char *duk_str_invalid_call_args; -DUK_INTERNAL_DECL const char *duk_str_not_constructable; -DUK_INTERNAL_DECL const char *duk_str_not_callable; -DUK_INTERNAL_DECL const char *duk_str_not_extensible; -DUK_INTERNAL_DECL const char *duk_str_not_writable; -DUK_INTERNAL_DECL const char *duk_str_not_configurable; -#endif /* !DUK_SINGLE_FILE */ - -#define DUK_STR_INVALID_CONTEXT duk_str_invalid_context -#define DUK_STR_INVALID_INDEX duk_str_invalid_call_args -#define DUK_STR_PUSH_BEYOND_ALLOC_STACK duk_str_push_beyond_alloc_stack -#define DUK_STR_NOT_UNDEFINED duk_str_unexpected_type -#define DUK_STR_NOT_NULL duk_str_unexpected_type -#define DUK_STR_NOT_BOOLEAN duk_str_unexpected_type -#define DUK_STR_NOT_NUMBER duk_str_unexpected_type -#define DUK_STR_NOT_STRING duk_str_unexpected_type -#define DUK_STR_NOT_OBJECT duk_str_unexpected_type -#define DUK_STR_NOT_POINTER duk_str_unexpected_type -#define DUK_STR_NOT_BUFFER duk_str_not_buffer /* still in use with verbose messages */ -#define DUK_STR_UNEXPECTED_TYPE duk_str_unexpected_type -#define DUK_STR_NOT_THREAD duk_str_unexpected_type -#define DUK_STR_NOT_COMPILEDFUNCTION duk_str_unexpected_type -#define DUK_STR_NOT_NATIVEFUNCTION duk_str_unexpected_type -#define DUK_STR_NOT_C_FUNCTION duk_str_unexpected_type -#define DUK_STR_NOT_FUNCTION duk_str_unexpected_type -#define DUK_STR_NOT_REGEXP duk_str_unexpected_type -#define DUK_STR_DEFAULTVALUE_COERCE_FAILED duk_str_defaultvalue_coerce_failed -#define DUK_STR_NUMBER_OUTSIDE_RANGE duk_str_number_outside_range -#define DUK_STR_NOT_OBJECT_COERCIBLE duk_str_not_object_coercible -#define DUK_STR_STRING_TOO_LONG duk_str_string_too_long -#define DUK_STR_BUFFER_TOO_LONG duk_str_buffer_too_long -#define DUK_STR_SPRINTF_TOO_LONG duk_str_sprintf_too_long -#define DUK_STR_ALLOC_FAILED duk_str_alloc_failed -#define DUK_STR_POP_TOO_MANY duk_str_pop_too_many -#define DUK_STR_WRONG_BUFFER_TYPE duk_str_wrong_buffer_type -#define DUK_STR_ENCODE_FAILED duk_str_encode_failed -#define DUK_STR_DECODE_FAILED duk_str_decode_failed -#define DUK_STR_NO_SOURCECODE duk_str_no_sourcecode -#define DUK_STR_CONCAT_RESULT_TOO_LONG duk_str_concat_result_too_long -#define DUK_STR_UNIMPLEMENTED duk_str_unimplemented -#define DUK_STR_UNSUPPORTED duk_str_unsupported -#define DUK_STR_ARRAY_LENGTH_OVER_2G duk_str_array_length_over_2g - -#if !defined(DUK_SINGLE_FILE) -DUK_INTERNAL_DECL const char *duk_str_invalid_context; -DUK_INTERNAL_DECL const char *duk_str_push_beyond_alloc_stack; -DUK_INTERNAL_DECL const char *duk_str_not_buffer; -DUK_INTERNAL_DECL const char *duk_str_unexpected_type; -DUK_INTERNAL_DECL const char *duk_str_defaultvalue_coerce_failed; -DUK_INTERNAL_DECL const char *duk_str_number_outside_range; -DUK_INTERNAL_DECL const char *duk_str_not_object_coercible; -DUK_INTERNAL_DECL const char *duk_str_string_too_long; -DUK_INTERNAL_DECL const char *duk_str_buffer_too_long; -DUK_INTERNAL_DECL const char *duk_str_sprintf_too_long; -DUK_INTERNAL_DECL const char *duk_str_alloc_failed; -DUK_INTERNAL_DECL const char *duk_str_pop_too_many; -DUK_INTERNAL_DECL const char *duk_str_wrong_buffer_type; -DUK_INTERNAL_DECL const char *duk_str_encode_failed; -DUK_INTERNAL_DECL const char *duk_str_decode_failed; -DUK_INTERNAL_DECL const char *duk_str_no_sourcecode; -DUK_INTERNAL_DECL const char *duk_str_concat_result_too_long; -DUK_INTERNAL_DECL const char *duk_str_unimplemented; -DUK_INTERNAL_DECL const char *duk_str_unsupported; -DUK_INTERNAL_DECL const char *duk_str_array_length_over_2g; -#endif /* !DUK_SINGLE_FILE */ - -#define DUK_STR_FMT_PTR duk_str_fmt_ptr -#define DUK_STR_FMT_INVALID_JSON duk_str_fmt_invalid_json -#define DUK_STR_JSONDEC_RECLIMIT duk_str_jsondec_reclimit -#define DUK_STR_JSONENC_RECLIMIT duk_str_jsonenc_reclimit -#define DUK_STR_CYCLIC_INPUT duk_str_cyclic_input - -#if !defined(DUK_SINGLE_FILE) -DUK_INTERNAL_DECL const char *duk_str_fmt_ptr; -DUK_INTERNAL_DECL const char *duk_str_fmt_invalid_json; -DUK_INTERNAL_DECL const char *duk_str_jsondec_reclimit; -DUK_INTERNAL_DECL const char *duk_str_jsonenc_reclimit; -DUK_INTERNAL_DECL const char *duk_str_cyclic_input; -#endif /* !DUK_SINGLE_FILE */ - -#define DUK_STR_PROXY_REVOKED duk_str_proxy_revoked -#define DUK_STR_INVALID_BASE duk_str_invalid_base -#define DUK_STR_STRICT_CALLER_READ duk_str_strict_caller_read -#define DUK_STR_PROXY_REJECTED duk_str_proxy_rejected -#define DUK_STR_INVALID_ARRAY_LENGTH duk_str_invalid_array_length -#define DUK_STR_ARRAY_LENGTH_WRITE_FAILED duk_str_array_length_write_failed -#define DUK_STR_ARRAY_LENGTH_NOT_WRITABLE duk_str_array_length_not_writable -#define DUK_STR_SETTER_UNDEFINED duk_str_setter_undefined -#define DUK_STR_REDEFINE_VIRT_PROP duk_str_redefine_virt_prop -#define DUK_STR_INVALID_DESCRIPTOR duk_str_invalid_descriptor -#define DUK_STR_PROPERTY_IS_VIRTUAL duk_str_property_is_virtual - -#if !defined(DUK_SINGLE_FILE) -DUK_INTERNAL_DECL const char *duk_str_proxy_revoked; -DUK_INTERNAL_DECL const char *duk_str_invalid_base; -DUK_INTERNAL_DECL const char *duk_str_strict_caller_read; -DUK_INTERNAL_DECL const char *duk_str_proxy_rejected; -DUK_INTERNAL_DECL const char *duk_str_invalid_array_length; -DUK_INTERNAL_DECL const char *duk_str_array_length_write_failed; -DUK_INTERNAL_DECL const char *duk_str_array_length_not_writable; -DUK_INTERNAL_DECL const char *duk_str_setter_undefined; -DUK_INTERNAL_DECL const char *duk_str_redefine_virt_prop; -DUK_INTERNAL_DECL const char *duk_str_invalid_descriptor; -DUK_INTERNAL_DECL const char *duk_str_property_is_virtual; -#endif /* !DUK_SINGLE_FILE */ - -#define DUK_STR_PARSE_ERROR duk_str_parse_error -#define DUK_STR_DUPLICATE_LABEL duk_str_duplicate_label -#define DUK_STR_INVALID_LABEL duk_str_invalid_label -#define DUK_STR_INVALID_ARRAY_LITERAL duk_str_invalid_array_literal -#define DUK_STR_INVALID_OBJECT_LITERAL duk_str_invalid_object_literal -#define DUK_STR_INVALID_VAR_DECLARATION duk_str_invalid_var_declaration -#define DUK_STR_CANNOT_DELETE_IDENTIFIER duk_str_cannot_delete_identifier -#define DUK_STR_INVALID_EXPRESSION duk_str_invalid_expression -#define DUK_STR_INVALID_LVALUE duk_str_invalid_lvalue -#define DUK_STR_EXPECTED_IDENTIFIER duk_str_expected_identifier -#define DUK_STR_EMPTY_EXPR_NOT_ALLOWED duk_str_empty_expr_not_allowed -#define DUK_STR_INVALID_FOR duk_str_invalid_for -#define DUK_STR_INVALID_SWITCH duk_str_invalid_switch -#define DUK_STR_INVALID_BREAK_CONT_LABEL duk_str_invalid_break_cont_label -#define DUK_STR_INVALID_RETURN duk_str_invalid_return -#define DUK_STR_INVALID_TRY duk_str_invalid_try -#define DUK_STR_INVALID_THROW duk_str_invalid_throw -#define DUK_STR_WITH_IN_STRICT_MODE duk_str_with_in_strict_mode -#define DUK_STR_FUNC_STMT_NOT_ALLOWED duk_str_func_stmt_not_allowed -#define DUK_STR_UNTERMINATED_STMT duk_str_unterminated_stmt -#define DUK_STR_INVALID_ARG_NAME duk_str_invalid_arg_name -#define DUK_STR_INVALID_FUNC_NAME duk_str_invalid_func_name -#define DUK_STR_INVALID_GETSET_NAME duk_str_invalid_getset_name -#define DUK_STR_FUNC_NAME_REQUIRED duk_str_func_name_required - -#if !defined(DUK_SINGLE_FILE) -DUK_INTERNAL_DECL const char *duk_str_parse_error; -DUK_INTERNAL_DECL const char *duk_str_duplicate_label; -DUK_INTERNAL_DECL const char *duk_str_invalid_label; -DUK_INTERNAL_DECL const char *duk_str_invalid_array_literal; -DUK_INTERNAL_DECL const char *duk_str_invalid_object_literal; -DUK_INTERNAL_DECL const char *duk_str_invalid_var_declaration; -DUK_INTERNAL_DECL const char *duk_str_cannot_delete_identifier; -DUK_INTERNAL_DECL const char *duk_str_invalid_expression; -DUK_INTERNAL_DECL const char *duk_str_invalid_lvalue; -DUK_INTERNAL_DECL const char *duk_str_expected_identifier; -DUK_INTERNAL_DECL const char *duk_str_empty_expr_not_allowed; -DUK_INTERNAL_DECL const char *duk_str_invalid_for; -DUK_INTERNAL_DECL const char *duk_str_invalid_switch; -DUK_INTERNAL_DECL const char *duk_str_invalid_break_cont_label; -DUK_INTERNAL_DECL const char *duk_str_invalid_return; -DUK_INTERNAL_DECL const char *duk_str_invalid_try; -DUK_INTERNAL_DECL const char *duk_str_invalid_throw; -DUK_INTERNAL_DECL const char *duk_str_with_in_strict_mode; -DUK_INTERNAL_DECL const char *duk_str_func_stmt_not_allowed; -DUK_INTERNAL_DECL const char *duk_str_unterminated_stmt; -DUK_INTERNAL_DECL const char *duk_str_invalid_arg_name; -DUK_INTERNAL_DECL const char *duk_str_invalid_func_name; -DUK_INTERNAL_DECL const char *duk_str_invalid_getset_name; -DUK_INTERNAL_DECL const char *duk_str_func_name_required; -#endif /* !DUK_SINGLE_FILE */ +/* 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_ENCODE_FAILED "encode failed" +#define DUK_STR_DECODE_FAILED "decode failed" +#define DUK_STR_NO_SOURCECODE "no sourcecode" +#define DUK_STR_RESULT_TOO_LONG "result too long" -#define DUK_STR_INVALID_QUANTIFIER_NO_ATOM duk_str_invalid_quantifier_no_atom -#define DUK_STR_INVALID_QUANTIFIER_VALUES duk_str_invalid_quantifier_values -#define DUK_STR_QUANTIFIER_TOO_MANY_COPIES duk_str_quantifier_too_many_copies -#define DUK_STR_UNEXPECTED_CLOSING_PAREN duk_str_unexpected_closing_paren -#define DUK_STR_UNEXPECTED_END_OF_PATTERN duk_str_unexpected_end_of_pattern -#define DUK_STR_UNEXPECTED_REGEXP_TOKEN duk_str_unexpected_regexp_token -#define DUK_STR_INVALID_REGEXP_FLAGS duk_str_invalid_regexp_flags -#define DUK_STR_INVALID_BACKREFS duk_str_invalid_backrefs +/* JSON */ +#define DUK_STR_FMT_PTR "%p" +#define DUK_STR_FMT_INVALID_JSON "invalid json (at offset %ld)" +#define DUK_STR_JSONDEC_RECLIMIT "json decode recursion limit" +#define DUK_STR_JSONENC_RECLIMIT "json encode recursion limit" +#define DUK_STR_CYCLIC_INPUT "cyclic input" -#if !defined(DUK_SINGLE_FILE) -DUK_INTERNAL_DECL const char *duk_str_invalid_quantifier_no_atom; -DUK_INTERNAL_DECL const char *duk_str_invalid_quantifier_values; -DUK_INTERNAL_DECL const char *duk_str_quantifier_too_many_copies; -DUK_INTERNAL_DECL const char *duk_str_unexpected_closing_paren; -DUK_INTERNAL_DECL const char *duk_str_unexpected_end_of_pattern; -DUK_INTERNAL_DECL const char *duk_str_unexpected_regexp_token; -DUK_INTERNAL_DECL const char *duk_str_invalid_regexp_flags; -DUK_INTERNAL_DECL const char *duk_str_invalid_backrefs; -#endif /* !DUK_SINGLE_FILE */ +/* Object property access */ +#define DUK_STR_PROXY_REVOKED "proxy revoked" +#define DUK_STR_INVALID_BASE "invalid base value" +#define DUK_STR_STRICT_CALLER_READ "cannot read strict 'caller'" +#define DUK_STR_PROXY_REJECTED "proxy rejected" +#define DUK_STR_INVALID_ARRAY_LENGTH "invalid array length" +#define DUK_STR_SETTER_UNDEFINED "setter undefined" +#define DUK_STR_INVALID_DESCRIPTOR "invalid descriptor" + +/* Proxy */ +#define DUK_STR_INVALID_TRAP_RESULT "invalid trap result" + +/* Variables */ + +/* Lexer */ +#define DUK_STR_INVALID_ESCAPE "invalid escape" +#define DUK_STR_UNTERMINATED_STRING "unterminated string" +#define DUK_STR_UNTERMINATED_COMMENT "unterminated comment" +#define DUK_STR_UNTERMINATED_REGEXP "unterminated regexp" +#define DUK_STR_TOKEN_LIMIT "token limit" +#define DUK_STR_REGEXP_SUPPORT_DISABLED "regexp support disabled" +#define DUK_STR_INVALID_NUMBER_LITERAL "invalid number literal" +#define DUK_STR_INVALID_TOKEN "invalid token" -#define DUK_STR_VALSTACK_LIMIT duk_str_valstack_limit -#define DUK_STR_CALLSTACK_LIMIT duk_str_callstack_limit -#define DUK_STR_CATCHSTACK_LIMIT duk_str_catchstack_limit -#define DUK_STR_PROTOTYPE_CHAIN_LIMIT duk_str_prototype_chain_limit -#define DUK_STR_BOUND_CHAIN_LIMIT duk_str_bound_chain_limit -#define DUK_STR_C_CALLSTACK_LIMIT duk_str_c_callstack_limit -#define DUK_STR_COMPILER_RECURSION_LIMIT duk_str_compiler_recursion_limit -#define DUK_STR_BYTECODE_LIMIT duk_str_bytecode_limit -#define DUK_STR_REG_LIMIT duk_str_reg_limit -#define DUK_STR_TEMP_LIMIT duk_str_temp_limit -#define DUK_STR_CONST_LIMIT duk_str_const_limit -#define DUK_STR_FUNC_LIMIT duk_str_func_limit -#define DUK_STR_REGEXP_COMPILER_RECURSION_LIMIT duk_str_regexp_compiler_recursion_limit -#define DUK_STR_REGEXP_EXECUTOR_RECURSION_LIMIT duk_str_regexp_executor_recursion_limit -#define DUK_STR_REGEXP_EXECUTOR_STEP_LIMIT duk_str_regexp_executor_step_limit +/* Compiler */ +#define DUK_STR_PARSE_ERROR "parse error" +#define DUK_STR_DUPLICATE_LABEL "duplicate label" +#define DUK_STR_INVALID_LABEL "invalid label" +#define DUK_STR_INVALID_ARRAY_LITERAL "invalid array literal" +#define DUK_STR_INVALID_OBJECT_LITERAL "invalid object literal" +#define DUK_STR_INVALID_VAR_DECLARATION "invalid variable declaration" +#define DUK_STR_CANNOT_DELETE_IDENTIFIER "cannot delete identifier" +#define DUK_STR_INVALID_EXPRESSION "invalid expression" +#define DUK_STR_INVALID_LVALUE "invalid lvalue" +#define DUK_STR_EXPECTED_IDENTIFIER "expected identifier" +#define DUK_STR_EMPTY_EXPR_NOT_ALLOWED "empty expression not allowed" +#define DUK_STR_INVALID_FOR "invalid for statement" +#define DUK_STR_INVALID_SWITCH "invalid switch statement" +#define DUK_STR_INVALID_BREAK_CONT_LABEL "invalid break/continue label" +#define DUK_STR_INVALID_RETURN "invalid return" +#define DUK_STR_INVALID_TRY "invalid try" +#define DUK_STR_INVALID_THROW "invalid throw" +#define DUK_STR_WITH_IN_STRICT_MODE "with in strict mode" +#define DUK_STR_FUNC_STMT_NOT_ALLOWED "function statement not allowed" +#define DUK_STR_UNTERMINATED_STMT "unterminated statement" +#define DUK_STR_INVALID_ARG_NAME "invalid argument name" +#define DUK_STR_INVALID_FUNC_NAME "invalid function name" +#define DUK_STR_INVALID_GETSET_NAME "invalid getter/setter name" +#define DUK_STR_FUNC_NAME_REQUIRED "function name required" -#if !defined(DUK_SINGLE_FILE) -DUK_INTERNAL_DECL const char *duk_str_valstack_limit; -DUK_INTERNAL_DECL const char *duk_str_callstack_limit; -DUK_INTERNAL_DECL const char *duk_str_catchstack_limit; -DUK_INTERNAL_DECL const char *duk_str_prototype_chain_limit; -DUK_INTERNAL_DECL const char *duk_str_bound_chain_limit; -DUK_INTERNAL_DECL const char *duk_str_c_callstack_limit; -DUK_INTERNAL_DECL const char *duk_str_compiler_recursion_limit; -DUK_INTERNAL_DECL const char *duk_str_bytecode_limit; -DUK_INTERNAL_DECL const char *duk_str_reg_limit; -DUK_INTERNAL_DECL const char *duk_str_temp_limit; -DUK_INTERNAL_DECL const char *duk_str_const_limit; -DUK_INTERNAL_DECL const char *duk_str_func_limit; -DUK_INTERNAL_DECL const char *duk_str_regexp_compiler_recursion_limit; -DUK_INTERNAL_DECL const char *duk_str_regexp_executor_recursion_limit; -DUK_INTERNAL_DECL const char *duk_str_regexp_executor_step_limit; -#endif /* !DUK_SINGLE_FILE */ +/* Regexp */ +#define DUK_STR_INVALID_QUANTIFIER "invalid regexp quantifier" +#define DUK_STR_INVALID_QUANTIFIER_NO_ATOM "quantifier without preceding atom" +#define DUK_STR_INVALID_QUANTIFIER_VALUES "quantifier values invalid (qmin > qmax)" +#define DUK_STR_QUANTIFIER_TOO_MANY_COPIES "quantifier requires too many atom copies" +#define DUK_STR_UNEXPECTED_CLOSING_PAREN "unexpected closing parenthesis" +#define DUK_STR_UNEXPECTED_END_OF_PATTERN "unexpected end of pattern" +#define DUK_STR_UNEXPECTED_REGEXP_TOKEN "unexpected token in regexp" +#define DUK_STR_INVALID_REGEXP_FLAGS "invalid regexp flags" +#define DUK_STR_INVALID_REGEXP_ESCAPE "invalid regexp escape" +#define DUK_STR_INVALID_BACKREFS "invalid backreference(s)" +#define DUK_STR_INVALID_REGEXP_CHARACTER "invalid regexp character" +#define DUK_STR_UNTERMINATED_CHARCLASS "unterminated character class" +#define DUK_STR_INVALID_RANGE "invalid range" -#if !defined(DUK_SINGLE_FILE) -DUK_INTERNAL_DECL const char *duk_str_anon; -#endif /* !DUK_SINGLE_FILE */ +/* Limits */ +#define DUK_STR_VALSTACK_LIMIT "valstack limit" +#define DUK_STR_CALLSTACK_LIMIT "callstack limit" +#define DUK_STR_CATCHSTACK_LIMIT "catchstack limit" +#define DUK_STR_PROTOTYPE_CHAIN_LIMIT "prototype chain limit" +#define DUK_STR_BOUND_CHAIN_LIMIT "function call bound chain limit" +#define DUK_STR_C_CALLSTACK_LIMIT "C call stack depth limit" +#define DUK_STR_COMPILER_RECURSION_LIMIT "compiler recursion limit" +#define DUK_STR_BYTECODE_LIMIT "bytecode limit" +#define DUK_STR_REG_LIMIT "register limit" +#define DUK_STR_TEMP_LIMIT "temp limit" +#define DUK_STR_CONST_LIMIT "const limit" +#define DUK_STR_FUNC_LIMIT "function limit" +#define DUK_STR_REGEXP_COMPILER_RECURSION_LIMIT "regexp compiler recursion limit" +#define DUK_STR_REGEXP_EXECUTOR_RECURSION_LIMIT "regexp executor recursion limit" +#define DUK_STR_REGEXP_EXECUTOR_STEP_LIMIT "regexp step limit" #endif /* DUK_ERRMSG_H_INCLUDED */ -#line 1 "duk_js_bytecode.h" +/* #include duk_js_bytecode.h */ /* * Ecmascript bytecode */ -#ifndef DUK_JS_BYTECODE_H_INCLUDED +#if !defined(DUK_JS_BYTECODE_H_INCLUDED) #define DUK_JS_BYTECODE_H_INCLUDED /* - * Logical instruction layout - * ========================== + * Bytecode instruction layout + * =========================== + * + * Instructions are unsigned 32-bit integers divided 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 ! - * +---------------------------------------------------+-----------+ + * +-----------------------------------------------+---------------+ + * ! C ! B ! A ! OP ! + * +-----------------------------------------------+---------------+ * - * OP (6 bits): opcode (DUK_OP_*), access should be fastest - * A (8 bits): typically a target register number - * B (9 bits): typically first source register/constant number - * C (9 bits): typically second source register/constant number + * 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. B and C may denote a register or a constant, see - * DUK_BC_ISREG() and DUK_BC_ISCONST(). + * 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! + * +-----------------------------------------------+---------------+ * - * Note: macro naming is a bit misleading, e.g. "ABC" in macro name but - * the field layout is logically "CBA". + * 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_DEC_OP(x) ((x) & 0x3fUL) -#define DUK_DEC_A(x) (((x) >> 6) & 0xffUL) -#define DUK_DEC_B(x) (((x) >> 14) & 0x1ffUL) -#define DUK_DEC_C(x) (((x) >> 23) & 0x1ffUL) -#define DUK_DEC_BC(x) (((x) >> 14) & 0x3ffffUL) -#define DUK_DEC_ABC(x) (((x) >> 6) & 0x3ffffffUL) +#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)) << 6) | \ + (((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)) << 14) | \ - (((duk_instr_t) (a)) << 6) | \ + (((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)) << 23) | \ - (((duk_instr_t) (b)) << 14) | \ - (((duk_instr_t) (a)) << 6) | \ + (((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_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 0x3fL +#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 0x1ffL +#define DUK_BC_B_MAX 0xffL #define DUK_BC_C_MIN 0 -#define DUK_BC_C_MAX 0x1ffL +#define DUK_BC_C_MAX 0xffL #define DUK_BC_BC_MIN 0 -#define DUK_BC_BC_MAX 0x3ffffL +#define DUK_BC_BC_MAX 0xffffL #define DUK_BC_ABC_MIN 0 -#define DUK_BC_ABC_MAX 0x3ffffffL -#define DUK_BC_EXTRAOP_MIN DUK_BC_A_MIN -#define DUK_BC_EXTRAOP_MAX DUK_BC_A_MAX +#define DUK_BC_ABC_MAX 0xffffffL + +/* Masks for B/C reg/const indicator in opcode field. */ +#define DUK_BC_REGCONST_B (0x01UL) +#define DUK_BC_REGCONST_C (0x02UL) +/* Misc. masks for opcode field. */ +#define DUK_BC_INCDECP_FLAG_DEC (0x04UL) +#define DUK_BC_INCDECP_FLAG_POST (0x08UL) + +/* Opcodes. */ #define DUK_OP_LDREG 0 #define DUK_OP_STREG 1 #define DUK_OP_LDCONST 2 #define DUK_OP_LDINT 3 #define DUK_OP_LDINTX 4 -#define DUK_OP_MPUTOBJ 5 -#define DUK_OP_MPUTOBJI 6 -#define DUK_OP_MPUTARR 7 -#define DUK_OP_MPUTARRI 8 -#define DUK_OP_NEW 9 -#define DUK_OP_NEWI 10 -#define DUK_OP_REGEXP 11 -#define DUK_OP_CSREG 12 -#define DUK_OP_CSREGI 13 -#define DUK_OP_GETVAR 14 -#define DUK_OP_PUTVAR 15 -#define DUK_OP_DECLVAR 16 -#define DUK_OP_DELVAR 17 -#define DUK_OP_CSVAR 18 -#define DUK_OP_CSVARI 19 -#define DUK_OP_CLOSURE 20 -#define DUK_OP_GETPROP 21 -#define DUK_OP_PUTPROP 22 -#define DUK_OP_DELPROP 23 -#define DUK_OP_CSPROP 24 -#define DUK_OP_CSPROPI 25 -#define DUK_OP_ADD 26 -#define DUK_OP_SUB 27 -#define DUK_OP_MUL 28 -#define DUK_OP_DIV 29 -#define DUK_OP_MOD 30 -#define DUK_OP_BAND 31 -#define DUK_OP_BOR 32 -#define DUK_OP_BXOR 33 -#define DUK_OP_BASL 34 -#define DUK_OP_BLSR 35 -#define DUK_OP_BASR 36 -#define DUK_OP_EQ 37 -#define DUK_OP_NEQ 38 -#define DUK_OP_SEQ 39 -#define DUK_OP_SNEQ 40 -#define DUK_OP_GT 41 -#define DUK_OP_GE 42 -#define DUK_OP_LT 43 +#define DUK_OP_LDTHIS 5 +#define DUK_OP_LDUNDEF 6 +#define DUK_OP_LDNULL 7 +#define DUK_OP_LDTRUE 8 +#define DUK_OP_LDFALSE 9 +#define DUK_OP_BNOT 10 +#define DUK_OP_LNOT 11 +#define DUK_OP_UNM 12 +#define DUK_OP_UNP 13 +#define DUK_OP_TYPEOF 14 +#define DUK_OP_TYPEOFID 15 +#define DUK_OP_EQ 16 +#define DUK_OP_EQ_RR 16 +#define DUK_OP_EQ_CR 17 +#define DUK_OP_EQ_RC 18 +#define DUK_OP_EQ_CC 19 +#define DUK_OP_NEQ 20 +#define DUK_OP_NEQ_RR 20 +#define DUK_OP_NEQ_CR 21 +#define DUK_OP_NEQ_RC 22 +#define DUK_OP_NEQ_CC 23 +#define DUK_OP_SEQ 24 +#define DUK_OP_SEQ_RR 24 +#define DUK_OP_SEQ_CR 25 +#define DUK_OP_SEQ_RC 26 +#define DUK_OP_SEQ_CC 27 +#define DUK_OP_SNEQ 28 +#define DUK_OP_SNEQ_RR 28 +#define DUK_OP_SNEQ_CR 29 +#define DUK_OP_SNEQ_RC 30 +#define DUK_OP_SNEQ_CC 31 +#define DUK_OP_GT 32 +#define DUK_OP_GT_RR 32 +#define DUK_OP_GT_CR 33 +#define DUK_OP_GT_RC 34 +#define DUK_OP_GT_CC 35 +#define DUK_OP_GE 36 +#define DUK_OP_GE_RR 36 +#define DUK_OP_GE_CR 37 +#define DUK_OP_GE_RC 38 +#define DUK_OP_GE_CC 39 +#define DUK_OP_LT 40 +#define DUK_OP_LT_RR 40 +#define DUK_OP_LT_CR 41 +#define DUK_OP_LT_RC 42 +#define DUK_OP_LT_CC 43 #define DUK_OP_LE 44 -#define DUK_OP_IF 45 -#define DUK_OP_JUMP 46 -#define DUK_OP_RETURN 47 -#define DUK_OP_CALL 48 -#define DUK_OP_CALLI 49 -#define DUK_OP_TRYCATCH 50 -#define DUK_OP_EXTRA 51 -#define DUK_OP_PREINCR 52 /* pre/post opcode values have constraints, */ -#define DUK_OP_PREDECR 53 /* see duk_js_executor.c */ -#define DUK_OP_POSTINCR 54 -#define DUK_OP_POSTDECR 55 -#define DUK_OP_PREINCV 56 -#define DUK_OP_PREDECV 57 -#define DUK_OP_POSTINCV 58 -#define DUK_OP_POSTDECV 59 -#define DUK_OP_PREINCP 60 -#define DUK_OP_PREDECP 61 -#define DUK_OP_POSTINCP 62 -#define DUK_OP_POSTDECP 63 -#define DUK_OP_NONE 64 /* dummy value used as marker */ - -/* DUK_OP_EXTRA, sub-operation in A */ -#define DUK_EXTRAOP_NOP 0 -#define DUK_EXTRAOP_INVALID 1 -#define DUK_EXTRAOP_LDTHIS 2 -#define DUK_EXTRAOP_LDUNDEF 3 -#define DUK_EXTRAOP_LDNULL 4 -#define DUK_EXTRAOP_LDTRUE 5 -#define DUK_EXTRAOP_LDFALSE 6 -#define DUK_EXTRAOP_NEWOBJ 7 -#define DUK_EXTRAOP_NEWARR 8 -#define DUK_EXTRAOP_SETALEN 9 -#define DUK_EXTRAOP_TYPEOF 10 -#define DUK_EXTRAOP_TYPEOFID 11 -#define DUK_EXTRAOP_INITENUM 12 -#define DUK_EXTRAOP_NEXTENUM 13 -#define DUK_EXTRAOP_INITSET 14 -#define DUK_EXTRAOP_INITSETI 15 -#define DUK_EXTRAOP_INITGET 16 -#define DUK_EXTRAOP_INITGETI 17 -#define DUK_EXTRAOP_ENDTRY 18 -#define DUK_EXTRAOP_ENDCATCH 19 -#define DUK_EXTRAOP_ENDFIN 20 -#define DUK_EXTRAOP_THROW 21 -#define DUK_EXTRAOP_INVLHS 22 -#define DUK_EXTRAOP_UNM 23 -#define DUK_EXTRAOP_UNP 24 -#define DUK_EXTRAOP_DEBUGGER 25 -#define DUK_EXTRAOP_BREAK 26 -#define DUK_EXTRAOP_CONTINUE 27 -#define DUK_EXTRAOP_BNOT 28 -#define DUK_EXTRAOP_LNOT 29 -#define DUK_EXTRAOP_INSTOF 30 -#define DUK_EXTRAOP_IN 31 -#define DUK_EXTRAOP_LABEL 32 -#define DUK_EXTRAOP_ENDLABEL 33 - -/* DUK_OP_CALL flags in A */ -#define DUK_BC_CALL_FLAG_TAILCALL (1 << 0) -#define DUK_BC_CALL_FLAG_EVALCALL (1 << 1) - +#define DUK_OP_LE_RR 44 +#define DUK_OP_LE_CR 45 +#define DUK_OP_LE_RC 46 +#define DUK_OP_LE_CC 47 +#define DUK_OP_IFTRUE 48 +#define DUK_OP_IFTRUE_R 48 +#define DUK_OP_IFTRUE_C 49 +#define DUK_OP_IFFALSE 50 +#define DUK_OP_IFFALSE_R 50 +#define DUK_OP_IFFALSE_C 51 +#define DUK_OP_ADD 52 +#define DUK_OP_ADD_RR 52 +#define DUK_OP_ADD_CR 53 +#define DUK_OP_ADD_RC 54 +#define DUK_OP_ADD_CC 55 +#define DUK_OP_SUB 56 +#define DUK_OP_SUB_RR 56 +#define DUK_OP_SUB_CR 57 +#define DUK_OP_SUB_RC 58 +#define DUK_OP_SUB_CC 59 +#define DUK_OP_MUL 60 +#define DUK_OP_MUL_RR 60 +#define DUK_OP_MUL_CR 61 +#define DUK_OP_MUL_RC 62 +#define DUK_OP_MUL_CC 63 +#define DUK_OP_DIV 64 +#define DUK_OP_DIV_RR 64 +#define DUK_OP_DIV_CR 65 +#define DUK_OP_DIV_RC 66 +#define DUK_OP_DIV_CC 67 +#define DUK_OP_MOD 68 +#define DUK_OP_MOD_RR 68 +#define DUK_OP_MOD_CR 69 +#define DUK_OP_MOD_RC 70 +#define DUK_OP_MOD_CC 71 +#define DUK_OP_EXP 72 +#define DUK_OP_EXP_RR 72 +#define DUK_OP_EXP_CR 73 +#define DUK_OP_EXP_RC 74 +#define DUK_OP_EXP_CC 75 +#define DUK_OP_BAND 76 +#define DUK_OP_BAND_RR 76 +#define DUK_OP_BAND_CR 77 +#define DUK_OP_BAND_RC 78 +#define DUK_OP_BAND_CC 79 +#define DUK_OP_BOR 80 +#define DUK_OP_BOR_RR 80 +#define DUK_OP_BOR_CR 81 +#define DUK_OP_BOR_RC 82 +#define DUK_OP_BOR_CC 83 +#define DUK_OP_BXOR 84 +#define DUK_OP_BXOR_RR 84 +#define DUK_OP_BXOR_CR 85 +#define DUK_OP_BXOR_RC 86 +#define DUK_OP_BXOR_CC 87 +#define DUK_OP_BASL 88 +#define DUK_OP_BASL_RR 88 +#define DUK_OP_BASL_CR 89 +#define DUK_OP_BASL_RC 90 +#define DUK_OP_BASL_CC 91 +#define DUK_OP_BLSR 92 +#define DUK_OP_BLSR_RR 92 +#define DUK_OP_BLSR_CR 93 +#define DUK_OP_BLSR_RC 94 +#define DUK_OP_BLSR_CC 95 +#define DUK_OP_BASR 96 +#define DUK_OP_BASR_RR 96 +#define DUK_OP_BASR_CR 97 +#define DUK_OP_BASR_RC 98 +#define DUK_OP_BASR_CC 99 +#define DUK_OP_INSTOF 100 +#define DUK_OP_INSTOF_RR 100 +#define DUK_OP_INSTOF_CR 101 +#define DUK_OP_INSTOF_RC 102 +#define DUK_OP_INSTOF_CC 103 +#define DUK_OP_IN 104 +#define DUK_OP_IN_RR 104 +#define DUK_OP_IN_CR 105 +#define DUK_OP_IN_RC 106 +#define DUK_OP_IN_CC 107 +#define DUK_OP_GETPROP 108 +#define DUK_OP_GETPROP_RR 108 +#define DUK_OP_GETPROP_CR 109 +#define DUK_OP_GETPROP_RC 110 +#define DUK_OP_GETPROP_CC 111 +#define DUK_OP_PUTPROP 112 +#define DUK_OP_PUTPROP_RR 112 +#define DUK_OP_PUTPROP_CR 113 +#define DUK_OP_PUTPROP_RC 114 +#define DUK_OP_PUTPROP_CC 115 +#define DUK_OP_DELPROP 116 +#define DUK_OP_DELPROP_RR 116 +#define DUK_OP_DELPROP_CR_UNUSED 117 /* unused now */ +#define DUK_OP_DELPROP_RC 118 +#define DUK_OP_DELPROP_CC_UNUSED 119 /* unused now */ +#define DUK_OP_PREINCR 120 /* pre/post opcode values have constraints, */ +#define DUK_OP_PREDECR 121 /* see duk_js_executor.c and duk_js_compiler.c. */ +#define DUK_OP_POSTINCR 122 +#define DUK_OP_POSTDECR 123 +#define DUK_OP_PREINCV 124 +#define DUK_OP_PREDECV 125 +#define DUK_OP_POSTINCV 126 +#define DUK_OP_POSTDECV 127 +#define DUK_OP_PREINCP 128 /* pre/post inc/dec prop opcodes have constraints */ +#define DUK_OP_PREINCP_RR 128 +#define DUK_OP_PREINCP_CR 129 +#define DUK_OP_PREINCP_RC 130 +#define DUK_OP_PREINCP_CC 131 +#define DUK_OP_PREDECP 132 +#define DUK_OP_PREDECP_RR 132 +#define DUK_OP_PREDECP_CR 133 +#define DUK_OP_PREDECP_RC 134 +#define DUK_OP_PREDECP_CC 135 +#define DUK_OP_POSTINCP 136 +#define DUK_OP_POSTINCP_RR 136 +#define DUK_OP_POSTINCP_CR 137 +#define DUK_OP_POSTINCP_RC 138 +#define DUK_OP_POSTINCP_CC 139 +#define DUK_OP_POSTDECP 140 +#define DUK_OP_POSTDECP_RR 140 +#define DUK_OP_POSTDECP_CR 141 +#define DUK_OP_POSTDECP_RC 142 +#define DUK_OP_POSTDECP_CC 143 +#define DUK_OP_DECLVAR 144 +#define DUK_OP_DECLVAR_RR 144 +#define DUK_OP_DECLVAR_CR 145 +#define DUK_OP_DECLVAR_RC 146 +#define DUK_OP_DECLVAR_CC 147 +#define DUK_OP_REGEXP 148 +#define DUK_OP_REGEXP_RR 148 +#define DUK_OP_REGEXP_CR 149 +#define DUK_OP_REGEXP_RC 150 +#define DUK_OP_REGEXP_CC 151 +#define DUK_OP_CSVAR 152 +#define DUK_OP_CSVAR_RR 152 +#define DUK_OP_CSVAR_CR 153 +#define DUK_OP_CSVAR_RC 154 +#define DUK_OP_CSVAR_CC 155 +#define DUK_OP_CLOSURE 156 +#define DUK_OP_GETVAR 157 +#define DUK_OP_PUTVAR 158 +#define DUK_OP_DELVAR 159 +#define DUK_OP_JUMP 160 +#define DUK_OP_RETREG 161 +#define DUK_OP_RETUNDEF 162 +#define DUK_OP_RETCONST 163 +#define DUK_OP_RETCONSTN 164 /* return const without incref (e.g. number) */ +#define DUK_OP_LABEL 165 +#define DUK_OP_ENDLABEL 166 +#define DUK_OP_BREAK 167 +#define DUK_OP_CONTINUE 168 +#define DUK_OP_TRYCATCH 169 +#define DUK_OP_ENDTRY 170 +#define DUK_OP_ENDCATCH 171 +#define DUK_OP_ENDFIN 172 +#define DUK_OP_THROW 173 +#define DUK_OP_CSREG 174 +#define DUK_OP_EVALCALL 175 +#define DUK_OP_CALL 176 /* must be even */ +#define DUK_OP_TAILCALL 177 /* must be odd */ +#define DUK_OP_NEW 178 +#define DUK_OP_NEWOBJ 179 +#define DUK_OP_NEWARR 180 +#define DUK_OP_MPUTOBJ 181 +#define DUK_OP_MPUTOBJI 182 +#define DUK_OP_INITSET 183 +#define DUK_OP_INITGET 184 +#define DUK_OP_MPUTARR 185 +#define DUK_OP_MPUTARRI 186 +#define DUK_OP_SETALEN 187 +#define DUK_OP_INITENUM 188 +#define DUK_OP_NEXTENUM 189 +#define DUK_OP_INVLHS 190 +#define DUK_OP_DEBUGGER 191 +#define DUK_OP_NOP 192 +#define DUK_OP_INVALID 193 +#define DUK_OP_UNUSED194 194 +#define DUK_OP_UNUSED195 195 +#define DUK_OP_UNUSED196 196 +#define DUK_OP_UNUSED197 197 +#define DUK_OP_UNUSED198 198 +#define DUK_OP_UNUSED199 199 +#define DUK_OP_UNUSED200 200 +#define DUK_OP_UNUSED201 201 +#define DUK_OP_UNUSED202 202 +#define DUK_OP_UNUSED203 203 +#define DUK_OP_UNUSED204 204 +#define DUK_OP_UNUSED205 205 +#define DUK_OP_UNUSED206 206 +#define DUK_OP_UNUSED207 207 +#define DUK_OP_UNUSED208 208 +#define DUK_OP_UNUSED209 209 +#define DUK_OP_UNUSED210 210 +#define DUK_OP_UNUSED211 211 +#define DUK_OP_UNUSED212 212 +#define DUK_OP_UNUSED213 213 +#define DUK_OP_UNUSED214 214 +#define DUK_OP_UNUSED215 215 +#define DUK_OP_UNUSED216 216 +#define DUK_OP_UNUSED217 217 +#define DUK_OP_UNUSED218 218 +#define DUK_OP_UNUSED219 219 +#define DUK_OP_UNUSED220 220 +#define DUK_OP_UNUSED221 221 +#define DUK_OP_UNUSED222 222 +#define DUK_OP_UNUSED223 223 +#define DUK_OP_UNUSED224 224 +#define DUK_OP_UNUSED225 225 +#define DUK_OP_UNUSED226 226 +#define DUK_OP_UNUSED227 227 +#define DUK_OP_UNUSED228 228 +#define DUK_OP_UNUSED229 229 +#define DUK_OP_UNUSED230 230 +#define DUK_OP_UNUSED231 231 +#define DUK_OP_UNUSED232 232 +#define DUK_OP_UNUSED233 233 +#define DUK_OP_UNUSED234 234 +#define DUK_OP_UNUSED235 235 +#define DUK_OP_UNUSED236 236 +#define DUK_OP_UNUSED237 237 +#define DUK_OP_UNUSED238 238 +#define DUK_OP_UNUSED239 239 +#define DUK_OP_UNUSED240 240 +#define DUK_OP_UNUSED241 241 +#define DUK_OP_UNUSED242 242 +#define DUK_OP_UNUSED243 243 +#define DUK_OP_UNUSED244 244 +#define DUK_OP_UNUSED245 245 +#define DUK_OP_UNUSED246 246 +#define DUK_OP_UNUSED247 247 +#define DUK_OP_UNUSED248 248 +#define DUK_OP_UNUSED249 249 +#define DUK_OP_UNUSED250 250 +#define DUK_OP_UNUSED251 251 +#define DUK_OP_UNUSED252 252 +#define DUK_OP_UNUSED253 253 +#define DUK_OP_UNUSED254 254 +#define DUK_OP_UNUSED255 255 +#define DUK_OP_NONE 256 /* dummy value used as marker (doesn't fit in 8-bit field) */ + +/* XXX: Allocate flags from opcode field? Would take 16 opcode slots + * but avoids shuffling in more cases. Maybe not worth it. + */ /* DUK_OP_TRYCATCH flags in A */ #define DUK_BC_TRYCATCH_FLAG_HAVE_CATCH (1 << 0) #define DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY (1 << 1) #define DUK_BC_TRYCATCH_FLAG_CATCH_BINDING (1 << 2) #define DUK_BC_TRYCATCH_FLAG_WITH_BINDING (1 << 3) -/* DUK_OP_RETURN flags in A */ -#define DUK_BC_RETURN_FLAG_HAVE_RETVAL (1 << 0) - /* DUK_OP_DECLVAR flags in A; bottom bits are reserved for propdesc flags (DUK_PROPDESC_FLAG_XXX) */ #define DUK_BC_DECLVAR_FLAG_UNDEF_VALUE (1 << 4) /* use 'undefined' for value automatically */ #define DUK_BC_DECLVAR_FLAG_FUNC_DECL (1 << 5) /* function declaration */ -/* misc constants and helper macros */ -#define DUK_BC_REGLIMIT 256 /* if B/C is >= this value, refers to a const */ -#define DUK_BC_ISREG(x) ((x) < DUK_BC_REGLIMIT) -#define DUK_BC_ISCONST(x) ((x) >= DUK_BC_REGLIMIT) -#define DUK_BC_LDINT_BIAS (1L << 17) -#define DUK_BC_LDINTX_SHIFT 18 -#define DUK_BC_JUMP_BIAS (1L << 25) +/* Misc constants and helper macros. */ +#define DUK_BC_LDINT_BIAS (1L << 15) +#define DUK_BC_LDINTX_SHIFT 16 +#define DUK_BC_JUMP_BIAS (1L << 23) #endif /* DUK_JS_BYTECODE_H_INCLUDED */ -#line 1 "duk_lexer.h" +/* #include duk_lexer.h */ /* * Lexer defines. */ -#ifndef DUK_LEXER_H_INCLUDED +#if !defined(DUK_LEXER_H_INCLUDED) #define DUK_LEXER_H_INCLUDED typedef void (*duk_re_range_callback)(void *user, duk_codepoint_t r1, duk_codepoint_t r2, duk_bool_t direct); @@ -2754,8 +3039,7 @@ typedef void (*duk_re_range_callback)(void *user, duk_codepoint_t r1, duk_codepo #define DUK_LEXER_SETPOINT(ctx,pt) duk_lexer_setpoint((ctx), (pt)) -#define DUK_LEXER_GETPOINT(ctx,pt) do { (pt)->offset = (ctx)->window[0].offset; \ - (pt)->line = (ctx)->window[0].line; } while (0) +#define DUK_LEXER_GETPOINT(ctx,pt) duk_lexer_getpoint((ctx), (pt)) /* currently 6 characters of lookup are actually needed (duk_lexer.c) */ #define DUK_LEXER_WINDOW_SIZE 6 @@ -2859,41 +3143,43 @@ typedef void (*duk_re_range_callback)(void *user, duk_codepoint_t r1, duk_codepo #define DUK_TOK_MUL 68 #define DUK_TOK_DIV 69 #define DUK_TOK_MOD 70 -#define DUK_TOK_INCREMENT 71 -#define DUK_TOK_DECREMENT 72 -#define DUK_TOK_ALSHIFT 73 /* named "arithmetic" because result is signed */ -#define DUK_TOK_ARSHIFT 74 -#define DUK_TOK_RSHIFT 75 -#define DUK_TOK_BAND 76 -#define DUK_TOK_BOR 77 -#define DUK_TOK_BXOR 78 -#define DUK_TOK_LNOT 79 -#define DUK_TOK_BNOT 80 -#define DUK_TOK_LAND 81 -#define DUK_TOK_LOR 82 -#define DUK_TOK_QUESTION 83 -#define DUK_TOK_COLON 84 -#define DUK_TOK_EQUALSIGN 85 -#define DUK_TOK_ADD_EQ 86 -#define DUK_TOK_SUB_EQ 87 -#define DUK_TOK_MUL_EQ 88 -#define DUK_TOK_DIV_EQ 89 -#define DUK_TOK_MOD_EQ 90 -#define DUK_TOK_ALSHIFT_EQ 91 -#define DUK_TOK_ARSHIFT_EQ 92 -#define DUK_TOK_RSHIFT_EQ 93 -#define DUK_TOK_BAND_EQ 94 -#define DUK_TOK_BOR_EQ 95 -#define DUK_TOK_BXOR_EQ 96 +#define DUK_TOK_EXP 71 +#define DUK_TOK_INCREMENT 72 +#define DUK_TOK_DECREMENT 73 +#define DUK_TOK_ALSHIFT 74 /* named "arithmetic" because result is signed */ +#define DUK_TOK_ARSHIFT 75 +#define DUK_TOK_RSHIFT 76 +#define DUK_TOK_BAND 77 +#define DUK_TOK_BOR 78 +#define DUK_TOK_BXOR 79 +#define DUK_TOK_LNOT 80 +#define DUK_TOK_BNOT 81 +#define DUK_TOK_LAND 82 +#define DUK_TOK_LOR 83 +#define DUK_TOK_QUESTION 84 +#define DUK_TOK_COLON 85 +#define DUK_TOK_EQUALSIGN 86 +#define DUK_TOK_ADD_EQ 87 +#define DUK_TOK_SUB_EQ 88 +#define DUK_TOK_MUL_EQ 89 +#define DUK_TOK_DIV_EQ 90 +#define DUK_TOK_MOD_EQ 91 +#define DUK_TOK_EXP_EQ 92 +#define DUK_TOK_ALSHIFT_EQ 93 +#define DUK_TOK_ARSHIFT_EQ 94 +#define DUK_TOK_RSHIFT_EQ 95 +#define DUK_TOK_BAND_EQ 96 +#define DUK_TOK_BOR_EQ 97 +#define DUK_TOK_BXOR_EQ 98 /* literals (E5 Section 7.8), except null, true, false, which are treated * like reserved words (above). */ -#define DUK_TOK_NUMBER 97 -#define DUK_TOK_STRING 98 -#define DUK_TOK_REGEXP 99 +#define DUK_TOK_NUMBER 99 +#define DUK_TOK_STRING 100 +#define DUK_TOK_REGEXP 101 -#define DUK_TOK_MAXVAL 99 /* inclusive */ +#define DUK_TOK_MAXVAL 101 /* inclusive */ /* Convert heap string index to a token (reserved words) */ #define DUK_STRIDX_TO_TOK(x) ((x) - DUK_STRIDX_START_RESERVED + DUK_TOK_START_RESERVED) @@ -3052,12 +3338,12 @@ typedef void (*duk_re_range_callback)(void *user, duk_codepoint_t r1, duk_codepo #define DUK_RETOK_ASSERT_START_NEG_LOOKAHEAD 8 #define DUK_RETOK_ATOM_PERIOD 9 #define DUK_RETOK_ATOM_CHAR 10 -#define DUK_RETOK_ATOM_DIGIT 11 -#define DUK_RETOK_ATOM_NOT_DIGIT 12 -#define DUK_RETOK_ATOM_WHITE 13 -#define DUK_RETOK_ATOM_NOT_WHITE 14 -#define DUK_RETOK_ATOM_WORD_CHAR 15 -#define DUK_RETOK_ATOM_NOT_WORD_CHAR 16 +#define DUK_RETOK_ATOM_DIGIT 11 /* assumptions in regexp compiler */ +#define DUK_RETOK_ATOM_NOT_DIGIT 12 /* -""- */ +#define DUK_RETOK_ATOM_WHITE 13 /* -""- */ +#define DUK_RETOK_ATOM_NOT_WHITE 14 /* -""- */ +#define DUK_RETOK_ATOM_WORD_CHAR 15 /* -""- */ +#define DUK_RETOK_ATOM_NOT_WORD_CHAR 16 /* -""- */ #define DUK_RETOK_ATOM_BACKREFERENCE 17 #define DUK_RETOK_ATOM_START_CAPTURE_GROUP 18 #define DUK_RETOK_ATOM_START_NONCAPTURE_GROUP 19 @@ -3141,6 +3427,7 @@ struct duk_lexer_ctx { DUK_INTERNAL_DECL void duk_lexer_initctx(duk_lexer_ctx *lex_ctx); +DUK_INTERNAL_DECL void duk_lexer_getpoint(duk_lexer_ctx *lex_ctx, duk_lexer_point *pt); DUK_INTERNAL_DECL void duk_lexer_setpoint(duk_lexer_ctx *lex_ctx, duk_lexer_point *pt); DUK_INTERNAL_DECL @@ -3148,18 +3435,18 @@ void duk_lexer_parse_js_input_element(duk_lexer_ctx *lex_ctx, duk_token *out_token, duk_bool_t strict_mode, duk_bool_t regexp_mode); -#ifdef DUK_USE_REGEXP_SUPPORT +#if defined(DUK_USE_REGEXP_SUPPORT) DUK_INTERNAL_DECL void duk_lexer_parse_re_token(duk_lexer_ctx *lex_ctx, duk_re_token *out_token); DUK_INTERNAL_DECL void duk_lexer_parse_re_ranges(duk_lexer_ctx *lex_ctx, duk_re_range_callback gen_range, void *userdata); #endif /* DUK_USE_REGEXP_SUPPORT */ #endif /* DUK_LEXER_H_INCLUDED */ -#line 1 "duk_js_compiler.h" +/* #include duk_js_compiler.h */ /* * Ecmascript compiler. */ -#ifndef DUK_JS_COMPILER_H_INCLUDED +#if !defined(DUK_JS_COMPILER_H_INCLUDED) #define DUK_JS_COMPILER_H_INCLUDED /* ecmascript compiler limits */ @@ -3182,16 +3469,18 @@ DUK_INTERNAL_DECL void duk_lexer_parse_re_ranges(duk_lexer_ctx *lex_ctx, duk_re_ #define DUK_IVAL_NONE 0 /* no value */ #define DUK_IVAL_PLAIN 1 /* register, constant, or value */ #define DUK_IVAL_ARITH 2 /* binary arithmetic; DUK_OP_ADD, DUK_OP_EQ, other binary ops */ -#define DUK_IVAL_ARITH_EXTRAOP 3 /* binary arithmetic using extraops; DUK_EXTRAOP_INSTOF etc */ -#define DUK_IVAL_PROP 4 /* property access */ -#define DUK_IVAL_VAR 5 /* variable access */ +#define DUK_IVAL_PROP 3 /* property access */ +#define DUK_IVAL_VAR 4 /* variable access */ #define DUK_ISPEC_NONE 0 /* no value */ #define DUK_ISPEC_VALUE 1 /* value resides in 'valstack_idx' */ #define DUK_ISPEC_REGCONST 2 /* value resides in a register or constant */ -/* bit mask which indicates that a regconst is a constant instead of a register */ -#define DUK_JS_CONST_MARKER 0x80000000UL +/* Bit mask which indicates that a regconst is a constant instead of a register. + * Chosen so that when a regconst is cast to duk_int32_t, all consts are + * negative values. + */ +#define DUK_REGCONST_CONST_MARKER 0x80000000UL /* type to represent a reg/const reference during compilation */ typedef duk_uint32_t duk_regconst_t; @@ -3215,7 +3504,7 @@ typedef struct { /* XXX: can be optimized for smaller footprint esp. on 32-bit environments */ duk_small_uint_t t; /* DUK_IVAL_XXX */ - duk_small_uint_t op; /* bytecode opcode (or extraop) for binary ops */ + duk_small_uint_t op; /* bytecode opcode for binary ops */ duk_ispec x1; duk_ispec x2; } duk_ivalue; @@ -3261,7 +3550,7 @@ typedef struct { */ } duk_labelinfo; -/* Compiling state of one function, eventually converted to duk_hcompiledfunction */ +/* Compiling state of one function, eventually converted to duk_hcompfunc */ struct duk_compiler_func { /* These pointers are at the start of the struct so that they pack * nicely. Mixing pointers and integer values is bad on some @@ -3285,7 +3574,7 @@ struct duk_compiler_func { duk_hobject *h_argnames; /* array of formal argument names (-> _Formals) */ duk_hobject *h_varmap; /* variable map for pass 2 (identifier -> register number or null (unmapped)) */ - /* value stack indices for tracking objects */ + /* Value stack indices for tracking objects. */ /* code_idx: not needed */ duk_idx_t consts_idx; duk_idx_t funcs_idx; @@ -3295,24 +3584,24 @@ struct duk_compiler_func { duk_idx_t argnames_idx; duk_idx_t varmap_idx; - /* temp reg handling */ + /* Temp reg handling. */ duk_reg_t temp_first; /* first register that is a temporary (below: variables) */ duk_reg_t temp_next; /* next temporary register to allocate */ duk_reg_t temp_max; /* highest value of temp_reg (temp_max - 1 is highest used reg) */ - /* shuffle registers if large number of regs/consts */ + /* Shuffle registers if large number of regs/consts. */ duk_reg_t shuffle1; duk_reg_t shuffle2; duk_reg_t shuffle3; - /* stats for current expression being parsed */ + /* Stats for current expression being parsed. */ duk_int_t nud_count; duk_int_t led_count; duk_int_t paren_level; /* parenthesis count, 0 = top level */ duk_bool_t expr_lhs; /* expression is left-hand-side compatible */ duk_bool_t allow_in; /* current paren level allows 'in' token */ - /* misc */ + /* Misc. */ duk_int_t stmt_next; /* statement id allocation (running counter) */ duk_int_t label_next; /* label id allocation (running counter) */ duk_int_t catch_depth; /* catch stack depth */ @@ -3321,26 +3610,28 @@ struct duk_compiler_func { duk_int_t num_formals; /* number of formal arguments */ duk_reg_t reg_stmt_value; /* register for writing value of 'non-empty' statements (global or eval code), -1 is marker */ #if defined(DUK_USE_DEBUGGER_SUPPORT) - duk_int_t min_line; /* XXX: typing (duk_hcompiledfunction has duk_uint32_t) */ + duk_int_t min_line; /* XXX: typing (duk_hcompfunc has duk_uint32_t) */ duk_int_t max_line; #endif - /* status booleans */ - duk_bool_t is_function; /* is an actual function (not global/eval code) */ - duk_bool_t is_eval; /* is eval code */ - duk_bool_t is_global; /* is global code */ - duk_bool_t is_setget; /* is a setter/getter */ - duk_bool_t is_decl; /* is a function declaration (as opposed to function expression) */ - duk_bool_t is_strict; /* function is strict */ - duk_bool_t is_notail; /* function must not be tail called */ - duk_bool_t in_directive_prologue; /* parsing in "directive prologue", recognize directives */ - duk_bool_t in_scanning; /* parsing in "scanning" phase (first pass) */ - duk_bool_t may_direct_eval; /* function may call direct eval */ - duk_bool_t id_access_arguments; /* function refers to 'arguments' identifier */ - duk_bool_t id_access_slow; /* function makes one or more slow path accesses */ - duk_bool_t is_arguments_shadowed; /* argument/function declaration shadows 'arguments' */ - duk_bool_t needs_shuffle; /* function needs shuffle registers */ - duk_bool_t reject_regexp_in_adv; /* reject RegExp literal on next advance() call; needed for handling IdentifierName productions */ + /* Status booleans. */ + duk_uint8_t is_function; /* is an actual function (not global/eval code) */ + duk_uint8_t is_eval; /* is eval code */ + duk_uint8_t is_global; /* is global code */ + duk_uint8_t is_namebinding; /* needs a name binding */ + duk_uint8_t is_constructable; /* result is constructable */ + duk_uint8_t is_setget; /* is a setter/getter */ + duk_uint8_t is_strict; /* function is strict */ + duk_uint8_t is_notail; /* function must not be tail called */ + duk_uint8_t in_directive_prologue; /* parsing in "directive prologue", recognize directives */ + duk_uint8_t in_scanning; /* parsing in "scanning" phase (first pass) */ + duk_uint8_t may_direct_eval; /* function may call direct eval */ + duk_uint8_t id_access_arguments; /* function refers to 'arguments' identifier */ + duk_uint8_t id_access_slow; /* function makes one or more slow path accesses that won't match own static variables */ + duk_uint8_t id_access_slow_own; /* function makes one or more slow path accesses that may match own static variables */ + duk_uint8_t is_arguments_shadowed; /* argument/function declaration shadows 'arguments' */ + duk_uint8_t needs_shuffle; /* function needs shuffle registers */ + duk_uint8_t reject_regexp_in_adv; /* reject RegExp literal on next advance() call; needed for handling IdentifierName productions */ }; struct duk_compiler_ctx { @@ -3382,12 +3673,12 @@ struct duk_compiler_ctx { DUK_INTERNAL_DECL void duk_js_compile(duk_hthread *thr, const duk_uint8_t *src_buffer, duk_size_t src_length, duk_small_uint_t flags); #endif /* DUK_JS_COMPILER_H_INCLUDED */ -#line 1 "duk_regexp.h" +/* #include duk_regexp.h */ /* * Regular expression structs, constants, and bytecode defines. */ -#ifndef DUK_REGEXP_H_INCLUDED +#if !defined(DUK_REGEXP_H_INCLUDED) #define DUK_REGEXP_H_INCLUDED /* maximum bytecode copies for {n,m} quantifiers */ @@ -3459,19 +3750,21 @@ struct duk_re_compiler_ctx { * Prototypes */ +#if defined(DUK_USE_REGEXP_SUPPORT) DUK_INTERNAL_DECL void duk_regexp_compile(duk_hthread *thr); DUK_INTERNAL_DECL void duk_regexp_create_instance(duk_hthread *thr); DUK_INTERNAL_DECL void duk_regexp_match(duk_hthread *thr); DUK_INTERNAL_DECL void duk_regexp_match_force_global(duk_hthread *thr); /* hacky helper for String.prototype.split() */ +#endif #endif /* DUK_REGEXP_H_INCLUDED */ -#line 1 "duk_heaphdr.h" +/* #include duk_heaphdr.h */ /* * Heap header definition and assorted macros, including ref counting. * Access all fields through the accessor macros. */ -#ifndef DUK_HEAPHDR_H_INCLUDED +#if !defined(DUK_HEAPHDR_H_INCLUDED) #define DUK_HEAPHDR_H_INCLUDED /* @@ -3548,6 +3841,8 @@ struct duk_heaphdr_string { #else duk_size_t h_refcount; #endif +#else + duk_uint16_t h_strextra16; #endif }; @@ -3569,11 +3864,11 @@ struct duk_heaphdr_string { #define DUK_HEAPHDR_FLAG_FINALIZED DUK_HEAPHDR_HEAP_FLAG(3) /* mark-and-sweep: finalized (on previous pass) */ #define DUK_HEAPHDR_FLAG_READONLY DUK_HEAPHDR_HEAP_FLAG(4) /* read-only object, in code section */ -#define DUK_HTYPE_MIN 1 -#define DUK_HTYPE_STRING 1 -#define DUK_HTYPE_OBJECT 2 -#define DUK_HTYPE_BUFFER 3 -#define DUK_HTYPE_MAX 3 +#define DUK_HTYPE_MIN 0 +#define DUK_HTYPE_STRING 0 +#define DUK_HTYPE_OBJECT 1 +#define DUK_HTYPE_BUFFER 2 +#define DUK_HTYPE_MAX 2 #if defined(DUK_USE_HEAPPTR16) #define DUK_HEAPHDR_GET_NEXT(heap,h) \ @@ -3620,7 +3915,7 @@ struct duk_heaphdr_string { #define DUK_HEAPHDR_PREDEC_REFCOUNT(h) (--(h)->h_refcount) /* result: updated refcount */ #endif #else -/* refcount macros not defined without refcounting, caller must #ifdef now */ +/* refcount macros not defined without refcounting, caller must #if defined() now */ #endif /* DUK_USE_REFERENCE_COUNTING */ /* @@ -3629,19 +3924,22 @@ struct duk_heaphdr_string { */ #define DUK_HEAPHDR_GET_FLAGS_RAW(h) ((h)->h_flags) - +#define DUK_HEAPHDR_SET_FLAGS_RAW(h,val) do { \ + (h)->h_flags = (val); } \ + } #define DUK_HEAPHDR_GET_FLAGS(h) ((h)->h_flags & DUK_HEAPHDR_FLAGS_FLAG_MASK) #define DUK_HEAPHDR_SET_FLAGS(h,val) do { \ (h)->h_flags = ((h)->h_flags & ~(DUK_HEAPHDR_FLAGS_FLAG_MASK)) | (val); \ } while (0) - #define DUK_HEAPHDR_GET_TYPE(h) ((h)->h_flags & DUK_HEAPHDR_FLAGS_TYPE_MASK) #define DUK_HEAPHDR_SET_TYPE(h,val) do { \ (h)->h_flags = ((h)->h_flags & ~(DUK_HEAPHDR_FLAGS_TYPE_MASK)) | (val); \ } while (0) +/* Comparison for type >= DUK_HTYPE_MIN skipped; because DUK_HTYPE_MIN is zero + * and the comparison is unsigned, it's always true and generates warnings. + */ #define DUK_HEAPHDR_HTYPE_VALID(h) ( \ - DUK_HEAPHDR_GET_TYPE((h)) >= DUK_HTYPE_MIN && \ DUK_HEAPHDR_GET_TYPE((h)) <= DUK_HTYPE_MAX \ ) @@ -3687,7 +3985,7 @@ struct duk_heaphdr_string { #define DUK_HEAPHDR_SET_FLAG_RANGE(h,m,n,v) do { \ (h)->h_flags = \ - ((h)->h_flags & (~(((1 << (n)) - 1) << (m)))) \ + ((h)->h_flags & (~(((1UL << (n)) - 1UL) << (m)))) \ | ((v) << (m)); \ } while (0) @@ -3706,6 +4004,17 @@ struct duk_heaphdr_string { #define DUK_HEAPHDR_STRING_INIT_NULLS(h) /* currently nop */ /* + * Type tests + */ + +#define DUK_HEAPHDR_IS_OBJECT(h) \ + (DUK_HEAPHDR_GET_TYPE((h)) == DUK_HTYPE_OBJECT) +#define DUK_HEAPHDR_IS_STRING(h) \ + (DUK_HEAPHDR_GET_TYPE((h)) == DUK_HTYPE_STRING) +#define DUK_HEAPHDR_IS_BUFFER(h) \ + (DUK_HEAPHDR_GET_TYPE((h)) == DUK_HTYPE_BUFFER) + +/* * Assert helpers */ @@ -3733,7 +4042,7 @@ struct duk_heaphdr_string { * it is not required for INCREF, but it is included just in case. * * Note that 'raw' macros such as DUK_HEAPHDR_GET_REFCOUNT() are not - * defined without DUK_USE_REFERENCE_COUNTING, so caller must #ifdef + * defined without DUK_USE_REFERENCE_COUNTING, so caller must #if defined() * around them. */ @@ -3781,6 +4090,19 @@ struct duk_heaphdr_string { } \ } \ } while (0) +#define DUK_TVAL_DECREF_NORZ_FAST(thr,tv) do { \ + duk_tval *duk__tv = (tv); \ + DUK_ASSERT(duk__tv != NULL); \ + if (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk__tv)) { \ + duk_heaphdr *duk__h = DUK_TVAL_GET_HEAPHDR(duk__tv); \ + DUK_ASSERT(duk__h != NULL); \ + DUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \ + DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) > 0); \ + if (DUK_HEAPHDR_PREDEC_REFCOUNT(duk__h) == 0) { \ + duk_heaphdr_refzero_norz((thr), duk__h); \ + } \ + } \ + } while (0) #define DUK_HEAPHDR_INCREF_FAST(thr,h) do { \ duk_heaphdr *duk__h = (duk_heaphdr *) (h); \ DUK_ASSERT(duk__h != NULL); \ @@ -3789,79 +4111,181 @@ struct duk_heaphdr_string { DUK_HEAPHDR_PREINC_REFCOUNT(duk__h); \ } \ } while (0) -#define DUK_HEAPHDR_DECREF_FAST(thr,h) do { \ +#define DUK_HEAPHDR_DECREF_FAST_RAW(thr,h,rzcall,rzcast) do { \ duk_heaphdr *duk__h = (duk_heaphdr *) (h); \ DUK_ASSERT(duk__h != NULL); \ DUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \ DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) > 0); \ if (DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(duk__h)) { \ if (DUK_HEAPHDR_PREDEC_REFCOUNT(duk__h) == 0) { \ - duk_heaphdr_refzero((thr), duk__h); \ + (rzcall)((thr), (rzcast) duk__h); \ } \ } \ } while (0) +#define DUK_HEAPHDR_DECREF_FAST(thr,h) \ + DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_heaphdr_refzero,duk_heaphdr *) +#define DUK_HEAPHDR_DECREF_NORZ_FAST(thr,h) \ + DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_heaphdr_refzero_norz,duk_heaphdr *) /* Slow variants, call to a helper to reduce code size. * Can be used explicitly when size is always more important than speed. */ -#define DUK_TVAL_INCREF_SLOW(thr,tv) do { \ - duk_tval_incref((tv)); \ - } while (0) -#define DUK_TVAL_DECREF_SLOW(thr,tv) do { \ - duk_tval_decref((thr), (tv)); \ - } while (0) -#define DUK_HEAPHDR_INCREF_SLOW(thr,h) do { \ - duk_heaphdr_incref((duk_heaphdr *) (h)); \ - } while (0) -#define DUK_HEAPHDR_DECREF_SLOW(thr,h) do { \ - duk_heaphdr_decref((thr), (duk_heaphdr *) (h)); \ - } while (0) +#define DUK_TVAL_INCREF_SLOW(thr,tv) do { duk_tval_incref((tv)); } while (0) +#define DUK_TVAL_DECREF_SLOW(thr,tv) do { duk_tval_decref((thr), (tv)); } while (0) +#define DUK_TVAL_DECREF_NORZ_SLOW(thr,tv) do { duk_tval_decref_norz((thr), (tv)); } while (0) +#define DUK_HEAPHDR_INCREF_SLOW(thr,h) do { duk_heaphdr_incref((duk_heaphdr *) (h)); } while (0) +#define DUK_HEAPHDR_DECREF_SLOW(thr,h) do { duk_heaphdr_decref((thr), (duk_heaphdr *) (h)); } while (0) +#define DUK_HEAPHDR_DECREF_NORZ_SLOW(thr,h) do { duk_heaphdr_decref_norz((thr), (duk_heaphdr *) (h)); } while (0) +#define DUK_HSTRING_INCREF_SLOW(thr,h) do { duk_heaphdr_incref((duk_heaphdr *) (h)); } while (0) +#define DUK_HSTRING_DECREF_SLOW(thr,h) do { duk_heaphdr_decref((thr), (duk_heaphdr *) (h)); } while (0) +#define DUK_HSTRING_DECREF_NORZ_SLOW(thr,h) do { duk_heaphdr_decref_norz((thr), (duk_heaphdr *) (h)); } while (0) +#define DUK_HBUFFER_INCREF_SLOW(thr,h) do { duk_heaphdr_incref((duk_heaphdr *) (h)); } while (0) +#define DUK_HBUFFER_DECREF_SLOW(thr,h) do { duk_heaphdr_decref((thr), (duk_heaphdr *) (h)); } while (0) +#define DUK_HBUFFER_DECREF_NORZ_SLOW(thr,h) do { duk_heaphdr_decref_norz((thr), (duk_heaphdr *) (h)); } while (0) +#define DUK_HOBJECT_INCREF_SLOW(thr,h) do { duk_heaphdr_incref((duk_heaphdr *) (h)); } while (0) +#define DUK_HOBJECT_DECREF_SLOW(thr,h) do { duk_heaphdr_decref((thr), (duk_heaphdr *) (h)); } while (0) +#define DUK_HOBJECT_DECREF_NORZ_SLOW(thr,h) do { duk_heaphdr_decref_norz((thr), (duk_heaphdr *) (h)); } while (0) /* Default variants. Selection depends on speed/size preference. * Concretely: with gcc 4.8.1 -Os x64 the difference in final binary * is about +1kB for _FAST variants. */ #if defined(DUK_USE_FAST_REFCOUNT_DEFAULT) +/* XXX: It would be nice to specialize for specific duk_hobject subtypes + * but current refzero queue handling prevents that. + */ #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((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)) -#endif - -/* Casting convenience. */ +#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_HEAPHDR_DECREF((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_HEAPHDR_DECREF((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_HEAPHDR_DECREF((thr),(duk_heaphdr *) (h)) -#define DUK_HCOMPILEDFUNCTION_INCREF(thr,h) DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj) -#define DUK_HCOMPILEDFUNCTION_DECREF(thr,h) DUK_HEAPHDR_DECREF((thr),(duk_heaphdr *) &(h)->obj) -#define DUK_HNATIVEFUNCTION_INCREF(thr,h) DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj) -#define DUK_HNATIVEFUNCTION_DECREF(thr,h) DUK_HEAPHDR_DECREF((thr),(duk_heaphdr *) &(h)->obj) -#define DUK_HBUFFEROBJECT_INCREF(thr,h) DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj) -#define DUK_HBUFFEROBJECT_DECREF(thr,h) DUK_HEAPHDR_DECREF((thr),(duk_heaphdr *) &(h)->obj) +#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_HEAPHDR_DECREF((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. + * for performance reasons. Macros cover only actually needed cases. */ -#define DUK_HOBJECT_INCREF_ALLOWNULL(thr,h) do { \ +#define DUK_HEAPHDR_INCREF_ALLOWNULL(thr,h) do { \ if ((h) != NULL) { \ DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) (h)); \ } \ } while (0) -#define DUK_HOBJECT_DECREF_ALLOWNULL(thr,h) do { \ +#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) + +/* Free pending refzero entries; quick check to avoid call because often + * the queue is empty. + */ +#define DUK_REFZERO_CHECK_FAST(thr) do { \ + if ((thr)->heap->refzero_list != NULL) { \ + duk_refzero_free_pending((thr)); \ + } \ + } while (0) +#define DUK_REFZERO_CHECK_SLOW(thr) do { \ + duk_refzero_free_pending((thr)); \ + } while (0) /* * Macros to set a duk_tval and update refcount of the target (decref the @@ -3876,6 +4300,13 @@ struct duk_heaphdr_string { 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); \ @@ -3906,7 +4337,7 @@ struct duk_heaphdr_string { #define DUK_TVAL_SET_NUMBER_CHKFAST_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_NUMBER_CHKFAST(tv__dst, (newval)); \ + DUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv__dst, (newval)); \ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ } while (0) #define DUK_TVAL_SET_DOUBLE_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ @@ -3922,22 +4353,22 @@ struct duk_heaphdr_string { DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ } while (0) #if defined(DUK_USE_FASTINT) -#define DUK_TVAL_SET_FASTINT_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ +#define DUK_TVAL_SET_I48_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_FASTINT(tv__dst, (newval)); \ + DUK_TVAL_SET_I48(tv__dst, (newval)); \ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ } while (0) -#define DUK_TVAL_SET_FASTINT_I32_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ +#define DUK_TVAL_SET_I32_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_FASTINT_I32(tv__dst, (newval)); \ + DUK_TVAL_SET_I32(tv__dst, (newval)); \ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ } while (0) -#define DUK_TVAL_SET_FASTINT_U32_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ +#define DUK_TVAL_SET_U32_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_FASTINT_U32(tv__dst, (newval)); \ + DUK_TVAL_SET_U32(tv__dst, (newval)); \ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ } while (0) #else @@ -4019,6 +4450,7 @@ struct duk_heaphdr_string { /* XXX: no optimized variants yet */ #define DUK_TVAL_SET_UNDEFINED_UPDREF DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0 +#define DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ_ALT0 #define DUK_TVAL_SET_UNUSED_UPDREF DUK_TVAL_SET_UNUSED_UPDREF_ALT0 #define DUK_TVAL_SET_NULL_UPDREF DUK_TVAL_SET_NULL_UPDREF_ALT0 #define DUK_TVAL_SET_BOOLEAN_UPDREF DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0 @@ -4027,14 +4459,15 @@ struct duk_heaphdr_string { #define DUK_TVAL_SET_DOUBLE_UPDREF DUK_TVAL_SET_DOUBLE_UPDREF_ALT0 #define DUK_TVAL_SET_NAN_UPDREF DUK_TVAL_SET_NAN_UPDREF_ALT0 #if defined(DUK_USE_FASTINT) -#define DUK_TVAL_SET_FASTINT_UPDREF DUK_TVAL_SET_FASTINT_UPDREF_ALT0 -#define DUK_TVAL_SET_FASTINT_I32_UPDREF DUK_TVAL_SET_FASTINT_I32_UPDREF_ALT0 -#define DUK_TVAL_SET_FASTINT_U32_UPDREF DUK_TVAL_SET_FASTINT_U32_UPDREF_ALT0 +#define DUK_TVAL_SET_I48_UPDREF DUK_TVAL_SET_I48_UPDREF_ALT0 +#define DUK_TVAL_SET_I32_UPDREF DUK_TVAL_SET_I32_UPDREF_ALT0 +#define DUK_TVAL_SET_U32_UPDREF DUK_TVAL_SET_U32_UPDREF_ALT0 #else -#define DUK_TVAL_SET_FASTINT_UPDREF DUK_TVAL_SET_DOUBLE_CAST_UPDREF /* XXX: fast int-to-double */ -#define DUK_TVAL_SET_FASTINT_I32_UPDREF DUK_TVAL_SET_DOUBLE_CAST_UPDREF -#define DUK_TVAL_SET_FASTINT_U32_UPDREF DUK_TVAL_SET_DOUBLE_CAST_UPDREF +#define DUK_TVAL_SET_I48_UPDREF DUK_TVAL_SET_DOUBLE_CAST_UPDREF /* XXX: fast int-to-double */ +#define DUK_TVAL_SET_I32_UPDREF DUK_TVAL_SET_DOUBLE_CAST_UPDREF +#define DUK_TVAL_SET_U32_UPDREF DUK_TVAL_SET_DOUBLE_CAST_UPDREF #endif /* DUK_USE_FASTINT */ +#define DUK_TVAL_SET_FASTINT_UPDREF DUK_TVAL_SET_I48_UPDREF /* convenience */ #define DUK_TVAL_SET_LIGHTFUNC_UPDREF DUK_TVAL_SET_LIGHTFUNC_UPDREF_ALT0 #define DUK_TVAL_SET_STRING_UPDREF DUK_TVAL_SET_STRING_UPDREF_ALT0 #define DUK_TVAL_SET_OBJECT_UPDREF DUK_TVAL_SET_OBJECT_UPDREF_ALT0 @@ -4055,34 +4488,76 @@ struct duk_heaphdr_string { #else /* DUK_USE_REFERENCE_COUNTING */ +#define DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv) 0 +#define DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(h) 0 + #define DUK_TVAL_INCREF_FAST(thr,v) do {} while (0) /* nop */ #define DUK_TVAL_DECREF_FAST(thr,v) do {} while (0) /* nop */ +#define DUK_TVAL_DECREF_NORZ_FAST(thr,v) do {} while (0) /* nop */ #define DUK_TVAL_INCREF_SLOW(thr,v) do {} while (0) /* nop */ #define DUK_TVAL_DECREF_SLOW(thr,v) do {} while (0) /* nop */ +#define DUK_TVAL_DECREF_NORZ_SLOW(thr,v) do {} while (0) /* nop */ #define DUK_TVAL_INCREF(thr,v) do {} while (0) /* nop */ #define DUK_TVAL_DECREF(thr,v) do {} while (0) /* nop */ +#define DUK_TVAL_DECREF_NORZ(thr,v) do {} while (0) /* nop */ #define DUK_HEAPHDR_INCREF_FAST(thr,h) do {} while (0) /* nop */ #define DUK_HEAPHDR_DECREF_FAST(thr,h) do {} while (0) /* nop */ +#define DUK_HEAPHDR_DECREF_NORZ_FAST(thr,h) do {} while (0) /* nop */ #define DUK_HEAPHDR_INCREF_SLOW(thr,h) do {} while (0) /* nop */ #define DUK_HEAPHDR_DECREF_SLOW(thr,h) do {} while (0) /* nop */ +#define DUK_HEAPHDR_DECREF_NORZ_SLOW(thr,h) do {} while (0) /* nop */ #define DUK_HEAPHDR_INCREF(thr,h) do {} while (0) /* nop */ #define DUK_HEAPHDR_DECREF(thr,h) do {} while (0) /* nop */ +#define DUK_HEAPHDR_DECREF_NORZ(thr,h) do {} while (0) /* nop */ +#define DUK_HSTRING_INCREF_FAST(thr,h) do {} while (0) /* nop */ +#define DUK_HSTRING_DECREF_FAST(thr,h) do {} while (0) /* nop */ +#define DUK_HSTRING_DECREF_NORZ_FAST(thr,h) do {} while (0) /* nop */ +#define DUK_HSTRING_INCREF_SLOW(thr,h) do {} while (0) /* nop */ +#define DUK_HSTRING_DECREF_SLOW(thr,h) do {} while (0) /* nop */ +#define DUK_HSTRING_DECREF_NORZ_SLOW(thr,h) do {} while (0) /* nop */ #define DUK_HSTRING_INCREF(thr,h) do {} while (0) /* nop */ #define DUK_HSTRING_DECREF(thr,h) do {} while (0) /* nop */ +#define DUK_HSTRING_DECREF_NORZ(thr,h) do {} while (0) /* nop */ +#define DUK_HOBJECT_INCREF_FAST(thr,h) do {} while (0) /* nop */ +#define DUK_HOBJECT_DECREF_FAST(thr,h) do {} while (0) /* nop */ +#define DUK_HOBJECT_DECREF_NORZ_FAST(thr,h) do {} while (0) /* nop */ +#define DUK_HOBJECT_INCREF_SLOW(thr,h) do {} while (0) /* nop */ +#define DUK_HOBJECT_DECREF_SLOW(thr,h) do {} while (0) /* nop */ +#define DUK_HOBJECT_DECREF_NORZ_SLOW(thr,h) do {} while (0) /* nop */ #define DUK_HOBJECT_INCREF(thr,h) do {} while (0) /* nop */ #define DUK_HOBJECT_DECREF(thr,h) do {} while (0) /* nop */ +#define DUK_HOBJECT_DECREF_NORZ(thr,h) do {} while (0) /* nop */ +#define DUK_HBUFFER_INCREF_FAST(thr,h) do {} while (0) /* nop */ +#define DUK_HBUFFER_DECREF_FAST(thr,h) do {} while (0) /* nop */ +#define DUK_HBUFFER_DECREF_NORZ_FAST(thr,h) do {} while (0) /* nop */ +#define DUK_HBUFFER_INCREF_SLOW(thr,h) do {} while (0) /* nop */ +#define DUK_HBUFFER_DECREF_SLOW(thr,h) do {} while (0) /* nop */ +#define DUK_HBUFFER_DECREF_NORZ_SLOW(thr,h) do {} while (0) /* nop */ #define DUK_HBUFFER_INCREF(thr,h) do {} while (0) /* nop */ #define DUK_HBUFFER_DECREF(thr,h) do {} while (0) /* nop */ -#define DUK_HCOMPILEDFUNCTION_INCREF(thr,h) do {} while (0) /* nop */ -#define DUK_HCOMPILEDFUNCTION_DECREF(thr,h) do {} while (0) /* nop */ -#define DUK_HNATIVEFUNCTION_INCREF(thr,h) do {} while (0) /* nop */ -#define DUK_HNATIVEFUNCTION_DECREF(thr,h) do {} while (0) /* nop */ -#define DUK_HBUFFEROBJECT_INCREF(thr,h) do {} while (0) /* nop */ -#define DUK_HBUFFEROBJECT_DECREF(thr,h) do {} while (0) /* nop */ +#define DUK_HBUFFER_DECREF_NORZ(thr,h) do {} while (0) /* nop */ + +#define DUK_HCOMPFUNC_INCREF(thr,h) do {} while (0) /* nop */ +#define DUK_HCOMPFUNC_DECREF(thr,h) do {} while (0) /* nop */ +#define DUK_HCOMPFUNC_DECREF_NORZ(thr,h) do {} while (0) /* nop */ +#define DUK_HNATFUNC_INCREF(thr,h) do {} while (0) /* nop */ +#define DUK_HNATFUNC_DECREF(thr,h) do {} while (0) /* nop */ +#define DUK_HNATFUNC_DECREF_NORZ(thr,h) do {} while (0) /* nop */ +#define DUK_HBUFOBJ_INCREF(thr,h) do {} while (0) /* nop */ +#define DUK_HBUFOBJ_DECREF(thr,h) do {} while (0) /* nop */ +#define DUK_HBUFOBJ_DECREF_NORZ(thr,h) do {} while (0) /* nop */ #define DUK_HTHREAD_INCREF(thr,h) do {} while (0) /* nop */ #define DUK_HTHREAD_DECREF(thr,h) do {} while (0) /* nop */ +#define DUK_HTHREAD_DECREF_NORZ(thr,h) do {} while (0) /* nop */ #define DUK_HOBJECT_INCREF_ALLOWNULL(thr,h) do {} while (0) /* nop */ #define DUK_HOBJECT_DECREF_ALLOWNULL(thr,h) do {} while (0) /* nop */ +#define DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr,h) do {} while (0) /* nop */ +#define DUK_HBUFFER_INCREF_ALLOWNULL(thr,h) do {} while (0) /* nop */ +#define DUK_HBUFFER_DECREF_ALLOWNULL(thr,h) do {} while (0) /* nop */ +#define DUK_HBUFFER_DECREF_NORZ_ALLOWNULL(thr,h) do {} while (0) /* nop */ + +#define DUK_REFZERO_CHECK_FAST(thr) do {} while (0) /* nop */ +#define DUK_REFZERO_CHECK_SLOW(thr) do {} while (0) /* nop */ #define DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0(thr,tvptr_dst) do { \ duk_tval *tv__dst; tv__dst = (tvptr_dst); \ @@ -4115,7 +4590,7 @@ struct duk_heaphdr_string { } while (0) #define DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ duk_tval *tv__dst; tv__dst = (tvptr_dst); \ - DUK_TVAL_SET_NUMBER_CHKFAST(tv__dst, (newval)); \ + DUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv__dst, (newval)); \ DUK_UNREF((thr)); \ } while (0) #define DUK_TVAL_SET_DOUBLE_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ @@ -4129,19 +4604,19 @@ struct duk_heaphdr_string { DUK_UNREF((thr)); \ } while (0) #if defined(DUK_USE_FASTINT) -#define DUK_TVAL_SET_FASTINT_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ +#define DUK_TVAL_SET_I48_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ duk_tval *tv__dst; tv__dst = (tvptr_dst); \ - DUK_TVAL_SET_FASTINT(tv__dst, (newval)); \ + DUK_TVAL_SET_I48(tv__dst, (newval)); \ DUK_UNREF((thr)); \ } while (0) -#define DUK_TVAL_SET_FASTINT_I32_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ +#define DUK_TVAL_SET_I32_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ duk_tval *tv__dst; tv__dst = (tvptr_dst); \ - DUK_TVAL_SET_FASTINT_I32(tv__dst, (newval)); \ + DUK_TVAL_SET_I32(tv__dst, (newval)); \ DUK_UNREF((thr)); \ } while (0) -#define DUK_TVAL_SET_FASTINT_U32_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ +#define DUK_TVAL_SET_U32_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ duk_tval *tv__dst; tv__dst = (tvptr_dst); \ - DUK_TVAL_SET_FASTINT_U32(tv__dst, (newval)); \ + DUK_TVAL_SET_U32(tv__dst, (newval)); \ DUK_UNREF((thr)); \ } while (0) #else @@ -4187,6 +4662,7 @@ struct duk_heaphdr_string { } while (0) #define DUK_TVAL_SET_UNDEFINED_UPDREF DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0 +#define DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0 #define DUK_TVAL_SET_UNUSED_UPDREF DUK_TVAL_SET_UNUSED_UPDREF_ALT0 #define DUK_TVAL_SET_NULL_UPDREF DUK_TVAL_SET_NULL_UPDREF_ALT0 #define DUK_TVAL_SET_BOOLEAN_UPDREF DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0 @@ -4195,14 +4671,15 @@ struct duk_heaphdr_string { #define DUK_TVAL_SET_DOUBLE_UPDREF DUK_TVAL_SET_DOUBLE_UPDREF_ALT0 #define DUK_TVAL_SET_NAN_UPDREF DUK_TVAL_SET_NAN_UPDREF_ALT0 #if defined(DUK_USE_FASTINT) -#define DUK_TVAL_SET_FASTINT_UPDREF DUK_TVAL_SET_FASTINT_UPDREF_ALT0 -#define DUK_TVAL_SET_FASTINT_I32_UPDREF DUK_TVAL_SET_FASTINT_I32_UPDREF_ALT0 -#define DUK_TVAL_SET_FASTINT_U32_UPDREF DUK_TVAL_SET_FASTINT_U32_UPDREF_ALT0 +#define DUK_TVAL_SET_I48_UPDREF DUK_TVAL_SET_I48_UPDREF_ALT0 +#define DUK_TVAL_SET_I32_UPDREF DUK_TVAL_SET_I32_UPDREF_ALT0 +#define DUK_TVAL_SET_U32_UPDREF DUK_TVAL_SET_U32_UPDREF_ALT0 #else -#define DUK_TVAL_SET_FASTINT_UPDREF DUK_TVAL_SET_DOUBLE_CAST_UPDREF /* XXX: fast-int-to-double */ -#define DUK_TVAL_SET_FASTINT_I32_UPDREF DUK_TVAL_SET_DOUBLE_CAST_UPDREF -#define DUK_TVAL_SET_FASTINT_U32_UPDREF DUK_TVAL_SET_DOUBLE_CAST_UPDREF +#define DUK_TVAL_SET_I48_UPDREF DUK_TVAL_SET_DOUBLE_CAST_UPDREF /* XXX: fast-int-to-double */ +#define DUK_TVAL_SET_I32_UPDREF DUK_TVAL_SET_DOUBLE_CAST_UPDREF +#define DUK_TVAL_SET_U32_UPDREF DUK_TVAL_SET_DOUBLE_CAST_UPDREF #endif /* DUK_USE_FASTINT */ +#define DUK_TVAL_SET_FASTINT_UPDREF DUK_TVAL_SET_I48_UPDREF /* convenience */ #define DUK_TVAL_SET_LIGHTFUNC_UPDREF DUK_TVAL_SET_LIGHTFUNC_UPDREF_ALT0 #define DUK_TVAL_SET_STRING_UPDREF DUK_TVAL_SET_STRING_UPDREF_ALT0 #define DUK_TVAL_SET_OBJECT_UPDREF DUK_TVAL_SET_OBJECT_UPDREF_ALT0 @@ -4216,13 +4693,13 @@ struct duk_heaphdr_string { #endif /* DUK_USE_REFERENCE_COUNTING */ #endif /* DUK_HEAPHDR_H_INCLUDED */ -#line 1 "duk_api_internal.h" +/* #include duk_api_internal.h */ /* * Internal API calls which have (stack and other) semantics similar * to the public API. */ -#ifndef DUK_API_INTERNAL_H_INCLUDED +#if !defined(DUK_API_INTERNAL_H_INCLUDED) #define DUK_API_INTERNAL_H_INCLUDED /* duk_push_sprintf constants */ @@ -4247,12 +4724,27 @@ duk_bool_t duk_valstack_resize_raw(duk_context *ctx, duk_size_t min_new_size, duk_small_uint_t flags); +DUK_INTERNAL_DECL void duk_dup_0(duk_context *ctx); +DUK_INTERNAL_DECL void duk_dup_1(duk_context *ctx); +DUK_INTERNAL_DECL void duk_dup_2(duk_context *ctx); +/* duk_dup_m1() would be same as duk_dup_top() */ +DUK_INTERNAL_DECL void duk_dup_m2(duk_context *ctx); +DUK_INTERNAL_DECL void duk_dup_m3(duk_context *ctx); +DUK_INTERNAL_DECL void duk_dup_m4(duk_context *ctx); + +DUK_INTERNAL_DECL void duk_remove_m2(duk_context *ctx); + +DUK_INTERNAL_DECL duk_int_t duk_get_type_tval(duk_tval *tv); +DUK_INTERNAL_DECL duk_uint_t duk_get_type_mask_tval(duk_tval *tv); + #if defined(DUK_USE_VERBOSE_ERRORS) && defined(DUK_USE_PARANOID_ERRORS) -DUK_INTERNAL_DECL const char *duk_get_type_name(duk_context *ctx, duk_idx_t index); +DUK_INTERNAL_DECL const char *duk_get_type_name(duk_context *ctx, duk_idx_t idx); #endif +DUK_INTERNAL_DECL duk_small_uint_t duk_get_class_number(duk_context *ctx, duk_idx_t idx); -DUK_INTERNAL_DECL duk_tval *duk_get_tval(duk_context *ctx, duk_idx_t index); -DUK_INTERNAL_DECL duk_tval *duk_require_tval(duk_context *ctx, duk_idx_t index); +DUK_INTERNAL_DECL duk_tval *duk_get_tval(duk_context *ctx, duk_idx_t idx); +DUK_INTERNAL_DECL duk_tval *duk_get_tval_or_unused(duk_context *ctx, duk_idx_t idx); +DUK_INTERNAL_DECL duk_tval *duk_require_tval(duk_context *ctx, duk_idx_t idx); DUK_INTERNAL_DECL void duk_push_tval(duk_context *ctx, duk_tval *tv); /* Push the current 'this' binding; throw TypeError if binding is not object @@ -4266,6 +4758,8 @@ DUK_INTERNAL_DECL duk_hobject *duk_push_this_coercible_to_object(duk_context *ct /* duk_push_this() + CheckObjectCoercible() + duk_to_string() */ DUK_INTERNAL_DECL duk_hstring *duk_push_this_coercible_to_string(duk_context *ctx); +DUK_INTERNAL_DECL duk_hstring *duk_push_uint_to_hstring(duk_context *ctx, duk_uint_t i); + /* Get a borrowed duk_tval pointer to the current 'this' binding. Caller must * make sure there's an active callstack entry. Note that the returned pointer * is unstable with regards to side effects. @@ -4292,105 +4786,200 @@ DUK_INTERNAL_DECL duk_tval *duk_get_borrowed_this_tval(duk_context *ctx); #define duk_push_size_t(ctx,val) \ duk_push_uint((ctx), (duk_uint_t) (val)) /* XXX: assumed to fit for now */ -DUK_INTERNAL_DECL duk_hstring *duk_get_hstring(duk_context *ctx, duk_idx_t index); -DUK_INTERNAL_DECL duk_hobject *duk_get_hobject(duk_context *ctx, duk_idx_t index); -DUK_INTERNAL_DECL duk_hbuffer *duk_get_hbuffer(duk_context *ctx, duk_idx_t index); -DUK_INTERNAL_DECL duk_hthread *duk_get_hthread(duk_context *ctx, duk_idx_t index); -DUK_INTERNAL_DECL duk_hcompiledfunction *duk_get_hcompiledfunction(duk_context *ctx, duk_idx_t index); -DUK_INTERNAL_DECL duk_hnativefunction *duk_get_hnativefunction(duk_context *ctx, duk_idx_t index); +DUK_INTERNAL_DECL duk_bool_t duk_is_string_notsymbol(duk_context *ctx, duk_idx_t idx); -DUK_INTERNAL_DECL duk_hobject *duk_get_hobject_with_class(duk_context *ctx, duk_idx_t index, duk_small_uint_t classnum); +DUK_INTERNAL_DECL duk_hstring *duk_get_hstring(duk_context *ctx, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hstring *duk_get_hstring_notsymbol(duk_context *ctx, duk_idx_t idx); +DUK_INTERNAL_DECL const char *duk_get_string_notsymbol(duk_context *ctx, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hobject *duk_get_hobject(duk_context *ctx, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hbuffer *duk_get_hbuffer(duk_context *ctx, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hthread *duk_get_hthread(duk_context *ctx, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hcompfunc *duk_get_hcompfunc(duk_context *ctx, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hnatfunc *duk_get_hnatfunc(duk_context *ctx, duk_idx_t idx); -#if 0 /* This would be pointless: unexpected type and lightfunc would both return NULL */ -DUK_INTERNAL_DECL duk_hobject *duk_get_hobject_or_lfunc(duk_context *ctx, duk_idx_t index); -#endif -DUK_INTERNAL_DECL duk_hobject *duk_get_hobject_or_lfunc_coerce(duk_context *ctx, duk_idx_t index); +DUK_INTERNAL_DECL void *duk_get_buffer_data_raw(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, duk_bool_t throw_flag, duk_bool_t *out_found); + +DUK_INTERNAL_DECL duk_hobject *duk_get_hobject_with_class(duk_context *ctx, duk_idx_t idx, duk_small_uint_t classnum); + +DUK_INTERNAL_DECL duk_hobject *duk_get_hobject_promote_mask(duk_context *ctx, duk_idx_t idx, duk_uint_t type_mask); +DUK_INTERNAL_DECL duk_hobject *duk_require_hobject_promote_mask(duk_context *ctx, duk_idx_t idx, duk_uint_t type_mask); +DUK_INTERNAL_DECL duk_hobject *duk_require_hobject_accept_mask(duk_context *ctx, duk_idx_t idx, duk_uint_t type_mask); +#define duk_require_hobject_promote_lfunc(ctx,idx) \ + duk_require_hobject_promote_mask((ctx), (idx), DUK_TYPE_MASK_LIGHTFUNC) +#define duk_get_hobject_promote_lfunc(ctx,idx) \ + duk_get_hobject_promote_mask((ctx), (idx), DUK_TYPE_MASK_LIGHTFUNC) #if 0 /*unused*/ -DUK_INTERNAL_DECL void *duk_get_voidptr(duk_context *ctx, duk_idx_t index); +DUK_INTERNAL_DECL void *duk_get_voidptr(duk_context *ctx, duk_idx_t idx); #endif -DUK_INTERNAL_DECL duk_hstring *duk_to_hstring(duk_context *ctx, duk_idx_t index); +DUK_INTERNAL_DECL duk_hstring *duk_known_hstring(duk_context *ctx, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hobject *duk_known_hobject(duk_context *ctx, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hbuffer *duk_known_hbuffer(duk_context *ctx, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hcompfunc *duk_known_hcompfunc(duk_context *ctx, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hnatfunc *duk_known_hnatfunc(duk_context *ctx, duk_idx_t idx); + +DUK_INTERNAL_DECL duk_double_t duk_to_number_tval(duk_context *ctx, duk_tval *tv); + +DUK_INTERNAL_DECL duk_hstring *duk_to_hstring(duk_context *ctx, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hstring *duk_to_hstring_m1(duk_context *ctx); +DUK_INTERNAL_DECL duk_hstring *duk_to_hstring_acceptsymbol(duk_context *ctx, duk_idx_t idx); + +DUK_INTERNAL_DECL duk_hobject *duk_to_hobject(duk_context *ctx, duk_idx_t idx); + +DUK_INTERNAL_DECL duk_double_t duk_to_number_m1(duk_context *ctx); +DUK_INTERNAL_DECL duk_double_t duk_to_number_m2(duk_context *ctx); + #if defined(DUK_USE_DEBUGGER_SUPPORT) /* only needed by debugger for now */ -DUK_INTERNAL_DECL duk_hstring *duk_safe_to_hstring(duk_context *ctx, duk_idx_t index); -#endif -DUK_INTERNAL_DECL void duk_to_object_class_string_top(duk_context *ctx); -#if !defined(DUK_USE_PARANOID_ERRORS) -DUK_INTERNAL_DECL void duk_push_hobject_class_string(duk_context *ctx, duk_hobject *h); +DUK_INTERNAL_DECL duk_hstring *duk_safe_to_hstring(duk_context *ctx, duk_idx_t idx); #endif +DUK_INTERNAL_DECL void duk_push_class_string_tval(duk_context *ctx, duk_tval *tv); -DUK_INTERNAL_DECL duk_int_t duk_to_int_clamped_raw(duk_context *ctx, duk_idx_t index, duk_int_t minval, duk_int_t maxval, duk_bool_t *out_clamped); /* out_clamped=NULL, RangeError if outside range */ -DUK_INTERNAL_DECL duk_int_t duk_to_int_clamped(duk_context *ctx, duk_idx_t index, duk_int_t minval, duk_int_t maxval); -DUK_INTERNAL_DECL duk_int_t duk_to_int_check_range(duk_context *ctx, duk_idx_t index, duk_int_t minval, duk_int_t maxval); +DUK_INTERNAL_DECL duk_int_t duk_to_int_clamped_raw(duk_context *ctx, duk_idx_t idx, duk_int_t minval, duk_int_t maxval, duk_bool_t *out_clamped); /* out_clamped=NULL, RangeError if outside range */ +DUK_INTERNAL_DECL duk_int_t duk_to_int_clamped(duk_context *ctx, duk_idx_t idx, duk_int_t minval, duk_int_t maxval); +DUK_INTERNAL_DECL duk_int_t duk_to_int_check_range(duk_context *ctx, duk_idx_t idx, duk_int_t minval, duk_int_t maxval); #if defined(DUK_USE_BUFFEROBJECT_SUPPORT) -DUK_INTERNAL_DECL duk_uint8_t duk_to_uint8clamped(duk_context *ctx, duk_idx_t index); +DUK_INTERNAL_DECL duk_uint8_t duk_to_uint8clamped(duk_context *ctx, duk_idx_t idx); #endif +DUK_INTERNAL_DECL duk_hstring *duk_to_property_key_hstring(duk_context *ctx, duk_idx_t idx); -DUK_INTERNAL_DECL duk_hstring *duk_require_hstring(duk_context *ctx, duk_idx_t index); -DUK_INTERNAL_DECL duk_hobject *duk_require_hobject(duk_context *ctx, duk_idx_t index); -DUK_INTERNAL_DECL duk_hbuffer *duk_require_hbuffer(duk_context *ctx, duk_idx_t index); -DUK_INTERNAL_DECL duk_hthread *duk_require_hthread(duk_context *ctx, duk_idx_t index); -DUK_INTERNAL_DECL duk_hcompiledfunction *duk_require_hcompiledfunction(duk_context *ctx, duk_idx_t index); -DUK_INTERNAL_DECL duk_hnativefunction *duk_require_hnativefunction(duk_context *ctx, duk_idx_t index); - -DUK_INTERNAL_DECL duk_hobject *duk_require_hobject_with_class(duk_context *ctx, duk_idx_t index, duk_small_uint_t classnum); +DUK_INTERNAL_DECL duk_hstring *duk_require_hstring(duk_context *ctx, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hstring *duk_require_hstring_notsymbol(duk_context *ctx, duk_idx_t idx); +DUK_INTERNAL_DECL const char *duk_require_lstring_notsymbol(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len); +DUK_INTERNAL_DECL const char *duk_require_string_notsymbol(duk_context *ctx, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hobject *duk_require_hobject(duk_context *ctx, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hbuffer *duk_require_hbuffer(duk_context *ctx, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hthread *duk_require_hthread(duk_context *ctx, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hcompfunc *duk_require_hcompfunc(duk_context *ctx, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hnatfunc *duk_require_hnatfunc(duk_context *ctx, duk_idx_t idx); -DUK_INTERNAL_DECL duk_hobject *duk_require_hobject_or_lfunc(duk_context *ctx, duk_idx_t index); -DUK_INTERNAL_DECL duk_hobject *duk_require_hobject_or_lfunc_coerce(duk_context *ctx, duk_idx_t index); +DUK_INTERNAL_DECL duk_hobject *duk_require_hobject_with_class(duk_context *ctx, duk_idx_t idx, duk_small_uint_t classnum); DUK_INTERNAL_DECL void duk_push_hstring(duk_context *ctx, duk_hstring *h); -DUK_INTERNAL_DECL void duk_push_hstring_stridx(duk_context *ctx, duk_small_int_t stridx); +DUK_INTERNAL_DECL void duk_push_hstring_stridx(duk_context *ctx, duk_small_uint_t stridx); +DUK_INTERNAL_DECL void duk_push_hstring_empty(duk_context *ctx); DUK_INTERNAL_DECL void duk_push_hobject(duk_context *ctx, duk_hobject *h); DUK_INTERNAL_DECL void duk_push_hbuffer(duk_context *ctx, duk_hbuffer *h); #define duk_push_hthread(ctx,h) \ duk_push_hobject((ctx), (duk_hobject *) (h)) -#define duk_push_hcompiledfunction(ctx,h) \ - duk_push_hobject((ctx), (duk_hobject *) (h)) -#define duk_push_hnativefunction(ctx,h) \ +#define duk_push_hnatfunc(ctx,h) \ duk_push_hobject((ctx), (duk_hobject *) (h)) DUK_INTERNAL_DECL void duk_push_hobject_bidx(duk_context *ctx, duk_small_int_t builtin_idx); -DUK_INTERNAL_DECL duk_idx_t duk_push_object_helper(duk_context *ctx, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx); -DUK_INTERNAL_DECL duk_idx_t duk_push_object_helper_proto(duk_context *ctx, duk_uint_t hobject_flags_and_class, duk_hobject *proto); -DUK_INTERNAL_DECL duk_idx_t duk_push_object_internal(duk_context *ctx); -DUK_INTERNAL_DECL duk_idx_t duk_push_compiledfunction(duk_context *ctx); +DUK_INTERNAL_DECL duk_hobject *duk_push_object_helper(duk_context *ctx, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx); +DUK_INTERNAL_DECL duk_hobject *duk_push_object_helper_proto(duk_context *ctx, duk_uint_t hobject_flags_and_class, duk_hobject *proto); +DUK_INTERNAL_DECL duk_hcompfunc *duk_push_hcompfunc(duk_context *ctx); DUK_INTERNAL_DECL void duk_push_c_function_noexotic(duk_context *ctx, duk_c_function func, duk_int_t nargs); DUK_INTERNAL_DECL void duk_push_c_function_noconstruct_noexotic(duk_context *ctx, duk_c_function func, duk_int_t nargs); +/* XXX: duk_push_harray() and duk_push_hcompfunc() are inconsistent with + * duk_push_hobject() etc which don't create a new value. + */ +DUK_INTERNAL_DECL duk_harray *duk_push_harray(duk_context *ctx); +DUK_INTERNAL_DECL duk_harray *duk_push_harray_with_size(duk_context *ctx, duk_uint32_t size); + DUK_INTERNAL_DECL void duk_push_string_funcptr(duk_context *ctx, duk_uint8_t *ptr, duk_size_t sz); +DUK_INTERNAL_DECL void duk_push_lightfunc_name_raw(duk_context *ctx, duk_c_function func, duk_small_uint_t lf_flags); DUK_INTERNAL_DECL void duk_push_lightfunc_name(duk_context *ctx, duk_tval *tv); DUK_INTERNAL_DECL void duk_push_lightfunc_tostring(duk_context *ctx, duk_tval *tv); -DUK_INTERNAL_DECL duk_hbufferobject *duk_push_bufferobject_raw(duk_context *ctx, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx); +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_INTERNAL_DECL duk_hbufobj *duk_push_bufobj_raw(duk_context *ctx, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx); +#endif -#if !defined(DUK_USE_PARANOID_ERRORS) -DUK_INTERNAL_DECL const char *duk_push_string_readable(duk_context *ctx, duk_idx_t index); +DUK_INTERNAL_DECL void *duk_push_fixed_buffer_nozero(duk_context *ctx, duk_size_t len); +DUK_INTERNAL_DECL void *duk_push_fixed_buffer_zero(duk_context *ctx, duk_size_t len); + +DUK_INTERNAL_DECL const char *duk_push_string_readable(duk_context *ctx, duk_idx_t idx); DUK_INTERNAL_DECL const char *duk_push_string_tval_readable(duk_context *ctx, duk_tval *tv); +DUK_INTERNAL_DECL const char *duk_push_string_tval_readable_error(duk_context *ctx, duk_tval *tv); + +/* The duk_xxx_prop_stridx_short() variants expect their arguments to be short + * enough to be packed into a single 32-bit integer argument. Argument limits + * vary per call; typically 16 bits are assigned to the signed value stack index + * and the stridx. In practice these work well for footprint with constant + * arguments and such call sites are also easiest to verify to be correct. + */ + +DUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx); /* [] -> [val] */ +DUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx_short_raw(duk_context *ctx, duk_uint_t packed_args); +#define duk_get_prop_stridx_short(ctx,obj_idx,stridx) \ + (DUK_ASSERT_EXPR((duk_int_t) (obj_idx) >= -0x8000L && (duk_int_t) (obj_idx) <= 0x7fffL), \ + DUK_ASSERT_EXPR((duk_int_t) (stridx) >= 0 && (duk_int_t) (stridx) <= 0xffffL), \ + duk_get_prop_stridx_short_raw((ctx), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx)))) +DUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx_boolean(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_bool_t *out_has_prop); /* [] -> [] */ + +DUK_INTERNAL_DECL duk_bool_t duk_put_prop_stridx(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx); /* [val] -> [] */ +DUK_INTERNAL_DECL duk_bool_t duk_put_prop_stridx_short_raw(duk_context *ctx, duk_uint_t packed_args); +#define duk_put_prop_stridx_short(ctx,obj_idx,stridx) \ + (DUK_ASSERT_EXPR((duk_int_t) (obj_idx) >= -0x8000L && (duk_int_t) (obj_idx) <= 0x7fffL), \ + DUK_ASSERT_EXPR((duk_int_t) (stridx) >= 0 && (duk_int_t) (stridx) <= 0xffffL), \ + duk_put_prop_stridx_short_raw((ctx), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx)))) + +DUK_INTERNAL_DECL duk_bool_t duk_del_prop_stridx(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx); /* [] -> [] */ +#if 0 /* Too few call sites to be useful. */ +DUK_INTERNAL_DECL duk_bool_t duk_del_prop_stridx_short_raw(duk_context *ctx, duk_uint_t packed_args); +#define duk_del_prop_stridx_short(ctx,obj_idx,stridx) \ + (DUK_ASSERT_EXPR((obj_idx) >= -0x8000L && (obj_idx) <= 0x7fffL), \ + DUK_ASSERT_EXPR((stridx) >= 0 && (stridx) <= 0xffffL), \ + duk_del_prop_stridx_short_raw((ctx), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx)))) +#endif +#define duk_del_prop_stridx_short(ctx,obj_idx,stridx) \ + duk_del_prop_stridx((ctx), (obj_idx), (stridx)) + +DUK_INTERNAL_DECL duk_bool_t duk_has_prop_stridx(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx); /* [] -> [] */ +#if 0 /* Too few call sites to be useful. */ +DUK_INTERNAL_DECL duk_bool_t duk_has_prop_stridx_short_raw(duk_context *ctx, duk_uint_t packed_args); +#define duk_has_prop_stridx_short(ctx,obj_idx,stridx) \ + (DUK_ASSERT_EXPR((obj_idx) >= -0x8000L && (obj_idx) <= 0x7fffL), \ + DUK_ASSERT_EXPR((stridx) >= 0 && (stridx) <= 0xffffL), \ + duk_has_prop_stridx_short_raw((ctx), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx)))) +#endif +#define duk_has_prop_stridx_short(ctx,obj_idx,stridx) \ + duk_has_prop_stridx((ctx), (obj_idx), (stridx)) + +DUK_INTERNAL_DECL void duk_xdef_prop(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t desc_flags); /* [key val] -> [] */ + +DUK_INTERNAL_DECL void duk_xdef_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx, duk_small_uint_t desc_flags); /* [val] -> [] */ + +/* XXX: Because stridx and desc_flags have a limited range, this call could + * always pack stridx and desc_flags into a single argument. + */ +DUK_INTERNAL_DECL void duk_xdef_prop_stridx(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_uint_t desc_flags); /* [val] -> [] */ +DUK_INTERNAL_DECL void duk_xdef_prop_stridx_short_raw(duk_context *ctx, duk_uint_t packed_args); +#define duk_xdef_prop_stridx_short(ctx,obj_idx,stridx,desc_flags) \ + (DUK_ASSERT_EXPR((duk_int_t) (obj_idx) >= -0x80L && (duk_int_t) (obj_idx) <= 0x7fL), \ + DUK_ASSERT_EXPR((duk_int_t) (stridx) >= 0 && (duk_int_t) (stridx) <= 0xffffL), \ + DUK_ASSERT_EXPR((duk_int_t) (desc_flags) >= 0 && (duk_int_t) (desc_flags) <= 0xffL), \ + duk_xdef_prop_stridx_short_raw((ctx), (((duk_uint_t) (obj_idx)) << 24) + (((duk_uint_t) (stridx)) << 8) + (duk_uint_t) (desc_flags))) + +#define duk_xdef_prop_wec(ctx,obj_idx) \ + duk_xdef_prop((ctx), (obj_idx), DUK_PROPDESC_FLAGS_WEC) +#define duk_xdef_prop_index_wec(ctx,obj_idx,arr_idx) \ + duk_xdef_prop_index((ctx), (obj_idx), (arr_idx), DUK_PROPDESC_FLAGS_WEC) +#define duk_xdef_prop_stridx_wec(ctx,obj_idx,stridx) \ + duk_xdef_prop_stridx((ctx), (obj_idx), (stridx), DUK_PROPDESC_FLAGS_WEC) +#define duk_xdef_prop_stridx_short_wec(ctx,obj_idx,stridx) \ + duk_xdef_prop_stridx_short((ctx), (obj_idx), (stridx), DUK_PROPDESC_FLAGS_WEC) + +DUK_INTERNAL_DECL void duk_xdef_prop_stridx_builtin(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_int_t builtin_idx, duk_small_uint_t desc_flags); /* [] -> [] */ + +DUK_INTERNAL_DECL void duk_xdef_prop_stridx_thrower(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx); /* [] -> [] */ + +DUK_INTERNAL_DECL void duk_pack(duk_context *ctx, duk_idx_t count); +#if 0 +DUK_INTERNAL_DECL void duk_unpack(duk_context *ctx); #endif -DUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx(duk_context *ctx, duk_idx_t obj_index, duk_small_int_t stridx); /* [] -> [val] */ -DUK_INTERNAL_DECL duk_bool_t duk_put_prop_stridx(duk_context *ctx, duk_idx_t obj_index, duk_small_int_t stridx); /* [val] -> [] */ -DUK_INTERNAL_DECL duk_bool_t duk_del_prop_stridx(duk_context *ctx, duk_idx_t obj_index, duk_small_int_t stridx); /* [] -> [] */ -DUK_INTERNAL_DECL duk_bool_t duk_has_prop_stridx(duk_context *ctx, duk_idx_t obj_index, duk_small_int_t stridx); /* [] -> [] */ +DUK_INTERNAL_DECL void duk_require_constructor_call(duk_context *ctx); +DUK_INTERNAL_DECL void duk_require_constructable(duk_context *ctx, duk_idx_t idx); +DUK_INTERNAL_DECL void duk_push_symbol_descriptive_string(duk_context *ctx, duk_hstring *h); -DUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx_boolean(duk_context *ctx, duk_idx_t obj_index, duk_small_int_t stridx, duk_bool_t *out_has_prop); /* [] -> [] */ +DUK_INTERNAL_DECL void duk_resolve_nonbound_function(duk_context *ctx); -DUK_INTERNAL_DECL void duk_xdef_prop(duk_context *ctx, duk_idx_t obj_index, duk_small_uint_t desc_flags); /* [key val] -> [] */ -DUK_INTERNAL_DECL void duk_xdef_prop_index(duk_context *ctx, duk_idx_t obj_index, duk_uarridx_t arr_index, duk_small_uint_t desc_flags); /* [val] -> [] */ -DUK_INTERNAL_DECL void duk_xdef_prop_stridx(duk_context *ctx, duk_idx_t obj_index, duk_small_int_t stridx, duk_small_uint_t desc_flags); /* [val] -> [] */ -DUK_INTERNAL_DECL void duk_xdef_prop_stridx_builtin(duk_context *ctx, duk_idx_t obj_index, duk_small_int_t stridx, duk_small_int_t builtin_idx, duk_small_uint_t desc_flags); /* [] -> [] */ -DUK_INTERNAL_DECL void duk_xdef_prop_stridx_thrower(duk_context *ctx, duk_idx_t obj_index, duk_small_int_t stridx, duk_small_uint_t desc_flags); /* [] -> [] */ - -/* These are macros for now, but could be separate functions to reduce code - * footprint (check call site count before refactoring). - */ -#define duk_xdef_prop_wec(ctx,obj_index) \ - duk_xdef_prop((ctx), (obj_index), DUK_PROPDESC_FLAGS_WEC) -#define duk_xdef_prop_index_wec(ctx,obj_index,arr_index) \ - duk_xdef_prop_index((ctx), (obj_index), (arr_index), DUK_PROPDESC_FLAGS_WEC) -#define duk_xdef_prop_stridx_wec(ctx,obj_index,stridx) \ - duk_xdef_prop_stridx((ctx), (obj_index), (stridx), DUK_PROPDESC_FLAGS_WEC) +DUK_INTERNAL_DECL duk_idx_t duk_get_top_require_min(duk_context *ctx, duk_idx_t min_top); +DUK_INTERNAL_DECL duk_idx_t duk_get_top_index_unsafe(duk_context *ctx); +DUK_INTERNAL_DECL void duk_pop_unsafe(duk_context *ctx); -/* Set object 'length'. */ -DUK_INTERNAL_DECL void duk_set_length(duk_context *ctx, duk_idx_t index, duk_size_t length); +DUK_INTERNAL_DECL void duk_compact_m1(duk_context *ctx); /* Raw internal valstack access macros: access is unsafe so call site * must have a guarantee that the index is valid. When that is the case, @@ -4398,9 +4987,9 @@ DUK_INTERNAL_DECL void duk_set_length(duk_context *ctx, duk_idx_t index, duk_siz * Both 'ctx' and 'idx' are evaluted multiple times, but only for asserts. */ #define DUK_ASSERT_VALID_NEGIDX(ctx,idx) \ - (DUK_ASSERT_EXPR((idx) < 0), DUK_ASSERT_EXPR(duk_is_valid_index((ctx), (idx)))) + (DUK_ASSERT_EXPR((duk_int_t) (idx) < 0), DUK_ASSERT_EXPR(duk_is_valid_index((ctx), (idx)))) #define DUK_ASSERT_VALID_POSIDX(ctx,idx) \ - (DUK_ASSERT_EXPR((idx) >= 0), DUK_ASSERT_EXPR(duk_is_valid_index((ctx), (idx)))) + (DUK_ASSERT_EXPR((duk_int_t) (idx) >= 0), DUK_ASSERT_EXPR(duk_is_valid_index((ctx), (idx)))) #define DUK_GET_TVAL_NEGIDX(ctx,idx) \ (DUK_ASSERT_VALID_NEGIDX((ctx),(idx)), ((duk_hthread *) (ctx))->valstack_top + (idx)) #define DUK_GET_TVAL_POSIDX(ctx,idx) \ @@ -4410,8 +4999,12 @@ DUK_INTERNAL_DECL void duk_set_length(duk_context *ctx, duk_idx_t index, duk_siz #define DUK_GET_HOBJECT_POSIDX(ctx,idx) \ (DUK_ASSERT_VALID_POSIDX((ctx),(idx)), DUK_TVAL_GET_OBJECT(((duk_hthread *) (ctx))->valstack_bottom + (idx))) +#define DUK_GET_THIS_TVAL_PTR(thr) \ + (DUK_ASSERT_EXPR((thr)->valstack_bottom > (thr)->valstack), \ + (thr)->valstack_bottom - 1) + #endif /* DUK_API_INTERNAL_H_INCLUDED */ -#line 1 "duk_hstring.h" +/* #include duk_hstring.h */ /* * Heap string representation. * @@ -4428,7 +5021,7 @@ DUK_INTERNAL_DECL void duk_set_length(duk_context *ctx, duk_idx_t index, duk_siz * really a practical issue. */ -#ifndef DUK_HSTRING_H_INCLUDED +#if !defined(DUK_HSTRING_H_INCLUDED) #define DUK_HSTRING_H_INCLUDED /* Impose a maximum string length for now. Restricted artificially to @@ -4454,15 +5047,17 @@ DUK_INTERNAL_DECL void duk_set_length(duk_context *ctx, duk_idx_t index, duk_siz #define DUK_HSTRING_FLAG_ASCII DUK_HEAPHDR_USER_FLAG(0) /* string is ASCII, clen == blen */ #define DUK_HSTRING_FLAG_ARRIDX DUK_HEAPHDR_USER_FLAG(1) /* string is a valid array index */ -#define DUK_HSTRING_FLAG_INTERNAL DUK_HEAPHDR_USER_FLAG(2) /* string is internal */ -#define DUK_HSTRING_FLAG_RESERVED_WORD DUK_HEAPHDR_USER_FLAG(3) /* string is a reserved word (non-strict) */ -#define DUK_HSTRING_FLAG_STRICT_RESERVED_WORD DUK_HEAPHDR_USER_FLAG(4) /* string is a reserved word (strict) */ -#define DUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS DUK_HEAPHDR_USER_FLAG(5) /* string is 'eval' or 'arguments' */ -#define DUK_HSTRING_FLAG_EXTDATA DUK_HEAPHDR_USER_FLAG(6) /* string data is external (duk_hstring_external) */ +#define DUK_HSTRING_FLAG_SYMBOL DUK_HEAPHDR_USER_FLAG(2) /* string is a symbol (invalid utf-8) */ +#define DUK_HSTRING_FLAG_HIDDEN DUK_HEAPHDR_USER_FLAG(3) /* string is a hidden symbol (implies symbol, Duktape 1.x internal string) */ +#define DUK_HSTRING_FLAG_RESERVED_WORD DUK_HEAPHDR_USER_FLAG(4) /* string is a reserved word (non-strict) */ +#define DUK_HSTRING_FLAG_STRICT_RESERVED_WORD DUK_HEAPHDR_USER_FLAG(5) /* string is a reserved word (strict) */ +#define DUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS DUK_HEAPHDR_USER_FLAG(6) /* string is 'eval' or 'arguments' */ +#define DUK_HSTRING_FLAG_EXTDATA DUK_HEAPHDR_USER_FLAG(7) /* string data is external (duk_hstring_external) */ #define DUK_HSTRING_HAS_ASCII(x) DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ASCII) #define DUK_HSTRING_HAS_ARRIDX(x) DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ARRIDX) -#define DUK_HSTRING_HAS_INTERNAL(x) DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_INTERNAL) +#define DUK_HSTRING_HAS_SYMBOL(x) DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_SYMBOL) +#define DUK_HSTRING_HAS_HIDDEN(x) DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_HIDDEN) #define DUK_HSTRING_HAS_RESERVED_WORD(x) DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_RESERVED_WORD) #define DUK_HSTRING_HAS_STRICT_RESERVED_WORD(x) DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_STRICT_RESERVED_WORD) #define DUK_HSTRING_HAS_EVAL_OR_ARGUMENTS(x) DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS) @@ -4470,7 +5065,8 @@ DUK_INTERNAL_DECL void duk_set_length(duk_context *ctx, duk_idx_t index, duk_siz #define DUK_HSTRING_SET_ASCII(x) DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ASCII) #define DUK_HSTRING_SET_ARRIDX(x) DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ARRIDX) -#define DUK_HSTRING_SET_INTERNAL(x) DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_INTERNAL) +#define DUK_HSTRING_SET_SYMBOL(x) DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_SYMBOL) +#define DUK_HSTRING_SET_HIDDEN(x) DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_HIDDEN) #define DUK_HSTRING_SET_RESERVED_WORD(x) DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_RESERVED_WORD) #define DUK_HSTRING_SET_STRICT_RESERVED_WORD(x) DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_STRICT_RESERVED_WORD) #define DUK_HSTRING_SET_EVAL_OR_ARGUMENTS(x) DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS) @@ -4478,7 +5074,8 @@ DUK_INTERNAL_DECL void duk_set_length(duk_context *ctx, duk_idx_t index, duk_siz #define DUK_HSTRING_CLEAR_ASCII(x) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ASCII) #define DUK_HSTRING_CLEAR_ARRIDX(x) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ARRIDX) -#define DUK_HSTRING_CLEAR_INTERNAL(x) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_INTERNAL) +#define DUK_HSTRING_CLEAR_SYMBOL(x) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_SYMBOL) +#define DUK_HSTRING_CLEAR_HIDDEN(x) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_HIDDEN) #define DUK_HSTRING_CLEAR_RESERVED_WORD(x) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_RESERVED_WORD) #define DUK_HSTRING_CLEAR_STRICT_RESERVED_WORD(x) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_STRICT_RESERVED_WORD) #define DUK_HSTRING_CLEAR_EVAL_OR_ARGUMENTS(x) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS) @@ -4548,15 +5145,20 @@ DUK_INTERNAL_DECL void duk_set_length(duk_context *ctx, duk_idx_t index, duk_siz /* marker value; in E5 2^32-1 is not a valid array index (2^32-2 is highest valid) */ #define DUK_HSTRING_NO_ARRAY_INDEX (0xffffffffUL) -/* get array index related to string (or return DUK_HSTRING_NO_ARRAY_INDEX); +#if defined(DUK_USE_HSTRING_ARRIDX) +#define DUK_HSTRING_GET_ARRIDX_FAST(h) ((h)->arridx) +#define DUK_HSTRING_GET_ARRIDX_SLOW(h) ((h)->arridx) +#else +/* Get array index related to string (or return DUK_HSTRING_NO_ARRAY_INDEX); * avoids helper call if string has no array index value. */ #define DUK_HSTRING_GET_ARRIDX_FAST(h) \ (DUK_HSTRING_HAS_ARRIDX((h)) ? duk_js_to_arrayindex_string_helper((h)) : DUK_HSTRING_NO_ARRAY_INDEX) -/* slower but more compact variant */ +/* Slower but more compact variant. */ #define DUK_HSTRING_GET_ARRIDX_SLOW(h) \ (duk_js_to_arrayindex_string_helper((h))) +#endif /* * Misc @@ -4581,6 +5183,11 @@ struct duk_hstring { duk_uint32_t hash; #endif + /* precomputed array index (or DUK_HSTRING_NO_ARRAY_INDEX) */ +#if defined(DUK_USE_HSTRING_ARRIDX) + duk_uarridx_t arridx; +#endif + /* length in bytes (not counting NUL term) */ #if defined(DUK_USE_STRLEN16) /* placed in duk_heaphdr_string */ @@ -4624,14 +5231,14 @@ struct duk_hstring_external { * Prototypes */ -DUK_INTERNAL_DECL duk_ucodepoint_t duk_hstring_char_code_at_raw(duk_hthread *thr, duk_hstring *h, duk_uint_t pos); +DUK_INTERNAL_DECL duk_ucodepoint_t duk_hstring_char_code_at_raw(duk_hthread *thr, duk_hstring *h, duk_uint_t pos, duk_bool_t surrogate_aware); #if !defined(DUK_USE_HSTRING_CLEN) DUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h); #endif #endif /* DUK_HSTRING_H_INCLUDED */ -#line 1 "duk_hobject.h" +/* #include duk_hobject.h */ /* * Heap object representation. * @@ -4663,23 +5270,27 @@ DUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h); * parts are resized together, and makes property access a bit complicated. */ -#ifndef DUK_HOBJECT_H_INCLUDED +#if !defined(DUK_HOBJECT_H_INCLUDED) #define DUK_HOBJECT_H_INCLUDED -/* Object flag. There are currently 26 flag bits available. Make sure +/* Object flag. There are currently 25 flag bits available. 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_BOUND DUK_HEAPHDR_USER_FLAG(2) /* object established using Function.prototype.bind() */ -#define DUK_HOBJECT_FLAG_COMPILEDFUNCTION DUK_HEAPHDR_USER_FLAG(4) /* object is a compiled function (duk_hcompiledfunction) */ -#define DUK_HOBJECT_FLAG_NATIVEFUNCTION DUK_HEAPHDR_USER_FLAG(5) /* object is a native function (duk_hnativefunction) */ -#define DUK_HOBJECT_FLAG_BUFFEROBJECT DUK_HEAPHDR_USER_FLAG(6) /* object is a buffer object (duk_hbufferobject) (always exotic) */ +#define DUK_HOBJECT_FLAG_BOUNDFUNC DUK_HEAPHDR_USER_FLAG(2) /* 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_THREAD DUK_HEAPHDR_USER_FLAG(7) /* object is a thread (duk_hthread) */ #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_hcompiledfunction) */ +#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_ENVRECCLOSED DUK_HEAPHDR_USER_FLAG(14) /* envrec: (declarative) record is closed */ @@ -4708,26 +5319,27 @@ DUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h); #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_UNUSED 0 -#define DUK_HOBJECT_CLASS_ARGUMENTS 1 +#define DUK_HOBJECT_CLASS_NONE 0 +#define DUK_HOBJECT_CLASS_OBJECT 1 #define DUK_HOBJECT_CLASS_ARRAY 2 -#define DUK_HOBJECT_CLASS_BOOLEAN 3 -#define DUK_HOBJECT_CLASS_DATE 4 -#define DUK_HOBJECT_CLASS_ERROR 5 -#define DUK_HOBJECT_CLASS_FUNCTION 6 -#define DUK_HOBJECT_CLASS_JSON 7 -#define DUK_HOBJECT_CLASS_MATH 8 -#define DUK_HOBJECT_CLASS_NUMBER 9 -#define DUK_HOBJECT_CLASS_OBJECT 10 +#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_OBJENV 14 /* custom */ -#define DUK_HOBJECT_CLASS_DECENV 15 /* custom */ -#define DUK_HOBJECT_CLASS_BUFFER 16 /* custom; implies DUK_HOBJECT_IS_BUFFEROBJECT */ +#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_ARRAYBUFFER 19 /* implies DUK_HOBJECT_IS_BUFFEROBJECT */ +#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 @@ -4738,11 +5350,12 @@ DUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h); #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 */ +/* Class masks. */ #define DUK_HOBJECT_CMASK_ALL ((1UL << (DUK_HOBJECT_CLASS_MAX + 1)) - 1UL) -#define DUK_HOBJECT_CMASK_UNUSED (1UL << DUK_HOBJECT_CLASS_UNUSED) +#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) @@ -4756,9 +5369,9 @@ DUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h); #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) -#define DUK_HOBJECT_CMASK_BUFFER (1UL << DUK_HOBJECT_CLASS_BUFFER) #define DUK_HOBJECT_CMASK_POINTER (1UL << DUK_HOBJECT_CLASS_POINTER) #define DUK_HOBJECT_CMASK_THREAD (1UL << DUK_HOBJECT_CLASS_THREAD) #define DUK_HOBJECT_CMASK_ARRAYBUFFER (1UL << DUK_HOBJECT_CLASS_ARRAYBUFFER) @@ -4773,9 +5386,8 @@ DUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h); #define DUK_HOBJECT_CMASK_FLOAT32ARRAY (1UL << DUK_HOBJECT_CLASS_FLOAT32ARRAY) #define DUK_HOBJECT_CMASK_FLOAT64ARRAY (1UL << DUK_HOBJECT_CLASS_FLOAT64ARRAY) -#define DUK_HOBJECT_CMASK_ALL_BUFFEROBJECTS \ - (DUK_HOBJECT_CMASK_BUFFER | \ - DUK_HOBJECT_CMASK_ARRAYBUFFER | \ +#define DUK_HOBJECT_CMASK_ALL_BUFOBJS \ + (DUK_HOBJECT_CMASK_ARRAYBUFFER | \ DUK_HOBJECT_CMASK_DATAVIEW | \ DUK_HOBJECT_CMASK_INT8ARRAY | \ DUK_HOBJECT_CMASK_UINT8ARRAY | \ @@ -4790,42 +5402,49 @@ DUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h); #define DUK_HOBJECT_IS_OBJENV(h) (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_OBJENV) #define DUK_HOBJECT_IS_DECENV(h) (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_DECENV) #define DUK_HOBJECT_IS_ENV(h) (DUK_HOBJECT_IS_OBJENV((h)) || DUK_HOBJECT_IS_DECENV((h))) -#define DUK_HOBJECT_IS_ARRAY(h) (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_ARRAY) -#define DUK_HOBJECT_IS_COMPILEDFUNCTION(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPILEDFUNCTION) -#define DUK_HOBJECT_IS_NATIVEFUNCTION(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATIVEFUNCTION) -#define DUK_HOBJECT_IS_BUFFEROBJECT(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFFEROBJECT) +#define DUK_HOBJECT_IS_ARRAY(h) DUK_HOBJECT_HAS_EXOTIC_ARRAY((h)) /* Rely on class Array <=> exotic Array */ +#define DUK_HOBJECT_IS_BOUNDFUNC(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUNDFUNC) +#define DUK_HOBJECT_IS_COMPFUNC(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPFUNC) +#define DUK_HOBJECT_IS_NATFUNC(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATFUNC) +#define DUK_HOBJECT_IS_BUFOBJ(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFOBJ) #define DUK_HOBJECT_IS_THREAD(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_THREAD) #define DUK_HOBJECT_IS_NONBOUND_FUNCTION(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, \ - DUK_HOBJECT_FLAG_COMPILEDFUNCTION | \ - DUK_HOBJECT_FLAG_NATIVEFUNCTION) + DUK_HOBJECT_FLAG_COMPFUNC | \ + DUK_HOBJECT_FLAG_NATFUNC) #define DUK_HOBJECT_IS_FUNCTION(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, \ - DUK_HOBJECT_FLAG_BOUND | \ - DUK_HOBJECT_FLAG_COMPILEDFUNCTION | \ - DUK_HOBJECT_FLAG_NATIVEFUNCTION) + DUK_HOBJECT_FLAG_BOUNDFUNC | \ + DUK_HOBJECT_FLAG_COMPFUNC | \ + DUK_HOBJECT_FLAG_NATFUNC) #define DUK_HOBJECT_IS_CALLABLE(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, \ - DUK_HOBJECT_FLAG_BOUND | \ - DUK_HOBJECT_FLAG_COMPILEDFUNCTION | \ - DUK_HOBJECT_FLAG_NATIVEFUNCTION) + DUK_HOBJECT_FLAG_BOUNDFUNC | \ + DUK_HOBJECT_FLAG_COMPFUNC | \ + DUK_HOBJECT_FLAG_NATFUNC) -/* object has any exotic behavior(s) */ +/* Object has any exotic behavior(s). */ #define DUK_HOBJECT_EXOTIC_BEHAVIOR_FLAGS (DUK_HOBJECT_FLAG_EXOTIC_ARRAY | \ DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS | \ DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ | \ DUK_HOBJECT_FLAG_EXOTIC_DUKFUNC | \ - DUK_HOBJECT_FLAG_BUFFEROBJECT | \ + DUK_HOBJECT_FLAG_BUFOBJ | \ DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ) - #define DUK_HOBJECT_HAS_EXOTIC_BEHAVIOR(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_EXOTIC_BEHAVIOR_FLAGS) +/* Object has any virtual properties (not counting Proxy behavior). */ +#define DUK_HOBJECT_VIRTUAL_PROPERTY_FLAGS (DUK_HOBJECT_FLAG_EXOTIC_ARRAY | \ + DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ | \ + DUK_HOBJECT_FLAG_EXOTIC_DUKFUNC | \ + DUK_HOBJECT_FLAG_BUFOBJ) +#define DUK_HOBJECT_HAS_VIRTUAL_PROPERTIES(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_VIRTUAL_PROPERTY_FLAGS) + #define DUK_HOBJECT_HAS_EXTENSIBLE(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXTENSIBLE) #define DUK_HOBJECT_HAS_CONSTRUCTABLE(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CONSTRUCTABLE) -#define DUK_HOBJECT_HAS_BOUND(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUND) -#define DUK_HOBJECT_HAS_COMPILEDFUNCTION(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPILEDFUNCTION) -#define DUK_HOBJECT_HAS_NATIVEFUNCTION(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATIVEFUNCTION) -#define DUK_HOBJECT_HAS_BUFFEROBJECT(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFFEROBJECT) +#define DUK_HOBJECT_HAS_BOUNDFUNC(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUNDFUNC) +#define DUK_HOBJECT_HAS_COMPFUNC(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPFUNC) +#define DUK_HOBJECT_HAS_NATFUNC(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATFUNC) +#define DUK_HOBJECT_HAS_BUFOBJ(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFOBJ) #define DUK_HOBJECT_HAS_THREAD(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_THREAD) #define DUK_HOBJECT_HAS_ARRAY_PART(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ARRAY_PART) #define DUK_HOBJECT_HAS_STRICT(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_STRICT) @@ -4842,10 +5461,10 @@ DUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h); #define DUK_HOBJECT_SET_EXTENSIBLE(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXTENSIBLE) #define DUK_HOBJECT_SET_CONSTRUCTABLE(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CONSTRUCTABLE) -#define DUK_HOBJECT_SET_BOUND(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUND) -#define DUK_HOBJECT_SET_COMPILEDFUNCTION(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPILEDFUNCTION) -#define DUK_HOBJECT_SET_NATIVEFUNCTION(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATIVEFUNCTION) -#define DUK_HOBJECT_SET_BUFFEROBJECT(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFFEROBJECT) +#define DUK_HOBJECT_SET_BOUNDFUNC(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUNDFUNC) +#define DUK_HOBJECT_SET_COMPFUNC(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPFUNC) +#define DUK_HOBJECT_SET_NATFUNC(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATFUNC) +#define DUK_HOBJECT_SET_BUFOBJ(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFOBJ) #define DUK_HOBJECT_SET_THREAD(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_THREAD) #define DUK_HOBJECT_SET_ARRAY_PART(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ARRAY_PART) #define DUK_HOBJECT_SET_STRICT(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_STRICT) @@ -4862,10 +5481,10 @@ DUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h); #define DUK_HOBJECT_CLEAR_EXTENSIBLE(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXTENSIBLE) #define DUK_HOBJECT_CLEAR_CONSTRUCTABLE(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CONSTRUCTABLE) -#define DUK_HOBJECT_CLEAR_BOUND(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUND) -#define DUK_HOBJECT_CLEAR_COMPILEDFUNCTION(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPILEDFUNCTION) -#define DUK_HOBJECT_CLEAR_NATIVEFUNCTION(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATIVEFUNCTION) -#define DUK_HOBJECT_CLEAR_BUFFEROBJECT(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFFEROBJECT) +#define DUK_HOBJECT_CLEAR_BOUNDFUNC(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUNDFUNC) +#define DUK_HOBJECT_CLEAR_COMPFUNC(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPFUNC) +#define DUK_HOBJECT_CLEAR_NATFUNC(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATFUNC) +#define DUK_HOBJECT_CLEAR_BUFOBJ(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFOBJ) #define DUK_HOBJECT_CLEAR_THREAD(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_THREAD) #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) @@ -4880,7 +5499,9 @@ DUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h); #define DUK_HOBJECT_CLEAR_EXOTIC_DUKFUNC(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_DUKFUNC) #define DUK_HOBJECT_CLEAR_EXOTIC_PROXYOBJ(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ) -/* flags used for property attributes in duk_propdesc and packed flags */ +/* Flags used for property attributes in duk_propdesc and packed flags. + * Must fit into 8 bits. + */ #define DUK_PROPDESC_FLAG_WRITABLE (1 << 0) /* E5 Section 8.6.1 */ #define DUK_PROPDESC_FLAG_ENUMERABLE (1 << 1) /* E5 Section 8.6.1 */ #define DUK_PROPDESC_FLAG_CONFIGURABLE (1 << 2) /* E5 Section 8.6.1 */ @@ -4893,12 +5514,12 @@ DUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h); DUK_PROPDESC_FLAG_CONFIGURABLE | \ DUK_PROPDESC_FLAG_ACCESSOR) -/* additional flags which are passed in the same flags argument as property +/* 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 (1 << 4) /* internal define property: skip write silently if exists */ -/* convenience */ +/* 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) @@ -4910,7 +5531,7 @@ DUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h); DUK_PROPDESC_FLAG_ENUMERABLE | \ DUK_PROPDESC_FLAG_CONFIGURABLE) -/* flags for duk_hobject_get_own_propdesc() and variants */ +/* Flags for duk_hobject_get_own_propdesc() and variants. */ #define DUK_GETDESC_FLAG_PUSH_VALUE (1 << 0) /* push value to stack */ #define DUK_GETDESC_FLAG_IGNORE_PROTOLOOP (1 << 1) /* don't throw for prototype loop */ @@ -4924,9 +5545,8 @@ DUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h); DUK_ASSERT((h) != NULL); \ DUK_ASSERT(!DUK_HOBJECT_IS_CALLABLE((h)) || \ DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_FUNCTION); \ - DUK_ASSERT(!DUK_HOBJECT_IS_BUFFEROBJECT((h)) || \ - (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_BUFFER || \ - DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_ARRAYBUFFER || \ + DUK_ASSERT(!DUK_HOBJECT_IS_BUFOBJ((h)) || \ + (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_ARRAYBUFFER || \ DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_DATAVIEW || \ DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_INT8ARRAY || \ DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_UINT8ARRAY || \ @@ -4937,6 +5557,9 @@ DUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h); DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_UINT32ARRAY || \ DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_FLOAT32ARRAY || \ DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_FLOAT64ARRAY)); \ + /* Object is an Array <=> object has exotic array behavior */ \ + DUK_ASSERT((DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_ARRAY && DUK_HOBJECT_HAS_EXOTIC_ARRAY((h))) || \ + (DUK_HOBJECT_GET_CLASS_NUMBER((h)) != DUK_HOBJECT_CLASS_ARRAY && !DUK_HOBJECT_HAS_EXOTIC_ARRAY((h)))); \ } while (0) /* @@ -5418,7 +6041,7 @@ struct duk_hobject { #if defined(DUK_USE_HEAPPTR16) /* Located in duk_heaphdr h_extra16. Subclasses of duk_hobject (like - * duk_hcompiledfunction) are not free to use h_extra16 for this reason. + * duk_hcompfunc) are not free to use h_extra16 for this reason. */ #else duk_uint8_t *props; @@ -5465,11 +6088,22 @@ DUK_INTERNAL_DECL duk_hobject *duk_hobject_alloc(duk_heap *heap, duk_uint_t hobj #if 0 /* unused */ DUK_INTERNAL_DECL duk_hobject *duk_hobject_alloc_checked(duk_hthread *thr, duk_uint_t hobject_flags); #endif -DUK_INTERNAL_DECL duk_hcompiledfunction *duk_hcompiledfunction_alloc(duk_heap *heap, duk_uint_t hobject_flags); -DUK_INTERNAL_DECL duk_hnativefunction *duk_hnativefunction_alloc(duk_heap *heap, duk_uint_t hobject_flags); -DUK_INTERNAL duk_hbufferobject *duk_hbufferobject_alloc(duk_heap *heap, duk_uint_t hobject_flags); +DUK_INTERNAL_DECL duk_harray *duk_harray_alloc(duk_heap *heap, duk_uint_t hobject_flags); +DUK_INTERNAL_DECL duk_hcompfunc *duk_hcompfunc_alloc(duk_heap *heap, duk_uint_t hobject_flags); +DUK_INTERNAL_DECL duk_hnatfunc *duk_hnatfunc_alloc(duk_heap *heap, duk_uint_t hobject_flags); +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_INTERNAL_DECL duk_hbufobj *duk_hbufobj_alloc(duk_heap *heap, duk_uint_t hobject_flags); +#endif DUK_INTERNAL_DECL duk_hthread *duk_hthread_alloc(duk_heap *heap, duk_uint_t hobject_flags); +/* resize */ +DUK_INTERNAL_DECL void duk_hobject_realloc_props(duk_hthread *thr, + duk_hobject *obj, + duk_uint32_t new_e_size, + duk_uint32_t new_a_size, + duk_uint32_t new_h_size, + duk_bool_t abandon_array); + /* low-level property functions */ DUK_INTERNAL_DECL void duk_hobject_find_existing_entry(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *e_idx, duk_int_t *h_idx); DUK_INTERNAL_DECL duk_tval *duk_hobject_find_existing_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_hstring *key); @@ -5496,10 +6130,7 @@ DUK_INTERNAL_DECL duk_bool_t duk_hobject_delprop_raw(duk_hthread *thr, duk_hobje DUK_INTERNAL_DECL duk_bool_t duk_hobject_hasprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key); DUK_INTERNAL_DECL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags); DUK_INTERNAL_DECL void duk_hobject_define_property_internal_arridx(duk_hthread *thr, duk_hobject *obj, duk_uarridx_t arr_idx, duk_small_uint_t flags); -DUK_INTERNAL_DECL void duk_hobject_define_accessor_internal(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_hobject *getter, duk_hobject *setter, duk_small_uint_t propflags); -DUK_INTERNAL_DECL void duk_hobject_set_length(duk_hthread *thr, duk_hobject *obj, duk_uint32_t length); /* XXX: duk_uarridx_t? */ -DUK_INTERNAL_DECL void duk_hobject_set_length_zero(duk_hthread *thr, duk_hobject *obj); -DUK_INTERNAL_DECL duk_uint32_t duk_hobject_get_length(duk_hthread *thr, duk_hobject *obj); /* XXX: duk_uarridx_t? */ +DUK_INTERNAL_DECL duk_size_t duk_hobject_get_length(duk_hthread *thr, duk_hobject *obj); /* helpers for defineProperty() and defineProperties() */ DUK_INTERNAL_DECL @@ -5510,16 +6141,17 @@ void duk_hobject_prepare_property_descriptor(duk_context *ctx, duk_hobject **out_getter, duk_hobject **out_setter); DUK_INTERNAL_DECL -void duk_hobject_define_property_helper(duk_context *ctx, - duk_uint_t defprop_flags, - duk_hobject *obj, - duk_hstring *key, - duk_idx_t idx_value, - duk_hobject *get, - duk_hobject *set); +duk_bool_t duk_hobject_define_property_helper(duk_context *ctx, + duk_uint_t defprop_flags, + duk_hobject *obj, + duk_hstring *key, + duk_idx_t idx_value, + duk_hobject *get, + duk_hobject *set, + duk_bool_t throw_flag); /* Object built-in methods */ -DUK_INTERNAL_DECL duk_ret_t duk_hobject_object_get_own_property_descriptor(duk_context *ctx); +DUK_INTERNAL_DECL void duk_hobject_object_get_own_property_descriptor(duk_context *ctx, duk_idx_t obj_idx); DUK_INTERNAL_DECL void duk_hobject_object_seal_freeze_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_freeze); DUK_INTERNAL_DECL duk_bool_t duk_hobject_object_is_sealed_frozen_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_frozen); DUK_INTERNAL_DECL duk_bool_t duk_hobject_object_ownprop_helper(duk_context *ctx, duk_small_uint_t required_desc_flags); @@ -5531,7 +6163,7 @@ DUK_INTERNAL_DECL duk_hstring *duk_hobject_get_internal_value_string(duk_heap *h /* hobject management functions */ DUK_INTERNAL_DECL void duk_hobject_compact_props(duk_hthread *thr, duk_hobject *obj); -/* ES6 proxy */ +/* ES2015 proxy */ #if defined(DUK_USE_ES6_PROXY) DUK_INTERNAL_DECL duk_bool_t duk_hobject_proxy_check(duk_hthread *thr, duk_hobject *obj, duk_hobject **out_target, duk_hobject **out_handler); DUK_INTERNAL_DECL duk_hobject *duk_hobject_resolve_proxy_target(duk_hthread *thr, duk_hobject *obj); @@ -5546,7 +6178,9 @@ DUK_INTERNAL_DECL duk_bool_t duk_hobject_enumerator_next(duk_context *ctx, duk_b DUK_INTERNAL_DECL void duk_hobject_set_prototype_updref(duk_hthread *thr, duk_hobject *h, duk_hobject *p); /* finalization */ +#if defined(DUK_USE_FINALIZER_SUPPORT) DUK_INTERNAL_DECL void duk_hobject_run_finalizer(duk_hthread *thr, duk_hobject *obj); +#endif /* pc2line */ #if defined(DUK_USE_PC2LINE) @@ -5557,8 +6191,16 @@ DUK_INTERNAL_DECL duk_uint_fast32_t duk_hobject_pc2line_query(duk_context *ctx, /* misc */ DUK_INTERNAL_DECL duk_bool_t duk_hobject_prototype_chain_contains(duk_hthread *thr, duk_hobject *h, duk_hobject *p, duk_bool_t ignore_loop); +#if !defined(DUK_USE_OBJECT_BUILTIN) +/* These declarations are needed when related built-in is disabled and + * genbuiltins.py won't automatically emit the declerations. + */ +DUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_to_string(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype(duk_context *ctx); +#endif + #endif /* DUK_HOBJECT_H_INCLUDED */ -#line 1 "duk_hcompiledfunction.h" +/* #include duk_hcompfunc.h */ /* * Heap compiled function (Ecmascript function) representation. * @@ -5566,8 +6208,8 @@ DUK_INTERNAL_DECL duk_bool_t duk_hobject_prototype_chain_contains(duk_hthread *t * bytecode, constants, and inner functions. */ -#ifndef DUK_HCOMPILEDFUNCTION_H_INCLUDED -#define DUK_HCOMPILEDFUNCTION_H_INCLUDED +#if !defined(DUK_HCOMPFUNC_H_INCLUDED) +#define DUK_HCOMPFUNC_H_INCLUDED /* * Field accessor macros @@ -5576,37 +6218,52 @@ DUK_INTERNAL_DECL duk_bool_t duk_hobject_prototype_chain_contains(duk_hthread *t /* XXX: casts could be improved, especially for GET/SET DATA */ #if defined(DUK_USE_HEAPPTR16) -#define DUK_HCOMPILEDFUNCTION_GET_DATA(heap,h) \ +#define DUK_HCOMPFUNC_GET_DATA(heap,h) \ ((duk_hbuffer_fixed *) (void *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->data16)) -#define DUK_HCOMPILEDFUNCTION_SET_DATA(heap,h,v) do { \ +#define DUK_HCOMPFUNC_SET_DATA(heap,h,v) do { \ (h)->data16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \ } while (0) -#define DUK_HCOMPILEDFUNCTION_GET_FUNCS(heap,h) \ +#define DUK_HCOMPFUNC_GET_FUNCS(heap,h) \ ((duk_hobject **) (void *) (DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->funcs16))) -#define DUK_HCOMPILEDFUNCTION_SET_FUNCS(heap,h,v) do { \ +#define DUK_HCOMPFUNC_SET_FUNCS(heap,h,v) do { \ (h)->funcs16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \ } while (0) -#define DUK_HCOMPILEDFUNCTION_GET_BYTECODE(heap,h) \ +#define DUK_HCOMPFUNC_GET_BYTECODE(heap,h) \ ((duk_instr_t *) (void *) (DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->bytecode16))) -#define DUK_HCOMPILEDFUNCTION_SET_BYTECODE(heap,h,v) do { \ +#define DUK_HCOMPFUNC_SET_BYTECODE(heap,h,v) do { \ (h)->bytecode16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \ } while (0) +#define DUK_HCOMPFUNC_GET_LEXENV(heap,h) \ + ((duk_hobject *) (void *) (DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->lex_env16))) +#define DUK_HCOMPFUNC_SET_LEXENV(heap,h,v) do { \ + (h)->lex_env16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \ + } while (0) +#define DUK_HCOMPFUNC_GET_VARENV(heap,h) \ + ((duk_hobject *) (void *) (DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->var_env16))) +#define DUK_HCOMPFUNC_SET_VARENV(heap,h,v) do { \ + (h)->var_env16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \ + } while (0) #else -#define DUK_HCOMPILEDFUNCTION_GET_DATA(heap,h) \ - ((duk_hbuffer_fixed *) (void *) (h)->data) -#define DUK_HCOMPILEDFUNCTION_SET_DATA(heap,h,v) do { \ +#define DUK_HCOMPFUNC_GET_DATA(heap,h) ((duk_hbuffer_fixed *) (void *) (h)->data) +#define DUK_HCOMPFUNC_SET_DATA(heap,h,v) do { \ (h)->data = (duk_hbuffer *) (v); \ } while (0) -#define DUK_HCOMPILEDFUNCTION_GET_FUNCS(heap,h) \ - ((h)->funcs) -#define DUK_HCOMPILEDFUNCTION_SET_FUNCS(heap,h,v) do { \ +#define DUK_HCOMPFUNC_GET_FUNCS(heap,h) ((h)->funcs) +#define DUK_HCOMPFUNC_SET_FUNCS(heap,h,v) do { \ (h)->funcs = (v); \ } while (0) -#define DUK_HCOMPILEDFUNCTION_GET_BYTECODE(heap,h) \ - ((h)->bytecode) -#define DUK_HCOMPILEDFUNCTION_SET_BYTECODE(heap,h,v) do { \ +#define DUK_HCOMPFUNC_GET_BYTECODE(heap,h) ((h)->bytecode) +#define DUK_HCOMPFUNC_SET_BYTECODE(heap,h,v) do { \ (h)->bytecode = (v); \ } while (0) +#define DUK_HCOMPFUNC_GET_LEXENV(heap,h) ((h)->lex_env) +#define DUK_HCOMPFUNC_SET_LEXENV(heap,h,v) do { \ + (h)->lex_env = (v); \ + } while (0) +#define DUK_HCOMPFUNC_GET_VARENV(heap,h) ((h)->var_env) +#define DUK_HCOMPFUNC_SET_VARENV(heap,h,v) do { \ + (h)->var_env = (v); \ + } while (0) #endif /* @@ -5614,71 +6271,71 @@ DUK_INTERNAL_DECL duk_bool_t duk_hobject_prototype_chain_contains(duk_hthread *t */ /* Note: assumes 'data' is always a fixed buffer */ -#define DUK_HCOMPILEDFUNCTION_GET_BUFFER_BASE(heap,h) \ - DUK_HBUFFER_FIXED_GET_DATA_PTR((heap), DUK_HCOMPILEDFUNCTION_GET_DATA((heap), (h))) +#define DUK_HCOMPFUNC_GET_BUFFER_BASE(heap,h) \ + DUK_HBUFFER_FIXED_GET_DATA_PTR((heap), DUK_HCOMPFUNC_GET_DATA((heap), (h))) -#define DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE(heap,h) \ - ((duk_tval *) (void *) DUK_HCOMPILEDFUNCTION_GET_BUFFER_BASE((heap), (h))) +#define DUK_HCOMPFUNC_GET_CONSTS_BASE(heap,h) \ + ((duk_tval *) (void *) DUK_HCOMPFUNC_GET_BUFFER_BASE((heap), (h))) -#define DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE(heap,h) \ - DUK_HCOMPILEDFUNCTION_GET_FUNCS((heap), (h)) +#define DUK_HCOMPFUNC_GET_FUNCS_BASE(heap,h) \ + DUK_HCOMPFUNC_GET_FUNCS((heap), (h)) -#define DUK_HCOMPILEDFUNCTION_GET_CODE_BASE(heap,h) \ - DUK_HCOMPILEDFUNCTION_GET_BYTECODE((heap), (h)) +#define DUK_HCOMPFUNC_GET_CODE_BASE(heap,h) \ + DUK_HCOMPFUNC_GET_BYTECODE((heap), (h)) -#define DUK_HCOMPILEDFUNCTION_GET_CONSTS_END(heap,h) \ - ((duk_tval *) (void *) DUK_HCOMPILEDFUNCTION_GET_FUNCS((heap), (h))) +#define DUK_HCOMPFUNC_GET_CONSTS_END(heap,h) \ + ((duk_tval *) (void *) DUK_HCOMPFUNC_GET_FUNCS((heap), (h))) -#define DUK_HCOMPILEDFUNCTION_GET_FUNCS_END(heap,h) \ - ((duk_hobject **) (void *) DUK_HCOMPILEDFUNCTION_GET_BYTECODE((heap), (h))) +#define DUK_HCOMPFUNC_GET_FUNCS_END(heap,h) \ + ((duk_hobject **) (void *) DUK_HCOMPFUNC_GET_BYTECODE((heap), (h))) -/* XXX: double evaluation of DUK_HCOMPILEDFUNCTION_GET_DATA() */ -#define DUK_HCOMPILEDFUNCTION_GET_CODE_END(heap,h) \ - ((duk_instr_t *) (void *) (DUK_HBUFFER_FIXED_GET_DATA_PTR((heap), DUK_HCOMPILEDFUNCTION_GET_DATA((heap), (h))) + \ - DUK_HBUFFER_GET_SIZE((duk_hbuffer *) DUK_HCOMPILEDFUNCTION_GET_DATA((heap), h)))) +/* XXX: double evaluation of DUK_HCOMPFUNC_GET_DATA() */ +#define DUK_HCOMPFUNC_GET_CODE_END(heap,h) \ + ((duk_instr_t *) (void *) (DUK_HBUFFER_FIXED_GET_DATA_PTR((heap), DUK_HCOMPFUNC_GET_DATA((heap), (h))) + \ + DUK_HBUFFER_GET_SIZE((duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA((heap), h)))) -#define DUK_HCOMPILEDFUNCTION_GET_CONSTS_SIZE(heap,h) \ +#define DUK_HCOMPFUNC_GET_CONSTS_SIZE(heap,h) \ ( \ (duk_size_t) \ ( \ - ((const duk_uint8_t *) DUK_HCOMPILEDFUNCTION_GET_CONSTS_END((heap), (h))) - \ - ((const duk_uint8_t *) DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE((heap), (h))) \ + ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_CONSTS_END((heap), (h))) - \ + ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_CONSTS_BASE((heap), (h))) \ ) \ ) -#define DUK_HCOMPILEDFUNCTION_GET_FUNCS_SIZE(heap,h) \ +#define DUK_HCOMPFUNC_GET_FUNCS_SIZE(heap,h) \ ( \ (duk_size_t) \ ( \ - ((const duk_uint8_t *) DUK_HCOMPILEDFUNCTION_GET_FUNCS_END((heap), (h))) - \ - ((const duk_uint8_t *) DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE((heap), (h))) \ + ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_FUNCS_END((heap), (h))) - \ + ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_FUNCS_BASE((heap), (h))) \ ) \ ) -#define DUK_HCOMPILEDFUNCTION_GET_CODE_SIZE(heap,h) \ +#define DUK_HCOMPFUNC_GET_CODE_SIZE(heap,h) \ ( \ (duk_size_t) \ ( \ - ((const duk_uint8_t *) DUK_HCOMPILEDFUNCTION_GET_CODE_END((heap),(h))) - \ - ((const duk_uint8_t *) DUK_HCOMPILEDFUNCTION_GET_CODE_BASE((heap),(h))) \ + ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_CODE_END((heap),(h))) - \ + ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_CODE_BASE((heap),(h))) \ ) \ ) -#define DUK_HCOMPILEDFUNCTION_GET_CONSTS_COUNT(heap,h) \ - ((duk_size_t) (DUK_HCOMPILEDFUNCTION_GET_CONSTS_SIZE((heap), (h)) / sizeof(duk_tval))) +#define DUK_HCOMPFUNC_GET_CONSTS_COUNT(heap,h) \ + ((duk_size_t) (DUK_HCOMPFUNC_GET_CONSTS_SIZE((heap), (h)) / sizeof(duk_tval))) -#define DUK_HCOMPILEDFUNCTION_GET_FUNCS_COUNT(heap,h) \ - ((duk_size_t) (DUK_HCOMPILEDFUNCTION_GET_FUNCS_SIZE((heap), (h)) / sizeof(duk_hobject *))) +#define DUK_HCOMPFUNC_GET_FUNCS_COUNT(heap,h) \ + ((duk_size_t) (DUK_HCOMPFUNC_GET_FUNCS_SIZE((heap), (h)) / sizeof(duk_hobject *))) -#define DUK_HCOMPILEDFUNCTION_GET_CODE_COUNT(heap,h) \ - ((duk_size_t) (DUK_HCOMPILEDFUNCTION_GET_CODE_SIZE((heap), (h)) / sizeof(duk_instr_t))) +#define DUK_HCOMPFUNC_GET_CODE_COUNT(heap,h) \ + ((duk_size_t) (DUK_HCOMPFUNC_GET_CODE_SIZE((heap), (h)) / sizeof(duk_instr_t))) /* * Main struct */ -struct duk_hcompiledfunction { +struct duk_hcompfunc { /* shared object part */ duk_hobject obj; @@ -5725,6 +6382,17 @@ struct duk_hcompiledfunction { duk_instr_t *bytecode; #endif + /* Lexenv: lexical environment of closure, NULL for templates. + * Varenv: variable environment of closure, NULL for templates. + */ +#if defined(DUK_USE_HEAPPTR16) + duk_uint16_t lex_env16; + duk_uint16_t var_env16; +#else + duk_hobject *lex_env; + duk_hobject *var_env; +#endif + /* * 'nregs' registers are allocated on function entry, at most 'nargs' * are initialized to arguments, and the rest to undefined. Arguments @@ -5780,8 +6448,6 @@ struct duk_hcompiledfunction { * _Formals: [ "arg1", "arg2" ], * _Source: "function func(arg1, arg2) { ... }", * _Pc2line: <debug info for pc-to-line mapping>, - * _Varenv: <variable environment of closure>, - * _Lexenv: <lexical environment of closure (if differs from _Varenv)> * } * * More detailed description of these properties can be found @@ -5797,19 +6463,19 @@ struct duk_hcompiledfunction { #endif }; -#endif /* DUK_HCOMPILEDFUNCTION_H_INCLUDED */ -#line 1 "duk_hnativefunction.h" +#endif /* DUK_HCOMPFUNC_H_INCLUDED */ +/* #include duk_hnatfunc.h */ /* * Heap native function representation. */ -#ifndef DUK_HNATIVEFUNCTION_H_INCLUDED -#define DUK_HNATIVEFUNCTION_H_INCLUDED +#if !defined(DUK_HNATFUNC_H_INCLUDED) +#define DUK_HNATFUNC_H_INCLUDED -#define DUK_HNATIVEFUNCTION_NARGS_VARARGS ((duk_int16_t) -1) -#define DUK_HNATIVEFUNCTION_NARGS_MAX ((duk_int16_t) 0x7fff) +#define DUK_HNATFUNC_NARGS_VARARGS ((duk_int16_t) -1) +#define DUK_HNATFUNC_NARGS_MAX ((duk_int16_t) 0x7fff) -struct duk_hnativefunction { +struct duk_hnatfunc { /* shared object part */ duk_hobject obj; @@ -5830,42 +6496,44 @@ struct duk_hnativefunction { */ }; -#endif /* DUK_HNATIVEFUNCTION_H_INCLUDED */ -#line 1 "duk_hbufferobject.h" +#endif /* DUK_HNATFUNC_H_INCLUDED */ +/* #include duk_hbufobj.h */ /* * Heap Buffer object representation. Used for all Buffer variants. */ -#ifndef DUK_HBUFFEROBJECT_H_INCLUDED -#define DUK_HBUFFEROBJECT_H_INCLUDED +#if !defined(DUK_HBUFOBJ_H_INCLUDED) +#define DUK_HBUFOBJ_H_INCLUDED + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) /* All element accessors are host endian now (driven by TypedArray spec). */ -#define DUK_HBUFFEROBJECT_ELEM_UINT8 0 -#define DUK_HBUFFEROBJECT_ELEM_UINT8CLAMPED 1 -#define DUK_HBUFFEROBJECT_ELEM_INT8 2 -#define DUK_HBUFFEROBJECT_ELEM_UINT16 3 -#define DUK_HBUFFEROBJECT_ELEM_INT16 4 -#define DUK_HBUFFEROBJECT_ELEM_UINT32 5 -#define DUK_HBUFFEROBJECT_ELEM_INT32 6 -#define DUK_HBUFFEROBJECT_ELEM_FLOAT32 7 -#define DUK_HBUFFEROBJECT_ELEM_FLOAT64 8 -#define DUK_HBUFFEROBJECT_ELEM_MAX 8 - -#define DUK_ASSERT_HBUFFEROBJECT_VALID(h) do { \ +#define DUK_HBUFOBJ_ELEM_UINT8 0 +#define DUK_HBUFOBJ_ELEM_UINT8CLAMPED 1 +#define DUK_HBUFOBJ_ELEM_INT8 2 +#define DUK_HBUFOBJ_ELEM_UINT16 3 +#define DUK_HBUFOBJ_ELEM_INT16 4 +#define DUK_HBUFOBJ_ELEM_UINT32 5 +#define DUK_HBUFOBJ_ELEM_INT32 6 +#define DUK_HBUFOBJ_ELEM_FLOAT32 7 +#define DUK_HBUFOBJ_ELEM_FLOAT64 8 +#define DUK_HBUFOBJ_ELEM_MAX 8 + +#define DUK_ASSERT_HBUFOBJ_VALID(h) do { \ DUK_ASSERT((h) != NULL); \ DUK_ASSERT((h)->shift <= 3); \ - DUK_ASSERT((h)->elem_type <= DUK_HBUFFEROBJECT_ELEM_MAX); \ - DUK_ASSERT(((h)->shift == 0 && (h)->elem_type == DUK_HBUFFEROBJECT_ELEM_UINT8) || \ - ((h)->shift == 0 && (h)->elem_type == DUK_HBUFFEROBJECT_ELEM_UINT8CLAMPED) || \ - ((h)->shift == 0 && (h)->elem_type == DUK_HBUFFEROBJECT_ELEM_INT8) || \ - ((h)->shift == 1 && (h)->elem_type == DUK_HBUFFEROBJECT_ELEM_UINT16) || \ - ((h)->shift == 1 && (h)->elem_type == DUK_HBUFFEROBJECT_ELEM_INT16) || \ - ((h)->shift == 2 && (h)->elem_type == DUK_HBUFFEROBJECT_ELEM_UINT32) || \ - ((h)->shift == 2 && (h)->elem_type == DUK_HBUFFEROBJECT_ELEM_INT32) || \ - ((h)->shift == 2 && (h)->elem_type == DUK_HBUFFEROBJECT_ELEM_FLOAT32) || \ - ((h)->shift == 3 && (h)->elem_type == DUK_HBUFFEROBJECT_ELEM_FLOAT64)); \ - DUK_ASSERT((h)->is_view == 0 || (h)->is_view == 1); \ - DUK_ASSERT(DUK_HOBJECT_IS_BUFFEROBJECT((duk_hobject *) (h))); \ + DUK_ASSERT((h)->elem_type <= DUK_HBUFOBJ_ELEM_MAX); \ + DUK_ASSERT(((h)->shift == 0 && (h)->elem_type == DUK_HBUFOBJ_ELEM_UINT8) || \ + ((h)->shift == 0 && (h)->elem_type == DUK_HBUFOBJ_ELEM_UINT8CLAMPED) || \ + ((h)->shift == 0 && (h)->elem_type == DUK_HBUFOBJ_ELEM_INT8) || \ + ((h)->shift == 1 && (h)->elem_type == DUK_HBUFOBJ_ELEM_UINT16) || \ + ((h)->shift == 1 && (h)->elem_type == DUK_HBUFOBJ_ELEM_INT16) || \ + ((h)->shift == 2 && (h)->elem_type == DUK_HBUFOBJ_ELEM_UINT32) || \ + ((h)->shift == 2 && (h)->elem_type == DUK_HBUFOBJ_ELEM_INT32) || \ + ((h)->shift == 2 && (h)->elem_type == DUK_HBUFOBJ_ELEM_FLOAT32) || \ + ((h)->shift == 3 && (h)->elem_type == DUK_HBUFOBJ_ELEM_FLOAT64)); \ + DUK_ASSERT((h)->is_typedarray == 0 || (h)->is_typedarray == 1); \ + DUK_ASSERT(DUK_HOBJECT_IS_BUFOBJ((duk_hobject *) (h))); \ if ((h)->buf == NULL) { \ DUK_ASSERT((h)->offset == 0); \ DUK_ASSERT((h)->length == 0); \ @@ -5881,58 +6549,64 @@ struct duk_hnativefunction { /* Get the current data pointer (caller must ensure buf != NULL) as a * duk_uint8_t ptr. */ -#define DUK_HBUFFEROBJECT_GET_SLICE_BASE(heap,h) \ +#define DUK_HBUFOBJ_GET_SLICE_BASE(heap,h) \ (DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \ (((duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR((heap), (h)->buf)) + (h)->offset)) /* True if slice is full, i.e. offset is zero and length covers the entire - * buffer. This status may change independently of the duk_hbufferobject if - * the underlying buffer is dynamic and changes without the hbufferobject + * buffer. This status may change independently of the duk_hbufobj if + * the underlying buffer is dynamic and changes without the hbufobj * being changed. */ -#define DUK_HBUFFEROBJECT_FULL_SLICE(h) \ +#define DUK_HBUFOBJ_FULL_SLICE(h) \ (DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \ ((h)->offset == 0 && (h)->length == DUK_HBUFFER_GET_SIZE((h)->buf))) /* Validate that the whole slice [0,length[ is contained in the underlying * buffer. Caller must ensure 'buf' != NULL. */ -#define DUK_HBUFFEROBJECT_VALID_SLICE(h) \ +#define DUK_HBUFOBJ_VALID_SLICE(h) \ (DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \ ((h)->offset + (h)->length <= DUK_HBUFFER_GET_SIZE((h)->buf))) /* Validate byte read/write for virtual 'offset', i.e. check that the * offset, taking into account h->offset, is within the underlying * buffer size. This is a safety check which is needed to ensure - * that even a misconfigured duk_hbufferobject never causes memory - * unsafe behavior (e.g. if an underlying dynamic buffer changes - * after being setup). Caller must ensure 'buf' != NULL. + * that even a misconfigured duk_hbufobj never causes memory unsafe + * behavior (e.g. if an underlying dynamic buffer changes after being + * setup). Caller must ensure 'buf' != NULL. */ -#define DUK_HBUFFEROBJECT_VALID_BYTEOFFSET_INCL(h,off) \ +#define DUK_HBUFOBJ_VALID_BYTEOFFSET_INCL(h,off) \ (DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \ ((h)->offset + (off) < DUK_HBUFFER_GET_SIZE((h)->buf))) -#define DUK_HBUFFEROBJECT_VALID_BYTEOFFSET_EXCL(h,off) \ +#define DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h,off) \ (DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \ ((h)->offset + (off) <= DUK_HBUFFER_GET_SIZE((h)->buf))) /* Clamp an input byte length (already assumed to be within the nominal - * duk_hbufferobject 'length') to the current dynamic buffer limits to - * yield a byte length limit that's safe for memory accesses. This value - * can be invalidated by any side effect because it may trigger a user + * duk_hbufobj 'length') to the current dynamic buffer limits to yield + * a byte length limit that's safe for memory accesses. This value can + * be invalidated by any side effect because it may trigger a user * callback that resizes the underlying buffer. */ -#define DUK_HBUFFEROBJECT_CLAMP_BYTELENGTH(h,len) \ +#define DUK_HBUFOBJ_CLAMP_BYTELENGTH(h,len) \ (DUK_ASSERT_EXPR((h) != NULL), \ - duk_hbufferobject_clamp_bytelength((h), (len))) + duk_hbufobj_clamp_bytelength((h), (len))) -struct duk_hbufferobject { +/* Typed arrays have virtual indices, ArrayBuffer and DataView do not. */ +#define DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h) ((h)->is_typedarray) + +struct duk_hbufobj { /* Shared object part. */ duk_hobject obj; /* Underlying buffer (refcounted), may be NULL. */ duk_hbuffer *buf; + /* .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 @@ -5955,17 +6629,18 @@ struct duk_hbufferobject { * 3 = double */ duk_uint8_t elem_type; /* element type */ - duk_uint8_t is_view; + duk_uint8_t is_typedarray; }; -#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) -DUK_INTERNAL_DECL duk_uint_t duk_hbufferobject_clamp_bytelength(duk_hbufferobject *h_bufobj, duk_uint_t len); -#endif -DUK_INTERNAL_DECL void duk_hbufferobject_push_validated_read(duk_context *ctx, duk_hbufferobject *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size); -DUK_INTERNAL_DECL void duk_hbufferobject_validated_write(duk_context *ctx, duk_hbufferobject *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size); +DUK_INTERNAL_DECL duk_uint_t duk_hbufobj_clamp_bytelength(duk_hbufobj *h_bufobj, duk_uint_t len); +DUK_INTERNAL_DECL void duk_hbufobj_push_uint8array_from_plain(duk_hthread *thr, duk_hbuffer *h_buf); +DUK_INTERNAL_DECL void duk_hbufobj_push_validated_read(duk_context *ctx, duk_hbufobj *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size); +DUK_INTERNAL_DECL void duk_hbufobj_validated_write(duk_context *ctx, duk_hbufobj *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size); +DUK_INTERNAL_DECL void duk_hbufobj_promote_plain(duk_context *ctx, duk_idx_t idx); -#endif /* DUK_HBUFFEROBJECT_H_INCLUDED */ -#line 1 "duk_hthread.h" +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ +#endif /* DUK_HBUFOBJ_H_INCLUDED */ +/* #include duk_hthread.h */ /* * Heap thread object representation. * @@ -5973,7 +6648,7 @@ DUK_INTERNAL_DECL void duk_hbufferobject_validated_write(duk_context *ctx, duk_h * which mostly operate on the topmost frame of the value stack. */ -#ifndef DUK_HTHREAD_H_INCLUDED +#if !defined(DUK_HTHREAD_H_INCLUDED) #define DUK_HTHREAD_H_INCLUDED /* @@ -6150,6 +6825,26 @@ DUK_INTERNAL_DECL void duk_hbufferobject_validated_write(duk_context *ctx, duk_h } while (0) /* + * Assertion helpers. + */ + +#define DUK_ASSERT_STRIDX_VALID(val) \ + DUK_ASSERT((duk_uint_t) (val) < DUK_HEAP_NUM_STRINGS) + +#define DUK_ASSERT_BIDX_VALID(val) \ + DUK_ASSERT((duk_uint_t) (val) < DUK_NUM_BUILTINS) + +/* + * Misc + */ + +/* Fast access to 'this' binding. Assumes there's a call in progress. */ +#define DUK_HTHREAD_THIS_PTR(thr) \ + (DUK_ASSERT_EXPR((thr) != NULL), \ + DUK_ASSERT_EXPR((thr)->valstack_bottom > (thr)->valstack), \ + (thr)->valstack_bottom - 1) + +/* * Struct defines */ @@ -6163,7 +6858,7 @@ struct duk_activation { duk_hobject *func; /* borrowed: function being executed; for bound function calls, this is the final, real function, NULL for lightfuncs */ duk_hobject *var_env; /* current variable environment (may be NULL if delayed) */ duk_hobject *lex_env; /* current lexical environment (may be NULL if delayed) */ -#ifdef DUK_USE_NONSTD_FUNC_CALLER_PROPERTY +#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY) /* Previous value of 'func' caller, restored when unwound. Only in use * when 'func' is non-strict. */ @@ -6346,7 +7041,55 @@ DUK_INTERNAL_DECL void duk_hthread_sync_currpc(duk_hthread *thr); DUK_INTERNAL_DECL void duk_hthread_sync_and_null_currpc(duk_hthread *thr); #endif /* DUK_HTHREAD_H_INCLUDED */ -#line 1 "duk_hbuffer.h" +/* #include duk_harray.h */ +/* + * Heap Array object representation. Used for actual Array instances. + * + * All objects with the exotic array behavior (which must coincide with having + * internal class array) MUST be duk_harrays. No other object can be a + * duk_harray. However, duk_harrays may not always have an array part. + */ + +#if !defined(DUK_HARRAY_H_INCLUDED) +#define DUK_HARRAY_H_INCLUDED + +#define DUK_ASSERT_HARRAY_VALID(h) do { \ + DUK_ASSERT((h) != NULL); \ + DUK_ASSERT(DUK_HOBJECT_IS_ARRAY((duk_hobject *) (h))); \ + DUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY((duk_hobject *) (h))); \ + } while (0) + +#define DUK_HARRAY_LENGTH_WRITABLE(h) (!(h)->length_nonwritable) +#define DUK_HARRAY_LENGTH_NONWRITABLE(h) ((h)->length_nonwritable) +#define DUK_HARRAY_SET_LENGTH_WRITABLE(h) do { (h)->length_nonwritable = 0; } while (0) +#define DUK_HARRAY_SET_LENGTH_NONWRITABLE(h) do { (h)->length_nonwritable = 1; } while (0) + +struct duk_harray { + /* Shared object part. */ + duk_hobject obj; + + /* Array .length. + * + * At present Array .length may be smaller, equal, or even larger + * than the allocated underlying array part. Fast path code must + * always take this into account carefully. + */ + duk_uint32_t length; + + /* Array .length property attributes. The property is always + * non-enumerable and non-configurable. It's initially writable + * but per Object.defineProperty() rules it can be made non-writable + * even if it is non-configurable. Thus we need to track the + * writability explicitly. + * + * XXX: this field to be eliminated and moved into duk_hobject + * flags field to save space. + */ + duk_bool_t length_nonwritable; +}; + +#endif /* DUK_HARRAY_H_INCLUDED */ +/* #include duk_hbuffer.h */ /* * Heap buffer representation. * @@ -6358,7 +7101,7 @@ DUK_INTERNAL_DECL void duk_hthread_sync_and_null_currpc(duk_hthread *thr); * The data pointer for a variable size buffer of zero size may be NULL. */ -#ifndef DUK_HBUFFER_H_INCLUDED +#if !defined(DUK_HBUFFER_H_INCLUDED) #define DUK_HBUFFER_H_INCLUDED /* @@ -6675,7 +7418,7 @@ DUK_INTERNAL_DECL void duk_hbuffer_resize(duk_hthread *thr, duk_hbuffer_dynamic DUK_INTERNAL_DECL void duk_hbuffer_reset(duk_hthread *thr, duk_hbuffer_dynamic *buf); #endif /* DUK_HBUFFER_H_INCLUDED */ -#line 1 "duk_heap.h" +/* #include duk_heap.h */ /* * Heap structure. * @@ -6683,7 +7426,7 @@ DUK_INTERNAL_DECL void duk_hbuffer_reset(duk_hthread *thr, duk_hbuffer_dynamic * * strings for one or more threads. */ -#ifndef DUK_HEAP_H_INCLUDED +#if !defined(DUK_HEAP_H_INCLUDED) #define DUK_HEAP_H_INCLUDED /* alloc function typedefs in duktape.h */ @@ -6698,6 +7441,7 @@ DUK_INTERNAL_DECL void duk_hbuffer_reset(duk_hthread *thr, duk_hbuffer_dynamic * #define DUK_HEAP_FLAG_ERRHANDLER_RUNNING (1 << 3) /* an error handler (user callback to augment/replace error) is running */ #define DUK_HEAP_FLAG_INTERRUPT_RUNNING (1 << 4) /* executor interrupt running (used to avoid nested interrupts) */ #define DUK_HEAP_FLAG_FINALIZER_NORESCUE (1 << 5) /* heap destruction ongoing, finalizer rescue no longer possible */ +#define DUK_HEAP_FLAG_DEBUGGER_PAUSED (1 << 6) /* debugger is paused: talk with debug client until step/resume */ #define DUK__HEAP_HAS_FLAGS(heap,bits) ((heap)->flags & (bits)) #define DUK__HEAP_SET_FLAGS(heap,bits) do { \ @@ -6713,6 +7457,7 @@ DUK_INTERNAL_DECL void duk_hbuffer_reset(duk_hthread *thr, duk_hbuffer_dynamic * #define DUK_HEAP_HAS_ERRHANDLER_RUNNING(heap) DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_ERRHANDLER_RUNNING) #define DUK_HEAP_HAS_INTERRUPT_RUNNING(heap) DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_INTERRUPT_RUNNING) #define DUK_HEAP_HAS_FINALIZER_NORESCUE(heap) DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_FINALIZER_NORESCUE) +#define DUK_HEAP_HAS_DEBUGGER_PAUSED(heap) DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_DEBUGGER_PAUSED) #define DUK_HEAP_SET_MARKANDSWEEP_RUNNING(heap) DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_MARKANDSWEEP_RUNNING) #define DUK_HEAP_SET_MARKANDSWEEP_RECLIMIT_REACHED(heap) DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED) @@ -6720,6 +7465,7 @@ DUK_INTERNAL_DECL void duk_hbuffer_reset(duk_hthread *thr, duk_hbuffer_dynamic * #define DUK_HEAP_SET_ERRHANDLER_RUNNING(heap) DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_ERRHANDLER_RUNNING) #define DUK_HEAP_SET_INTERRUPT_RUNNING(heap) DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_INTERRUPT_RUNNING) #define DUK_HEAP_SET_FINALIZER_NORESCUE(heap) DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_FINALIZER_NORESCUE) +#define DUK_HEAP_SET_DEBUGGER_PAUSED(heap) DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_DEBUGGER_PAUSED) #define DUK_HEAP_CLEAR_MARKANDSWEEP_RUNNING(heap) DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_MARKANDSWEEP_RUNNING) #define DUK_HEAP_CLEAR_MARKANDSWEEP_RECLIMIT_REACHED(heap) DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED) @@ -6727,6 +7473,7 @@ DUK_INTERNAL_DECL void duk_hbuffer_reset(duk_hthread *thr, duk_hbuffer_dynamic * #define DUK_HEAP_CLEAR_ERRHANDLER_RUNNING(heap) DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_ERRHANDLER_RUNNING) #define DUK_HEAP_CLEAR_INTERRUPT_RUNNING(heap) DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_INTERRUPT_RUNNING) #define DUK_HEAP_CLEAR_FINALIZER_NORESCUE(heap) DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_FINALIZER_NORESCUE) +#define DUK_HEAP_CLEAR_DEBUGGER_PAUSED(heap) DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_DEBUGGER_PAUSED) /* * Longjmp types, also double as identifying continuation type for a rethrow (in 'finally') @@ -6785,7 +7532,6 @@ DUK_INTERNAL_DECL void duk_hbuffer_reset(duk_hthread *thr, duk_hbuffer_dynamic * * GC is skipped because there is no thread do it with yet (happens * only during init phases). */ -#if defined(DUK_USE_MARK_AND_SWEEP) #if defined(DUK_USE_REFERENCE_COUNTING) #define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_MULT 12800L /* 50x heap size */ #define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_ADD 1024L @@ -6795,7 +7541,6 @@ DUK_INTERNAL_DECL void duk_hbuffer_reset(duk_hthread *thr, duk_hbuffer_dynamic * #define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_ADD 1024L #define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_SKIP 256L #endif -#endif /* Stringcache is used for speeding up char-offset-to-byte-offset * translations for non-ASCII strings. @@ -6953,16 +7698,16 @@ struct duk_breakpoint { (heap)->dbg_step_startline = 0; \ } while (0) #define DUK_HEAP_SET_PAUSED(heap) do { \ - (heap)->dbg_paused = 1; \ + DUK_HEAP_SET_DEBUGGER_PAUSED(heap); \ (heap)->dbg_state_dirty = 1; \ DUK_HEAP_CLEAR_STEP_STATE((heap)); \ } while (0) #define DUK_HEAP_CLEAR_PAUSED(heap) do { \ - (heap)->dbg_paused = 0; \ + DUK_HEAP_CLEAR_DEBUGGER_PAUSED(heap); \ (heap)->dbg_state_dirty = 1; \ DUK_HEAP_CLEAR_STEP_STATE((heap)); \ } while (0) -#define DUK_HEAP_IS_PAUSED(heap) ((heap)->dbg_paused) +#define DUK_HEAP_IS_PAUSED(heap) (DUK_HEAP_HAS_DEBUGGER_PAUSED((heap))) #endif /* DUK_USE_DEBUGGER_SUPPORT */ /* @@ -7029,7 +7774,7 @@ struct duk_heap { duk_free_function free_func; /* Heap udata, used for allocator functions but also for other heap - * level callbacks like pointer compression, etc. + * level callbacks like fatal function, pointer compression, etc. */ void *heap_udata; @@ -7058,7 +7803,6 @@ struct duk_heap { duk_heaphdr *refzero_list_tail; #endif -#if defined(DUK_USE_MARK_AND_SWEEP) /* mark-and-sweep control */ #if defined(DUK_USE_VOLUNTARY_GC) duk_int_t mark_and_sweep_trigger_counter; @@ -7070,7 +7814,6 @@ struct duk_heap { /* work list for objects to be finalized (by mark-and-sweep) */ duk_heaphdr *finalize_list; -#endif /* longjmp state */ duk_ljstate lj; @@ -7095,7 +7838,20 @@ struct duk_heap { duk_uint32_t hash_seed; /* rnd_state for duk_util_tinyrandom.c */ - duk_uint32_t rnd_state; +#if !defined(DUK_USE_GET_RANDOM_DOUBLE) +#if defined(DUK_USE_PREFER_SIZE) || !defined(DUK_USE_64BIT_OPS) + duk_uint32_t rnd_state; /* State for Shamir's three-op algorithm */ +#else + duk_uint64_t rnd_state[2]; /* State for xoroshiro128+ */ +#endif +#endif + + /* counter for unique local symbol creation */ + /* XXX: When 64-bit types are available, it would be more efficient to + * use a duk_uint64_t at least for incrementing but maybe also for + * string formatting in the Symbol constructor. + */ + duk_uint32_t sym_counter[2]; /* For manual debugging: instruction count based on executor and * interrupt counter book-keeping. Inspect debug logs to see how @@ -7121,7 +7877,6 @@ struct duk_heap { /* debugger state, only relevant when attached */ duk_bool_t dbg_processing; /* currently processing messages or breakpoints: don't enter message processing recursively (e.g. no breakpoints when processing debugger eval) */ - duk_bool_t dbg_paused; /* currently paused: talk with debug client until step/resume */ duk_bool_t dbg_state_dirty; /* resend state next time executor is about to run */ duk_bool_t dbg_force_restart; /* force executor restart to recheck breakpoints; used to handle function returns (see GH-303) */ duk_bool_t dbg_detaching; /* debugger detaching; used to avoid calling detach handler recursively */ @@ -7190,9 +7945,9 @@ duk_heap *duk_heap_alloc(duk_alloc_function alloc_func, void *heap_udata, duk_fatal_function fatal_func); DUK_INTERNAL_DECL void duk_heap_free(duk_heap *heap); -DUK_INTERNAL_DECL void duk_free_hobject_inner(duk_heap *heap, duk_hobject *h); -DUK_INTERNAL_DECL void duk_free_hbuffer_inner(duk_heap *heap, duk_hbuffer *h); -DUK_INTERNAL_DECL void duk_free_hstring_inner(duk_heap *heap, duk_hstring *h); +DUK_INTERNAL_DECL void duk_free_hobject(duk_heap *heap, duk_hobject *h); +DUK_INTERNAL_DECL void duk_free_hbuffer(duk_heap *heap, duk_hbuffer *h); +DUK_INTERNAL_DECL void duk_free_hstring(duk_heap *heap, duk_hstring *h); DUK_INTERNAL_DECL void duk_heap_free_heaphdr_raw(duk_heap *heap, duk_heaphdr *hdr); DUK_INTERNAL_DECL void duk_heap_insert_into_heap_allocated(duk_heap *heap, duk_heaphdr *hdr); @@ -7216,7 +7971,7 @@ DUK_INTERNAL_DECL duk_hstring *duk_heap_string_intern_u32_checked(duk_hthread *t #if defined(DUK_USE_REFERENCE_COUNTING) DUK_INTERNAL_DECL void duk_heap_string_remove(duk_heap *heap, duk_hstring *h); #endif -#if defined(DUK_USE_MARK_AND_SWEEP) && defined(DUK_USE_MS_STRINGTABLE_RESIZE) +#if defined(DUK_USE_MS_STRINGTABLE_RESIZE) DUK_INTERNAL_DECL void duk_heap_force_strtab_resize(duk_heap *heap); #endif DUK_INTERNAL void duk_heap_free_strtab(duk_heap *heap); @@ -7224,7 +7979,6 @@ DUK_INTERNAL void duk_heap_free_strtab(duk_heap *heap); DUK_INTERNAL void duk_heap_dump_strtab(duk_heap *heap); #endif - DUK_INTERNAL_DECL void duk_heap_strcache_string_remove(duk_heap *heap, duk_hstring *h); DUK_INTERNAL_DECL duk_uint_fast32_t duk_heap_strcache_offset_char2byte(duk_hthread *thr, duk_hstring *h, duk_uint_fast32_t char_offset); @@ -7240,40 +7994,43 @@ DUK_INTERNAL_DECL void *duk_heap_mem_realloc(duk_heap *heap, void *ptr, duk_size DUK_INTERNAL_DECL void *duk_heap_mem_realloc_indirect(duk_heap *heap, duk_mem_getptr cb, void *ud, duk_size_t newsize); DUK_INTERNAL_DECL void duk_heap_mem_free(duk_heap *heap, void *ptr); -#ifdef DUK_USE_REFERENCE_COUNTING -#if !defined(DUK_USE_FAST_REFCOUNT_DEFAULT) -DUK_INTERNAL_DECL void duk_tval_incref(duk_tval *tv); -#endif -#if 0 /* unused */ -DUK_INTERNAL_DECL void duk_tval_incref_allownull(duk_tval *tv); +#if defined(DUK_USE_REFERENCE_COUNTING) +DUK_INTERNAL_DECL void duk_refzero_free_pending(duk_hthread *thr); +DUK_INTERNAL_DECL void duk_heaphdr_refcount_finalize(duk_hthread *thr, duk_heaphdr *hdr); +#if 0 /* Not needed: fast path handles inline; slow path uses duk_heaphdr_decref() which is needed anyway. */ +DUK_INTERNAL_DECL void duk_hstring_decref(duk_hthread *thr, duk_hstring *h); +DUK_INTERNAL_DECL void duk_hstring_decref_norz(duk_hthread *thr, duk_hstring *h); +DUK_INTERNAL_DECL void duk_hbuffer_decref(duk_hthread *thr, duk_hbuffer *h); +DUK_INTERNAL_DECL void duk_hbuffer_decref_norz(duk_hthread *thr, duk_hbuffer *h); +DUK_INTERNAL_DECL void duk_hobject_decref(duk_hthread *thr, duk_hobject *h); +DUK_INTERNAL_DECL void duk_hobject_decref_norz(duk_hthread *thr, duk_hobject *h); #endif +DUK_INTERNAL_DECL void duk_heaphdr_refzero(duk_hthread *thr, duk_heaphdr *h); +DUK_INTERNAL_DECL void duk_heaphdr_refzero_norz(duk_hthread *thr, duk_heaphdr *h); +#if defined(DUK_USE_FAST_REFCOUNT_DEFAULT) +DUK_INTERNAL_DECL void duk_hstring_refzero(duk_hthread *thr, duk_hstring *h); /* no 'norz' variant */ +DUK_INTERNAL_DECL void duk_hbuffer_refzero(duk_hthread *thr, duk_hbuffer *h); /* no 'norz' variant */ +DUK_INTERNAL_DECL void duk_hobject_refzero(duk_hthread *thr, duk_hobject *h); +DUK_INTERNAL_DECL void duk_hobject_refzero_norz(duk_hthread *thr, duk_hobject *h); +#else +DUK_INTERNAL_DECL void duk_tval_incref(duk_tval *tv); DUK_INTERNAL_DECL void duk_tval_decref(duk_hthread *thr, duk_tval *tv); -#if 0 /* unused */ -DUK_INTERNAL_DECL void duk_tval_decref_allownull(duk_hthread *thr, duk_tval *tv); -#endif -#if !defined(DUK_USE_FAST_REFCOUNT_DEFAULT) +DUK_INTERNAL_DECL void duk_tval_decref_norz(duk_hthread *thr, duk_tval *tv); DUK_INTERNAL_DECL void duk_heaphdr_incref(duk_heaphdr *h); -#endif -#if 0 /* unused */ -DUK_INTERNAL_DECL void duk_heaphdr_incref_allownull(duk_heaphdr *h); -#endif DUK_INTERNAL_DECL void duk_heaphdr_decref(duk_hthread *thr, duk_heaphdr *h); -DUK_INTERNAL_DECL void duk_heaphdr_decref_allownull(duk_hthread *thr, duk_heaphdr *h); -DUK_INTERNAL_DECL void duk_heaphdr_refzero(duk_hthread *thr, duk_heaphdr *h); -DUK_INTERNAL_DECL void duk_heaphdr_refcount_finalize(duk_hthread *thr, duk_heaphdr *hdr); -#else -/* no refcounting */ +DUK_INTERNAL_DECL void duk_heaphdr_decref_norz(duk_hthread *thr, duk_heaphdr *h); #endif +#else /* DUK_USE_REFERENCE_COUNTING */ +/* no refcounting */ +#endif /* DUK_USE_REFERENCE_COUNTING */ -#if defined(DUK_USE_MARK_AND_SWEEP) DUK_INTERNAL_DECL duk_bool_t duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags); -#endif DUK_INTERNAL_DECL duk_uint32_t duk_heap_hashstring(duk_heap *heap, const duk_uint8_t *str, duk_size_t len); #endif /* DUK_HEAP_H_INCLUDED */ -#line 1 "duk_debugger.h" -#ifndef DUK_DEBUGGER_H_INCLUDED +/* #include duk_debugger.h */ +#if !defined(DUK_DEBUGGER_H_INCLUDED) #define DUK_DEBUGGER_H_INCLUDED /* Debugger protocol version is defined in the public API header. */ @@ -7314,9 +8071,9 @@ DUK_INTERNAL_DECL duk_uint32_t duk_heap_hashstring(duk_heap *heap, const duk_uin /* Commands and notifys initiated by Duktape. */ #define DUK_DBG_CMD_STATUS 0x01 -#define DUK_DBG_CMD_PRINT 0x02 -#define DUK_DBG_CMD_ALERT 0x03 -#define DUK_DBG_CMD_LOG 0x04 +#define DUK_DBG_CMD_UNUSED_2 0x02 /* Duktape 1.x: print notify */ +#define DUK_DBG_CMD_UNUSED_3 0x03 /* Duktape 1.x: alert notify */ +#define DUK_DBG_CMD_UNUSED_4 0x04 /* Duktape 1.x: log notify */ #define DUK_DBG_CMD_THROW 0x05 #define DUK_DBG_CMD_DETACHING 0x06 #define DUK_DBG_CMD_APPNOTIFY 0x07 @@ -7348,7 +8105,8 @@ DUK_INTERNAL_DECL duk_uint32_t duk_heap_hashstring(duk_heap *heap, const duk_uin /* The low 8 bits map directly to duk_hobject.h DUK_PROPDESC_FLAG_xxx. * The remaining flags are specific to the debugger. */ -#define DUK_DBG_PROPFLAG_INTERNAL (1 << 8) +#define DUK_DBG_PROPFLAG_SYMBOL (1 << 8) +#define DUK_DBG_PROPFLAG_HIDDEN (1 << 9) #if defined(DUK_USE_DEBUGGER_SUPPORT) DUK_INTERNAL_DECL void duk_debug_do_detach(duk_heap *heap); @@ -7417,7 +8175,7 @@ DUK_INTERNAL_DECL duk_bool_t duk_debug_remove_breakpoint(duk_hthread *thr, duk_s #endif #endif /* DUK_DEBUGGER_H_INCLUDED */ -#line 1 "duk_debug.h" +/* #include duk_debug.h */ /* * Debugging macros, DUK_DPRINT() and its variants in particular. * @@ -7440,24 +8198,24 @@ DUK_INTERNAL_DECL duk_bool_t duk_debug_remove_breakpoint(duk_hthread *thr, duk_s * works poorly with threading. */ -#ifndef DUK_DEBUG_H_INCLUDED +#if !defined(DUK_DEBUG_H_INCLUDED) #define DUK_DEBUG_H_INCLUDED -#ifdef DUK_USE_DEBUG +#if defined(DUK_USE_DEBUG) -#if defined(DUK_USE_DPRINT) +#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 0) #define DUK_D(x) x #else #define DUK_D(x) do { } while (0) /* omit */ #endif -#if defined(DUK_USE_DDPRINT) +#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 1) #define DUK_DD(x) x #else #define DUK_DD(x) do { } while (0) /* omit */ #endif -#if defined(DUK_USE_DDDPRINT) +#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2) #define DUK_DDD(x) x #else #define DUK_DDD(x) do { } while (0) /* omit */ @@ -7467,26 +8225,26 @@ DUK_INTERNAL_DECL duk_bool_t duk_debug_remove_breakpoint(duk_hthread *thr, duk_s * Exposed debug macros: debugging enabled */ -#define DUK_LEVEL_DEBUG 1 -#define DUK_LEVEL_DDEBUG 2 -#define DUK_LEVEL_DDDEBUG 3 - -#ifdef DUK_USE_VARIADIC_MACROS +#if defined(DUK_USE_VARIADIC_MACROS) /* Note: combining __FILE__, __LINE__, and __func__ into fmt would be * possible compile time, but waste some space with shared function names. */ -#define DUK__DEBUG_LOG(lev,...) duk_debug_log((duk_small_int_t) (lev), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, DUK_FUNC_MACRO, __VA_ARGS__); +#define DUK__DEBUG_LOG(lev,...) duk_debug_log((duk_int_t) (lev), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, DUK_FUNC_MACRO, __VA_ARGS__); +#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 0) #define DUK_DPRINT(...) DUK__DEBUG_LOG(DUK_LEVEL_DEBUG, __VA_ARGS__) +#else +#define DUK_DPRINT(...) +#endif -#ifdef DUK_USE_DDPRINT +#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 1) #define DUK_DDPRINT(...) DUK__DEBUG_LOG(DUK_LEVEL_DDEBUG, __VA_ARGS__) #else #define DUK_DDPRINT(...) #endif -#ifdef DUK_USE_DDDPRINT +#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2) #define DUK_DDDPRINT(...) DUK__DEBUG_LOG(DUK_LEVEL_DDDEBUG, __VA_ARGS__) #else #define DUK_DDDPRINT(...) @@ -7496,11 +8254,10 @@ DUK_INTERNAL_DECL duk_bool_t duk_debug_remove_breakpoint(duk_hthread *thr, duk_s #define DUK__DEBUG_STASH(lev) \ (void) DUK_SNPRINTF(duk_debug_file_stash, DUK_DEBUG_STASH_SIZE, "%s", (const char *) DUK_FILE_MACRO), \ - duk_debug_file_stash[DUK_DEBUG_STASH_SIZE - 1] = (char) 0; \ - (void) DUK_SNPRINTF(duk_debug_line_stash, DUK_DEBUG_STASH_SIZE, "%ld", (long) DUK_LINE_MACRO), \ - duk_debug_line_stash[DUK_DEBUG_STASH_SIZE - 1] = (char) 0; \ + (void) (duk_debug_file_stash[DUK_DEBUG_STASH_SIZE - 1] = (char) 0), \ + (void) (duk_debug_line_stash = (duk_int_t) DUK_LINE_MACRO), \ (void) DUK_SNPRINTF(duk_debug_func_stash, DUK_DEBUG_STASH_SIZE, "%s", (const char *) DUK_FUNC_MACRO), \ - duk_debug_func_stash[DUK_DEBUG_STASH_SIZE - 1] = (char) 0; \ + (void) (duk_debug_func_stash[DUK_DEBUG_STASH_SIZE - 1] = (char) 0), \ (void) (duk_debug_level_stash = (lev)) /* Without variadic macros resort to comma expression trickery to handle debug @@ -7509,19 +8266,19 @@ DUK_INTERNAL_DECL duk_bool_t duk_debug_remove_breakpoint(duk_hthread *thr, duk_s * statement from the compiler. */ -#ifdef DUK_USE_DPRINT +#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 0) #define DUK_DPRINT DUK__DEBUG_STASH(DUK_LEVEL_DEBUG), (void) duk_debug_log /* args go here in parens */ #else #define DUK_DPRINT 0 && /* args go here as a comma expression in parens */ #endif -#ifdef DUK_USE_DDPRINT +#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 1) #define DUK_DDPRINT DUK__DEBUG_STASH(DUK_LEVEL_DDEBUG), (void) duk_debug_log /* args go here in parens */ #else #define DUK_DDPRINT 0 && /* args */ #endif -#ifdef DUK_USE_DDDPRINT +#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2) #define DUK_DDDPRINT DUK__DEBUG_STASH(DUK_LEVEL_DDDEBUG), (void) duk_debug_log /* args go here in parens */ #else #define DUK_DDDPRINT 0 && /* args */ @@ -7539,7 +8296,7 @@ DUK_INTERNAL_DECL duk_bool_t duk_debug_remove_breakpoint(duk_hthread *thr, duk_s #define DUK_DD(x) do { } while (0) /* omit */ #define DUK_DDD(x) do { } while (0) /* omit */ -#ifdef DUK_USE_VARIADIC_MACROS +#if defined(DUK_USE_VARIADIC_MACROS) #define DUK_DPRINT(...) #define DUK_DDPRINT(...) @@ -7559,7 +8316,7 @@ DUK_INTERNAL_DECL duk_bool_t duk_debug_remove_breakpoint(duk_hthread *thr, duk_s * Structs */ -#ifdef DUK_USE_DEBUG +#if defined(DUK_USE_DEBUG) struct duk_fixedbuffer { duk_uint8_t *buffer; duk_size_t length; @@ -7572,23 +8329,23 @@ struct duk_fixedbuffer { * Prototypes */ -#ifdef DUK_USE_DEBUG +#if defined(DUK_USE_DEBUG) DUK_INTERNAL_DECL duk_int_t duk_debug_vsnprintf(char *str, duk_size_t size, const char *format, va_list ap); #if 0 /*unused*/ DUK_INTERNAL_DECL duk_int_t duk_debug_snprintf(char *str, duk_size_t size, const char *format, ...); #endif DUK_INTERNAL_DECL void duk_debug_format_funcptr(char *buf, duk_size_t buf_size, duk_uint8_t *fptr, duk_size_t fptr_size); -#ifdef DUK_USE_VARIADIC_MACROS -DUK_INTERNAL_DECL void duk_debug_log(duk_small_int_t level, const char *file, duk_int_t line, const char *func, const char *fmt, ...); +#if defined(DUK_USE_VARIADIC_MACROS) +DUK_INTERNAL_DECL void duk_debug_log(duk_int_t level, const char *file, duk_int_t line, const char *func, const char *fmt, ...); #else /* DUK_USE_VARIADIC_MACROS */ /* parameter passing, not thread safe */ #define DUK_DEBUG_STASH_SIZE 128 #if !defined(DUK_SINGLE_FILE) DUK_INTERNAL_DECL char duk_debug_file_stash[DUK_DEBUG_STASH_SIZE]; -DUK_INTERNAL_DECL char duk_debug_line_stash[DUK_DEBUG_STASH_SIZE]; +DUK_INTERNAL_DECL duk_int_t duk_debug_line_stash; DUK_INTERNAL_DECL char duk_debug_func_stash[DUK_DEBUG_STASH_SIZE]; -DUK_INTERNAL_DECL duk_small_int_t duk_debug_level_stash; +DUK_INTERNAL_DECL duk_int_t duk_debug_level_stash; #endif DUK_INTERNAL_DECL void duk_debug_log(const char *fmt, ...); #endif /* DUK_USE_VARIADIC_MACROS */ @@ -7603,22 +8360,23 @@ DUK_INTERNAL_DECL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb); #endif /* DUK_USE_DEBUG */ #endif /* DUK_DEBUG_H_INCLUDED */ -#line 1 "duk_error.h" +/* #include duk_error.h */ /* * Error handling macros, assertion macro, error codes. * - * There are three level of 'errors': + * There are three types of 'errors': * - * 1. Ordinary errors, relative to a thread, cause a longjmp, catchable. - * 2. Fatal errors, relative to a heap, cause fatal handler to be called. - * 3. Panic errors, unrelated to a heap and cause a process exit. + * 1. Ordinary errors relative to a thread, cause a longjmp, catchable. + * 2. Fatal errors relative to a heap, cause fatal handler to be called. + * 3. Fatal errors without context, cause the default (not heap specific) + * fatal handler to be called. * - * Panics are used by the default fatal error handler and by debug code - * such as assertions. By providing a proper fatal error handler, user - * code can avoid panics in non-debug builds. + * Fatal errors without context are used by debug code such as assertions. + * By providing a fatal error handler for a Duktape heap, user code can + * avoid fatal errors without context in non-debug builds. */ -#ifndef DUK_ERROR_H_INCLUDED +#if !defined(DUK_ERROR_H_INCLUDED) #define DUK_ERROR_H_INCLUDED /* @@ -7733,66 +8491,231 @@ DUK_INTERNAL_DECL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb); #endif /* DUK_USE_VERBOSE_ERRORS */ /* - * Fatal error + * Fatal error without context * - * There are no fatal error macros at the moment. There are so few call - * sites that the fatal error handler is called directly. + * The macro is an expression to make it compatible with DUK_ASSERT_EXPR(). */ +#define DUK_FATAL_WITHOUT_CONTEXT(msg) \ + duk_default_fatal_handler(NULL, (msg)) + /* - * Panic error + * Error throwing helpers * - * Panic errors are not relative to either a heap or a thread, and cause - * DUK_PANIC() macro to be invoked. Unless a user provides DUK_USE_PANIC_HANDLER, - * DUK_PANIC() calls a helper which prints out the error and causes a process - * exit. + * The goal is to provide verbose and configurable error messages. Call + * sites should be clean in source code and compile to a small footprint. + * Small footprint is also useful for performance because small cold paths + * reduce code cache pressure. Adding macros here only makes sense if there + * are enough call sites to get concrete benefits. * - * The user can override the macro to provide custom handling. A macro is - * used to allow the user to have inline panic handling if desired (without - * causing a potentially risky function call). + * DUK_ERROR_xxx() macros are generic and can be used anywhere. * - * Panics are only used in debug code such as assertions, and by the default - * fatal error handler. + * DUK_DCERROR_xxx() macros can only be used in Duktape/C functions where + * the "return DUK_RET_xxx;" shorthand is available for low memory targets. + * The DUK_DCERROR_xxx() macros always either throw or perform a + * 'return DUK_RET_xxx' from the calling function. */ -#if defined(DUK_USE_PANIC_HANDLER) -/* already defined, good */ -#define DUK_PANIC(code,msg) DUK_USE_PANIC_HANDLER((code),(msg)) -#else -#define DUK_PANIC(code,msg) duk_default_panic_handler((code),(msg)) -#endif /* DUK_USE_PANIC_HANDLER */ +#if defined(DUK_USE_VERBOSE_ERRORS) +/* Verbose errors with key/value summaries (non-paranoid) or without key/value + * summaries (paranoid, for some security sensitive environments), the paranoid + * vs. non-paranoid distinction affects only a few specific errors. + */ +#if defined(DUK_USE_PARANOID_ERRORS) +#define DUK_ERROR_REQUIRE_TYPE_INDEX(thr,idx,expectname,lowmemstr) do { \ + duk_err_require_type_index((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (idx), (expectname)); \ + } while (0) +#else /* DUK_USE_PARANOID_ERRORS */ +#define DUK_ERROR_REQUIRE_TYPE_INDEX(thr,idx,expectname,lowmemstr) do { \ + duk_err_require_type_index((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (idx), (expectname)); \ + } while (0) +#endif /* DUK_USE_PARANOID_ERRORS */ + +#define DUK_ERROR_INTERNAL(thr) do { \ + duk_err_error_internal((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \ + } while (0) +#define DUK_ERROR_ALLOC_FAILED(thr) do { \ + duk_err_error_alloc_failed((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \ + } while (0) +#define DUK_ERROR_UNSUPPORTED(thr) do { \ + DUK_ERROR((thr), DUK_ERR_ERROR, DUK_STR_UNSUPPORTED); \ + } while (0) +#define DUK_ERROR_ERROR(thr,msg) do { \ + duk_err_error((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (msg)); \ + } while (0) +#define DUK_ERROR_RANGE_INDEX(thr,idx) do { \ + duk_err_range_index((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (idx)); \ + } while (0) +#define DUK_ERROR_RANGE_PUSH_BEYOND(thr) do { \ + duk_err_range_push_beyond((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \ + } while (0) +#define DUK_ERROR_RANGE_INVALID_ARGS(thr) do { \ + DUK_ERROR_RANGE((thr), DUK_STR_INVALID_ARGS); \ + } while (0) +#define DUK_DCERROR_RANGE_INVALID_ARGS(thr) do { \ + DUK_ERROR_RANGE_INVALID_ARGS((thr)); \ + return 0; \ + } while (0) +#define DUK_ERROR_RANGE_INVALID_COUNT(thr) do { \ + DUK_ERROR_RANGE((thr), DUK_STR_INVALID_COUNT); \ + } while (0) +#define DUK_ERROR_RANGE_INVALID_LENGTH(thr) do { \ + DUK_ERROR_RANGE((thr), DUK_STR_INVALID_LENGTH); \ + } while (0) +#define DUK_DCERROR_RANGE_INVALID_LENGTH(thr) do { \ + DUK_ERROR_RANGE_INVALID_LENGTH((thr)); \ + return 0; \ + } while (0) +#define DUK_ERROR_RANGE(thr,msg) do { \ + duk_err_range((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (msg)); \ + } while (0) +#define DUK_ERROR_EVAL(thr,msg) do { \ + DUK_ERROR((thr), DUK_ERR_EVAL_ERROR, (msg)); \ + } while (0) +#define DUK_ERROR_REFERENCE(thr,msg) do { \ + DUK_ERROR((thr), DUK_ERR_REFERENCE_ERROR, (msg)); \ + } while (0) +#define DUK_ERROR_SYNTAX(thr,msg) do { \ + DUK_ERROR((thr), DUK_ERR_SYNTAX_ERROR, (msg)); \ + } while (0) +#define DUK_ERROR_TYPE_INVALID_ARGS(thr) do { \ + duk_err_type_invalid_args((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \ + } while (0) +#define DUK_DCERROR_TYPE_INVALID_ARGS(thr) do { \ + DUK_ERROR_TYPE_INVALID_ARGS((thr)); \ + return 0; \ + } while (0) +#define DUK_ERROR_TYPE_INVALID_STATE(thr) do { \ + duk_err_type_invalid_state((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \ + } while (0) +#define DUK_DCERROR_TYPE_INVALID_STATE(thr) do { \ + DUK_ERROR_TYPE_INVALID_STATE((thr)); \ + return 0; \ + } while (0) +#define DUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \ + duk_err_type_invalid_trap_result((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \ + } while (0) +#define DUK_DCERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \ + DUK_ERROR_TYPE((thr), DUK_STR_INVALID_TRAP_RESULT); \ + } while (0) +#define DUK_ERROR_TYPE(thr,msg) do { \ + DUK_ERROR((thr), DUK_ERR_TYPE_ERROR, (msg)); \ + } while (0) +#define DUK_ERROR_URI(thr,msg) do { \ + DUK_ERROR((thr), DUK_ERR_URI_ERROR, (msg)); \ + } while (0) +#else /* DUK_USE_VERBOSE_ERRORS */ +/* Non-verbose errors for low memory targets: no file, line, or message. */ + +#define DUK_ERROR_REQUIRE_TYPE_INDEX(thr,idx,expectname,lowmemstr) do { \ + duk_err_type((thr)); \ + } while (0) + +#define DUK_ERROR_INTERNAL(thr) do { \ + duk_err_error((thr)); \ + } while (0) +#define DUK_ERROR_ALLOC_FAILED(thr) do { \ + duk_err_error((thr)); \ + } while (0) +#define DUK_ERROR_UNSUPPORTED(thr) do { \ + duk_err_error((thr)); \ + } while (0) +#define DUK_ERROR_ERROR(thr,msg) do { \ + duk_err_error((thr)); \ + } while (0) +#define DUK_ERROR_RANGE_INDEX(thr,idx) do { \ + duk_err_range((thr)); \ + } while (0) +#define DUK_ERROR_RANGE_PUSH_BEYOND(thr) do { \ + duk_err_range((thr)); \ + } while (0) +#define DUK_ERROR_RANGE_INVALID_ARGS(thr) do { \ + duk_err_range((thr)); \ + } while (0) +#define DUK_DCERROR_RANGE_INVALID_ARGS(thr) do { \ + DUK_UNREF((thr)); \ + return DUK_RET_RANGE_ERROR; \ + } while (0) +#define DUK_ERROR_RANGE_INVALID_COUNT(thr) do { \ + duk_err_range((thr)); \ + } while (0) +#define DUK_ERROR_RANGE_INVALID_LENGTH(thr) do { \ + duk_err_range((thr)); \ + } while (0) +#define DUK_DCERROR_RANGE_INVALID_LENGTH(thr) do { \ + DUK_UNREF((thr)); \ + return DUK_RET_RANGE_ERROR; \ + } while (0) +#define DUK_ERROR_RANGE(thr,msg) do { \ + duk_err_range((thr)); \ + } while (0) +#define DUK_ERROR_EVAL(thr,msg) do { \ + duk_err_eval((thr)); \ + } while (0) +#define DUK_ERROR_REFERENCE(thr,msg) do { \ + duk_err_reference((thr)); \ + } while (0) +#define DUK_ERROR_SYNTAX(thr,msg) do { \ + duk_err_syntax((thr)); \ + } while (0) +#define DUK_ERROR_TYPE_INVALID_ARGS(thr) do { \ + duk_err_type((thr)); \ + } while (0) +#define DUK_DCERROR_TYPE_INVALID_ARGS(thr) do { \ + DUK_UNREF((thr)); \ + return DUK_RET_TYPE_ERROR; \ + } while (0) +#define DUK_ERROR_TYPE_INVALID_STATE(thr) do { \ + duk_err_type((thr)); \ + } while (0) +#define DUK_DCERROR_TYPE_INVALID_STATE(thr) do { \ + duk_err_type((thr)); \ + } while (0) +#define DUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \ + duk_err_type((thr)); \ + } while (0) +#define DUK_DCERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \ + DUK_UNREF((thr)); \ + return DUK_RET_TYPE_ERROR; \ + } while (0) +#define DUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \ + duk_err_type((thr)); \ + } while (0) +#define DUK_ERROR_TYPE(thr,msg) do { \ + duk_err_type((thr)); \ + } while (0) +#define DUK_ERROR_URI(thr,msg) do { \ + duk_err_uri((thr)); \ + } while (0) +#endif /* DUK_USE_VERBOSE_ERRORS */ /* - * Assert macro: failure causes panic. + * Assert macro: failure causes a fatal error. + * + * NOTE: since the assert macro doesn't take a heap/context argument, there's + * no way to look up a heap/context specific fatal error handler which may have + * been given by the application. Instead, assertion failures always use the + * internal default fatal error handler; it can be replaced via duk_config.h + * and then applies to all Duktape heaps. */ #if defined(DUK_USE_ASSERTIONS) -/* the message should be a compile time constant without formatting (less risk); +/* The message should be a compile time constant without formatting (less risk); * we don't care about assertion text size because they're not used in production * builds. */ #define DUK_ASSERT(x) do { \ if (!(x)) { \ - DUK_PANIC(DUK_ERR_ASSERTION_ERROR, \ - "assertion failed: " #x \ + DUK_FATAL_WITHOUT_CONTEXT("assertion failed: " #x \ " (" DUK_FILE_MACRO ":" DUK_MACRO_STRINGIFY(DUK_LINE_MACRO) ")"); \ } \ } while (0) -/* Assertion compatible inside a comma expression, evaluates to void. - * Currently not compatible with DUK_USE_PANIC_HANDLER() which may have - * a statement block. - */ -#if defined(DUK_USE_PANIC_HANDLER) -/* XXX: resolve macro definition issue or call through a helper function? */ -#define DUK_ASSERT_EXPR(x) ((void) 0) -#else +/* Assertion compatible inside a comma expression, evaluates to void. */ #define DUK_ASSERT_EXPR(x) \ - ((void) ((x) ? 0 : (DUK_PANIC(DUK_ERR_ASSERTION_ERROR, \ - "assertion failed: " #x \ + ((void) ((x) ? 0 : (DUK_FATAL_WITHOUT_CONTEXT("assertion failed: " #x \ " (" DUK_FILE_MACRO ":" DUK_MACRO_STRINGIFY(DUK_LINE_MACRO) ")"), 0))) -#endif #else /* DUK_USE_ASSERTIONS */ @@ -7837,6 +8760,9 @@ DUK_INTERNAL_DECL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb); #define DUK_ASSERT_DOUBLE_IS_NORMALIZED(dval) /* nop */ #endif +#define DUK_ASSERT_VS_SPACE(thr) \ + DUK_ASSERT(thr->valstack_top < thr->valstack_end) + /* * Helper for valstack space * @@ -7858,126 +8784,6 @@ DUK_INTERNAL_DECL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb); #endif /* - * Error throwing helpers - * - * The goal is to provide verbose and configurable error messages. Call - * sites should be clean in source code and compile to a small footprint. - * Small footprint is also useful for performance because small cold paths - * reduce code cache pressure. Adding macros here only makes sense if there - * are enough call sites to get concrete benefits. - */ - -#if defined(DUK_USE_VERBOSE_ERRORS) -/* Verbose errors with key/value summaries (non-paranoid) or without key/value - * summaries (paranoid, for some security sensitive environments), the paranoid - * vs. non-paranoid distinction affects only a few specific errors. - */ -#if defined(DUK_USE_PARANOID_ERRORS) -#define DUK_ERROR_REQUIRE_TYPE_INDEX(thr,index,expectname,lowmemstr) do { \ - duk_err_require_type_index((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (index), (expectname)); \ - } while (0) -#else /* DUK_USE_PARANOID_ERRORS */ -#define DUK_ERROR_REQUIRE_TYPE_INDEX(thr,index,expectname,lowmemstr) do { \ - duk_err_require_type_index((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (index), (expectname)); \ - } while (0) -#endif /* DUK_USE_PARANOID_ERRORS */ - -#define DUK_ERROR_UNIMPLEMENTED(thr,msg) do { \ - DUK_ERROR((thr), DUK_ERR_UNIMPLEMENTED_ERROR, (msg)); \ - } while (0) -#define DUK_ERROR_UNIMPLEMENTED_DEFMSG(thr) do { \ - duk_err_unimplemented_defmsg((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \ - } while (0) -#define DUK_ERROR_UNSUPPORTED(thr,msg) do { \ - DUK_ERROR((thr), DUK_ERR_UNSUPPORTED_ERROR, (msg)); \ - } while (0) -#if !defined(DUK_USE_BYTECODE_DUMP_SUPPORT) -#define DUK_ERROR_UNSUPPORTED_DEFMSG(thr) do { \ - duk_err_unsupported_defmsg((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \ - } while (0) -#endif -#define DUK_ERROR_INTERNAL(thr,msg) do { \ - duk_err_internal((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (msg)); \ - } while (0) -#define DUK_ERROR_INTERNAL_DEFMSG(thr) do { \ - duk_err_internal_defmsg((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \ - } while (0) -#define DUK_ERROR_ALLOC(thr,msg) do { \ - duk_err_alloc((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (msg)); \ - } while (0) -#define DUK_ERROR_ALLOC_DEFMSG(thr) do { \ - DUK_ERROR_ALLOC((thr), DUK_STR_ALLOC_FAILED); \ - } while (0) -/* DUK_ERR_ASSERTION_ERROR: no macros needed */ -#define DUK_ERROR_API_INDEX(thr,index) do { \ - duk_err_api_index((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (index)); \ - } while (0) -#define DUK_ERROR_API(thr,msg) do { \ - duk_err_api((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (msg)); \ - } while (0) -/* DUK_ERR_UNCAUGHT_ERROR: no macros needed */ -/* DUK_ERR_ERROR: no macros needed */ -/* DUK_ERR_EVAL: no macros needed */ -#define DUK_ERROR_RANGE(thr,msg) do { \ - duk_err_range((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (msg)); \ - } while (0) -/* DUK_ERR_REFERENCE_ERROR: no macros needed */ -#define DUK_ERROR_SYNTAX(thr,msg) do { \ - DUK_ERROR((thr), DUK_ERR_SYNTAX_ERROR, (msg)); \ - } while (0) -#define DUK_ERROR_TYPE(thr,msg) do { \ - DUK_ERROR((thr), DUK_ERR_TYPE_ERROR, (msg)); \ - } while (0) -/* DUK_ERR_URI_ERROR: no macros needed */ -#else /* DUK_USE_VERBOSE_ERRORS */ -/* Non-verbose errors for low memory targets: no file, line, or message. */ - -#define DUK_ERROR_REQUIRE_TYPE_INDEX(thr,index,expectname,lowmemstr) do { \ - duk_err_type((thr)); \ - } while (0) - -#define DUK_ERROR_UNIMPLEMENTED(thr,msg) do { \ - duk_err_unimplemented((thr)); \ - } while (0) -#define DUK_ERROR_UNIMPLEMENTED_DEFMSG(thr) do { \ - duk_err_unimplemented((thr)); \ - } while (0) -#define DUK_ERROR_UNSUPPORTED(thr,msg) do { \ - duk_err_unsupported((thr)); \ - } while (0) -#define DUK_ERROR_UNSUPPORTED_DEFMSG(thr) do { \ - duk_err_unsupported((thr)); \ - } while (0) -#define DUK_ERROR_INTERNAL(thr,msg) do { \ - duk_err_internal((thr)); \ - } while (0) -#define DUK_ERROR_INTERNAL_DEFMSG(thr) do { \ - duk_err_internal((thr)); \ - } while (0) -#define DUK_ERROR_ALLOC(thr,msg) do { \ - duk_err_alloc((thr)); \ - } while (0) -#define DUK_ERROR_ALLOC_DEFMSG(thr) do { \ - duk_err_alloc((thr)); \ - } while (0) -#define DUK_ERROR_API_INDEX(thr,index) do { \ - duk_err_api((thr)); \ - } while (0) -#define DUK_ERROR_API(thr,msg) do { \ - duk_err_api((thr)); \ - } while (0) -#define DUK_ERROR_RANGE(thr,msg) do { \ - duk_err_range((thr)); \ - } while (0) -#define DUK_ERROR_SYNTAX(thr,msg) do { \ - duk_err_syntax((thr)); \ - } while (0) -#define DUK_ERROR_TYPE(thr,msg) do { \ - duk_err_type((thr)); \ - } while (0) -#endif /* DUK_USE_VERBOSE_ERRORS */ - -/* * Prototypes */ @@ -8005,50 +8811,44 @@ DUK_INTERNAL_DECL void duk_err_augment_error_throw(duk_hthread *thr); #if defined(DUK_USE_VERBOSE_ERRORS) #if defined(DUK_USE_PARANOID_ERRORS) -DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t index, const char *expect_name)); +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx, const char *expect_name)); #else -DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t index, const char *expect_name)); +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx, const char *expect_name)); #endif -DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_api_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t index)); -DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_api(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message)); +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_error_internal(duk_hthread *thr, const char *filename, duk_int_t linenumber)); +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_error_alloc_failed(duk_hthread *thr, const char *filename, duk_int_t linenumber)); +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_error(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message)); +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx)); +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range_push_beyond(duk_hthread *thr, const char *filename, duk_int_t linenumber)); DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message)); -DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_unimplemented_defmsg(duk_hthread *thr, const char *filename, duk_int_t linenumber)); -#if !defined(DUK_USE_BYTECODE_DUMP_SUPPORT) -DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_unsupported_defmsg(duk_hthread *thr, const char *filename, duk_int_t linenumber)); -#endif -DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_internal_defmsg(duk_hthread *thr, const char *filename, duk_int_t linenumber)); -DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_internal(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message)); -DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_alloc(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message)); +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_type_invalid_args(duk_hthread *thr, const char *filename, duk_int_t linenumber)); +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_type_invalid_state(duk_hthread *thr, const char *filename, duk_int_t linenumber)); +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_type_invalid_trap_result(duk_hthread *thr, const char *filename, duk_int_t linenumber)); #else /* DUK_VERBOSE_ERRORS */ +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_error(duk_hthread *thr)); DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range(duk_hthread *thr)); +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_eval(duk_hthread *thr)); +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_reference(duk_hthread *thr)); DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_syntax(duk_hthread *thr)); DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_type(duk_hthread *thr)); -DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_api(duk_hthread *thr)); -DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_unimplemented(duk_hthread *thr)); -DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_unsupported(duk_hthread *thr)); -DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_internal(duk_hthread *thr)); -DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_alloc(duk_hthread *thr)); +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_uri(duk_hthread *thr)); #endif /* DUK_VERBOSE_ERRORS */ DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_longjmp(duk_hthread *thr)); -DUK_NORETURN(DUK_INTERNAL_DECL void duk_default_fatal_handler(duk_context *ctx, duk_errcode_t code, const char *msg)); - -#if !defined(DUK_USE_PANIC_HANDLER) -DUK_NORETURN(DUK_INTERNAL_DECL void duk_default_panic_handler(duk_errcode_t code, const char *msg)); -#endif +DUK_NORETURN(DUK_INTERNAL_DECL void duk_default_fatal_handler(void *udata, const char *msg)); DUK_INTERNAL_DECL void duk_err_setup_heap_ljstate(duk_hthread *thr, duk_small_int_t lj_type); DUK_INTERNAL_DECL duk_hobject *duk_error_prototype_from_code(duk_hthread *thr, duk_errcode_t err_code); #endif /* DUK_ERROR_H_INCLUDED */ -#line 1 "duk_unicode.h" +/* #include duk_unicode.h */ /* * Unicode helpers */ -#ifndef DUK_UNICODE_H_INCLUDED +#if !defined(DUK_UNICODE_H_INCLUDED) #define DUK_UNICODE_H_INCLUDED /* @@ -8212,24 +9012,33 @@ DUK_INTERNAL_DECL duk_hobject *duk_error_prototype_from_code(duk_hthread *thr, d #define DUK_ASC_DEL 0x7f /* + * Miscellaneous + */ + +/* Uppercase A is 0x41, lowercase a is 0x61; OR 0x20 to convert uppercase + * to lowercase. + */ +#define DUK_LOWERCASE_CHAR_ASCII(x) ((x) | 0x20) + +/* * Unicode tables */ -#ifdef DUK_USE_SOURCE_NONBMP +#if defined(DUK_USE_SOURCE_NONBMP) /* * Automatically generated by extract_chars.py, do not edit! */ -extern const duk_uint8_t duk_unicode_ids_noa[791]; +extern const duk_uint8_t duk_unicode_ids_noa[1036]; #else /* * Automatically generated by extract_chars.py, do not edit! */ -extern const duk_uint8_t duk_unicode_ids_noabmp[611]; +extern const duk_uint8_t duk_unicode_ids_noabmp[625]; #endif -#ifdef DUK_USE_SOURCE_NONBMP +#if defined(DUK_USE_SOURCE_NONBMP) /* * Automatically generated by extract_chars.py, do not edit! */ @@ -8243,26 +9052,26 @@ extern const duk_uint8_t duk_unicode_ids_m_let_noa[42]; extern const duk_uint8_t duk_unicode_ids_m_let_noabmp[24]; #endif -#ifdef DUK_USE_SOURCE_NONBMP +#if defined(DUK_USE_SOURCE_NONBMP) /* * Automatically generated by extract_chars.py, do not edit! */ -extern const duk_uint8_t duk_unicode_idp_m_ids_noa[397]; +extern const duk_uint8_t duk_unicode_idp_m_ids_noa[530]; #else /* * Automatically generated by extract_chars.py, do not edit! */ -extern const duk_uint8_t duk_unicode_idp_m_ids_noabmp[348]; +extern const duk_uint8_t duk_unicode_idp_m_ids_noabmp[357]; #endif /* * Automatically generated by extract_caseconv.py, do not edit! */ -extern const duk_uint8_t duk_unicode_caseconv_uc[1288]; -extern const duk_uint8_t duk_unicode_caseconv_lc[616]; +extern const duk_uint8_t duk_unicode_caseconv_uc[1386]; +extern const duk_uint8_t duk_unicode_caseconv_lc[680]; #if defined(DUK_USE_REGEXP_CANON_WORKAROUND) /* @@ -8307,16 +9116,18 @@ DUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_identifier_start(duk_codepoint_ DUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_identifier_part(duk_codepoint_t cp); DUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_letter(duk_codepoint_t cp); DUK_INTERNAL_DECL void duk_unicode_case_convert_string(duk_hthread *thr, duk_bool_t uppercase); +#if defined(DUK_USE_REGEXP_SUPPORT) DUK_INTERNAL_DECL duk_codepoint_t duk_unicode_re_canonicalize_char(duk_hthread *thr, duk_codepoint_t cp); DUK_INTERNAL_DECL duk_small_int_t duk_unicode_re_is_wordchar(duk_codepoint_t cp); +#endif #endif /* DUK_UNICODE_H_INCLUDED */ -#line 1 "duk_json.h" +/* #include duk_json.h */ /* * Defines for JSON, especially duk_bi_json.c. */ -#ifndef DUK_JSON_H_INCLUDED +#if !defined(DUK_JSON_H_INCLUDED) #define DUK_JSON_H_INCLUDED /* Encoding/decoding flags */ @@ -8380,12 +9191,12 @@ typedef struct { } duk_json_dec_ctx; #endif /* DUK_JSON_H_INCLUDED */ -#line 1 "duk_js.h" +/* #include duk_js.h */ /* * Ecmascript execution, support primitives. */ -#ifndef DUK_JS_H_INCLUDED +#if !defined(DUK_JS_H_INCLUDED) #define DUK_JS_H_INCLUDED /* Flags for call handling. */ @@ -8400,8 +9211,8 @@ typedef struct { #define DUK_EQUALS_FLAG_STRICT (1 << 1) /* use strict equality instead of non-strict equality */ /* Flags for duk_js_compare_helper(). */ -#define DUK_COMPARE_FLAG_EVAL_LEFT_FIRST (1 << 0) /* eval left argument first */ -#define DUK_COMPARE_FLAG_NEGATE (1 << 1) /* negate result */ +#define DUK_COMPARE_FLAG_NEGATE (1 << 0) /* negate result */ +#define DUK_COMPARE_FLAG_EVAL_LEFT_FIRST (1 << 1) /* eval left argument first */ /* conversions, coercions, comparison, etc */ DUK_INTERNAL_DECL duk_bool_t duk_js_toboolean(duk_tval *tv); @@ -8422,7 +9233,11 @@ DUK_INTERNAL_DECL duk_small_int_t duk_js_buffer_compare(duk_heap *heap, duk_hbuf DUK_INTERNAL_DECL duk_bool_t duk_js_compare_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_int_t flags); DUK_INTERNAL_DECL duk_bool_t duk_js_instanceof(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y); DUK_INTERNAL_DECL duk_bool_t duk_js_in(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y); -DUK_INTERNAL_DECL duk_hstring *duk_js_typeof(duk_hthread *thr, duk_tval *tv_x); +DUK_INTERNAL_DECL duk_small_uint_t duk_js_typeof_stridx(duk_tval *tv_x); + +/* arithmetic */ +DUK_INTERNAL_DECL double duk_js_arith_pow(double x, double y); +DUK_INTERNAL_DECL double duk_js_arith_mod(double x, double y); #define duk_js_equals(thr,tv_x,tv_y) \ duk_js_equals_helper((thr), (tv_x), (tv_y), 0) @@ -8465,7 +9280,7 @@ DUK_INTERNAL_DECL void duk_js_close_environment_record(duk_hthread *thr, duk_hob DUK_INTERNAL_DECL duk_hobject *duk_create_activation_environment_record(duk_hthread *thr, duk_hobject *func, duk_size_t idx_bottom); DUK_INTERNAL_DECL void duk_js_push_closure(duk_hthread *thr, - duk_hcompiledfunction *fun_temp, + duk_hcompfunc *fun_temp, duk_hobject *outer_var_env, duk_hobject *outer_lex_env, duk_bool_t add_auto_proto); @@ -8473,22 +9288,22 @@ void duk_js_push_closure(duk_hthread *thr, /* call handling */ DUK_INTERNAL_DECL duk_int_t duk_handle_call_protected(duk_hthread *thr, duk_idx_t num_stack_args, duk_small_uint_t call_flags); DUK_INTERNAL_DECL void duk_handle_call_unprotected(duk_hthread *thr, duk_idx_t num_stack_args, duk_small_uint_t call_flags); -DUK_INTERNAL_DECL duk_int_t duk_handle_safe_call(duk_hthread *thr, duk_safe_call_function func, duk_idx_t num_stack_args, duk_idx_t num_stack_res); +DUK_INTERNAL_DECL duk_int_t duk_handle_safe_call(duk_hthread *thr, duk_safe_call_function func, void *udata, duk_idx_t num_stack_args, duk_idx_t num_stack_res); DUK_INTERNAL_DECL duk_bool_t duk_handle_ecma_call_setup(duk_hthread *thr, duk_idx_t num_stack_args, duk_small_uint_t call_flags); /* bytecode execution */ DUK_INTERNAL_DECL void duk_js_execute_bytecode(duk_hthread *exec_thr); #endif /* DUK_JS_H_INCLUDED */ -#line 1 "duk_numconv.h" -#ifndef DUK_NUMCONV_H_INCLUDED -#define DUK_NUMCONV_H_INCLUDED - +/* #include duk_numconv.h */ /* * Number-to-string conversion. The semantics of these is very tightly * bound with the Ecmascript semantics required for call sites. */ +#if !defined(DUK_NUMCONV_H_INCLUDED) +#define DUK_NUMCONV_H_INCLUDED + /* Output a specified number of digits instead of using the shortest * form. Used for toPrecision() and toFixed(). */ @@ -8558,10 +9373,20 @@ DUK_INTERNAL_DECL void duk_js_execute_bytecode(duk_hthread *exec_thr); */ #define DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT (1 << 11) -/* Allow automatic detection of octal base, overrides radix - * argument and forces integer mode. +/* Allow automatic detection of legacy octal base ("0n"), + * overrides radix argument and forces integer mode. + */ +#define DUK_S2N_FLAG_ALLOW_AUTO_LEGACY_OCT_INT (1 << 12) + +/* Allow automatic detection of ES2015 octal base ("0o123"), + * overrides radix argument and forces integer mode. + */ +#define DUK_S2N_FLAG_ALLOW_AUTO_OCT_INT (1 << 13) + +/* Allow automatic detection of ES2015 binary base ("0b10001"), + * overrides radix argument and forces integer mode. */ -#define DUK_S2N_FLAG_ALLOW_AUTO_OCT_INT (1 << 12) +#define DUK_S2N_FLAG_ALLOW_AUTO_BIN_INT (1 << 14) /* * Prototypes @@ -8571,33 +9396,26 @@ DUK_INTERNAL_DECL void duk_numconv_stringify(duk_context *ctx, duk_small_int_t r DUK_INTERNAL_DECL void duk_numconv_parse(duk_context *ctx, duk_small_int_t radix, duk_small_uint_t flags); #endif /* DUK_NUMCONV_H_INCLUDED */ -#line 1 "duk_bi_protos.h" +/* #include duk_bi_protos.h */ /* * Prototypes for built-in functions not automatically covered by the * header declarations emitted by genbuiltins.py. */ -#ifndef DUK_BUILTIN_PROTOS_H_INCLUDED +#if !defined(DUK_BUILTIN_PROTOS_H_INCLUDED) #define DUK_BUILTIN_PROTOS_H_INCLUDED -/* Buffer size needed for duk_bi_date_format_timeval(). +/* Buffer size needed for ISO 8601 formatting. * Accurate value is 32 + 1 for NUL termination: * >>> len('+123456-01-23T12:34:56.123+12:34') * 32 * Include additional space to be safe. */ -#define DUK_BI_DATE_ISO8601_BUFSIZE 48 - -/* Maximum length of CommonJS module identifier to resolve. Length includes - * both current module ID, requested (possibly relative) module ID, and a - * slash in between. - */ -#define DUK_BI_COMMONJS_MODULE_ID_LIMIT 256 +#define DUK_BI_DATE_ISO8601_BUFSIZE 40 /* Helpers exposed for internal use */ DUK_INTERNAL_DECL 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_INTERNAL_DECL duk_double_t duk_bi_date_get_timeval_from_dparts(duk_double_t *dparts, duk_small_uint_t flags); -DUK_INTERNAL_DECL void duk_bi_date_format_timeval(duk_double_t timeval, duk_uint8_t *out_buf); DUK_INTERNAL_DECL duk_bool_t duk_bi_date_is_leap_year(duk_int_t year); DUK_INTERNAL_DECL duk_bool_t duk_bi_date_timeval_in_valid_range(duk_double_t x); DUK_INTERNAL_DECL duk_bool_t duk_bi_date_year_in_valid_range(duk_double_t year); @@ -8612,7 +9430,7 @@ DUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_time(duk_context *ctx); #if defined(DUK_USE_DATE_NOW_WINDOWS) DUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_windows(duk_context *ctx); #endif -#if defined(DUK_USE_DATE_TZO_GMTIME_R) || defined(DUK_USE_DATE_TZO_GMTIME) +#if defined(DUK_USE_DATE_TZO_GMTIME_R) || defined(DUK_USE_DATE_TZO_GMTIME_S) || defined(DUK_USE_DATE_TZO_GMTIME) DUK_INTERNAL_DECL duk_int_t duk_bi_date_get_local_tzoffset_gmtime(duk_double_t d); #endif #if defined(DUK_USE_DATE_TZO_WINDOWS) @@ -8640,33 +9458,31 @@ void duk_bi_json_stringify_helper(duk_context *ctx, duk_idx_t idx_space, duk_small_uint_t flags); +DUK_INTERNAL_DECL duk_ret_t duk_textdecoder_decode_utf8_nodejs(duk_context *ctx); + +#if defined(DUK_USE_ES6_PROXY) +DUK_INTERNAL_DECL void duk_proxy_ownkeys_postprocess(duk_context *ctx, duk_hobject *h_proxy_target, duk_uint_t flags); +#endif + #endif /* DUK_BUILTIN_PROTOS_H_INCLUDED */ -#line 1 "duk_selftest.h" +/* #include duk_selftest.h */ /* * Selftest code */ -#ifndef DUK_SELFTEST_H_INCLUDED +#if !defined(DUK_SELFTEST_H_INCLUDED) #define DUK_SELFTEST_H_INCLUDED #if defined(DUK_USE_SELF_TESTS) -DUK_INTERNAL_DECL void duk_selftest_run_tests(void); +DUK_INTERNAL_DECL duk_uint_t duk_selftest_run_tests(duk_alloc_function alloc_func, + duk_realloc_function realloc_func, + duk_free_function free_func, + void *udata); #endif #endif /* DUK_SELFTEST_H_INCLUDED */ -#line 78 "duk_internal.h" #endif /* DUK_INTERNAL_H_INCLUDED */ -#line 1 "duk_replacements.c" -/* - * Replacements for missing platform functions. - * - * Unlike the originals, fpclassify() and signbit() replacements don't - * work on any floating point types, only doubles. The C typing here - * mimics the standard prototypes. - */ - -/* include removed: duk_internal.h */ #if defined(DUK_USE_COMPUTED_NAN) DUK_INTERNAL double duk_computed_nan; @@ -8740,130 +9556,13 @@ DUK_INTERNAL int duk_repl_isinf(double x) { return (c == DUK_FP_INFINITE); } #endif -#line 1 "duk_strings.c" -/* - * Shared error message strings - * - * To minimize code footprint, try to share error messages inside Duktape - * code. Modern compilers will do this automatically anyway, this is mostly - * for older compilers. - */ - -/* include removed: duk_internal.h */ - -/* Mostly API and built-in method related */ -DUK_INTERNAL const char *duk_str_internal_error = "internal error"; -DUK_INTERNAL const char *duk_str_invalid_count = "invalid count"; -DUK_INTERNAL const char *duk_str_invalid_call_args = "invalid call args"; -DUK_INTERNAL const char *duk_str_not_constructable = "not constructable"; -DUK_INTERNAL const char *duk_str_not_callable = "not callable"; -DUK_INTERNAL const char *duk_str_not_extensible = "not extensible"; -DUK_INTERNAL const char *duk_str_not_writable = "not writable"; -DUK_INTERNAL const char *duk_str_not_configurable = "not configurable"; - -DUK_INTERNAL const char *duk_str_invalid_context = "invalid context"; -DUK_INTERNAL const char *duk_str_push_beyond_alloc_stack = "attempt to push beyond currently allocated stack"; -DUK_INTERNAL const char *duk_str_not_buffer = "not buffer"; /* still in use with verbose messages */ -DUK_INTERNAL const char *duk_str_unexpected_type = "unexpected type"; -DUK_INTERNAL const char *duk_str_defaultvalue_coerce_failed = "[[DefaultValue]] coerce failed"; -DUK_INTERNAL const char *duk_str_number_outside_range = "number outside range"; -DUK_INTERNAL const char *duk_str_not_object_coercible = "not object coercible"; -DUK_INTERNAL const char *duk_str_string_too_long = "string too long"; -DUK_INTERNAL const char *duk_str_buffer_too_long = "buffer too long"; -DUK_INTERNAL const char *duk_str_sprintf_too_long = "sprintf message too long"; -DUK_INTERNAL const char *duk_str_alloc_failed = "alloc failed"; -DUK_INTERNAL const char *duk_str_pop_too_many = "attempt to pop too many entries"; -DUK_INTERNAL const char *duk_str_wrong_buffer_type = "wrong buffer type"; -DUK_INTERNAL const char *duk_str_encode_failed = "encode failed"; -DUK_INTERNAL const char *duk_str_decode_failed = "decode failed"; -DUK_INTERNAL const char *duk_str_no_sourcecode = "no sourcecode"; -DUK_INTERNAL const char *duk_str_concat_result_too_long = "concat result too long"; -DUK_INTERNAL const char *duk_str_unimplemented = "unimplemented"; -DUK_INTERNAL const char *duk_str_unsupported = "unsupported"; -DUK_INTERNAL const char *duk_str_array_length_over_2g = "array length over 2G"; - -/* JSON */ -DUK_INTERNAL const char *duk_str_fmt_ptr = "%p"; -DUK_INTERNAL const char *duk_str_fmt_invalid_json = "invalid json (at offset %ld)"; -DUK_INTERNAL const char *duk_str_jsondec_reclimit = "json decode recursion limit"; -DUK_INTERNAL const char *duk_str_jsonenc_reclimit = "json encode recursion limit"; -DUK_INTERNAL const char *duk_str_cyclic_input = "cyclic input"; - -/* Object property access */ -DUK_INTERNAL const char *duk_str_proxy_revoked = "proxy revoked"; -DUK_INTERNAL const char *duk_str_invalid_base = "invalid base value"; -DUK_INTERNAL const char *duk_str_strict_caller_read = "attempt to read strict 'caller'"; -DUK_INTERNAL const char *duk_str_proxy_rejected = "proxy rejected"; -DUK_INTERNAL const char *duk_str_invalid_array_length = "invalid array length"; -DUK_INTERNAL const char *duk_str_array_length_write_failed = "array length write failed"; -DUK_INTERNAL const char *duk_str_array_length_not_writable = "array length non-writable"; -DUK_INTERNAL const char *duk_str_setter_undefined = "setter undefined"; -DUK_INTERNAL const char *duk_str_redefine_virt_prop = "attempt to redefine virtual property"; -DUK_INTERNAL const char *duk_str_invalid_descriptor = "invalid descriptor"; -DUK_INTERNAL const char *duk_str_property_is_virtual = "property is virtual"; - -/* Compiler */ -DUK_INTERNAL const char *duk_str_parse_error = "parse error"; -DUK_INTERNAL const char *duk_str_duplicate_label = "duplicate label"; -DUK_INTERNAL const char *duk_str_invalid_label = "invalid label"; -DUK_INTERNAL const char *duk_str_invalid_array_literal = "invalid array literal"; -DUK_INTERNAL const char *duk_str_invalid_object_literal = "invalid object literal"; -DUK_INTERNAL const char *duk_str_invalid_var_declaration = "invalid variable declaration"; -DUK_INTERNAL const char *duk_str_cannot_delete_identifier = "cannot delete identifier"; -DUK_INTERNAL const char *duk_str_invalid_expression = "invalid expression"; -DUK_INTERNAL const char *duk_str_invalid_lvalue = "invalid lvalue"; -DUK_INTERNAL const char *duk_str_expected_identifier = "expected identifier"; -DUK_INTERNAL const char *duk_str_empty_expr_not_allowed = "empty expression not allowed"; -DUK_INTERNAL const char *duk_str_invalid_for = "invalid for statement"; -DUK_INTERNAL const char *duk_str_invalid_switch = "invalid switch statement"; -DUK_INTERNAL const char *duk_str_invalid_break_cont_label = "invalid break/continue label"; -DUK_INTERNAL const char *duk_str_invalid_return = "invalid return"; -DUK_INTERNAL const char *duk_str_invalid_try = "invalid try"; -DUK_INTERNAL const char *duk_str_invalid_throw = "invalid throw"; -DUK_INTERNAL const char *duk_str_with_in_strict_mode = "with in strict mode"; -DUK_INTERNAL const char *duk_str_func_stmt_not_allowed = "function statement not allowed"; -DUK_INTERNAL const char *duk_str_unterminated_stmt = "unterminated statement"; -DUK_INTERNAL const char *duk_str_invalid_arg_name = "invalid argument name"; -DUK_INTERNAL const char *duk_str_invalid_func_name = "invalid function name"; -DUK_INTERNAL const char *duk_str_invalid_getset_name = "invalid getter/setter name"; -DUK_INTERNAL const char *duk_str_func_name_required = "function name required"; - -/* Regexp */ -DUK_INTERNAL const char *duk_str_invalid_quantifier_no_atom = "quantifier without preceding atom"; -DUK_INTERNAL const char *duk_str_invalid_quantifier_values = "quantifier values invalid (qmin > qmax)"; -DUK_INTERNAL const char *duk_str_quantifier_too_many_copies = "quantifier expansion requires too many atom copies"; -DUK_INTERNAL const char *duk_str_unexpected_closing_paren = "unexpected closing parenthesis"; -DUK_INTERNAL const char *duk_str_unexpected_end_of_pattern = "unexpected end of pattern"; -DUK_INTERNAL const char *duk_str_unexpected_regexp_token = "unexpected token in regexp"; -DUK_INTERNAL const char *duk_str_invalid_regexp_flags = "invalid regexp flags"; -DUK_INTERNAL const char *duk_str_invalid_backrefs = "invalid backreference(s)"; - -/* Limits */ -DUK_INTERNAL const char *duk_str_valstack_limit = "valstack limit"; -DUK_INTERNAL const char *duk_str_callstack_limit = "callstack limit"; -DUK_INTERNAL const char *duk_str_catchstack_limit = "catchstack limit"; -DUK_INTERNAL const char *duk_str_prototype_chain_limit = "prototype chain limit"; -DUK_INTERNAL const char *duk_str_bound_chain_limit = "function call bound chain limit"; -DUK_INTERNAL const char *duk_str_c_callstack_limit = "C call stack depth limit"; -DUK_INTERNAL const char *duk_str_compiler_recursion_limit = "compiler recursion limit"; -DUK_INTERNAL const char *duk_str_bytecode_limit = "bytecode limit"; -DUK_INTERNAL const char *duk_str_reg_limit = "register limit"; -DUK_INTERNAL const char *duk_str_temp_limit = "temp limit"; -DUK_INTERNAL const char *duk_str_const_limit = "const limit"; -DUK_INTERNAL const char *duk_str_func_limit = "function limit"; -DUK_INTERNAL const char *duk_str_regexp_compiler_recursion_limit = "regexp compiler recursion limit"; -DUK_INTERNAL const char *duk_str_regexp_executor_recursion_limit = "regexp executor recursion limit"; -DUK_INTERNAL const char *duk_str_regexp_executor_step_limit = "regexp step limit"; - -/* Misc */ -#line 1 "duk_debug_macros.c" /* * Debugging macro calls. */ -/* include removed: duk_internal.h */ +/* #include duk_internal.h -> already included */ -#ifdef DUK_USE_DEBUG +#if defined(DUK_USE_DEBUG) /* * Debugging enabled @@ -8873,91 +9572,34 @@ DUK_INTERNAL const char *duk_str_regexp_executor_step_limit = "regexp step limit #include <stdlib.h> #include <stdarg.h> -#define DUK__DEBUG_BUFSIZE DUK_USE_DEBUG_BUFSIZE -DUK_LOCAL char duk__debug_buf[DUK__DEBUG_BUFSIZE]; - -DUK_LOCAL const char *duk__get_level_string(duk_small_int_t level) { - switch ((int) level) { - case DUK_LEVEL_DEBUG: - return "D"; - case DUK_LEVEL_DDEBUG: - return "DD"; - case DUK_LEVEL_DDDEBUG: - return "DDD"; - } - return "???"; -} - -#ifdef DUK_USE_DPRINT_COLORS - -/* http://en.wikipedia.org/wiki/ANSI_escape_code */ -#define DUK__TERM_REVERSE "\x1b[7m" -#define DUK__TERM_BRIGHT "\x1b[1m" -#define DUK__TERM_RESET "\x1b[0m" -#define DUK__TERM_BLUE "\x1b[34m" -#define DUK__TERM_RED "\x1b[31m" - -DUK_LOCAL const char *duk__get_term_1(duk_small_int_t level) { - DUK_UNREF(level); - return (const char *) DUK__TERM_RED; -} - -DUK_LOCAL const char *duk__get_term_2(duk_small_int_t level) { - switch ((int) level) { - case DUK_LEVEL_DEBUG: - return (const char *) (DUK__TERM_RESET DUK__TERM_BRIGHT); - case DUK_LEVEL_DDEBUG: - return (const char *) (DUK__TERM_RESET); - case DUK_LEVEL_DDDEBUG: - return (const char *) (DUK__TERM_RESET DUK__TERM_BLUE); - } - return (const char *) DUK__TERM_RESET; -} - -DUK_LOCAL const char *duk__get_term_3(duk_small_int_t level) { - DUK_UNREF(level); - return (const char *) DUK__TERM_RESET; -} - -#else - -DUK_LOCAL const char *duk__get_term_1(duk_small_int_t level) { - DUK_UNREF(level); - return (const char *) ""; -} - -DUK_LOCAL const char *duk__get_term_2(duk_small_int_t level) { - DUK_UNREF(level); - return (const char *) ""; -} - -DUK_LOCAL const char *duk__get_term_3(duk_small_int_t level) { - DUK_UNREF(level); - return (const char *) ""; -} +#if !defined(DUK_USE_DEBUG_WRITE) +#error debugging enabled (DUK_USE_DEBUG) but DUK_USE_DEBUG_WRITE not defined +#endif -#endif /* DUK_USE_DPRINT_COLORS */ +#define DUK__DEBUG_BUFSIZE DUK_USE_DEBUG_BUFSIZE -#ifdef DUK_USE_VARIADIC_MACROS +#if defined(DUK_USE_VARIADIC_MACROS) -DUK_INTERNAL void duk_debug_log(duk_small_int_t level, const char *file, duk_int_t line, const char *func, const char *fmt, ...) { +DUK_INTERNAL void duk_debug_log(duk_int_t level, const char *file, duk_int_t line, const char *func, const char *fmt, ...) { va_list ap; + long arg_level; + const char *arg_file; + long arg_line; + const char *arg_func; + const char *arg_msg; + char buf[DUK__DEBUG_BUFSIZE]; va_start(ap, fmt); - DUK_MEMZERO((void *) duk__debug_buf, (size_t) DUK__DEBUG_BUFSIZE); - duk_debug_vsnprintf(duk__debug_buf, DUK__DEBUG_BUFSIZE - 1, fmt, ap); + DUK_MEMZERO((void *) buf, (size_t) DUK__DEBUG_BUFSIZE); + duk_debug_vsnprintf(buf, DUK__DEBUG_BUFSIZE - 1, fmt, ap); - DUK_FPRINTF(DUK_STDERR, "%s[%s] %s:%ld (%s):%s %s%s\n", - (const char *) duk__get_term_1(level), - (const char *) duk__get_level_string(level), - (const char *) file, - (long) line, - (const char *) func, - (const char *) duk__get_term_2(level), - (const char *) duk__debug_buf, - (const char *) duk__get_term_3(level)); - DUK_FFLUSH(DUK_STDERR); + arg_level = (long) level; + arg_file = (const char *) file; + arg_line = (long) line; + arg_func = (const char *) func; + arg_msg = (const char *) buf; + DUK_USE_DEBUG_WRITE(arg_level, arg_file, arg_line, arg_func, arg_msg); va_end(ap); } @@ -8965,29 +9607,30 @@ DUK_INTERNAL void duk_debug_log(duk_small_int_t level, const char *file, duk_int #else /* DUK_USE_VARIADIC_MACROS */ DUK_INTERNAL char duk_debug_file_stash[DUK_DEBUG_STASH_SIZE]; -DUK_INTERNAL char duk_debug_line_stash[DUK_DEBUG_STASH_SIZE]; +DUK_INTERNAL duk_int_t duk_debug_line_stash; DUK_INTERNAL char duk_debug_func_stash[DUK_DEBUG_STASH_SIZE]; -DUK_INTERNAL duk_small_int_t duk_debug_level_stash; +DUK_INTERNAL duk_int_t duk_debug_level_stash; DUK_INTERNAL void duk_debug_log(const char *fmt, ...) { va_list ap; - duk_small_int_t level = duk_debug_level_stash; + long arg_level; + const char *arg_file; + long arg_line; + const char *arg_func; + const char *arg_msg; + char buf[DUK__DEBUG_BUFSIZE]; va_start(ap, fmt); - DUK_MEMZERO((void *) duk__debug_buf, (size_t) DUK__DEBUG_BUFSIZE); - duk_debug_vsnprintf(duk__debug_buf, DUK__DEBUG_BUFSIZE - 1, fmt, ap); + DUK_MEMZERO((void *) buf, (size_t) DUK__DEBUG_BUFSIZE); + duk_debug_vsnprintf(buf, DUK__DEBUG_BUFSIZE - 1, fmt, ap); - DUK_FPRINTF(DUK_STDERR, "%s[%s] %s:%s (%s):%s %s%s\n", - (const char *) duk__get_term_1(level), - (const char *) duk__get_level_string(duk_debug_level_stash), - (const char *) duk_debug_file_stash, - (const char *) duk_debug_line_stash, - (const char *) duk_debug_func_stash, - (const char *) duk__get_term_2(level), - (const char *) duk__debug_buf, - (const char *) duk__get_term_3(level)); - DUK_FFLUSH(DUK_STDERR); + arg_level = (long) duk_debug_level_stash; + arg_file = (const char *) duk_debug_file_stash; + arg_line = (long) duk_debug_line_stash; + arg_func = (const char *) duk_debug_func_stash; + arg_msg = (const char *) buf; + DUK_USE_DEBUG_WRITE(arg_level, arg_file, arg_line, arg_func, arg_msg); va_end(ap); } @@ -9001,75 +9644,72 @@ DUK_INTERNAL void duk_debug_log(const char *fmt, ...) { */ #endif /* DUK_USE_DEBUG */ -#line 1 "duk_builtins.c" + +/* automatic undefs */ +#undef DUK__DEBUG_BUFSIZE /* * Automatically generated by genbuiltins.py, do not edit! */ -/* include removed: duk_internal.h */ +/* #include duk_internal.h -> already included */ #if defined(DUK_USE_ROM_STRINGS) -#error ROM support not enabled, rerun make_dist.py with --rom-support +#error ROM support not enabled, rerun configure.py with --rom-support #else /* DUK_USE_ROM_STRINGS */ -DUK_INTERNAL const duk_uint8_t duk_strings_data[1049] = { -79,104,209,144,168,105,6,78,182,139,90,122,8,154,140,35,103,35,117,193,73, -5,52,116,180,104,166,135,52,189,4,98,12,27,178,156,80,211,31,161,115,150, -64,52,221,109,24,18,68,157,24,38,67,118,36,55,73,119,151,164,140,93,18,117, -128,153,201,228,201,205,2,250,8,196,24,232,104,82,146,40,232,193,48,118, -168,37,147,212,54,127,113,208,70,32,194,187,68,54,127,113,208,70,32,196, -123,68,54,127,113,209,44,12,121,7,208,70,32,194,186,134,207,236,126,219, -160,140,65,133,246,136,108,254,199,237,186,8,196,24,87,80,217,253,159,217, -116,17,136,48,190,209,13,159,217,253,151,65,24,131,12,233,86,224,79,236, -254,203,160,140,65,134,116,171,112,39,246,223,105,208,70,32,193,140,183,4, -11,55,92,20,244,141,169,186,50,11,164,109,77,208,208,165,36,79,215,185,13, -153,34,110,204,241,32,6,66,84,11,112,200,84,52,157,124,92,242,70,120,45,64, -186,17,22,138,38,0,172,140,19,154,84,26,145,0,86,69,17,180,97,34,0,172,132, -75,144,215,77,221,91,132,5,147,178,156,80,211,30,160,93,9,215,21,115,119, -169,49,75,211,138,26,101,205,222,68,157,47,78,40,105,151,55,120,204,156, -189,56,161,166,52,157,72,136,138,65,154,232,147,162,4,136,150,81,115,66, -208,210,37,96,148,250,134,140,151,39,212,125,255,221,125,73,80,209,146,233, -124,93,55,79,15,34,196,230,202,113,160,166,232,157,132,148,128,98,28,46, -114,200,6,153,180,96,73,19,74,113,67,76,103,5,36,20,211,70,140,133,67,72, -49,245,160,235,81,212,52,168,106,39,132,253,111,80,210,161,168,158,5,245, -191,96,31,172,15,208,23,226,190,131,232,62,131,232,11,251,127,93,245,223, -93,251,172,234,27,80,45,3,250,14,140,19,34,65,19,81,132,108,228,97,1,107, -33,12,32,45,100,136,206,9,12,196,155,134,69,146,100,235,226,231,146,51,194, -72,218,48,145,4,200,119,89,189,81,49,39,72,147,235,226,233,186,120,121,58, -226,167,90,124,93,55,107,71,137,33,68,68,130,64,206,75,189,209,156,144,84, -44,141,3,8,137,187,178,156,80,211,26,110,242,100,230,146,120,121,8,48,76,6, -89,26,105,157,65,196,201,213,145,166,153,212,28,76,157,113,75,34,78,62,14, -38,73,105,228,142,136,178,48,141,152,228,73,150,83,0,148,39,137,75,67,73, -214,209,129,36,85,190,206,32,17,6,9,128,141,3,8,130,161,100,235,64,194,24, -52,41,73,19,189,200,108,201,19,111,181,2,232,66,239,173,37,230,157,244,56, -153,4,225,145,27,233,93,22,1,114,62,251,80,69,128,121,247,213,146,228,109, -79,190,212,17,35,106,125,246,78,164,68,68,111,175,23,217,45,13,33,119,208, -68,210,38,250,192,61,91,233,80,208,45,25,36,81,190,156,13,26,201,19,239, -162,2,214,66,31,125,153,226,64,13,27,236,72,96,130,68,62,251,48,68,196,153, -119,217,157,18,56,156,199,161,100,42,26,250,77,36,140,122,40,144,19,34,9, -24,246,103,139,172,150,56,125,145,1,17,29,44,112,250,183,0,100,24,200,218, -140,228,185,130,9,19,237,190,208,73,184,146,35,68,146,163,8,50,178,99,136, -44,89,196,2,33,70,64,208,196,67,74,226,88,17,105,73,24,186,37,40,38,5,133, -161,89,4,183,25,115,119,86,227,118,83,138,26,103,255,223,209,106,141,25,11, -244,95,117,56,208,159,250,223,251,250,45,52,13,250,47,186,156,104,79,253, -111,253,253,22,144,210,253,23,221,78,52,39,254,187,254,254,139,77,67,75, -244,95,117,56,208,159,250,239,251,250,45,22,141,23,209,125,212,227,66,127, -235,63,239,69,163,69,247,83,141,9,255,165,12,72,5,16,64,145,10,32,76,71,64, -156,217,161,180,34,6,64,208,198,36,78,50,20,20,92,204,50,44,147,32,134,226, -17,114,33,202,134,129,107,192,202,232,160,180,104,166,135,52,72,40,144,213, -33,178,152,26,34,56,163,105,44,104,146,116,139,77,43,34,98,57,38,116,72, -179,60,93,97,206,56,52,240,242,56,163,168,34,81,57,178,153,42,228,12,182, -58,22,66,89,19,57,68,176,74,68,35,104,195,18,239,116,102,114,94,100,104, -228,100,49,238,140,203,42,60,145,35,104,181,146,113,161,10,80,46,68,82,24, -245,145,132,108,228,148,54,100,137,64,34,13,100,153,222,1,40,6,33,223,20, -84,19,34,95,23,76,130,153,6,103,208,43,64,141,41,130,104,17,112,130,44,96, +DUK_INTERNAL const duk_uint8_t duk_strings_data[921] = { +79,40,209,144,168,105,6,78,54,139,89,185,44,48,46,90,120,8,154,140,35,103, +35,113,193,73,5,52,112,180,104,166,135,52,188,4,98,12,27,146,156,80,211,31, +129,115,150,64,52,220,109,24,18,68,156,24,38,67,114,36,55,9,119,151,132, +140,93,18,113,128,153,201,212,201,205,2,248,8,196,24,224,104,82,146,40,224, +193,48,114,168,37,147,196,54,123,28,4,98,12,43,148,67,103,177,192,70,32, +196,121,68,54,123,28,18,192,199,144,124,4,98,12,43,136,108,244,117,184,8, +196,24,95,40,134,207,71,91,128,140,65,133,113,13,158,158,151,1,24,131,11, +229,16,217,233,233,112,17,136,48,206,21,110,4,244,244,184,8,196,24,103,10, +183,2,122,218,156,4,98,12,24,203,112,64,179,113,193,79,8,218,155,131,32, +184,70,212,220,13,10,82,68,252,123,144,217,146,38,228,207,18,0,100,37,64, +178,212,11,161,17,104,162,96,10,200,193,57,165,65,169,16,5,100,81,27,70,18, +32,10,200,68,185,13,116,221,197,184,64,89,57,41,197,13,49,234,5,208,156, +113,87,55,118,147,20,187,56,161,166,92,221,212,73,210,236,226,134,153,115, +119,76,201,203,179,138,26,99,73,212,136,136,164,25,174,137,56,32,72,137, +101,23,52,45,13,34,86,9,79,136,104,201,114,149,96,52,138,134,140,151,75, +226,233,186,120,121,22,39,54,83,141,5,55,68,236,36,164,3,16,225,115,150,64, +52,205,163,2,72,154,83,138,26,99,75,12,11,150,103,5,36,20,211,70,140,133, +67,72,49,241,160,227,81,196,52,168,106,39,132,252,183,136,105,80,212,79,2, +249,110,128,126,88,95,133,109,237,237,237,151,235,127,46,249,119,203,190, +186,206,33,181,2,208,61,190,12,19,34,65,19,81,132,108,228,97,1,107,33,12, +32,45,100,139,134,69,146,100,227,226,231,146,51,192,204,73,140,224,145,221, +102,241,68,196,157,34,79,143,139,166,233,225,228,227,138,157,173,167,197, +211,118,214,210,38,238,74,113,67,76,105,187,169,147,154,73,225,228,32,193, +48,25,100,105,166,113,200,147,44,166,1,40,79,18,150,134,147,141,163,2,72, +171,115,147,136,4,65,130,96,35,64,194,32,168,89,56,208,48,135,123,144,217, +146,38,220,229,64,186,16,187,156,105,47,52,238,112,56,153,4,225,145,27,156, +43,162,192,46,71,220,229,65,22,1,231,220,228,157,72,136,136,220,227,197, +164,180,52,133,220,224,34,105,19,115,140,3,207,185,202,130,36,109,85,185, +194,161,160,90,50,72,163,115,135,3,70,178,68,251,156,16,22,178,16,251,156, +153,226,64,13,27,156,137,12,16,72,135,220,228,193,19,18,101,220,228,206, +137,28,78,99,208,178,21,13,125,38,146,70,60,20,72,9,145,4,140,121,51,197, +214,25,27,81,156,151,48,65,34,107,106,9,55,18,68,104,146,84,97,31,191,189, +181,70,140,133,222,249,212,227,66,125,245,187,251,219,77,3,119,190,117,56, +208,159,125,110,254,246,210,26,93,239,157,78,52,39,223,93,191,189,180,212, +52,187,223,58,156,104,79,190,187,127,123,104,180,104,183,190,117,56,208, +159,125,102,254,209,104,209,124,234,113,161,62,250,80,196,128,81,4,9,16, +162,4,196,116,9,205,154,27,66,32,100,13,12,98,68,227,33,65,69,204,195,34, +201,50,8,110,33,23,34,28,168,104,22,188,12,174,138,11,70,138,104,115,68, +130,137,13,82,27,41,129,162,35,138,54,146,198,137,39,72,180,210,178,38,35, +146,103,68,139,51,197,214,28,227,131,79,15,35,138,58,130,37,19,155,41,146, +174,64,203,99,161,100,37,145,51,148,75,4,164,66,54,140,49,46,247,70,103,37, +230,70,142,70,67,30,232,204,178,163,201,18,54,139,89,39,26,16,165,2,228,69, +33,143,89,24,70,206,73,67,102,72,148,2,32,214,73,157,224,18,128,98,29,241, +69,65,50,37,241,116,200,41,144,102,125,2,180,8,210,152,38,129,23,8,34,198, }; #endif /* DUK_USE_ROM_STRINGS */ #if defined(DUK_USE_ROM_OBJECTS) -#error ROM support not enabled, rerun make_dist.py with --rom-support +#error ROM support not enabled, rerun configure.py with --rom-support #else /* DUK_USE_ROM_OBJECTS */ -/* native functions: 149 */ -DUK_INTERNAL const duk_c_function duk_bi_native_functions[149] = { +/* native functions: 164 */ +DUK_INTERNAL const duk_c_function duk_bi_native_functions[164] = { + NULL, duk_bi_array_constructor, duk_bi_array_constructor_is_array, duk_bi_array_prototype_concat, @@ -9091,8 +9731,6 @@ DUK_INTERNAL const duk_c_function duk_bi_native_functions[149] = { duk_bi_boolean_constructor, duk_bi_boolean_prototype_tostring_shared, duk_bi_buffer_compare_shared, - duk_bi_buffer_constructor, - duk_bi_buffer_prototype_tostring_shared, duk_bi_buffer_readfield, duk_bi_buffer_slice_shared, duk_bi_buffer_writefield, @@ -9139,15 +9777,10 @@ DUK_INTERNAL const duk_c_function duk_bi_native_functions[149] = { duk_bi_global_object_is_nan, duk_bi_global_object_parse_float, duk_bi_global_object_parse_int, - duk_bi_global_object_print_helper, - duk_bi_global_object_require, duk_bi_global_object_unescape, duk_bi_json_object_parse, duk_bi_json_object_stringify, - duk_bi_logger_constructor, - duk_bi_logger_prototype_fmt, - duk_bi_logger_prototype_log_shared, - duk_bi_logger_prototype_raw, + duk_bi_math_object_hypot, duk_bi_math_object_max, duk_bi_math_object_min, duk_bi_math_object_onearg_shared, @@ -9171,10 +9804,12 @@ DUK_INTERNAL const duk_c_function duk_bi_native_functions[149] = { duk_bi_number_prototype_to_string, duk_bi_number_prototype_value_of, duk_bi_object_constructor, + duk_bi_object_constructor_assign, duk_bi_object_constructor_create, duk_bi_object_constructor_define_properties, duk_bi_object_constructor_define_property, duk_bi_object_constructor_get_own_property_descriptor, + duk_bi_object_constructor_is, duk_bi_object_constructor_is_extensible, duk_bi_object_constructor_is_sealed_frozen_shared, duk_bi_object_constructor_keys_shared, @@ -9191,12 +9826,19 @@ DUK_INTERNAL const duk_c_function duk_bi_native_functions[149] = { duk_bi_pointer_constructor, duk_bi_pointer_prototype_tostring_shared, duk_bi_proxy_constructor, + duk_bi_reflect_object_delete_property, + duk_bi_reflect_object_get, + duk_bi_reflect_object_has, + duk_bi_reflect_object_set, duk_bi_regexp_constructor, duk_bi_regexp_prototype_exec, + duk_bi_regexp_prototype_flags, + duk_bi_regexp_prototype_shared_getter, duk_bi_regexp_prototype_test, - duk_bi_regexp_prototype_to_string, + duk_bi_regexp_prototype_tostring, duk_bi_string_constructor, duk_bi_string_constructor_from_char_code, + duk_bi_string_constructor_from_code_point, duk_bi_string_prototype_caseconv_shared, duk_bi_string_prototype_char_at, duk_bi_string_prototype_char_code_at, @@ -9204,6 +9846,7 @@ DUK_INTERNAL const duk_c_function duk_bi_native_functions[149] = { duk_bi_string_prototype_indexof_shared, duk_bi_string_prototype_locale_compare, duk_bi_string_prototype_match, + duk_bi_string_prototype_repeat, duk_bi_string_prototype_replace, duk_bi_string_prototype_search, duk_bi_string_prototype_slice, @@ -9212,578 +9855,565 @@ DUK_INTERNAL const duk_c_function duk_bi_native_functions[149] = { duk_bi_string_prototype_substring, duk_bi_string_prototype_to_string, duk_bi_string_prototype_trim, + duk_bi_textdecoder_constructor, + duk_bi_textdecoder_prototype_decode, + duk_bi_textdecoder_prototype_shared_getter, + duk_bi_textencoder_constructor, + duk_bi_textencoder_prototype_encode, + duk_bi_textencoder_prototype_encoding_getter, duk_bi_thread_constructor, duk_bi_thread_current, duk_bi_thread_resume, duk_bi_thread_yield, duk_bi_type_error_thrower, + duk_bi_typedarray_buffer_getter, + duk_bi_typedarray_bytelength_getter, + duk_bi_typedarray_byteoffset_getter, duk_bi_typedarray_constructor, duk_bi_typedarray_set, + duk_bi_uint8array_allocplain, + duk_bi_uint8array_plainof, }; -#if defined(DUK_USE_BUILTIN_INITJS) -DUK_INTERNAL const duk_uint8_t duk_initjs_data[204] = { -40,102,117,110,99,116,105,111,110,40,100,44,97,41,123,102,117,110,99,116, -105,111,110,32,98,40,97,44,98,44,99,41,123,79,98,106,101,99,116,46,100,101, -102,105,110,101,80,114,111,112,101,114,116,121,40,97,44,98,44,123,118,97, -108,117,101,58,99,44,119,114,105,116,97,98,108,101,58,33,48,44,101,110,117, -109,101,114,97,98,108,101,58,33,49,44,99,111,110,102,105,103,117,114,97,98, -108,101,58,33,48,125,41,125,98,40,97,46,76,111,103,103,101,114,44,34,99, -108,111,103,34,44,110,101,119,32,97,46,76,111,103,103,101,114,40,34,67,34, -41,41,59,98,40,97,44,34,109,111,100,76,111,97,100,101,100,34,44,79,98,106, -101,99,116,46,99,114,101,97,116,101,40,110,117,108,108,41,41,125,41,40,116, -104,105,115,44,68,117,107,116,97,112,101,41,59,10,0, -}; -#endif /* DUK_USE_BUILTIN_INITJS */ #if defined(DUK_USE_DOUBLE_LE) -DUK_INTERNAL const duk_uint8_t duk_builtins_data[3833] = { -105,195,75,32,3,148,52,154,248,9,26,13,128,112,105,0,240,22,20,26,95,124,6, -152,52,137,0,120,99,74,239,129,18,70,241,191,2,98,13,79,32,42,88,210,90,2, -240,1,50,141,37,168,76,94,216,118,69,229,203,127,44,0,84,163,73,106,21,75, -14,236,249,98,242,229,191,150,0,46,81,164,181,14,165,151,54,94,89,119,99, -203,23,151,45,252,176,1,146,141,37,168,93,63,59,186,97,241,23,151,45,252, -176,1,178,141,37,168,77,79,60,50,197,229,203,127,44,0,116,163,73,106,17,86, -148,152,188,185,111,229,128,15,148,129,198,137,36,58,166,142,91,251,212, -243,195,44,94,92,183,242,13,79,8,45,14,91,252,121,148,52,199,120,63,72,105, -21,240,118,128,210,237,224,245,17,165,43,224,211,55,231,207,151,148,161,70, -145,0,31,40,107,26,2,18,138,26,228,192,142,0,16,161,174,76,9,74,26,228,192, -158,0,8,161,174,76,10,96,2,42,26,228,192,174,0,26,161,174,76,11,96,3,74,26, -228,192,190,0,44,161,174,76,12,96,3,202,26,228,192,206,0,70,161,169,84,14, -202,3,255,254,32,234,0,0,0,0,0,0,7,195,248,119,0,0,0,0,0,0,3,193,252,57, -136,1,152,32,16,194,0,166,24,6,49,0,57,138,2,12,96,18,99,128,163,32,5,153, -40,76,94,216,118,69,229,203,127,35,41,10,165,135,118,124,177,121,114,223, -200,203,67,169,101,205,151,150,93,216,242,197,229,203,127,35,49,11,167,231, -119,76,62,34,242,229,191,145,154,132,212,243,195,44,94,92,183,242,51,144, -138,180,164,197,229,203,127,35,60,6,26,0,52,208,193,226,117,215,211,15,12, -166,146,11,67,150,255,30,77,24,58,113,64,243,92,8,27,0,68,217,130,70,212, -19,54,224,161,185,5,77,216,44,111,65,115,126,12,28,16,100,225,156,16,32,18, -17,195,15,46,121,100,238,232,136,136,87,12,60,185,229,141,179,126,30,136, -100,130,233,231,59,12,228,34,66,52,243,141,167,118,158,153,80,73,9,201,151, -30,252,153,106,210,146,118,72,150,76,184,247,228,203,86,148,152,123,246, -240,223,187,46,238,135,132,132,229,221,143,126,76,181,105,73,61,36,75,46, -236,123,242,101,171,74,76,61,251,120,111,221,151,119,67,226,65,178,243,199, -135,134,83,242,66,58,238,203,207,30,30,25,81,201,5,225,203,78,238,136,163, -208,92,59,50,242,232,138,62,0,2,38,163,19,255,255,224,142,80,192,0,20,31, -240,14,135,103,203,210,135,45,253,55,244,243,195,44,252,205,197,0,1,18,221, -82,0,3,24,207,151,164,254,251,168,114,223,195,47,46,158,98,101,231,143,150, -158,29,55,242,104,68,79,62,94,147,251,238,161,203,127,12,188,186,121,157, -135,110,94,109,100,131,99,229,151,15,76,172,168,8,89,217,16,201,151,54,157, -217,104,114,223,195,47,46,154,114,243,102,68,19,158,92,59,27,73,6,205,203, -46,95,89,91,74,0,3,17,225,203,47,108,187,186,69,241,211,46,238,122,119,238, -230,216,72,70,158,116,242,225,217,151,35,81,33,26,121,198,229,191,214,93, -205,69,0,1,134,105,231,23,199,76,187,185,233,197,179,43,73,32,154,242,249, -230,214,80,0,31,255,193,2,38,103,110,117,24,81,115,0,78,228,0,161,208,16, -237,24,121,207,239,186,135,45,252,50,242,233,229,188,144,221,60,232,114, -223,211,127,79,60,50,207,204,224,72,167,14,91,248,101,229,211,204,158,113, -119,117,219,151,150,28,91,50,184,144,40,95,224,0,15,248,64,4,20,78,129,5, -195,195,134,207,38,232,130,99,195,179,97,201,244,19,22,157,217,14,15,130, -135,254,0,48,125,60,224,242,229,135,200,9,1,255,12,2,162,136,112,2,112,80, -128,0,193,177,239,221,143,15,64,35,224,152,20,144,62,27,248,3,2,9,195,175, -61,0,231,208,126,89,123,101,229,207,40,72,32,188,244,105,205,208,40,16,94, -123,52,227,202,22,136,39,61,252,186,6,18,13,207,134,205,56,242,134,175,65, -250,238,231,163,78,110,129,231,208,125,59,178,101,241,63,48,25,248,0,12,47, -102,30,125,36,238,201,151,196,252,192,103,255,255,240,92,189,178,242,242,8, -105,4,231,191,110,80,67,80,0,24,62,109,252,162,225,199,160,16,212,0,10,7, -183,15,0,67,80,0,56,54,109,59,58,101,228,8,106,0,9,6,229,151,39,92,121,66, -15,192,0,97,124,178,228,235,143,45,45,57,244,116,8,63,255,255,10,39,248,0, -195,51,114,223,182,30,140,60,161,239,201,149,248,248,31,241,0,140,80,129, -202,10,49,128,10,35,1,6,199,163,15,40,61,32,9,10,199,163,15,40,123,242,101, -131,210,4,144,108,123,247,99,195,210,8,250,15,167,118,76,190,39,230,131,52, -133,236,195,207,164,157,217,50,248,159,154,12,212,0,6,27,179,126,60,59,50, -195,223,183,134,30,89,97,9,5,219,135,166,61,16,164,131,242,203,195,102,28, -121,97,145,6,231,151,15,44,122,33,201,5,231,179,78,60,177,8,130,243,225, -179,79,72,148,66,121,245,197,207,167,45,59,179,197,162,23,211,124,205,253, -242,242,135,135,158,87,240,68,122,111,153,191,30,29,153,102,111,239,151, -148,60,60,242,191,130,23,211,125,94,28,50,242,135,135,158,87,240,128,0,196, -122,111,153,191,30,29,153,106,240,225,151,148,60,60,242,191,132,0,6,9,211, -150,157,177,160,131,115,235,139,159,78,81,72,10,47,248,0,3,254,40,17,138, -48,66,136,152,64,0,66,129,48,5,27,252,88,76,216,54,47,214,131,50,172,88,31, -255,255,255,255,255,253,239,240,153,178,103,95,173,6,101,88,176,0,64,0,0,0, -0,0,0,3,168,0,0,0,0,0,0,31,15,241,26,19,233,201,169,38,180,91,242,103,70, -147,58,77,75,48,0,0,0,0,0,0,60,31,226,51,162,199,131,82,77,104,183,228,206, -141,38,116,154,150,96,0,0,0,0,0,0,120,127,128,15,248,192,70,40,0,0,0,0,0,0, -0,0,3,10,44,68,9,216,8,20,49,130,15,211,124,109,62,50,228,95,36,55,166,248, -190,56,111,221,151,119,77,56,118,47,18,23,211,125,14,89,113,233,231,167, -126,230,18,5,31,252,0,224,188,48,242,231,148,116,144,58,181,33,143,127,64, -247,111,238,56,0,127,199,2,49,72,0,0,0,0,0,0,248,127,180,81,36,4,51,166, -248,152,122,101,167,211,150,157,217,201,2,0,3,12,233,190,166,157,185,105, -244,229,167,118,114,64,128,1,4,228,129,0,3,137,116,223,51,126,60,59,50,196, -195,211,45,62,156,180,238,206,72,16,0,72,151,77,243,55,227,195,179,45,77, -59,114,211,233,203,78,236,228,129,0,5,10,73,2,0,12,21,18,4,0,28,82,35,32, -80,74,8,62,124,189,42,105,219,148,148,16,188,249,122,70,235,179,101,156, -184,121,15,132,0,34,29,159,47,74,181,33,198,235,179,101,156,184,121,15,132, -0,38,17,159,47,73,187,247,116,208,62,16,0,168,94,124,189,42,212,135,55,126, -238,154,7,194,0,23,7,207,151,164,76,61,50,143,132,0,50,21,159,47,74,181,33, -196,195,211,40,248,64,3,96,217,242,244,137,135,200,248,64,3,161,57,242,244, -171,82,28,76,62,71,194,0,31,8,207,151,164,141,253,121,115,31,8,0,132,47,62, -94,149,106,67,145,191,175,46,99,225,0,17,133,103,203,210,110,157,221,122, -101,230,62,16,1,40,110,124,189,42,212,135,55,78,238,189,50,243,31,8,0,156, -43,62,94,148,242,227,223,187,39,49,240,128,10,67,115,229,233,86,164,58,121, -113,239,221,147,152,248,64,5,97,249,242,244,155,167,102,205,60,242,227,223, -187,39,49,240,128,11,68,179,229,233,86,164,57,186,118,108,211,207,46,61, -251,178,115,31,8,0,188,71,62,94,149,52,237,203,235,126,236,179,243,102,231, -151,161,0,32,252,242,244,169,167,110,82,34,67,249,229,233,55,78,205,154, -121,229,199,191,118,78,100,37,0,24,137,115,203,210,173,72,115,116,236,217, -167,158,92,123,247,100,230,66,80,1,152,87,60,189,41,229,199,191,118,78,100, -43,224,3,80,222,121,122,85,169,14,158,92,123,247,100,230,66,190,0,55,10, -231,151,164,221,59,186,244,203,204,133,252,0,114,27,207,47,74,181,33,205, -211,187,175,76,188,200,95,192,7,97,28,242,244,145,191,175,46,100,51,224,3, -208,190,121,122,85,169,14,70,254,188,185,144,207,128,15,193,249,229,233,19, -15,76,164,37,0,32,133,115,203,210,173,72,113,48,244,202,66,80,2,24,71,60, -189,38,239,221,211,65,10,248,1,20,47,158,94,149,106,67,155,191,119,77,4,43, -224,4,112,190,121,122,70,235,179,101,156,184,121,16,191,128,18,67,185,229, -233,86,164,56,221,118,108,179,151,15,34,23,240,2,88,62,124,189,44,229,195, -200,124,32,4,208,126,121,122,89,203,135,145,9,64,9,194,145,254,0,0,255,144, -24,100,130,14,0,16,176,2,192,129,11,33,12,1,168,193,108,96,186,48,95,32,0, -0,0,0,0,0,0,0,56,38,95,25,113,189,18,9,211,47,62,143,100,20,95,0,20,159, -240,0,7,252,144,162,241,2,195,66,7,11,89,204,140,197,252,229,197,226,230, -115,3,16,69,19,64,5,43,252,0,9,255,40,16,188,33,49,123,97,217,23,151,45, -252,131,66,7,0,20,191,240,0,39,252,176,66,240,133,82,195,187,62,88,188,185, -111,228,26,16,56,0,166,127,128,1,63,230,2,23,132,58,150,92,217,121,101,221, -143,44,94,92,183,242,13,8,28,0,83,127,192,0,159,243,65,11,194,23,79,206, -238,152,124,69,229,203,127,32,208,129,192,5,59,252,0,9,255,56,16,188,33,53, -60,240,203,23,151,45,252,131,66,7,0,20,255,240,0,39,252,240,66,240,132,85, -165,38,47,46,91,249,6,132,14,0,31,255,228,64,98,192,105,87,20,139,10,191,5, -64,130,76,156,197,132,1,101,91,91,187,22,176,36,8,28,201,204,160,119,156, -253,127,33,23,115,31,193,102,79,142,202,44,15,232,34,182,84,113,95,115,248, -52,201,241,216,176,139,0,59,148,152,85,239,47,108,254,5,66,76,1,130,212,69, -79,178,16,148,8,61,58,52,170,49,190,202,6,105,219,251,52,245,7,49,252,22, -157,26,85,25,64,205,59,127,102,158,160,246,63,74,7,135,23,53,2,65,48,227, -223,205,64,160,0,48,76,60,244,238,80,40,0,20,19,15,76,59,148,10,0,7,5,195, -211,14,230,74,72,130,99,203,167,98,129,64,1,32,120,247,243,80,40,0,44,15, -47,142,10,5,0,6,130,230,217,191,127,37,2,128,3,192,246,111,206,160,80,0, -136,30,220,62,19,151,160,123,116,238,79,94,129,240,223,221,73,32,0,48,110, -88,119,100,223,181,68,16,94,91,250,238,200,160,80,0,152,31,61,59,148,10,0, -21,4,231,199,151,69,2,128,5,192,250,97,220,160,80,0,192,127,255,128,20,23, -134,30,92,242,164,34,19,207,167,45,59,179,233,205,229,37,129,127,255,0,0, -191,255,128,0,63,255,197,131,246,203,203,158,157,251,160,0,0,0,0,0,90,98, -32,3,166,156,30,53,32,249,165,131,76,223,159,62,94,70,172,114,16,176,144, -60,56,250,19,18,5,159,25,89,32,121,180,238,42,30,129,229,221,140,164,122,7, -147,46,50,129,232,62,61,251,120,97,199,208,156,129,83,127,0,50,250,69,3, -252,131,32,248,250,242,229,151,119,72,240,3,254,148,0,2,168,254,0,0,255, -167,0,33,68,88,32,0,33,64,176,2,170,254,0,0,255,169,0,33,69,220,32,0,33,67, -184,2,172,254,0,0,255,171,8,137,144,0,0,0,0,0,0,0,128,68,73,4,195,187,126, -226,8,4,178,16,41,164,32,147,7,136,52,193,240,0,18,17,48,124,0,8,133,76,31, -0,3,33,147,7,192,1,8,116,193,240,0,82,127,255,132,47,65,11,137,191,174,45, -153,98,242,229,191,144,105,4,95,47,46,91,249,32,211,185,6,94,92,183,242,65, -163,14,236,155,52,238,206,0,85,255,192,6,13,167,157,109,57,123,136,144,31, -245,192,3,5,231,179,78,60,163,9,0,2,10,199,248,0,3,254,192,4,32,249,242, -244,147,187,163,129,116,128,24,66,51,229,233,87,78,238,142,5,210,0,65,8, -207,151,164,157,221,24,182,23,72,1,140,39,62,94,149,116,238,232,197,176, -186,64,8,97,25,242,244,147,187,163,54,66,233,0,50,132,231,203,210,174,157, -221,25,178,23,72,1,20,43,62,94,145,182,111,195,209,155,33,116,128,17,194, -179,229,233,27,102,252,61,27,52,23,72,1,36,31,158,94,146,119,116,112,50, -208,3,8,71,60,189,42,233,221,209,192,203,64,8,33,28,242,244,147,187,163,22, -195,45,0,49,132,243,203,210,174,157,221,24,182,25,104,1,12,35,158,94,146, -119,116,102,200,101,160,6,80,158,121,122,85,211,187,163,54,67,45,0,34,133, -115,203,210,54,205,248,122,51,100,50,208,2,56,87,60,189,35,108,223,135,163, -102,131,45,0,36,7,255,248,1,11,50,136,132,115,235,139,15,46,88,124,140,36, -0,4,43,79,224,139,16,0,0,0,0,0,0,60,15,192,101,253,152,0,5,109,252,17,98,0, -0,0,0,0,0,7,129,248,12,191,181,0,0,174,63,130,44,64,0,0,0,0,0,0,240,63,1, -151,246,224,0,21,215,240,69,136,0,0,0,0,0,0,0,8,0,50,254,228,0,2,188,254,8, -177,0,0,0,0,0,0,0,1,0,6,95,221,128,0,87,223,193,22,32,0,0,0,0,0,0,8,32,0, -203,251,208,0,11,3,248,34,196,0,0,0,0,0,0,1,4,0,25,127,126,0,1,97,127,4,88, -128,0,0,0,0,0,0,32,128,3,47,240,64,0,44,79,224,139,16,0,0,0,0,0,0,8,16,0, -101,254,24,0,5,141,252,1,96,216,247,238,199,135,162,162,33,90,121,197,221, -143,126,77,59,179,172,146,17,167,156,46,185,179,101,228,176,65,89,77,16, -124,123,246,240,195,203,40,162,64,0,193,255,138,5,144,158,89,112,228,171, -39,119,71,2,232,132,114,203,135,36,157,221,28,11,164,0,66,25,203,46,28,149, -100,238,232,197,180,200,162,233,0,1,134,114,203,135,37,89,59,186,49,109,10, -40,186,64,2,97,124,178,225,201,39,119,70,45,166,69,23,72,0,140,47,150,92, -57,36,238,232,197,180,40,162,233,0,25,134,114,203,135,37,89,59,186,51,101, -50,40,186,64,0,161,156,178,225,201,86,78,238,140,217,66,138,46,144,0,168, -95,44,184,114,73,221,209,155,41,145,69,210,0,37,11,229,151,14,73,59,186,51, -101,10,40,186,64,6,161,124,178,225,201,27,102,252,61,38,69,23,72,0,28,47, -150,92,57,35,108,223,135,164,40,162,233,0,11,134,114,203,135,36,77,253,113, -108,203,50,40,186,64,1,33,156,178,225,201,19,127,92,91,50,194,138,46,144,0, -200,87,44,184,114,85,147,187,164,200,162,237,0,5,133,114,203,135,37,89,59, -186,66,138,46,208,0,216,79,44,184,114,73,221,210,100,81,118,128,10,194,121, -101,195,146,78,238,144,162,139,180,0,118,21,223,150,158,153,106,201,221, -209,192,203,33,61,249,105,233,150,78,238,142,6,90,0,33,13,239,203,79,76, -181,100,238,232,197,180,200,163,45,0,1,134,247,229,167,166,90,178,119,116, -98,218,20,81,150,128,4,195,59,242,211,211,44,157,221,24,182,153,20,101,160, -2,48,206,252,180,244,203,39,119,70,45,161,69,25,104,0,204,55,191,45,61,50, -213,147,187,163,54,83,34,140,180,0,10,27,223,150,158,153,106,201,221,209, -155,40,81,70,90,0,21,12,239,203,79,76,178,119,116,102,202,100,81,150,128,9, -67,59,242,211,211,44,157,221,25,178,133,20,101,160,3,80,206,252,180,244, -203,27,102,252,61,38,69,25,104,0,28,51,191,45,61,50,198,217,191,15,72,81, -70,90,0,23,13,239,203,79,76,177,55,245,197,179,44,200,163,45,0,4,134,247, -229,167,166,88,155,250,226,217,150,20,81,150,128,6,66,251,242,211,211,45, -89,59,186,76,138,51,16,0,88,95,126,90,122,101,171,39,119,72,81,70,98,0,27, -10,239,203,79,76,178,119,116,153,20,102,32,2,176,174,252,180,244,203,39, -119,72,81,70,98,0,58,40,173,176,82,90,4,19,54,157,155,21,217,6,203,199,174, -29,156,197,9,7,199,191,111,12,60,178,138,20,0,6,9,143,127,15,42,208,130, -243,217,167,30,81,132,65,123,242,211,211,42,228,0, +DUK_INTERNAL const duk_uint8_t duk_builtins_data[3790] = { +144,148,105,221,32,68,52,228,62,12,104,200,165,134,148,248,81,77,61,191, +135,35,154,103,34,72,6,157,159,197,145,77,245,126,52,130,106,234,163,196, +52,226,18,51,161,26,113,1,60,37,64,190,18,49,116,116,33,26,113,1,92,136,26, +98,112,145,139,163,165,8,211,136,14,228,72,82,68,141,17,56,72,197,209,212, +132,105,196,5,242,88,108,193,126,18,49,116,117,161,26,113,1,60,158,30,78, +18,49,116,118,33,26,113,1,29,164,80,78,198,46,142,212,36,68,51,71,224,59, +147,60,93,110,79,15,39,9,24,186,33,13,63,79,185,38,154,121,223,110,76,66, +53,116,1,120,248,186,248,136,67,76,196,200,134,186,137,177,13,31,192,174, +79,15,32,248,8,196,24,8,107,254,39,97,161,175,248,159,16,215,252,80,186,26, +255,138,57,136,107,254,41,100,33,175,248,167,170,134,191,226,166,138,26, +255,138,187,40,107,254,43,111,33,171,86,181,16,209,241,11,228,201,121,240, +141,19,134,72,196,52,123,168,95,38,75,207,131,32,156,50,70,33,195,3,152, +128,0,0,0,0,0,1,240,255,153,128,0,0,0,0,0,1,224,255,151,137,0,214,9,188,35, +131,12,225,196,56,177,78,60,99,147,28,229,200,57,162,120,74,129,124,36,98, +232,156,241,92,136,26,98,112,145,139,162,116,71,114,36,41,34,70,136,156,36, +98,232,157,49,124,150,27,48,95,132,140,93,19,170,39,147,195,201,194,70,46, +137,215,17,218,69,4,236,98,232,157,153,39,110,81,220,15,193,209,83,3,200, +119,130,241,241,117,240,120,80,252,137,10,178,10,103,134,180,122,9,135,136, +154,120,169,199,142,158,121,10,7,146,162,121,74,71,150,166,121,138,135,154, +170,121,202,199,158,23,201,146,243,225,26,39,12,145,61,16,190,76,151,159,6, +65,56,100,137,233,35,93,205,144,33,224,140,137,196,54,121,244,5,60,17,145, +56,85,184,19,207,16,21,18,227,65,198,231,72,16,137,112,168,106,38,76,225,2, +70,65,56,100,237,34,140,177,4,134,65,56,100,237,34,129,117,204,123,154,70, +207,46,64,146,52,78,25,59,72,163,48,65,34,52,78,25,59,72,160,93,115,30,230, +145,179,204,144,24,146,16,30,76,209,2,40,210,72,64,121,52,4,0,156,88,97,5, +194,96,227,18,124,124,93,55,79,15,39,28,94,49,38,159,154,136,96,196,159,29, +102,241,241,115,201,25,227,131,36,133,20,62,110,142,253,2,102,36,248,235, +55,143,139,158,72,207,28,104,24,73,112,201,3,2,82,65,155,187,94,6,20,72,9, +147,120,128,225,144,168,105,56,248,185,228,140,241,190,96,128,200,84,52, +156,124,92,242,70,104,36,183,168,4,145,0,190,41,1,139,18,19,36,226,146,17, +124,73,82,54,124,37,230,70,201,14,108,184,132,8,68,185,34,1,100,31,8,129,8, +151,11,23,100,141,225,18,12,68,184,75,204,141,146,2,178,112,72,8,162,98,92, +50,10,152,147,227,172,222,62,46,121,35,60,114,88,96,92,185,112,201,65,34, +92,4,1,147,81,159,141,205,32,234,121,96,97,57,64,97,121,128,14,56,37,199, +89,188,124,92,242,70,120,227,144,53,18,227,226,233,186,120,121,56,226,242, +8,40,248,185,228,140,241,196,75,132,109,24,72,128,43,39,36,136,48,64,114,0, +250,156,168,1,64,247,175,25,36,2,8,11,94,80,248,16,40,104,242,103,200,48, +193,3,162,92,4,98,12,41,14,66,40,106,101,1,132,130,8,24,78,104,129,54,62, +96,224,144,13,238,124,32,2,62,146,60,51,224,120,146,164,140,137,20,0,178, +58,11,56,192,5,146,208,34,71,64,36,157,25,200,32,52,158,180,8,146,87,129, +232,217,29,5,156,179,224,116,52,100,191,28,87,62,130,214,9,79,136,104,201, +126,56,174,127,0,31,255,225,73,82,71,16,13,1,36,230,18,1,164,14,87,71,132, +0,143,0,210,131,96,31,0,211,6,42,23,50,70,1,167,13,18,14,130,36,67,232,46, +36,29,4,78,69,6,60,226,31,192,7,255,252,24,160,163,11,23,51,130,56,35,193, +56,100,238,31,6,150,46,103,4,225,147,143,114,27,62,233,241,200,137,182,133, +42,142,167,216,6,23,216,0,97,28,17,224,39,223,32,80,142,8,240,78,25,56,9, +248,8,22,39,12,156,123,144,217,240,19,240,18,6,19,154,32,79,194,124,14,134, +140,151,227,139,226,52,11,88,37,62,33,163,37,248,226,248,141,32,213,184,64, +89,56,39,49,224,137,60,100,5,96,38,35,249,8,15,18,61,96,17,60,200,6,145,1, +17,31,206,64,89,45,2,39,161,0,178,122,209,63,74,2,101,64,202,113,67,77,235, +64,92,221,197,186,196,143,4,9,19,188,1,25,187,139,112,128,178,113,110,177, +35,193,2,68,239,0,46,110,229,30,242,71,130,4,137,222,4,35,55,113,110,16,22, +78,81,239,36,120,32,72,157,224,64,147,138,25,237,0,52,72,242,2,126,82,3,74, +129,148,227,234,66,12,112,28,140,155,104,203,169,158,9,133,158,4,25,36,1, +61,96,47,181,80,46,132,129,255,255,255,255,255,255,222,254,39,172,67,118, +170,5,208,144,0,64,0,0,0,0,0,0,51,16,0,0,0,0,0,0,62,31,200,245,238,146,38, +138,147,105,13,42,26,137,226,0,0,0,0,0,0,7,131,249,30,180,134,4,209,82,109, +33,165,67,81,60,64,0,0,0,0,0,0,240,255,28,144,155,104,0,0,0,0,0,0,0,0,16, +117,59,130,48,155,98,48,187,144,3,205,220,42,46,65,237,72,27,55,112,151, +123,154,70,205,0,94,208,129,115,119,31,18,9,18,67,155,183,34,12,176,96,175, +4,100,74,228,3,237,38,43,31,192,109,117,171,0,228,164,219,72,0,0,0,0,0,0, +248,127,196,234,111,0,50,110,224,193,50,114,83,138,26,107,192,131,38,238, +77,12,39,37,56,161,166,188,11,132,188,12,74,110,226,220,32,44,156,24,38,78, +74,113,67,77,120,28,148,221,197,184,64,89,57,52,48,156,148,226,134,154,240, +64,195,94,8,56,123,193,11,85,116,140,45,240,3,152,147,228,208,194,95,0,89, +137,62,22,139,95,48,64,70,200,67,28,98,79,180,152,139,218,45,124,193,1,27, +33,16,65,137,62,49,205,153,236,132,81,102,36,251,73,137,157,115,102,123,33, +24,57,137,62,12,19,37,144,142,40,196,159,105,49,15,160,153,44,132,128,198, +36,248,48,98,200,73,18,98,79,180,152,135,208,98,200,74,16,98,79,135,117,35, +43,33,44,89,137,62,210,98,63,93,72,202,200,76,20,98,79,140,67,105,50,74, +200,77,26,98,79,180,152,153,212,54,147,36,172,132,225,70,36,249,34,9,205, +28,172,132,241,166,36,251,73,138,93,32,156,209,202,200,80,30,98,79,140,66, +214,137,16,78,104,229,100,40,146,49,39,218,76,76,234,22,180,72,130,115,71, +43,33,72,137,137,62,77,12,38,92,210,113,197,44,137,59,64,7,145,39,201,161, +132,184,64,249,18,124,98,22,180,72,130,115,71,43,101,76,148,137,62,210,98, +103,80,181,162,68,19,154,57,91,42,130,164,73,242,68,19,154,57,91,95,84,108, +137,62,210,98,151,72,39,52,114,182,190,176,169,18,124,98,27,73,146,86,223, +215,27,34,79,180,152,153,212,54,147,36,173,191,176,34,68,159,14,234,70,86, +231,217,23,34,79,180,152,143,215,82,50,183,62,208,121,18,124,24,38,75,101, +108,84,137,62,210,98,31,65,50,91,43,130,36,73,241,142,108,207,109,125,209, +114,36,251,73,137,157,115,102,123,107,239,11,145,39,194,209,107,230,8,8, +219,127,124,116,137,62,210,98,47,104,181,243,4,4,109,191,192,135,49,39,204, +16,17,178,24,32,242,36,249,130,2,54,203,7,6,104,14,76,131,140,144,0,0,0,0, +0,0,0,1,141,207,215,12,78,126,193,46,190,126,192,98,179,246,4,197,231,236, +10,193,9,114,11,172,64,73,146,83,236,145,169,237,1,6,120,14,78,129,179,40, +249,18,149,175,207,141,199,27,76,248,156,81,177,207,139,198,9,169,199,129, +58,136,19,202,11,179,20,240,149,2,248,72,197,209,200,148,162,117,48,39,148, +151,102,42,228,64,211,19,132,140,93,28,137,74,39,85,2,121,81,118,98,238,68, +133,36,72,209,19,132,140,93,28,137,74,39,87,2,121,89,118,98,190,75,13,152, +47,194,70,46,142,68,165,19,172,129,60,176,187,49,79,39,135,147,132,140,93, +28,137,74,39,91,2,121,105,118,98,142,210,40,39,99,23,71,34,82,135,8,128, +120,72,13,42,226,145,97,87,224,168,1,58,182,232,232,64,22,85,181,187,177, +107,2,64,7,213,183,74,7,121,207,215,242,17,119,49,248,94,173,198,210,36,15, +232,34,182,84,113,95,115,240,221,91,141,163,160,72,1,220,164,194,175,121, +123,103,224,186,244,64,24,45,68,84,251,33,9,64,15,217,66,51,209,218,210, +129,154,118,254,205,61,65,204,126,23,178,132,103,165,3,52,237,253,154,122, +131,216,252,167,224,121,44,48,46,95,203,166,238,74,113,67,77,201,128,219, +152,164,82,6,0,203,76,64,64,9,210,211,18,4,4,144,221,49,40,64,76,13,211,19, +5,4,192,221,45,66,1,4,24,207,76,82,2,8,136,94,152,156,24,157,45,49,64,6,75, +191,76,80,66,149,110,116,116,197,8,41,240,247,79,70,188,6,183,27,76,80,194, +45,198,210,211,20,144,171,113,180,116,52,197,40,27,1,125,34,240,27,16,221, +42,240,27,221,109,66,32,104,129,163,115,52,224,5,139,168,209,233,138,32,57, +33,186,98,138,18,80,140,244,197,24,28,192,221,49,71,11,56,209,162,211,20, +183,1,66,188,17,145,52,40,9,148,226,134,153,5,198,137,136,32,14,12,30,164, +140,144,230,192,0,0,0,0,128,136,211,64,182,120,43,135,126,16,68,52,174,195, +144,12,2,158,4,128,70,22,24,128,101,67,112,163,192,100,104,176,131,192,99, +32,176,99,192,226,115,30,1,79,4,68,28,16,54,0,0,41,254,232,116,62,204,7,21, +35,18,54,127,80,28,192,132,28,32,14,96,197,212,243,193,48,188,240,39,130, +236,224,175,131,117,2,178,112,145,139,163,145,131,114,70,46,142,218,27,182, +72,197,209,219,56,26,53,161,166,32,128,56,18,2,129,239,94,50,76,130,68,230, +202,113,160,167,146,94,163,134,66,161,164,227,226,231,146,51,198,249,147, +71,209,67,73,210,94,24,49,39,199,89,188,124,92,242,70,120,224,201,33,69,15, +155,163,191,68,28,98,79,143,139,166,233,225,228,227,139,198,37,210,244,208, +24,137,112,151,153,27,36,5,100,224,146,105,184,100,196,95,18,84,141,159,9, +121,145,178,67,155,46,33,38,187,168,252,211,243,81,92,2,14,40,16,50,37,202, +160,150,154,67,152,148,20,28,76,156,89,26,105,158,63,232,16,44,150,129,18, +146,44,28,96,14,98,216,80,113,50,113,100,105,166,120,255,160,20,28,76,156, +113,75,34,78,63,236,3,6,133,41,35,31,242,18,195,152,147,226,27,61,138,41, +140,16,98,79,148,67,103,177,69,45,136,49,39,196,54,122,58,212,83,26,36,196, +159,40,134,207,71,90,138,92,16,98,79,136,108,244,244,168,166,56,73,137,62, +81,13,158,158,149,20,186,40,196,159,10,183,2,122,122,84,82,240,163,18,124, +42,220,9,235,106,81,75,225,228,73,241,13,158,197,54,198,8,145,39,202,33, +179,216,166,214,196,72,147,226,27,61,29,106,109,141,19,34,79,148,67,103, +163,173,77,174,8,145,39,196,54,122,122,84,219,28,38,68,159,40,134,207,79, +74,155,93,21,34,79,133,91,129,61,61,42,109,120,84,137,62,21,110,4,245,181, +41,181,248,56,224,28,24,80,113,50,113,100,105,166,120,255,160,20,28,76,156, +113,75,34,78,63,236,3,6,133,41,35,31,242,11,174,254,160,34,84,8,35,16,98, +146,38,55,32,33,30,135,19,36,182,158,72,237,17,100,97,27,56,0,0,0,0,0,0,30, +7,230,56,199,161,30,135,19,36,182,158,72,237,17,100,97,27,56,0,0,0,0,0,0, +30,7,230,55,36,33,30,135,19,36,182,158,72,237,17,100,97,27,56,0,0,0,0,0,0, +30,7,234,40,11,91,133,199,172,8,111,248,128,239,88,16,222,56,191,242,49, +198,69,8,244,56,153,37,180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,240,63, +49,185,65,8,244,56,153,37,180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,240, +63,49,198,77,8,244,56,153,37,180,242,71,104,139,35,8,217,192,0,0,0,0,0,0, +240,63,49,185,97,8,244,56,153,37,180,242,71,104,139,35,8,217,192,0,0,0,0,0, +0,0,64,49,198,85,8,244,56,153,37,180,242,71,104,139,35,8,217,192,0,0,0,0,0, +0,0,64,49,185,129,8,244,56,153,37,180,242,71,104,139,35,8,217,192,0,0,0,0, +0,0,0,64,49,198,93,8,244,56,153,37,180,242,71,104,139,35,8,217,192,0,0,0,0, +0,0,0,64,49,185,161,8,244,56,153,37,180,242,71,104,139,35,8,217,192,0,0,0, +0,0,0,16,64,49,198,101,8,244,56,153,37,180,242,71,104,139,35,8,217,192,0,0, +0,0,0,0,16,64,49,185,193,8,244,56,153,37,180,242,71,104,139,35,8,217,192,0, +0,0,0,0,0,16,64,49,198,109,8,244,56,153,37,180,242,71,104,139,35,8,217,192, +0,0,0,0,0,0,16,64,49,185,225,8,244,56,153,37,180,242,71,104,139,35,8,217, +192,0,0,0,0,0,0,16,64,49,198,117,8,244,56,153,37,180,242,71,104,139,35,8, +217,192,0,0,0,0,0,0,16,64,49,186,1,8,244,56,153,37,180,242,71,104,139,35,8, +217,192,0,0,0,0,0,0,32,64,49,198,125,8,244,56,153,37,180,242,71,104,139,35, +8,217,192,0,0,0,0,0,0,32,64,32,232,130,0,97,57,162,4,245,72,10,68,184,70, +137,195,67,77,175,32,66,37,192,208,165,36,117,196,10,14,38,78,44,141,52, +207,169,64,56,156,199,130,36,160,141,146,52,38,32,76,72,1,246,136,235,103, +177,69,1,17,32,7,196,54,123,20,82,88,200,144,3,237,17,214,207,71,91,171,37, +20,65,145,32,7,218,35,173,158,142,183,66,74,41,16,92,72,1,241,13,158,142, +183,86,74,41,48,92,72,1,241,13,158,142,183,66,74,41,80,100,72,1,246,136, +235,103,167,165,213,146,138,40,200,144,3,237,17,214,207,79,75,161,37,20, +138,46,36,0,248,134,207,79,75,171,37,20,154,46,36,0,248,134,207,79,75,161, +37,20,170,46,36,0,248,85,184,19,234,201,69,24,92,72,1,240,171,112,39,208, +146,138,70,25,18,0,124,27,168,21,147,171,37,20,113,145,32,7,193,186,129,89, +58,18,81,72,226,162,64,15,180,71,91,62,172,148,90,0,168,144,3,237,17,214, +207,161,37,22,144,38,36,0,248,134,207,171,37,22,160,38,36,0,248,134,207, +161,37,22,176,42,209,68,201,218,35,173,158,197,54,4,218,40,153,56,134,207, +98,155,75,27,104,162,100,237,17,214,207,71,91,171,37,54,65,182,138,38,78, +209,29,108,244,117,186,18,83,104,131,45,20,76,156,67,103,163,173,213,146, +155,76,25,104,162,100,226,27,61,29,110,132,148,218,160,219,69,19,39,104, +142,182,122,122,93,89,41,178,141,180,81,50,118,136,235,103,167,165,208,146, +155,69,25,104,162,100,226,27,61,61,46,172,148,218,104,203,69,19,39,16,217, +233,233,116,36,166,213,70,90,40,153,56,85,184,19,234,201,77,152,101,162, +137,147,133,91,129,62,132,148,218,48,219,69,19,39,6,234,5,100,234,201,77, +156,109,162,137,147,131,117,2,178,116,36,166,209,197,218,40,153,59,68,117, +179,234,201,78,32,11,180,81,50,118,136,235,103,208,146,156,72,21,104,162, +100,226,27,62,172,148,226,128,171,69,19,39,16,217,244,36,167,22,53,59,22, +53,91,0,2,21,11,94,181,128,196,133,0,185,80,32,56,156,199,130,36,160,72,16, +78,126,53,144,5,146,208,34,82,72,1,109,20,76,155,40,32,233,0,115,70,130,8, +209,56,104,105,187,252,193,3,17,162,112,201,242,18,65,211,0,230,149,132,17, +162,112,208,211,119,248,0,82,130,96,95,127,128,130,80,102,186,36,232,92, +206,255,1,80,48,200,39,12,158,241,64, }; #elif defined(DUK_USE_DOUBLE_BE) -DUK_INTERNAL const duk_uint8_t duk_builtins_data[3833] = { -105,195,75,32,3,148,52,154,248,9,26,13,128,112,105,0,240,22,20,26,95,124,6, -152,52,137,0,120,99,74,239,129,18,70,241,191,2,98,13,79,32,42,88,210,90,2, -240,1,50,141,37,168,76,94,216,118,69,229,203,127,44,0,84,163,73,106,21,75, -14,236,249,98,242,229,191,150,0,46,81,164,181,14,165,151,54,94,89,119,99, -203,23,151,45,252,176,1,146,141,37,168,93,63,59,186,97,241,23,151,45,252, -176,1,178,141,37,168,77,79,60,50,197,229,203,127,44,0,116,163,73,106,17,86, -148,152,188,185,111,229,128,15,148,129,198,137,36,58,166,142,91,251,212, -243,195,44,94,92,183,242,13,79,8,45,14,91,252,121,148,52,199,120,63,72,105, -21,240,118,128,210,237,224,245,17,165,43,224,211,55,231,207,151,148,161,70, -145,0,31,40,107,26,2,18,138,26,228,192,142,0,16,161,174,76,9,74,26,228,192, -158,0,8,161,174,76,10,96,2,42,26,228,192,174,0,26,161,174,76,11,96,3,74,26, -228,192,190,0,44,161,174,76,12,96,3,202,26,228,192,206,0,70,161,169,84,14, -202,3,255,254,32,234,3,255,192,0,0,0,0,0,0,119,1,255,192,0,0,0,0,0,0,57, -136,1,152,32,16,194,0,166,24,6,49,0,57,138,2,12,96,18,99,128,163,32,5,153, -40,76,94,216,118,69,229,203,127,35,41,10,165,135,118,124,177,121,114,223, -200,203,67,169,101,205,151,150,93,216,242,197,229,203,127,35,49,11,167,231, -119,76,62,34,242,229,191,145,154,132,212,243,195,44,94,92,183,242,51,144, -138,180,164,197,229,203,127,35,60,6,26,0,52,208,193,226,117,215,211,15,12, -166,146,11,67,150,255,30,77,24,58,113,64,243,92,8,27,0,68,217,130,70,212, -19,54,224,161,185,5,77,216,44,111,65,115,126,12,28,16,100,225,156,16,32,18, -17,195,15,46,121,100,238,232,136,136,87,12,60,185,229,141,179,126,30,136, -100,130,233,231,59,12,228,34,66,52,243,141,167,118,158,153,80,73,9,201,151, -30,252,153,106,210,146,118,72,150,76,184,247,228,203,86,148,152,123,246, -240,223,187,46,238,135,132,132,229,221,143,126,76,181,105,73,61,36,75,46, -236,123,242,101,171,74,76,61,251,120,111,221,151,119,67,226,65,178,243,199, -135,134,83,242,66,58,238,203,207,30,30,25,81,201,5,225,203,78,238,136,163, -208,92,59,50,242,232,138,62,0,2,38,163,19,255,255,224,142,80,192,0,20,31, -240,14,135,103,203,210,135,45,253,55,244,243,195,44,252,205,197,0,1,18,221, -82,0,3,24,207,151,164,254,251,168,114,223,195,47,46,158,98,101,231,143,150, -158,29,55,242,104,68,79,62,94,147,251,238,161,203,127,12,188,186,121,157, -135,110,94,109,100,131,99,229,151,15,76,172,168,8,89,217,16,201,151,54,157, -217,104,114,223,195,47,46,154,114,243,102,68,19,158,92,59,27,73,6,205,203, -46,95,89,91,74,0,3,17,225,203,47,108,187,186,69,241,211,46,238,122,119,238, -230,216,72,70,158,116,242,225,217,151,35,81,33,26,121,198,229,191,214,93, -205,69,0,1,134,105,231,23,199,76,187,185,233,197,179,43,73,32,154,242,249, -230,214,80,0,31,255,193,2,38,103,110,117,24,81,115,0,78,228,0,161,208,16, -237,24,121,207,239,186,135,45,252,50,242,233,229,188,144,221,60,232,114, -223,211,127,79,60,50,207,204,224,72,167,14,91,248,101,229,211,204,158,113, -119,117,219,151,150,28,91,50,184,144,40,95,224,0,15,248,64,4,20,78,129,5, -195,195,134,207,38,232,130,99,195,179,97,201,244,19,22,157,217,14,15,130, -135,254,0,48,125,60,224,242,229,135,200,9,1,255,12,2,162,136,112,2,112,80, -128,0,193,177,239,221,143,15,64,35,224,152,20,144,62,27,248,3,2,9,195,175, -61,0,231,208,126,89,123,101,229,207,40,72,32,188,244,105,205,208,40,16,94, -123,52,227,202,22,136,39,61,252,186,6,18,13,207,134,205,56,242,134,175,65, -250,238,231,163,78,110,129,231,208,125,59,178,101,241,63,48,25,248,0,12,47, -102,30,125,36,238,201,151,196,252,192,103,255,255,240,92,189,178,242,242,8, -105,4,231,191,110,80,67,80,0,24,62,109,252,162,225,199,160,16,212,0,10,7, -183,15,0,67,80,0,56,54,109,59,58,101,228,8,106,0,9,6,229,151,39,92,121,66, -15,192,0,97,124,178,228,235,143,45,45,57,244,116,8,63,255,255,10,39,248,0, -195,51,114,223,182,30,140,60,161,239,201,149,248,248,31,241,0,140,80,129, -202,10,49,128,10,35,1,6,199,163,15,40,61,32,9,10,199,163,15,40,123,242,101, -131,210,4,144,108,123,247,99,195,210,8,250,15,167,118,76,190,39,230,131,52, -133,236,195,207,164,157,217,50,248,159,154,12,212,0,6,27,179,126,60,59,50, -195,223,183,134,30,89,97,9,5,219,135,166,61,16,164,131,242,203,195,102,28, -121,97,145,6,231,151,15,44,122,33,201,5,231,179,78,60,177,8,130,243,225, -179,79,72,148,66,121,245,197,207,167,45,59,179,197,162,23,211,124,205,253, -242,242,135,135,158,87,240,68,122,111,153,191,30,29,153,102,111,239,151, -148,60,60,242,191,130,23,211,125,94,28,50,242,135,135,158,87,240,128,0,196, -122,111,153,191,30,29,153,106,240,225,151,148,60,60,242,191,132,0,6,9,211, -150,157,177,160,131,115,235,139,159,78,81,72,10,47,248,0,3,254,40,17,138, -48,66,136,152,64,0,66,129,48,5,27,252,88,76,216,54,47,214,131,50,172,88,15, -253,255,255,255,255,255,255,240,153,178,103,95,173,6,101,88,176,0,0,0,0,0, -0,0,0,67,168,15,255,0,0,0,0,0,0,17,26,19,233,201,169,38,180,91,242,103,70, -147,58,77,75,48,31,252,0,0,0,0,0,0,34,51,162,199,131,82,77,104,183,228,206, -141,38,116,154,150,96,127,248,0,0,0,0,0,0,0,15,248,192,70,40,0,0,0,0,0,0,0, -0,3,10,44,68,9,216,8,20,49,130,15,211,124,109,62,50,228,95,36,55,166,248, -190,56,111,221,151,119,77,56,118,47,18,23,211,125,14,89,113,233,231,167, -126,230,18,5,31,252,0,224,188,48,242,231,148,116,144,58,181,33,143,127,64, -247,111,238,56,0,127,199,2,49,72,127,248,0,0,0,0,0,0,180,81,36,4,51,166, -248,152,122,101,167,211,150,157,217,201,2,0,3,12,233,190,166,157,185,105, -244,229,167,118,114,64,128,1,4,228,129,0,3,137,116,223,51,126,60,59,50,196, -195,211,45,62,156,180,238,206,72,16,0,72,151,77,243,55,227,195,179,45,77, -59,114,211,233,203,78,236,228,129,0,5,10,73,2,0,12,21,18,4,0,28,82,35,32, -80,74,8,62,124,189,42,105,219,148,148,16,188,249,122,70,235,179,101,156, -184,121,15,132,0,34,29,159,47,74,181,33,198,235,179,101,156,184,121,15,132, -0,38,17,159,47,73,187,247,116,208,62,16,0,168,94,124,189,42,212,135,55,126, -238,154,7,194,0,23,7,207,151,164,76,61,50,143,132,0,50,21,159,47,74,181,33, -196,195,211,40,248,64,3,96,217,242,244,137,135,200,248,64,3,161,57,242,244, -171,82,28,76,62,71,194,0,31,8,207,151,164,141,253,121,115,31,8,0,132,47,62, -94,149,106,67,145,191,175,46,99,225,0,17,133,103,203,210,110,157,221,122, -101,230,62,16,1,40,110,124,189,42,212,135,55,78,238,189,50,243,31,8,0,156, -43,62,94,148,242,227,223,187,39,49,240,128,10,67,115,229,233,86,164,58,121, -113,239,221,147,152,248,64,5,97,249,242,244,155,167,102,205,60,242,227,223, -187,39,49,240,128,11,68,179,229,233,86,164,57,186,118,108,211,207,46,61, -251,178,115,31,8,0,188,71,62,94,149,52,237,203,235,126,236,179,243,102,231, -151,161,0,32,252,242,244,169,167,110,82,34,67,249,229,233,55,78,205,154, -121,229,199,191,118,78,100,37,0,24,137,115,203,210,173,72,115,116,236,217, -167,158,92,123,247,100,230,66,80,1,152,87,60,189,41,229,199,191,118,78,100, -43,224,3,80,222,121,122,85,169,14,158,92,123,247,100,230,66,190,0,55,10, -231,151,164,221,59,186,244,203,204,133,252,0,114,27,207,47,74,181,33,205, -211,187,175,76,188,200,95,192,7,97,28,242,244,145,191,175,46,100,51,224,3, -208,190,121,122,85,169,14,70,254,188,185,144,207,128,15,193,249,229,233,19, -15,76,164,37,0,32,133,115,203,210,173,72,113,48,244,202,66,80,2,24,71,60, -189,38,239,221,211,65,10,248,1,20,47,158,94,149,106,67,155,191,119,77,4,43, -224,4,112,190,121,122,70,235,179,101,156,184,121,16,191,128,18,67,185,229, -233,86,164,56,221,118,108,179,151,15,34,23,240,2,88,62,124,189,44,229,195, -200,124,32,4,208,126,121,122,89,203,135,145,9,64,9,194,145,254,0,0,255,144, -24,100,130,14,0,16,176,2,192,129,11,33,12,1,168,193,108,96,186,48,95,32,0, -0,0,0,0,0,0,0,56,38,95,25,113,189,18,9,211,47,62,143,100,20,95,0,20,159, -240,0,7,252,144,162,241,2,195,66,7,11,89,204,140,197,252,229,197,226,230, -115,3,16,69,19,64,5,43,252,0,9,255,40,16,188,33,49,123,97,217,23,151,45, -252,131,66,7,0,20,191,240,0,39,252,176,66,240,133,82,195,187,62,88,188,185, -111,228,26,16,56,0,166,127,128,1,63,230,2,23,132,58,150,92,217,121,101,221, -143,44,94,92,183,242,13,8,28,0,83,127,192,0,159,243,65,11,194,23,79,206, -238,152,124,69,229,203,127,32,208,129,192,5,59,252,0,9,255,56,16,188,33,53, -60,240,203,23,151,45,252,131,66,7,0,20,255,240,0,39,252,240,66,240,132,85, -165,38,47,46,91,249,6,132,14,0,31,255,228,64,98,192,64,5,191,10,139,20,87, -105,130,76,156,197,132,4,0,38,187,27,187,85,81,104,28,201,204,160,31,243, -23,33,127,125,28,247,193,102,79,142,202,44,3,255,113,84,118,82,184,47,232, -52,201,241,216,176,139,0,255,111,45,236,84,155,148,58,5,66,76,4,0,146,31, -181,68,66,209,136,61,58,52,170,49,190,202,1,255,53,4,243,51,249,222,108,22, -157,26,85,25,64,63,246,160,158,102,127,59,205,74,7,135,23,53,2,65,48,227, -223,205,64,160,0,48,76,60,244,238,80,40,0,20,19,15,76,59,148,10,0,7,5,195, -211,14,230,74,72,130,99,203,167,98,129,64,1,32,120,247,243,80,40,0,44,15, -47,142,10,5,0,6,130,230,217,191,127,37,2,128,3,192,246,111,206,160,80,0, -136,30,220,62,19,151,160,123,116,238,79,94,129,240,223,221,73,32,0,48,110, -88,119,100,223,181,68,16,94,91,250,238,200,160,80,0,152,31,61,59,148,10,0, -21,4,231,199,151,69,2,128,5,192,250,97,220,160,80,0,192,127,255,128,20,23, -134,30,92,242,164,34,19,207,167,45,59,179,233,205,229,37,129,127,255,0,0, -191,255,128,0,63,255,197,131,246,203,203,158,157,251,160,32,98,90,0,0,0,0, -0,3,166,156,30,53,32,249,165,131,76,223,159,62,94,70,172,114,16,176,144,60, -56,250,19,18,5,159,25,89,32,121,180,238,42,30,129,229,221,140,164,122,7, -147,46,50,129,232,62,61,251,120,97,199,208,156,129,83,127,0,50,250,69,3, -252,131,32,248,250,242,229,151,119,72,240,3,254,148,0,2,168,254,0,0,255, -167,0,33,68,88,32,0,33,64,176,2,170,254,0,0,255,169,0,33,69,220,32,0,33,67, -184,2,172,254,0,0,255,171,8,137,144,128,0,0,0,0,0,0,0,68,73,4,195,187,126, -226,8,4,178,16,41,164,32,147,7,136,52,193,240,0,18,17,48,124,0,8,133,76,31, -0,3,33,147,7,192,1,8,116,193,240,0,82,127,255,132,47,65,11,137,191,174,45, -153,98,242,229,191,144,105,4,95,47,46,91,249,32,211,185,6,94,92,183,242,65, -163,14,236,155,52,238,206,0,85,255,192,6,13,167,157,109,57,123,136,144,31, -245,192,3,5,231,179,78,60,163,9,0,2,10,199,248,0,3,254,192,4,32,249,242, -244,147,187,163,129,116,128,24,66,51,229,233,87,78,238,142,5,210,0,65,8, -207,151,164,157,221,24,182,23,72,1,140,39,62,94,149,116,238,232,197,176, -186,64,8,97,25,242,244,147,187,163,54,66,233,0,50,132,231,203,210,174,157, -221,25,178,23,72,1,20,43,62,94,145,182,111,195,209,155,33,116,128,17,194, -179,229,233,27,102,252,61,27,52,23,72,1,36,31,158,94,146,119,116,112,50, -208,3,8,71,60,189,42,233,221,209,192,203,64,8,33,28,242,244,147,187,163,22, -195,45,0,49,132,243,203,210,174,157,221,24,182,25,104,1,12,35,158,94,146, -119,116,102,200,101,160,6,80,158,121,122,85,211,187,163,54,67,45,0,34,133, -115,203,210,54,205,248,122,51,100,50,208,2,56,87,60,189,35,108,223,135,163, -102,131,45,0,36,7,255,248,1,11,50,136,132,115,235,139,15,46,88,124,140,36, -0,4,43,79,224,139,16,15,252,0,0,0,0,0,0,0,101,253,152,0,5,109,252,17,98,1, -255,128,0,0,0,0,0,0,12,191,181,0,0,174,63,130,44,64,63,240,0,0,0,0,0,0,1, -151,246,224,0,21,215,240,69,136,8,0,0,0,0,0,0,0,0,50,254,228,0,2,188,254,8, -177,1,0,0,0,0,0,0,0,0,6,95,221,128,0,87,223,193,22,32,32,8,0,0,0,0,0,0,0, -203,251,208,0,11,3,248,34,196,4,1,0,0,0,0,0,0,0,25,127,126,0,1,97,127,4,88, -128,128,32,0,0,0,0,0,0,3,47,240,64,0,44,79,224,139,16,16,8,0,0,0,0,0,0,0, -101,254,24,0,5,141,252,1,96,216,247,238,199,135,162,162,33,90,121,197,221, -143,126,77,59,179,172,146,17,167,156,46,185,179,101,228,176,65,89,77,16, -124,123,246,240,195,203,40,162,64,0,193,255,138,5,144,158,89,112,228,171, -39,119,71,2,232,132,114,203,135,36,157,221,28,11,164,0,66,25,203,46,28,149, -100,238,232,197,180,200,162,233,0,1,134,114,203,135,37,89,59,186,49,109,10, -40,186,64,2,97,124,178,225,201,39,119,70,45,166,69,23,72,0,140,47,150,92, -57,36,238,232,197,180,40,162,233,0,25,134,114,203,135,37,89,59,186,51,101, -50,40,186,64,0,161,156,178,225,201,86,78,238,140,217,66,138,46,144,0,168, -95,44,184,114,73,221,209,155,41,145,69,210,0,37,11,229,151,14,73,59,186,51, -101,10,40,186,64,6,161,124,178,225,201,27,102,252,61,38,69,23,72,0,28,47, -150,92,57,35,108,223,135,164,40,162,233,0,11,134,114,203,135,36,77,253,113, -108,203,50,40,186,64,1,33,156,178,225,201,19,127,92,91,50,194,138,46,144,0, -200,87,44,184,114,85,147,187,164,200,162,237,0,5,133,114,203,135,37,89,59, -186,66,138,46,208,0,216,79,44,184,114,73,221,210,100,81,118,128,10,194,121, -101,195,146,78,238,144,162,139,180,0,118,21,223,150,158,153,106,201,221, -209,192,203,33,61,249,105,233,150,78,238,142,6,90,0,33,13,239,203,79,76, -181,100,238,232,197,180,200,163,45,0,1,134,247,229,167,166,90,178,119,116, -98,218,20,81,150,128,4,195,59,242,211,211,44,157,221,24,182,153,20,101,160, -2,48,206,252,180,244,203,39,119,70,45,161,69,25,104,0,204,55,191,45,61,50, -213,147,187,163,54,83,34,140,180,0,10,27,223,150,158,153,106,201,221,209, -155,40,81,70,90,0,21,12,239,203,79,76,178,119,116,102,202,100,81,150,128,9, -67,59,242,211,211,44,157,221,25,178,133,20,101,160,3,80,206,252,180,244, -203,27,102,252,61,38,69,25,104,0,28,51,191,45,61,50,198,217,191,15,72,81, -70,90,0,23,13,239,203,79,76,177,55,245,197,179,44,200,163,45,0,4,134,247, -229,167,166,88,155,250,226,217,150,20,81,150,128,6,66,251,242,211,211,45, -89,59,186,76,138,51,16,0,88,95,126,90,122,101,171,39,119,72,81,70,98,0,27, -10,239,203,79,76,178,119,116,153,20,102,32,2,176,174,252,180,244,203,39, -119,72,81,70,98,0,58,40,173,176,82,90,4,19,54,157,155,21,217,6,203,199,174, -29,156,197,9,7,199,191,111,12,60,178,138,20,0,6,9,143,127,15,42,208,130, -243,217,167,30,81,132,65,123,242,211,211,42,228,0, +DUK_INTERNAL const duk_uint8_t duk_builtins_data[3790] = { +144,148,105,221,32,68,52,228,62,12,104,200,165,134,148,248,81,77,61,191, +135,35,154,103,34,72,6,157,159,197,145,77,245,126,52,130,106,234,163,196, +52,226,18,51,161,26,113,1,60,37,64,190,18,49,116,116,33,26,113,1,92,136,26, +98,112,145,139,163,165,8,211,136,14,228,72,82,68,141,17,56,72,197,209,212, +132,105,196,5,242,88,108,193,126,18,49,116,117,161,26,113,1,60,158,30,78, +18,49,116,118,33,26,113,1,29,164,80,78,198,46,142,212,36,68,51,71,224,59, +147,60,93,110,79,15,39,9,24,186,33,13,63,79,185,38,154,121,223,110,76,66, +53,116,1,120,248,186,248,136,67,76,196,200,134,186,137,177,13,31,192,174, +79,15,32,248,8,196,24,8,107,254,39,97,161,175,248,159,16,215,252,80,186,26, +255,138,57,136,107,254,41,100,33,175,248,167,170,134,191,226,166,138,26, +255,138,187,40,107,254,43,111,33,171,86,181,16,209,241,11,228,201,121,240, +141,19,134,72,196,52,123,168,95,38,75,207,131,32,156,50,70,33,195,3,152, +128,255,240,0,0,0,0,0,1,153,128,255,224,0,0,0,0,0,1,151,137,0,214,9,188,35, +131,12,225,196,56,177,78,60,99,147,28,229,200,57,162,120,74,129,124,36,98, +232,156,241,92,136,26,98,112,145,139,162,116,71,114,36,41,34,70,136,156,36, +98,232,157,49,124,150,27,48,95,132,140,93,19,170,39,147,195,201,194,70,46, +137,215,17,218,69,4,236,98,232,157,153,39,110,81,220,15,193,209,83,3,200, +119,130,241,241,117,240,120,80,252,137,10,178,10,103,134,180,122,9,135,136, +154,120,169,199,142,158,121,10,7,146,162,121,74,71,150,166,121,138,135,154, +170,121,202,199,158,23,201,146,243,225,26,39,12,145,61,16,190,76,151,159,6, +65,56,100,137,233,35,93,205,144,33,224,140,137,196,54,121,244,5,60,17,145, +56,85,184,19,207,16,21,18,227,65,198,231,72,16,137,112,168,106,38,76,225,2, +70,65,56,100,237,34,140,177,4,134,65,56,100,237,34,129,117,204,123,154,70, +207,46,64,146,52,78,25,59,72,163,48,65,34,52,78,25,59,72,160,93,115,30,230, +145,179,204,144,24,146,16,30,76,209,2,40,210,72,64,121,52,4,0,156,88,97,5, +194,96,227,18,124,124,93,55,79,15,39,28,94,49,38,159,154,136,96,196,159,29, +102,241,241,115,201,25,227,131,36,133,20,62,110,142,253,2,102,36,248,235, +55,143,139,158,72,207,28,104,24,73,112,201,3,2,82,65,155,187,94,6,20,72,9, +147,120,128,225,144,168,105,56,248,185,228,140,241,190,96,128,200,84,52, +156,124,92,242,70,104,36,183,168,4,145,0,190,41,1,139,18,19,36,226,146,17, +124,73,82,54,124,37,230,70,201,14,108,184,132,8,68,185,34,1,100,31,8,129,8, +151,11,23,100,141,225,18,12,68,184,75,204,141,146,2,178,112,72,8,162,98,92, +50,10,152,147,227,172,222,62,46,121,35,60,114,88,96,92,185,112,201,65,34, +92,4,1,147,81,159,141,205,32,234,121,96,97,57,64,97,121,128,14,56,37,199, +89,188,124,92,242,70,120,227,144,53,18,227,226,233,186,120,121,56,226,242, +8,40,248,185,228,140,241,196,75,132,109,24,72,128,43,39,36,136,48,64,114,0, +250,156,168,1,64,247,175,25,36,2,8,11,94,80,248,16,40,104,242,103,200,48, +193,3,162,92,4,98,12,41,14,66,40,106,101,1,132,130,8,24,78,104,129,54,62, +96,224,144,13,238,124,32,2,62,146,60,51,224,120,146,164,140,137,20,0,178, +58,11,56,192,5,146,208,34,71,64,36,157,25,200,32,52,158,180,8,146,87,129, +232,217,29,5,156,179,224,116,52,100,191,28,87,62,130,214,9,79,136,104,201, +126,56,174,127,0,31,255,225,73,82,71,16,13,1,36,230,18,1,164,14,87,71,132, +0,143,0,210,131,96,31,0,211,6,42,23,50,70,1,167,13,18,14,130,36,67,232,46, +36,29,4,78,69,6,60,226,31,192,7,255,252,24,160,163,11,23,51,130,56,35,193, +56,100,238,31,6,150,46,103,4,225,147,143,114,27,62,233,241,200,137,182,133, +42,142,167,216,6,23,216,0,97,28,17,224,39,223,32,80,142,8,240,78,25,56,9, +248,8,22,39,12,156,123,144,217,240,19,240,18,6,19,154,32,79,194,124,14,134, +140,151,227,139,226,52,11,88,37,62,33,163,37,248,226,248,141,32,213,184,64, +89,56,39,49,224,137,60,100,5,96,38,35,249,8,15,18,61,96,17,60,200,6,145,1, +17,31,206,64,89,45,2,39,161,0,178,122,209,63,74,2,101,64,202,113,67,77,235, +64,92,221,197,186,196,143,4,9,19,188,1,25,187,139,112,128,178,113,110,177, +35,193,2,68,239,0,46,110,229,30,242,71,130,4,137,222,4,35,55,113,110,16,22, +78,81,239,36,120,32,72,157,224,64,147,138,25,237,0,52,72,242,2,126,82,3,74, +129,148,227,234,66,12,112,28,140,155,104,203,169,158,9,133,158,4,25,36,1, +61,96,47,181,80,46,132,128,255,223,255,255,255,255,255,254,39,172,67,118, +170,5,208,144,0,0,0,0,0,0,0,0,115,16,31,254,0,0,0,0,0,0,8,245,238,146,38, +138,147,105,13,42,26,137,226,3,255,128,0,0,0,0,0,1,30,180,134,4,209,82,109, +33,165,67,81,60,64,255,240,0,0,0,0,0,0,28,144,155,104,0,0,0,0,0,0,0,0,16, +117,59,130,48,155,98,48,187,144,3,205,220,42,46,65,237,72,27,55,112,151, +123,154,70,205,0,94,208,129,115,119,31,18,9,18,67,155,183,34,12,176,96,175, +4,100,74,228,3,237,38,43,31,192,109,117,171,0,228,164,219,72,127,248,0,0,0, +0,0,0,196,234,111,0,50,110,224,193,50,114,83,138,26,107,192,131,38,238,77, +12,39,37,56,161,166,188,11,132,188,12,74,110,226,220,32,44,156,24,38,78,74, +113,67,77,120,28,148,221,197,184,64,89,57,52,48,156,148,226,134,154,240,64, +195,94,8,56,123,193,11,85,116,140,45,240,3,152,147,228,208,194,95,0,89,137, +62,22,139,95,48,64,70,200,67,28,98,79,180,152,139,218,45,124,193,1,27,33, +16,65,137,62,49,205,153,236,132,81,102,36,251,73,137,157,115,102,123,33,24, +57,137,62,12,19,37,144,142,40,196,159,105,49,15,160,153,44,132,128,198,36, +248,48,98,200,73,18,98,79,180,152,135,208,98,200,74,16,98,79,135,117,35,43, +33,44,89,137,62,210,98,63,93,72,202,200,76,20,98,79,140,67,105,50,74,200, +77,26,98,79,180,152,153,212,54,147,36,172,132,225,70,36,249,34,9,205,28, +172,132,241,166,36,251,73,138,93,32,156,209,202,200,80,30,98,79,140,66,214, +137,16,78,104,229,100,40,146,49,39,218,76,76,234,22,180,72,130,115,71,43, +33,72,137,137,62,77,12,38,92,210,113,197,44,137,59,64,7,145,39,201,161,132, +184,64,249,18,124,98,22,180,72,130,115,71,43,101,76,148,137,62,210,98,103, +80,181,162,68,19,154,57,91,42,130,164,73,242,68,19,154,57,91,95,84,108,137, +62,210,98,151,72,39,52,114,182,190,176,169,18,124,98,27,73,146,86,223,215, +27,34,79,180,152,153,212,54,147,36,173,191,176,34,68,159,14,234,70,86,231, +217,23,34,79,180,152,143,215,82,50,183,62,208,121,18,124,24,38,75,101,108, +84,137,62,210,98,31,65,50,91,43,130,36,73,241,142,108,207,109,125,209,114, +36,251,73,137,157,115,102,123,107,239,11,145,39,194,209,107,230,8,8,219, +127,124,116,137,62,210,98,47,104,181,243,4,4,109,191,192,135,49,39,204,16, +17,178,24,32,242,36,249,130,2,54,203,7,6,104,14,76,131,140,144,0,0,0,0,0,0, +0,1,141,207,215,12,78,126,193,46,190,126,192,98,179,246,4,197,231,236,10, +193,9,114,11,172,64,73,146,83,236,145,169,237,1,6,120,14,78,129,179,40,249, +18,149,175,207,141,199,27,76,248,156,81,177,207,139,198,9,169,199,129,58, +136,19,202,11,179,20,240,149,2,248,72,197,209,200,148,162,117,48,39,148, +151,102,42,228,64,211,19,132,140,93,28,137,74,39,85,2,121,81,118,98,238,68, +133,36,72,209,19,132,140,93,28,137,74,39,87,2,121,89,118,98,190,75,13,152, +47,194,70,46,142,68,165,19,172,129,60,176,187,49,79,39,135,147,132,140,93, +28,137,74,39,91,2,121,105,118,98,142,210,40,39,99,23,71,34,82,135,8,128, +120,72,8,0,183,225,81,98,138,237,33,58,182,232,232,64,64,2,107,177,187,181, +85,22,7,213,183,74,1,255,49,114,23,247,209,207,120,94,173,198,210,36,3,255, +113,84,118,82,184,47,224,221,91,141,163,160,72,7,251,121,111,98,164,220, +161,192,186,244,64,64,9,33,251,84,68,45,24,15,217,66,51,209,218,210,128, +127,205,65,60,204,254,119,154,23,178,132,103,165,0,255,218,130,121,153,252, +239,52,167,224,121,44,48,46,95,203,166,238,74,113,67,77,201,128,219,152, +164,82,6,0,203,76,64,64,9,210,211,18,4,4,144,221,49,40,64,76,13,211,19,5,4, +192,221,45,66,1,4,24,207,76,82,2,8,136,94,152,156,24,157,45,49,64,6,75,191, +76,80,66,149,110,116,116,197,8,41,240,247,79,70,188,6,183,27,76,80,194,45, +198,210,211,20,144,171,113,180,116,52,197,40,27,1,125,34,240,27,16,221,42, +240,27,221,109,66,32,104,129,163,115,52,224,5,139,168,209,233,138,32,57,33, +186,98,138,18,80,140,244,197,24,28,192,221,49,71,11,56,209,162,211,20,183, +1,66,188,17,145,52,40,9,148,226,134,153,5,198,137,136,32,14,12,30,164,140, +144,230,192,64,211,136,128,0,0,0,0,182,120,43,135,126,16,68,52,174,195,144, +12,2,158,4,128,70,22,24,128,101,67,112,163,192,100,104,176,131,192,99,32, +176,99,192,226,115,30,1,79,4,68,28,16,54,0,0,41,254,232,116,62,204,7,21,35, +18,54,127,80,28,192,132,28,32,14,96,197,212,243,193,48,188,240,39,130,236, +224,175,131,117,2,178,112,145,139,163,145,131,114,70,46,142,218,27,182,72, +197,209,219,56,26,53,161,166,32,128,56,18,2,129,239,94,50,76,130,68,230, +202,113,160,167,146,94,163,134,66,161,164,227,226,231,146,51,198,249,147, +71,209,67,73,210,94,24,49,39,199,89,188,124,92,242,70,120,224,201,33,69,15, +155,163,191,68,28,98,79,143,139,166,233,225,228,227,139,198,37,210,244,208, +24,137,112,151,153,27,36,5,100,224,146,105,184,100,196,95,18,84,141,159,9, +121,145,178,67,155,46,33,38,187,168,252,211,243,81,92,2,14,40,16,50,37,202, +160,150,154,67,152,148,20,28,76,156,89,26,105,158,63,232,16,44,150,129,18, +146,44,28,96,14,98,216,80,113,50,113,100,105,166,120,255,160,20,28,76,156, +113,75,34,78,63,236,3,6,133,41,35,31,242,18,195,152,147,226,27,61,138,41, +140,16,98,79,148,67,103,177,69,45,136,49,39,196,54,122,58,212,83,26,36,196, +159,40,134,207,71,90,138,92,16,98,79,136,108,244,244,168,166,56,73,137,62, +81,13,158,158,149,20,186,40,196,159,10,183,2,122,122,84,82,240,163,18,124, +42,220,9,235,106,81,75,225,228,73,241,13,158,197,54,198,8,145,39,202,33, +179,216,166,214,196,72,147,226,27,61,29,106,109,141,19,34,79,148,67,103, +163,173,77,174,8,145,39,196,54,122,122,84,219,28,38,68,159,40,134,207,79, +74,155,93,21,34,79,133,91,129,61,61,42,109,120,84,137,62,21,110,4,245,181, +41,181,248,56,224,28,24,80,113,50,113,100,105,166,120,255,160,20,28,76,156, +113,75,34,78,63,236,3,6,133,41,35,31,242,11,174,254,160,34,84,8,35,16,98, +146,38,55,32,33,30,135,19,36,182,158,72,237,17,100,97,27,56,7,254,0,0,0,0, +0,0,6,56,199,161,30,135,19,36,182,158,72,237,17,100,97,27,56,7,254,0,0,0,0, +0,0,6,55,36,33,30,135,19,36,182,158,72,237,17,100,97,27,56,7,254,0,0,0,0,0, +0,10,40,11,91,133,199,172,8,111,248,128,239,88,16,222,56,191,242,49,198,69, +8,244,56,153,37,180,242,71,104,139,35,8,217,192,63,240,0,0,0,0,0,0,49,185, +65,8,244,56,153,37,180,242,71,104,139,35,8,217,192,63,240,0,0,0,0,0,0,49, +198,77,8,244,56,153,37,180,242,71,104,139,35,8,217,192,63,240,0,0,0,0,0,0, +49,185,97,8,244,56,153,37,180,242,71,104,139,35,8,217,192,64,0,0,0,0,0,0,0, +49,198,85,8,244,56,153,37,180,242,71,104,139,35,8,217,192,64,0,0,0,0,0,0,0, +49,185,129,8,244,56,153,37,180,242,71,104,139,35,8,217,192,64,0,0,0,0,0,0, +0,49,198,93,8,244,56,153,37,180,242,71,104,139,35,8,217,192,64,0,0,0,0,0,0, +0,49,185,161,8,244,56,153,37,180,242,71,104,139,35,8,217,192,64,16,0,0,0,0, +0,0,49,198,101,8,244,56,153,37,180,242,71,104,139,35,8,217,192,64,16,0,0,0, +0,0,0,49,185,193,8,244,56,153,37,180,242,71,104,139,35,8,217,192,64,16,0,0, +0,0,0,0,49,198,109,8,244,56,153,37,180,242,71,104,139,35,8,217,192,64,16,0, +0,0,0,0,0,49,185,225,8,244,56,153,37,180,242,71,104,139,35,8,217,192,64,16, +0,0,0,0,0,0,49,198,117,8,244,56,153,37,180,242,71,104,139,35,8,217,192,64, +16,0,0,0,0,0,0,49,186,1,8,244,56,153,37,180,242,71,104,139,35,8,217,192,64, +32,0,0,0,0,0,0,49,198,125,8,244,56,153,37,180,242,71,104,139,35,8,217,192, +64,32,0,0,0,0,0,0,32,232,130,0,97,57,162,4,245,72,10,68,184,70,137,195,67, +77,175,32,66,37,192,208,165,36,117,196,10,14,38,78,44,141,52,207,169,64,56, +156,199,130,36,160,141,146,52,38,32,76,72,1,246,136,235,103,177,69,1,17,32, +7,196,54,123,20,82,88,200,144,3,237,17,214,207,71,91,171,37,20,65,145,32,7, +218,35,173,158,142,183,66,74,41,16,92,72,1,241,13,158,142,183,86,74,41,48, +92,72,1,241,13,158,142,183,66,74,41,80,100,72,1,246,136,235,103,167,165, +213,146,138,40,200,144,3,237,17,214,207,79,75,161,37,20,138,46,36,0,248, +134,207,79,75,171,37,20,154,46,36,0,248,134,207,79,75,161,37,20,170,46,36, +0,248,85,184,19,234,201,69,24,92,72,1,240,171,112,39,208,146,138,70,25,18, +0,124,27,168,21,147,171,37,20,113,145,32,7,193,186,129,89,58,18,81,72,226, +162,64,15,180,71,91,62,172,148,90,0,168,144,3,237,17,214,207,161,37,22,144, +38,36,0,248,134,207,171,37,22,160,38,36,0,248,134,207,161,37,22,176,42,209, +68,201,218,35,173,158,197,54,4,218,40,153,56,134,207,98,155,75,27,104,162, +100,237,17,214,207,71,91,171,37,54,65,182,138,38,78,209,29,108,244,117,186, +18,83,104,131,45,20,76,156,67,103,163,173,213,146,155,76,25,104,162,100, +226,27,61,29,110,132,148,218,160,219,69,19,39,104,142,182,122,122,93,89,41, +178,141,180,81,50,118,136,235,103,167,165,208,146,155,69,25,104,162,100, +226,27,61,61,46,172,148,218,104,203,69,19,39,16,217,233,233,116,36,166,213, +70,90,40,153,56,85,184,19,234,201,77,152,101,162,137,147,133,91,129,62,132, +148,218,48,219,69,19,39,6,234,5,100,234,201,77,156,109,162,137,147,131,117, +2,178,116,36,166,209,197,218,40,153,59,68,117,179,234,201,78,32,11,180,81, +50,118,136,235,103,208,146,156,72,21,104,162,100,226,27,62,172,148,226,128, +171,69,19,39,16,217,244,36,167,22,53,59,22,53,91,0,2,21,11,94,181,128,196, +133,0,185,80,32,56,156,199,130,36,160,72,16,78,126,53,144,5,146,208,34,82, +72,1,109,20,76,155,40,32,233,0,115,70,130,8,209,56,104,105,187,252,193,3, +17,162,112,201,242,18,65,211,0,230,149,132,17,162,112,208,211,119,248,0,82, +130,96,95,127,128,130,80,102,186,36,232,92,206,255,1,80,48,200,39,12,158, +241,64, }; #elif defined(DUK_USE_DOUBLE_ME) -DUK_INTERNAL const duk_uint8_t duk_builtins_data[3833] = { -105,195,75,32,3,148,52,154,248,9,26,13,128,112,105,0,240,22,20,26,95,124,6, -152,52,137,0,120,99,74,239,129,18,70,241,191,2,98,13,79,32,42,88,210,90,2, -240,1,50,141,37,168,76,94,216,118,69,229,203,127,44,0,84,163,73,106,21,75, -14,236,249,98,242,229,191,150,0,46,81,164,181,14,165,151,54,94,89,119,99, -203,23,151,45,252,176,1,146,141,37,168,93,63,59,186,97,241,23,151,45,252, -176,1,178,141,37,168,77,79,60,50,197,229,203,127,44,0,116,163,73,106,17,86, -148,152,188,185,111,229,128,15,148,129,198,137,36,58,166,142,91,251,212, -243,195,44,94,92,183,242,13,79,8,45,14,91,252,121,148,52,199,120,63,72,105, -21,240,118,128,210,237,224,245,17,165,43,224,211,55,231,207,151,148,161,70, -145,0,31,40,107,26,2,18,138,26,228,192,142,0,16,161,174,76,9,74,26,228,192, -158,0,8,161,174,76,10,96,2,42,26,228,192,174,0,26,161,174,76,11,96,3,74,26, -228,192,190,0,44,161,174,76,12,96,3,202,26,228,192,206,0,70,161,169,84,14, -202,3,255,254,32,234,0,0,7,195,248,0,0,0,0,119,0,0,3,193,252,0,0,0,0,57, -136,1,152,32,16,194,0,166,24,6,49,0,57,138,2,12,96,18,99,128,163,32,5,153, -40,76,94,216,118,69,229,203,127,35,41,10,165,135,118,124,177,121,114,223, -200,203,67,169,101,205,151,150,93,216,242,197,229,203,127,35,49,11,167,231, -119,76,62,34,242,229,191,145,154,132,212,243,195,44,94,92,183,242,51,144, -138,180,164,197,229,203,127,35,60,6,26,0,52,208,193,226,117,215,211,15,12, -166,146,11,67,150,255,30,77,24,58,113,64,243,92,8,27,0,68,217,130,70,212, -19,54,224,161,185,5,77,216,44,111,65,115,126,12,28,16,100,225,156,16,32,18, -17,195,15,46,121,100,238,232,136,136,87,12,60,185,229,141,179,126,30,136, -100,130,233,231,59,12,228,34,66,52,243,141,167,118,158,153,80,73,9,201,151, -30,252,153,106,210,146,118,72,150,76,184,247,228,203,86,148,152,123,246, -240,223,187,46,238,135,132,132,229,221,143,126,76,181,105,73,61,36,75,46, -236,123,242,101,171,74,76,61,251,120,111,221,151,119,67,226,65,178,243,199, -135,134,83,242,66,58,238,203,207,30,30,25,81,201,5,225,203,78,238,136,163, -208,92,59,50,242,232,138,62,0,2,38,163,19,255,255,224,142,80,192,0,20,31, -240,14,135,103,203,210,135,45,253,55,244,243,195,44,252,205,197,0,1,18,221, -82,0,3,24,207,151,164,254,251,168,114,223,195,47,46,158,98,101,231,143,150, -158,29,55,242,104,68,79,62,94,147,251,238,161,203,127,12,188,186,121,157, -135,110,94,109,100,131,99,229,151,15,76,172,168,8,89,217,16,201,151,54,157, -217,104,114,223,195,47,46,154,114,243,102,68,19,158,92,59,27,73,6,205,203, -46,95,89,91,74,0,3,17,225,203,47,108,187,186,69,241,211,46,238,122,119,238, -230,216,72,70,158,116,242,225,217,151,35,81,33,26,121,198,229,191,214,93, -205,69,0,1,134,105,231,23,199,76,187,185,233,197,179,43,73,32,154,242,249, -230,214,80,0,31,255,193,2,38,103,110,117,24,81,115,0,78,228,0,161,208,16, -237,24,121,207,239,186,135,45,252,50,242,233,229,188,144,221,60,232,114, -223,211,127,79,60,50,207,204,224,72,167,14,91,248,101,229,211,204,158,113, -119,117,219,151,150,28,91,50,184,144,40,95,224,0,15,248,64,4,20,78,129,5, -195,195,134,207,38,232,130,99,195,179,97,201,244,19,22,157,217,14,15,130, -135,254,0,48,125,60,224,242,229,135,200,9,1,255,12,2,162,136,112,2,112,80, -128,0,193,177,239,221,143,15,64,35,224,152,20,144,62,27,248,3,2,9,195,175, -61,0,231,208,126,89,123,101,229,207,40,72,32,188,244,105,205,208,40,16,94, -123,52,227,202,22,136,39,61,252,186,6,18,13,207,134,205,56,242,134,175,65, -250,238,231,163,78,110,129,231,208,125,59,178,101,241,63,48,25,248,0,12,47, -102,30,125,36,238,201,151,196,252,192,103,255,255,240,92,189,178,242,242,8, -105,4,231,191,110,80,67,80,0,24,62,109,252,162,225,199,160,16,212,0,10,7, -183,15,0,67,80,0,56,54,109,59,58,101,228,8,106,0,9,6,229,151,39,92,121,66, -15,192,0,97,124,178,228,235,143,45,45,57,244,116,8,63,255,255,10,39,248,0, -195,51,114,223,182,30,140,60,161,239,201,149,248,248,31,241,0,140,80,129, -202,10,49,128,10,35,1,6,199,163,15,40,61,32,9,10,199,163,15,40,123,242,101, -131,210,4,144,108,123,247,99,195,210,8,250,15,167,118,76,190,39,230,131,52, -133,236,195,207,164,157,217,50,248,159,154,12,212,0,6,27,179,126,60,59,50, -195,223,183,134,30,89,97,9,5,219,135,166,61,16,164,131,242,203,195,102,28, -121,97,145,6,231,151,15,44,122,33,201,5,231,179,78,60,177,8,130,243,225, -179,79,72,148,66,121,245,197,207,167,45,59,179,197,162,23,211,124,205,253, -242,242,135,135,158,87,240,68,122,111,153,191,30,29,153,102,111,239,151, -148,60,60,242,191,130,23,211,125,94,28,50,242,135,135,158,87,240,128,0,196, -122,111,153,191,30,29,153,106,240,225,151,148,60,60,242,191,132,0,6,9,211, -150,157,177,160,131,115,235,139,159,78,81,72,10,47,248,0,3,254,40,17,138, -48,66,136,152,64,0,66,129,48,5,27,252,88,76,216,54,47,214,131,50,172,88,31, -255,253,239,255,255,255,255,240,153,178,103,95,173,6,101,88,176,0,0,0,0,0, -64,0,0,3,168,0,0,31,15,224,0,0,0,17,26,19,233,201,169,38,180,91,242,103,70, -147,58,77,75,48,0,0,60,31,192,0,0,0,34,51,162,199,131,82,77,104,183,228, -206,141,38,116,154,150,96,0,0,120,127,128,0,0,0,0,15,248,192,70,40,0,0,0,0, -0,0,0,0,3,10,44,68,9,216,8,20,49,130,15,211,124,109,62,50,228,95,36,55,166, -248,190,56,111,221,151,119,77,56,118,47,18,23,211,125,14,89,113,233,231, -167,126,230,18,5,31,252,0,224,188,48,242,231,148,116,144,58,181,33,143,127, -64,247,111,238,56,0,127,199,2,49,72,0,0,248,127,0,0,0,0,180,81,36,4,51,166, -248,152,122,101,167,211,150,157,217,201,2,0,3,12,233,190,166,157,185,105, -244,229,167,118,114,64,128,1,4,228,129,0,3,137,116,223,51,126,60,59,50,196, -195,211,45,62,156,180,238,206,72,16,0,72,151,77,243,55,227,195,179,45,77, -59,114,211,233,203,78,236,228,129,0,5,10,73,2,0,12,21,18,4,0,28,82,35,32, -80,74,8,62,124,189,42,105,219,148,148,16,188,249,122,70,235,179,101,156, -184,121,15,132,0,34,29,159,47,74,181,33,198,235,179,101,156,184,121,15,132, -0,38,17,159,47,73,187,247,116,208,62,16,0,168,94,124,189,42,212,135,55,126, -238,154,7,194,0,23,7,207,151,164,76,61,50,143,132,0,50,21,159,47,74,181,33, -196,195,211,40,248,64,3,96,217,242,244,137,135,200,248,64,3,161,57,242,244, -171,82,28,76,62,71,194,0,31,8,207,151,164,141,253,121,115,31,8,0,132,47,62, -94,149,106,67,145,191,175,46,99,225,0,17,133,103,203,210,110,157,221,122, -101,230,62,16,1,40,110,124,189,42,212,135,55,78,238,189,50,243,31,8,0,156, -43,62,94,148,242,227,223,187,39,49,240,128,10,67,115,229,233,86,164,58,121, -113,239,221,147,152,248,64,5,97,249,242,244,155,167,102,205,60,242,227,223, -187,39,49,240,128,11,68,179,229,233,86,164,57,186,118,108,211,207,46,61, -251,178,115,31,8,0,188,71,62,94,149,52,237,203,235,126,236,179,243,102,231, -151,161,0,32,252,242,244,169,167,110,82,34,67,249,229,233,55,78,205,154, -121,229,199,191,118,78,100,37,0,24,137,115,203,210,173,72,115,116,236,217, -167,158,92,123,247,100,230,66,80,1,152,87,60,189,41,229,199,191,118,78,100, -43,224,3,80,222,121,122,85,169,14,158,92,123,247,100,230,66,190,0,55,10, -231,151,164,221,59,186,244,203,204,133,252,0,114,27,207,47,74,181,33,205, -211,187,175,76,188,200,95,192,7,97,28,242,244,145,191,175,46,100,51,224,3, -208,190,121,122,85,169,14,70,254,188,185,144,207,128,15,193,249,229,233,19, -15,76,164,37,0,32,133,115,203,210,173,72,113,48,244,202,66,80,2,24,71,60, -189,38,239,221,211,65,10,248,1,20,47,158,94,149,106,67,155,191,119,77,4,43, -224,4,112,190,121,122,70,235,179,101,156,184,121,16,191,128,18,67,185,229, -233,86,164,56,221,118,108,179,151,15,34,23,240,2,88,62,124,189,44,229,195, -200,124,32,4,208,126,121,122,89,203,135,145,9,64,9,194,145,254,0,0,255,144, -24,100,130,14,0,16,176,2,192,129,11,33,12,1,168,193,108,96,186,48,95,32,0, -0,0,0,0,0,0,0,56,38,95,25,113,189,18,9,211,47,62,143,100,20,95,0,20,159, -240,0,7,252,144,162,241,2,195,66,7,11,89,204,140,197,252,229,197,226,230, -115,3,16,69,19,64,5,43,252,0,9,255,40,16,188,33,49,123,97,217,23,151,45, -252,131,66,7,0,20,191,240,0,39,252,176,66,240,133,82,195,187,62,88,188,185, -111,228,26,16,56,0,166,127,128,1,63,230,2,23,132,58,150,92,217,121,101,221, -143,44,94,92,183,242,13,8,28,0,83,127,192,0,159,243,65,11,194,23,79,206, -238,152,124,69,229,203,127,32,208,129,192,5,59,252,0,9,255,56,16,188,33,53, -60,240,203,23,151,45,252,131,66,7,0,20,255,240,0,39,252,240,66,240,132,85, -165,38,47,46,91,249,6,132,14,0,31,255,228,64,98,192,10,191,5,64,105,87,20, -139,130,76,156,197,132,11,22,176,36,1,101,91,91,184,28,201,204,160,33,23, -115,31,247,156,253,127,65,102,79,142,202,44,4,113,95,115,255,232,34,182,88, -52,201,241,216,176,139,1,239,47,108,252,59,148,152,86,5,66,76,15,178,16, -148,1,130,212,69,72,61,58,52,170,49,190,202,4,245,7,49,254,105,219,251,52, -22,157,26,85,25,64,158,160,246,63,205,59,127,102,74,7,135,23,53,2,65,48, -227,223,205,64,160,0,48,76,60,244,238,80,40,0,20,19,15,76,59,148,10,0,7,5, -195,211,14,230,74,72,130,99,203,167,98,129,64,1,32,120,247,243,80,40,0,44, -15,47,142,10,5,0,6,130,230,217,191,127,37,2,128,3,192,246,111,206,160,80,0, -136,30,220,62,19,151,160,123,116,238,79,94,129,240,223,221,73,32,0,48,110, -88,119,100,223,181,68,16,94,91,250,238,200,160,80,0,152,31,61,59,148,10,0, -21,4,231,199,151,69,2,128,5,192,250,97,220,160,80,0,192,127,255,128,20,23, -134,30,92,242,164,34,19,207,167,45,59,179,233,205,229,37,129,127,255,0,0, -191,255,128,0,63,255,197,131,246,203,203,158,157,251,160,0,90,98,32,0,0,0, -0,3,166,156,30,53,32,249,165,131,76,223,159,62,94,70,172,114,16,176,144,60, -56,250,19,18,5,159,25,89,32,121,180,238,42,30,129,229,221,140,164,122,7, -147,46,50,129,232,62,61,251,120,97,199,208,156,129,83,127,0,50,250,69,3, -252,131,32,248,250,242,229,151,119,72,240,3,254,148,0,2,168,254,0,0,255, -167,0,33,68,88,32,0,33,64,176,2,170,254,0,0,255,169,0,33,69,220,32,0,33,67, -184,2,172,254,0,0,255,171,8,137,144,0,0,0,128,0,0,0,0,68,73,4,195,187,126, -226,8,4,178,16,41,164,32,147,7,136,52,193,240,0,18,17,48,124,0,8,133,76,31, -0,3,33,147,7,192,1,8,116,193,240,0,82,127,255,132,47,65,11,137,191,174,45, -153,98,242,229,191,144,105,4,95,47,46,91,249,32,211,185,6,94,92,183,242,65, -163,14,236,155,52,238,206,0,85,255,192,6,13,167,157,109,57,123,136,144,31, -245,192,3,5,231,179,78,60,163,9,0,2,10,199,248,0,3,254,192,4,32,249,242, -244,147,187,163,129,116,128,24,66,51,229,233,87,78,238,142,5,210,0,65,8, -207,151,164,157,221,24,182,23,72,1,140,39,62,94,149,116,238,232,197,176, -186,64,8,97,25,242,244,147,187,163,54,66,233,0,50,132,231,203,210,174,157, -221,25,178,23,72,1,20,43,62,94,145,182,111,195,209,155,33,116,128,17,194, -179,229,233,27,102,252,61,27,52,23,72,1,36,31,158,94,146,119,116,112,50, -208,3,8,71,60,189,42,233,221,209,192,203,64,8,33,28,242,244,147,187,163,22, -195,45,0,49,132,243,203,210,174,157,221,24,182,25,104,1,12,35,158,94,146, -119,116,102,200,101,160,6,80,158,121,122,85,211,187,163,54,67,45,0,34,133, -115,203,210,54,205,248,122,51,100,50,208,2,56,87,60,189,35,108,223,135,163, -102,131,45,0,36,7,255,248,1,11,50,136,132,115,235,139,15,46,88,124,140,36, -0,4,43,79,224,139,16,0,0,60,15,192,0,0,0,0,101,253,152,0,5,109,252,17,98,0, -0,7,129,248,0,0,0,0,12,191,181,0,0,174,63,130,44,64,0,0,240,63,0,0,0,0,1, -151,246,224,0,21,215,240,69,136,0,0,0,8,0,0,0,0,0,50,254,228,0,2,188,254,8, -177,0,0,0,1,0,0,0,0,0,6,95,221,128,0,87,223,193,22,32,0,0,8,32,0,0,0,0,0, -203,251,208,0,11,3,248,34,196,0,0,1,4,0,0,0,0,0,25,127,126,0,1,97,127,4,88, -128,0,0,32,128,0,0,0,0,3,47,240,64,0,44,79,224,139,16,0,0,8,16,0,0,0,0,0, -101,254,24,0,5,141,252,1,96,216,247,238,199,135,162,162,33,90,121,197,221, -143,126,77,59,179,172,146,17,167,156,46,185,179,101,228,176,65,89,77,16, -124,123,246,240,195,203,40,162,64,0,193,255,138,5,144,158,89,112,228,171, -39,119,71,2,232,132,114,203,135,36,157,221,28,11,164,0,66,25,203,46,28,149, -100,238,232,197,180,200,162,233,0,1,134,114,203,135,37,89,59,186,49,109,10, -40,186,64,2,97,124,178,225,201,39,119,70,45,166,69,23,72,0,140,47,150,92, -57,36,238,232,197,180,40,162,233,0,25,134,114,203,135,37,89,59,186,51,101, -50,40,186,64,0,161,156,178,225,201,86,78,238,140,217,66,138,46,144,0,168, -95,44,184,114,73,221,209,155,41,145,69,210,0,37,11,229,151,14,73,59,186,51, -101,10,40,186,64,6,161,124,178,225,201,27,102,252,61,38,69,23,72,0,28,47, -150,92,57,35,108,223,135,164,40,162,233,0,11,134,114,203,135,36,77,253,113, -108,203,50,40,186,64,1,33,156,178,225,201,19,127,92,91,50,194,138,46,144,0, -200,87,44,184,114,85,147,187,164,200,162,237,0,5,133,114,203,135,37,89,59, -186,66,138,46,208,0,216,79,44,184,114,73,221,210,100,81,118,128,10,194,121, -101,195,146,78,238,144,162,139,180,0,118,21,223,150,158,153,106,201,221, -209,192,203,33,61,249,105,233,150,78,238,142,6,90,0,33,13,239,203,79,76, -181,100,238,232,197,180,200,163,45,0,1,134,247,229,167,166,90,178,119,116, -98,218,20,81,150,128,4,195,59,242,211,211,44,157,221,24,182,153,20,101,160, -2,48,206,252,180,244,203,39,119,70,45,161,69,25,104,0,204,55,191,45,61,50, -213,147,187,163,54,83,34,140,180,0,10,27,223,150,158,153,106,201,221,209, -155,40,81,70,90,0,21,12,239,203,79,76,178,119,116,102,202,100,81,150,128,9, -67,59,242,211,211,44,157,221,25,178,133,20,101,160,3,80,206,252,180,244, -203,27,102,252,61,38,69,25,104,0,28,51,191,45,61,50,198,217,191,15,72,81, -70,90,0,23,13,239,203,79,76,177,55,245,197,179,44,200,163,45,0,4,134,247, -229,167,166,88,155,250,226,217,150,20,81,150,128,6,66,251,242,211,211,45, -89,59,186,76,138,51,16,0,88,95,126,90,122,101,171,39,119,72,81,70,98,0,27, -10,239,203,79,76,178,119,116,153,20,102,32,2,176,174,252,180,244,203,39, -119,72,81,70,98,0,58,40,173,176,82,90,4,19,54,157,155,21,217,6,203,199,174, -29,156,197,9,7,199,191,111,12,60,178,138,20,0,6,9,143,127,15,42,208,130, -243,217,167,30,81,132,65,123,242,211,211,42,228,0, +DUK_INTERNAL const duk_uint8_t duk_builtins_data[3790] = { +144,148,105,221,32,68,52,228,62,12,104,200,165,134,148,248,81,77,61,191, +135,35,154,103,34,72,6,157,159,197,145,77,245,126,52,130,106,234,163,196, +52,226,18,51,161,26,113,1,60,37,64,190,18,49,116,116,33,26,113,1,92,136,26, +98,112,145,139,163,165,8,211,136,14,228,72,82,68,141,17,56,72,197,209,212, +132,105,196,5,242,88,108,193,126,18,49,116,117,161,26,113,1,60,158,30,78, +18,49,116,118,33,26,113,1,29,164,80,78,198,46,142,212,36,68,51,71,224,59, +147,60,93,110,79,15,39,9,24,186,33,13,63,79,185,38,154,121,223,110,76,66, +53,116,1,120,248,186,248,136,67,76,196,200,134,186,137,177,13,31,192,174, +79,15,32,248,8,196,24,8,107,254,39,97,161,175,248,159,16,215,252,80,186,26, +255,138,57,136,107,254,41,100,33,175,248,167,170,134,191,226,166,138,26, +255,138,187,40,107,254,43,111,33,171,86,181,16,209,241,11,228,201,121,240, +141,19,134,72,196,52,123,168,95,38,75,207,131,32,156,50,70,33,195,3,152, +128,0,1,240,254,0,0,0,1,153,128,0,1,224,254,0,0,0,1,151,137,0,214,9,188,35, +131,12,225,196,56,177,78,60,99,147,28,229,200,57,162,120,74,129,124,36,98, +232,156,241,92,136,26,98,112,145,139,162,116,71,114,36,41,34,70,136,156,36, +98,232,157,49,124,150,27,48,95,132,140,93,19,170,39,147,195,201,194,70,46, +137,215,17,218,69,4,236,98,232,157,153,39,110,81,220,15,193,209,83,3,200, +119,130,241,241,117,240,120,80,252,137,10,178,10,103,134,180,122,9,135,136, +154,120,169,199,142,158,121,10,7,146,162,121,74,71,150,166,121,138,135,154, +170,121,202,199,158,23,201,146,243,225,26,39,12,145,61,16,190,76,151,159,6, +65,56,100,137,233,35,93,205,144,33,224,140,137,196,54,121,244,5,60,17,145, +56,85,184,19,207,16,21,18,227,65,198,231,72,16,137,112,168,106,38,76,225,2, +70,65,56,100,237,34,140,177,4,134,65,56,100,237,34,129,117,204,123,154,70, +207,46,64,146,52,78,25,59,72,163,48,65,34,52,78,25,59,72,160,93,115,30,230, +145,179,204,144,24,146,16,30,76,209,2,40,210,72,64,121,52,4,0,156,88,97,5, +194,96,227,18,124,124,93,55,79,15,39,28,94,49,38,159,154,136,96,196,159,29, +102,241,241,115,201,25,227,131,36,133,20,62,110,142,253,2,102,36,248,235, +55,143,139,158,72,207,28,104,24,73,112,201,3,2,82,65,155,187,94,6,20,72,9, +147,120,128,225,144,168,105,56,248,185,228,140,241,190,96,128,200,84,52, +156,124,92,242,70,104,36,183,168,4,145,0,190,41,1,139,18,19,36,226,146,17, +124,73,82,54,124,37,230,70,201,14,108,184,132,8,68,185,34,1,100,31,8,129,8, +151,11,23,100,141,225,18,12,68,184,75,204,141,146,2,178,112,72,8,162,98,92, +50,10,152,147,227,172,222,62,46,121,35,60,114,88,96,92,185,112,201,65,34, +92,4,1,147,81,159,141,205,32,234,121,96,97,57,64,97,121,128,14,56,37,199, +89,188,124,92,242,70,120,227,144,53,18,227,226,233,186,120,121,56,226,242, +8,40,248,185,228,140,241,196,75,132,109,24,72,128,43,39,36,136,48,64,114,0, +250,156,168,1,64,247,175,25,36,2,8,11,94,80,248,16,40,104,242,103,200,48, +193,3,162,92,4,98,12,41,14,66,40,106,101,1,132,130,8,24,78,104,129,54,62, +96,224,144,13,238,124,32,2,62,146,60,51,224,120,146,164,140,137,20,0,178, +58,11,56,192,5,146,208,34,71,64,36,157,25,200,32,52,158,180,8,146,87,129, +232,217,29,5,156,179,224,116,52,100,191,28,87,62,130,214,9,79,136,104,201, +126,56,174,127,0,31,255,225,73,82,71,16,13,1,36,230,18,1,164,14,87,71,132, +0,143,0,210,131,96,31,0,211,6,42,23,50,70,1,167,13,18,14,130,36,67,232,46, +36,29,4,78,69,6,60,226,31,192,7,255,252,24,160,163,11,23,51,130,56,35,193, +56,100,238,31,6,150,46,103,4,225,147,143,114,27,62,233,241,200,137,182,133, +42,142,167,216,6,23,216,0,97,28,17,224,39,223,32,80,142,8,240,78,25,56,9, +248,8,22,39,12,156,123,144,217,240,19,240,18,6,19,154,32,79,194,124,14,134, +140,151,227,139,226,52,11,88,37,62,33,163,37,248,226,248,141,32,213,184,64, +89,56,39,49,224,137,60,100,5,96,38,35,249,8,15,18,61,96,17,60,200,6,145,1, +17,31,206,64,89,45,2,39,161,0,178,122,209,63,74,2,101,64,202,113,67,77,235, +64,92,221,197,186,196,143,4,9,19,188,1,25,187,139,112,128,178,113,110,177, +35,193,2,68,239,0,46,110,229,30,242,71,130,4,137,222,4,35,55,113,110,16,22, +78,81,239,36,120,32,72,157,224,64,147,138,25,237,0,52,72,242,2,126,82,3,74, +129,148,227,234,66,12,112,28,140,155,104,203,169,158,9,133,158,4,25,36,1, +61,96,47,181,80,46,132,129,255,255,222,255,255,255,255,254,39,172,67,118, +170,5,208,144,0,0,0,0,0,64,0,0,51,16,0,0,62,31,192,0,0,0,8,245,238,146,38, +138,147,105,13,42,26,137,226,0,0,7,131,248,0,0,0,1,30,180,134,4,209,82,109, +33,165,67,81,60,64,0,0,240,255,0,0,0,0,28,144,155,104,0,0,0,0,0,0,0,0,16, +117,59,130,48,155,98,48,187,144,3,205,220,42,46,65,237,72,27,55,112,151, +123,154,70,205,0,94,208,129,115,119,31,18,9,18,67,155,183,34,12,176,96,175, +4,100,74,228,3,237,38,43,31,192,109,117,171,0,228,164,219,72,0,0,248,127,0, +0,0,0,196,234,111,0,50,110,224,193,50,114,83,138,26,107,192,131,38,238,77, +12,39,37,56,161,166,188,11,132,188,12,74,110,226,220,32,44,156,24,38,78,74, +113,67,77,120,28,148,221,197,184,64,89,57,52,48,156,148,226,134,154,240,64, +195,94,8,56,123,193,11,85,116,140,45,240,3,152,147,228,208,194,95,0,89,137, +62,22,139,95,48,64,70,200,67,28,98,79,180,152,139,218,45,124,193,1,27,33, +16,65,137,62,49,205,153,236,132,81,102,36,251,73,137,157,115,102,123,33,24, +57,137,62,12,19,37,144,142,40,196,159,105,49,15,160,153,44,132,128,198,36, +248,48,98,200,73,18,98,79,180,152,135,208,98,200,74,16,98,79,135,117,35,43, +33,44,89,137,62,210,98,63,93,72,202,200,76,20,98,79,140,67,105,50,74,200, +77,26,98,79,180,152,153,212,54,147,36,172,132,225,70,36,249,34,9,205,28, +172,132,241,166,36,251,73,138,93,32,156,209,202,200,80,30,98,79,140,66,214, +137,16,78,104,229,100,40,146,49,39,218,76,76,234,22,180,72,130,115,71,43, +33,72,137,137,62,77,12,38,92,210,113,197,44,137,59,64,7,145,39,201,161,132, +184,64,249,18,124,98,22,180,72,130,115,71,43,101,76,148,137,62,210,98,103, +80,181,162,68,19,154,57,91,42,130,164,73,242,68,19,154,57,91,95,84,108,137, +62,210,98,151,72,39,52,114,182,190,176,169,18,124,98,27,73,146,86,223,215, +27,34,79,180,152,153,212,54,147,36,173,191,176,34,68,159,14,234,70,86,231, +217,23,34,79,180,152,143,215,82,50,183,62,208,121,18,124,24,38,75,101,108, +84,137,62,210,98,31,65,50,91,43,130,36,73,241,142,108,207,109,125,209,114, +36,251,73,137,157,115,102,123,107,239,11,145,39,194,209,107,230,8,8,219, +127,124,116,137,62,210,98,47,104,181,243,4,4,109,191,192,135,49,39,204,16, +17,178,24,32,242,36,249,130,2,54,203,7,6,104,14,76,131,140,144,0,0,0,0,0,0, +0,1,141,207,215,12,78,126,193,46,190,126,192,98,179,246,4,197,231,236,10, +193,9,114,11,172,64,73,146,83,236,145,169,237,1,6,120,14,78,129,179,40,249, +18,149,175,207,141,199,27,76,248,156,81,177,207,139,198,9,169,199,129,58, +136,19,202,11,179,20,240,149,2,248,72,197,209,200,148,162,117,48,39,148, +151,102,42,228,64,211,19,132,140,93,28,137,74,39,85,2,121,81,118,98,238,68, +133,36,72,209,19,132,140,93,28,137,74,39,87,2,121,89,118,98,190,75,13,152, +47,194,70,46,142,68,165,19,172,129,60,176,187,49,79,39,135,147,132,140,93, +28,137,74,39,91,2,121,105,118,98,142,210,40,39,99,23,71,34,82,135,8,128, +120,72,1,87,224,168,13,42,226,145,97,58,182,232,232,64,177,107,2,64,22,85, +181,187,7,213,183,74,2,17,119,49,255,121,207,215,240,94,173,198,210,36,4, +113,95,115,255,232,34,182,80,221,91,141,163,160,72,15,121,123,103,225,220, +164,194,160,186,244,64,251,33,9,64,24,45,68,84,15,217,66,51,209,218,210, +129,61,65,204,127,154,118,254,204,23,178,132,103,165,2,122,131,216,255,52, +237,253,152,167,224,121,44,48,46,95,203,166,238,74,113,67,77,201,128,219, +152,164,82,6,0,203,76,64,64,9,210,211,18,4,4,144,221,49,40,64,76,13,211,19, +5,4,192,221,45,66,1,4,24,207,76,82,2,8,136,94,152,156,24,157,45,49,64,6,75, +191,76,80,66,149,110,116,116,197,8,41,240,247,79,70,188,6,183,27,76,80,194, +45,198,210,211,20,144,171,113,180,116,52,197,40,27,1,125,34,240,27,16,221, +42,240,27,221,109,66,32,104,129,163,115,52,224,5,139,168,209,233,138,32,57, +33,186,98,138,18,80,140,244,197,24,28,192,221,49,71,11,56,209,162,211,20, +183,1,66,188,17,145,52,40,9,148,226,134,153,5,198,137,136,32,14,12,30,164, +140,144,230,192,128,136,211,64,0,0,0,0,182,120,43,135,126,16,68,52,174,195, +144,12,2,158,4,128,70,22,24,128,101,67,112,163,192,100,104,176,131,192,99, +32,176,99,192,226,115,30,1,79,4,68,28,16,54,0,0,41,254,232,116,62,204,7,21, +35,18,54,127,80,28,192,132,28,32,14,96,197,212,243,193,48,188,240,39,130, +236,224,175,131,117,2,178,112,145,139,163,145,131,114,70,46,142,218,27,182, +72,197,209,219,56,26,53,161,166,32,128,56,18,2,129,239,94,50,76,130,68,230, +202,113,160,167,146,94,163,134,66,161,164,227,226,231,146,51,198,249,147, +71,209,67,73,210,94,24,49,39,199,89,188,124,92,242,70,120,224,201,33,69,15, +155,163,191,68,28,98,79,143,139,166,233,225,228,227,139,198,37,210,244,208, +24,137,112,151,153,27,36,5,100,224,146,105,184,100,196,95,18,84,141,159,9, +121,145,178,67,155,46,33,38,187,168,252,211,243,81,92,2,14,40,16,50,37,202, +160,150,154,67,152,148,20,28,76,156,89,26,105,158,63,232,16,44,150,129,18, +146,44,28,96,14,98,216,80,113,50,113,100,105,166,120,255,160,20,28,76,156, +113,75,34,78,63,236,3,6,133,41,35,31,242,18,195,152,147,226,27,61,138,41, +140,16,98,79,148,67,103,177,69,45,136,49,39,196,54,122,58,212,83,26,36,196, +159,40,134,207,71,90,138,92,16,98,79,136,108,244,244,168,166,56,73,137,62, +81,13,158,158,149,20,186,40,196,159,10,183,2,122,122,84,82,240,163,18,124, +42,220,9,235,106,81,75,225,228,73,241,13,158,197,54,198,8,145,39,202,33, +179,216,166,214,196,72,147,226,27,61,29,106,109,141,19,34,79,148,67,103, +163,173,77,174,8,145,39,196,54,122,122,84,219,28,38,68,159,40,134,207,79, +74,155,93,21,34,79,133,91,129,61,61,42,109,120,84,137,62,21,110,4,245,181, +41,181,248,56,224,28,24,80,113,50,113,100,105,166,120,255,160,20,28,76,156, +113,75,34,78,63,236,3,6,133,41,35,31,242,11,174,254,160,34,84,8,35,16,98, +146,38,55,32,33,30,135,19,36,182,158,72,237,17,100,97,27,56,0,0,30,7,224,0, +0,0,6,56,199,161,30,135,19,36,182,158,72,237,17,100,97,27,56,0,0,30,7,224, +0,0,0,6,55,36,33,30,135,19,36,182,158,72,237,17,100,97,27,56,0,0,30,7,224, +0,0,0,10,40,11,91,133,199,172,8,111,248,128,239,88,16,222,56,191,242,49, +198,69,8,244,56,153,37,180,242,71,104,139,35,8,217,192,0,0,240,63,0,0,0,0, +49,185,65,8,244,56,153,37,180,242,71,104,139,35,8,217,192,0,0,240,63,0,0,0, +0,49,198,77,8,244,56,153,37,180,242,71,104,139,35,8,217,192,0,0,240,63,0,0, +0,0,49,185,97,8,244,56,153,37,180,242,71,104,139,35,8,217,192,0,0,0,64,0,0, +0,0,49,198,85,8,244,56,153,37,180,242,71,104,139,35,8,217,192,0,0,0,64,0,0, +0,0,49,185,129,8,244,56,153,37,180,242,71,104,139,35,8,217,192,0,0,0,64,0, +0,0,0,49,198,93,8,244,56,153,37,180,242,71,104,139,35,8,217,192,0,0,0,64,0, +0,0,0,49,185,161,8,244,56,153,37,180,242,71,104,139,35,8,217,192,0,0,16,64, +0,0,0,0,49,198,101,8,244,56,153,37,180,242,71,104,139,35,8,217,192,0,0,16, +64,0,0,0,0,49,185,193,8,244,56,153,37,180,242,71,104,139,35,8,217,192,0,0, +16,64,0,0,0,0,49,198,109,8,244,56,153,37,180,242,71,104,139,35,8,217,192,0, +0,16,64,0,0,0,0,49,185,225,8,244,56,153,37,180,242,71,104,139,35,8,217,192, +0,0,16,64,0,0,0,0,49,198,117,8,244,56,153,37,180,242,71,104,139,35,8,217, +192,0,0,16,64,0,0,0,0,49,186,1,8,244,56,153,37,180,242,71,104,139,35,8,217, +192,0,0,32,64,0,0,0,0,49,198,125,8,244,56,153,37,180,242,71,104,139,35,8, +217,192,0,0,32,64,0,0,0,0,32,232,130,0,97,57,162,4,245,72,10,68,184,70,137, +195,67,77,175,32,66,37,192,208,165,36,117,196,10,14,38,78,44,141,52,207, +169,64,56,156,199,130,36,160,141,146,52,38,32,76,72,1,246,136,235,103,177, +69,1,17,32,7,196,54,123,20,82,88,200,144,3,237,17,214,207,71,91,171,37,20, +65,145,32,7,218,35,173,158,142,183,66,74,41,16,92,72,1,241,13,158,142,183, +86,74,41,48,92,72,1,241,13,158,142,183,66,74,41,80,100,72,1,246,136,235, +103,167,165,213,146,138,40,200,144,3,237,17,214,207,79,75,161,37,20,138,46, +36,0,248,134,207,79,75,171,37,20,154,46,36,0,248,134,207,79,75,161,37,20, +170,46,36,0,248,85,184,19,234,201,69,24,92,72,1,240,171,112,39,208,146,138, +70,25,18,0,124,27,168,21,147,171,37,20,113,145,32,7,193,186,129,89,58,18, +81,72,226,162,64,15,180,71,91,62,172,148,90,0,168,144,3,237,17,214,207,161, +37,22,144,38,36,0,248,134,207,171,37,22,160,38,36,0,248,134,207,161,37,22, +176,42,209,68,201,218,35,173,158,197,54,4,218,40,153,56,134,207,98,155,75, +27,104,162,100,237,17,214,207,71,91,171,37,54,65,182,138,38,78,209,29,108, +244,117,186,18,83,104,131,45,20,76,156,67,103,163,173,213,146,155,76,25, +104,162,100,226,27,61,29,110,132,148,218,160,219,69,19,39,104,142,182,122, +122,93,89,41,178,141,180,81,50,118,136,235,103,167,165,208,146,155,69,25, +104,162,100,226,27,61,61,46,172,148,218,104,203,69,19,39,16,217,233,233, +116,36,166,213,70,90,40,153,56,85,184,19,234,201,77,152,101,162,137,147, +133,91,129,62,132,148,218,48,219,69,19,39,6,234,5,100,234,201,77,156,109, +162,137,147,131,117,2,178,116,36,166,209,197,218,40,153,59,68,117,179,234, +201,78,32,11,180,81,50,118,136,235,103,208,146,156,72,21,104,162,100,226, +27,62,172,148,226,128,171,69,19,39,16,217,244,36,167,22,53,59,22,53,91,0,2, +21,11,94,181,128,196,133,0,185,80,32,56,156,199,130,36,160,72,16,78,126,53, +144,5,146,208,34,82,72,1,109,20,76,155,40,32,233,0,115,70,130,8,209,56,104, +105,187,252,193,3,17,162,112,201,242,18,65,211,0,230,149,132,17,162,112, +208,211,119,248,0,82,130,96,95,127,128,130,80,102,186,36,232,92,206,255,1, +80,48,200,39,12,158,241,64, }; #else #error invalid endianness defines #endif #endif /* DUK_USE_ROM_OBJECTS */ -#line 1 "duk_error_macros.c" /* - * Error, fatal, and panic handling. + * Error and fatal handling. */ -/* include removed: duk_internal.h */ +/* #include duk_internal.h -> already included */ #define DUK__ERRFMT_BUFSIZE 256 /* size for formatting buffers */ @@ -9817,69 +10447,72 @@ DUK_INTERNAL void duk_err_handle_error(duk_hthread *thr, duk_errcode_t code) { #if defined(DUK_USE_VERBOSE_ERRORS) #if defined(DUK_USE_PARANOID_ERRORS) -DUK_INTERNAL void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t index, const char *expect_name) { +DUK_INTERNAL void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx, const char *expect_name) { DUK_ERROR_RAW_FMT3(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, "%s required, found %s (stack index %ld)", - expect_name, duk_get_type_name((duk_context *) thr, index), (long) index); + expect_name, duk_get_type_name((duk_context *) thr, idx), (long) idx); } #else -DUK_INTERNAL void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t index, const char *expect_name) { +DUK_INTERNAL void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx, const char *expect_name) { DUK_ERROR_RAW_FMT3(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, "%s required, found %s (stack index %ld)", - expect_name, duk_push_string_readable((duk_context *) thr, index), (long) index); + expect_name, duk_push_string_readable((duk_context *) thr, idx), (long) idx); } #endif -DUK_INTERNAL void duk_err_range(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message) { - DUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_RANGE_ERROR, message); +DUK_INTERNAL void duk_err_error_internal(duk_hthread *thr, const char *filename, duk_int_t linenumber) { + DUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_ERROR, DUK_STR_INTERNAL_ERROR); } -DUK_INTERNAL void duk_err_api_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t index) { - DUK_ERROR_RAW_FMT1(thr, filename, linenumber, DUK_ERR_API_ERROR, "invalid stack index %ld", (long) (index)); +DUK_INTERNAL void duk_err_error_alloc_failed(duk_hthread *thr, const char *filename, duk_int_t linenumber) { + DUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_ERROR, DUK_STR_ALLOC_FAILED); } -DUK_INTERNAL void duk_err_api(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message) { - DUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_API_ERROR, message); +DUK_INTERNAL void duk_err_error(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message) { + DUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_ERROR, message); } -DUK_INTERNAL void duk_err_unimplemented_defmsg(duk_hthread *thr, const char *filename, duk_int_t linenumber) { - DUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_UNIMPLEMENTED_ERROR, DUK_STR_UNIMPLEMENTED); +DUK_INTERNAL void duk_err_range(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message) { + DUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_RANGE_ERROR, message); } -#if !defined(DUK_USE_BYTECODE_DUMP_SUPPORT) -DUK_INTERNAL void duk_err_unsupported_defmsg(duk_hthread *thr, const char *filename, duk_int_t linenumber) { - DUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_UNSUPPORTED_ERROR, DUK_STR_UNSUPPORTED); +DUK_INTERNAL void duk_err_range_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx) { + DUK_ERROR_RAW_FMT1(thr, filename, linenumber, DUK_ERR_RANGE_ERROR, "invalid stack index %ld", (long) (idx)); } -#endif -DUK_INTERNAL void duk_err_internal_defmsg(duk_hthread *thr, const char *filename, duk_int_t linenumber) { - DUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_INTERNAL_ERROR, DUK_STR_INTERNAL_ERROR); +DUK_INTERNAL void duk_err_range_push_beyond(duk_hthread *thr, const char *filename, duk_int_t linenumber) { + DUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_RANGE_ERROR, DUK_STR_PUSH_BEYOND_ALLOC_STACK); } -DUK_INTERNAL void duk_err_internal(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message) { - DUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_INTERNAL_ERROR, message); +DUK_INTERNAL void duk_err_type_invalid_args(duk_hthread *thr, const char *filename, duk_int_t linenumber) { + DUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, DUK_STR_INVALID_ARGS); } -DUK_INTERNAL void duk_err_alloc(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message) { - DUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_ALLOC_ERROR, message); +DUK_INTERNAL void duk_err_type_invalid_state(duk_hthread *thr, const char *filename, duk_int_t linenumber) { + DUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, DUK_STR_INVALID_STATE); +} +DUK_INTERNAL void duk_err_type_invalid_trap_result(duk_hthread *thr, const char *filename, duk_int_t linenumber) { + DUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, DUK_STR_INVALID_TRAP_RESULT); } #else /* The file/line arguments are NULL and 0, they're ignored by DUK_ERROR_RAW() * when non-verbose errors are used. */ -DUK_INTERNAL void duk_err_type(duk_hthread *thr) { - DUK_ERROR_RAW(thr, NULL, 0, DUK_ERR_TYPE_ERROR, NULL); + +DUK_NORETURN(DUK_LOCAL_DECL void duk__err_shared(duk_hthread *thr, duk_uint_t code)); +DUK_LOCAL void duk__err_shared(duk_hthread *thr, duk_uint_t code) { + DUK_ERROR_RAW(thr, NULL, 0, code, NULL); } -DUK_INTERNAL void duk_err_api(duk_hthread *thr) { - DUK_ERROR_RAW(thr, NULL, 0, DUK_ERR_API_ERROR, NULL); +DUK_INTERNAL void duk_err_error(duk_hthread *thr) { + duk__err_shared(thr, DUK_ERR_ERROR); } DUK_INTERNAL void duk_err_range(duk_hthread *thr) { - DUK_ERROR_RAW(thr, NULL, 0, DUK_ERR_RANGE_ERROR, NULL); + duk__err_shared(thr, DUK_ERR_RANGE_ERROR); } -DUK_INTERNAL void duk_err_syntax(duk_hthread *thr) { - DUK_ERROR_RAW(thr, NULL, 0, DUK_ERR_SYNTAX_ERROR, NULL); +DUK_INTERNAL void duk_err_eval(duk_hthread *thr) { + duk__err_shared(thr, DUK_ERR_EVAL_ERROR); } -DUK_INTERNAL void duk_err_unimplemented(duk_hthread *thr) { - DUK_ERROR_RAW(thr, NULL, 0, DUK_ERR_UNIMPLEMENTED_ERROR, NULL); +DUK_INTERNAL void duk_err_reference(duk_hthread *thr) { + duk__err_shared(thr, DUK_ERR_REFERENCE_ERROR); } -DUK_INTERNAL void duk_err_unsupported(duk_hthread *thr) { - DUK_ERROR_RAW(thr, NULL, 0, DUK_ERR_UNSUPPORTED_ERROR, NULL); +DUK_INTERNAL void duk_err_syntax(duk_hthread *thr) { + duk__err_shared(thr, DUK_ERR_SYNTAX_ERROR); } -DUK_INTERNAL void duk_err_internal(duk_hthread *thr) { - DUK_ERROR_RAW(thr, NULL, 0, DUK_ERR_INTERNAL_ERROR, NULL); +DUK_INTERNAL void duk_err_type(duk_hthread *thr) { + duk__err_shared(thr, DUK_ERR_TYPE_ERROR); } -DUK_INTERNAL void duk_err_alloc(duk_hthread *thr) { - DUK_ERROR_RAW(thr, NULL, thr, DUK_ERR_ALLOC_ERROR, NULL); +DUK_INTERNAL void duk_err_uri(duk_hthread *thr) { + duk__err_shared(thr, DUK_ERR_URI_ERROR); } #endif @@ -9887,68 +10520,37 @@ DUK_INTERNAL void duk_err_alloc(duk_hthread *thr) { * Default fatal error handler */ -DUK_INTERNAL void duk_default_fatal_handler(duk_context *ctx, duk_errcode_t code, const char *msg) { - DUK_UNREF(ctx); -#if defined(DUK_USE_FILE_IO) - DUK_FPRINTF(DUK_STDERR, "FATAL %ld: %s\n", (long) code, (const char *) (msg ? msg : "null")); - DUK_FFLUSH(DUK_STDERR); -#else - /* omit print */ -#endif - DUK_D(DUK_DPRINT("default fatal handler called, code %ld -> calling DUK_PANIC()", (long) code)); - DUK_PANIC(code, msg); - DUK_UNREACHABLE(); -} - -/* - * Default panic handler - */ - -#if !defined(DUK_USE_PANIC_HANDLER) -DUK_INTERNAL void duk_default_panic_handler(duk_errcode_t code, const char *msg) { -#if defined(DUK_USE_FILE_IO) - DUK_FPRINTF(DUK_STDERR, "PANIC %ld: %s (" -#if defined(DUK_USE_PANIC_ABORT) - "calling abort" -#elif defined(DUK_USE_PANIC_EXIT) - "calling exit" -#elif defined(DUK_USE_PANIC_SEGFAULT) - "segfaulting on purpose" -#else -#error no DUK_USE_PANIC_xxx macro defined -#endif - ")\n", (long) code, (const char *) (msg ? msg : "null")); - DUK_FFLUSH(DUK_STDERR); -#else - /* omit print */ - DUK_UNREF(code); +DUK_INTERNAL void duk_default_fatal_handler(void *udata, const char *msg) { + DUK_UNREF(udata); DUK_UNREF(msg); -#endif -#if defined(DUK_USE_PANIC_ABORT) - DUK_ABORT(); -#elif defined(DUK_USE_PANIC_EXIT) - DUK_EXIT(-1); -#elif defined(DUK_USE_PANIC_SEGFAULT) - /* exit() afterwards to satisfy "noreturn" */ - DUK_CAUSE_SEGFAULT(); /* SCANBUILD: "Dereference of null pointer", normal */ - DUK_EXIT(-1); +#if defined(DUK_USE_FATAL_HANDLER) + /* duk_config.h provided a custom default fatal handler. */ + DUK_D(DUK_DPRINT("custom default fatal error handler called: %s", msg ? msg : "NULL")); + DUK_USE_FATAL_HANDLER(udata, msg); #else -#error no DUK_USE_PANIC_xxx macro defined + /* Default behavior is to abort() on error. There's no printout + * which makes this awkward, so it's always recommended to use an + * explicit fatal error handler. + */ + DUK_D(DUK_DPRINT("built-in default fatal error handler called: %s", msg ? msg : "NULL")); + DUK_ABORT(); #endif - DUK_UNREACHABLE(); + DUK_D(DUK_DPRINT("fatal error handler returned, enter forever loop")); + for (;;) { + /* Loop forever to ensure we don't return. */ + } } -#endif /* !DUK_USE_PANIC_HANDLER */ +/* automatic undefs */ #undef DUK__ERRFMT_BUFSIZE -#line 1 "duk_unicode_support.c" /* * Various Unicode help functions for character classification predicates, * case conversion, decoding, etc. */ -/* include removed: duk_internal.h */ +/* #include duk_internal.h -> already included */ /* * Fast path tables @@ -10195,8 +10797,17 @@ DUK_INTERNAL duk_small_int_t duk_unicode_decode_xutf8(duk_hthread *thr, const du while (n > 0) { DUK_ASSERT(p >= ptr_start && p < ptr_end); - res = res << 6; - res += (duk_uint32_t) ((*p++) & 0x3f); + ch = (duk_uint_fast8_t) (*p++); +#if 0 + if (ch & 0xc0 != 0x80) { + /* not a continuation byte */ + p--; + *ptr = p; + *out_cp = DUK_UNICODE_CP_REPLACEMENT_CHARACTER; + return 1; + } +#endif + res = (res << 6) + (duk_uint32_t) (ch & 0x3f); n--; } @@ -10215,7 +10826,7 @@ DUK_INTERNAL duk_ucodepoint_t duk_unicode_decode_xutf8_checked(duk_hthread *thr, if (duk_unicode_decode_xutf8(thr, ptr, ptr_start, ptr_end, &cp)) { return cp; } - DUK_ERROR_INTERNAL(thr, "utf-8 decode failed"); /* XXX: 'internal error' is a bit of a misnomer */ + DUK_ERROR_INTERNAL(thr); DUK_UNREACHABLE(); return 0; } @@ -10230,7 +10841,7 @@ DUK_INTERNAL duk_ucodepoint_t duk_unicode_decode_xutf8_checked(duk_hthread *thr, * chosen from several variants, based on x64 gcc -O2 testing. See: * https://github.com/svaarala/duktape/pull/422 * - * NOTE: must match src/dukutil.py:duk_unicode_unvalidated_utf8_length(). + * NOTE: must match tools/dukutil.py:duk_unicode_unvalidated_utf8_length(). */ #if defined(DUK_USE_PREFER_SIZE) @@ -10341,7 +10952,7 @@ DUK_INTERNAL duk_size_t duk_unicode_unvalidated_utf8_length(const duk_uint8_t *d * Used for slow path Unicode matching. */ -/* Must match src/extract_chars.py, generate_match_table3(). */ +/* Must match tools/extract_chars.py, generate_match_table3(). */ DUK_LOCAL duk_uint32_t duk__uni_decode_value(duk_bitdecoder_ctx *bd_ctx) { duk_uint32_t t; @@ -10412,7 +11023,7 @@ DUK_INTERNAL duk_small_int_t duk_unicode_is_whitespace(duk_codepoint_t cp) { * FEFF;ZERO WIDTH NO-BREAK SPACE;Cf;0;BN;;;;;N;BYTE ORDER MARK;;;; * * It also specifies any Unicode category 'Zs' characters as white - * space. These can be extracted with the "src/extract_chars.py" script. + * space. These can be extracted with the "tools/extract_chars.py" script. * Current result: * * RAW OUTPUT: @@ -10519,7 +11130,7 @@ DUK_INTERNAL duk_small_int_t duk_unicode_is_identifier_start(duk_codepoint_t cp) * * The "UnicodeLetter" alternative of the production allows letters * from various Unicode categories. These can be extracted with the - * "src/extract_chars.py" script. + * "tools/extract_chars.py" script. * * Because the result has hundreds of Unicode codepoint ranges, matching * for any values >= 0x80 are done using a very slow range-by-range scan @@ -10550,7 +11161,7 @@ DUK_INTERNAL duk_small_int_t duk_unicode_is_identifier_start(duk_codepoint_t cp) /* Non-ASCII slow path (range-by-range linear comparison), very slow */ -#ifdef DUK_USE_SOURCE_NONBMP +#if defined(DUK_USE_SOURCE_NONBMP) if (duk__uni_range_match(duk_unicode_ids_noa, (duk_size_t) sizeof(duk_unicode_ids_noa), (duk_codepoint_t) cp)) { @@ -10616,7 +11227,7 @@ DUK_INTERNAL duk_small_int_t duk_unicode_is_identifier_part(duk_codepoint_t cp) * The matching code reuses the "identifier start" tables, and then * consults a separate range set for characters in "identifier part" * but not in "identifier start". These can be extracted with the - * "src/extract_chars.py" script. + * "tools/extract_chars.py" script. * * UnicodeCombiningMark -> categories Mn, Mc * UnicodeDigit -> categories Nd @@ -10640,7 +11251,7 @@ DUK_INTERNAL duk_small_int_t duk_unicode_is_identifier_part(duk_codepoint_t cp) /* Non-ASCII slow path (range-by-range linear comparison), very slow */ -#ifdef DUK_USE_SOURCE_NONBMP +#if defined(DUK_USE_SOURCE_NONBMP) if (duk__uni_range_match(duk_unicode_ids_noa, sizeof(duk_unicode_ids_noa), (duk_codepoint_t) cp) || @@ -10699,7 +11310,7 @@ DUK_INTERNAL duk_small_int_t duk_unicode_is_letter(duk_codepoint_t cp) { /* Non-ASCII slow path (range-by-range linear comparison), very slow */ -#ifdef DUK_USE_SOURCE_NONBMP +#if defined(DUK_USE_SOURCE_NONBMP) if (duk__uni_range_match(duk_unicode_ids_noa, sizeof(duk_unicode_ids_noa), (duk_codepoint_t) cp) && @@ -10731,14 +11342,14 @@ DUK_INTERNAL duk_small_int_t duk_unicode_is_letter(duk_codepoint_t cp) { /* * Complex case conversion helper which decodes a bit-packed conversion - * control stream generated by unicode/extract_caseconv.py. The conversion + * control stream generated by tools/extract_caseconv.py. The conversion * is very slow because it runs through the conversion data in a linear * fashion to save space (which is why ASCII characters have a special * fast path before arriving here). * * The particular bit counts etc have been determined experimentally to * be small but still sufficient, and must match the Python script - * (src/extract_caseconv.py). + * (tools/extract_caseconv.py). * * The return value is the case converted codepoint or -1 if the conversion * results in multiple characters (this is useful for regexp Canonicalization @@ -10798,7 +11409,7 @@ duk_codepoint_t duk__slow_case_conversion(duk_hthread *thr, } /* 1:1 conversion */ - n = (duk_small_int_t) duk_bd_decode(bd_ctx, 6); + n = (duk_small_int_t) duk_bd_decode(bd_ctx, 7); DUK_DDD(DUK_DDDPRINT("checking 1:1 conversions (count %ld)", (long) n)); while (n--) { start_i = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16); @@ -10953,7 +11564,7 @@ DUK_INTERNAL void duk_unicode_case_convert_string(duk_hthread *thr, duk_small_in const duk_uint8_t *p, *p_start, *p_end; duk_codepoint_t prev, curr, next; - h_input = duk_require_hstring(ctx, -1); + h_input = duk_require_hstring(ctx, -1); /* Accept symbols. */ DUK_ASSERT(h_input != NULL); bw = &bw_alloc; @@ -10973,7 +11584,7 @@ DUK_INTERNAL void duk_unicode_case_convert_string(duk_hthread *thr, duk_small_in curr = next; next = -1; if (p < p_end) { - next = (int) duk_unicode_decode_xutf8_checked(thr, &p, p_start, p_end); + next = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(thr, &p, p_start, p_end); } else { /* end of input and last char has been processed */ if (curr < 0) { @@ -11000,11 +11611,12 @@ DUK_INTERNAL void duk_unicode_case_convert_string(duk_hthread *thr, duk_small_in } DUK_BW_COMPACT(thr, bw); - duk_to_string(ctx, -1); /* invalidates h_buf pointer */ - duk_remove(ctx, -2); + (void) duk_buffer_to_string(ctx, -1); /* Safe, output is encoded. */ + /* invalidates h_buf pointer */ + duk_remove_m2(ctx); } -#ifdef DUK_USE_REGEXP_SUPPORT +#if defined(DUK_USE_REGEXP_SUPPORT) /* * Canonicalize() abstract operation needed for canonicalization of individual @@ -11116,12 +11728,11 @@ DUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_not_wordchar[10] = { }; #endif /* DUK_USE_REGEXP_SUPPORT */ -#line 1 "duk_util_misc.c" /* * Misc util stuff */ -/* include removed: duk_internal.h */ +/* #include duk_internal.h -> already included */ /* * Lowercase digits for radix values 2 to 36. Also doubles as lowercase @@ -11339,7 +11950,189 @@ DUK_INTERNAL void duk_byteswap_bytes(duk_uint8_t *p, duk_small_uint_t len) { } } #endif -#line 1 "duk_util_hashprime.c" + +/* + * Miscellaneous coercion / clamping helpers. + */ + +/* Check whether a duk_double_t is a whole number in the 32-bit range (reject + * negative zero), and if so, return a duk_int32_t. + * For compiler use: don't allow negative zero as it will cause trouble with + * LDINT+LDINTX, positive zero is OK. + */ +DUK_INTERNAL duk_bool_t duk_is_whole_get_int32_nonegzero(duk_double_t x, duk_int32_t *ival) { + duk_int32_t t; + + t = (duk_int32_t) x; + if (!((duk_double_t) t == x)) { + return 0; + } + if (t == 0) { + duk_double_union du; + du.d = x; + if (DUK_DBLUNION_HAS_SIGNBIT(&du)) { + return 0; + } + } + *ival = t; + return 1; +} + +/* Check whether a duk_double_t is a whole number in the 32-bit range, and if + * so, return a duk_int32_t. + */ +DUK_INTERNAL duk_bool_t duk_is_whole_get_int32(duk_double_t x, duk_int32_t *ival) { + duk_int32_t t; + + t = (duk_int32_t) x; + if (!((duk_double_t) t == x)) { + return 0; + } + *ival = t; + return 1; +} + +/* + * IEEE double checks + */ + +DUK_INTERNAL duk_bool_t duk_double_is_anyinf(duk_double_t x) { + duk_double_union du; + du.d = x; + return DUK_DBLUNION_IS_ANYINF(&du); +} + +DUK_INTERNAL duk_bool_t duk_double_is_posinf(duk_double_t x) { + duk_double_union du; + du.d = x; + return DUK_DBLUNION_IS_POSINF(&du); +} + +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] & 0x000000007ff00000ULL) == 0x000000007ff00000ULL; +#else + return (du.ull[DUK_DBL_IDX_ULL0] & 0x7ff0000000000000ULL) == 0x7ff0000000000000ULL; +#endif +#else + return (du.ui[DUK_DBL_IDX_UI0] & 0x7ff00000UL) == 0x7ff00000UL; +#endif +} + +DUK_INTERNAL duk_bool_t duk_double_is_nan_zero_inf(duk_double_t x) { + duk_double_union du; +#if defined(DUK_USE_64BIT_OPS) + duk_uint64_t t; +#else + duk_uint32_t t; +#endif + du.d = x; +#if defined(DUK_USE_64BIT_OPS) +#if defined(DUK_USE_DOUBLE_ME) + t = du.ull[DUK_DBL_IDX_ULL0] & 0x000000007ff00000ULL; + if (t == 0x0000000000000000ULL) { + t = du.ull[DUK_DBL_IDX_ULL0] & 0x0000000080000000ULL; + return t == 0; + } + if (t == 0x000000007ff00000UL) { + return 1; + } +#else + t = du.ull[DUK_DBL_IDX_ULL0] & 0x7ff0000000000000ULL; + if (t == 0x0000000000000000ULL) { + t = du.ull[DUK_DBL_IDX_ULL0] & 0x8000000000000000ULL; + return t == 0; + } + if (t == 0x7ff0000000000000ULL) { + return 1; + } +#endif +#else + t = du.ui[DUK_DBL_IDX_UI0] & 0x7ff00000UL; + if (t == 0x00000000UL) { + return DUK_DBLUNION_IS_ANYZERO(&du); + } + if (t == 0x7ff00000UL) { + return 1; + } +#endif + return 0; +} + +DUK_INTERNAL duk_small_uint_t duk_double_signbit(duk_double_t x) { + duk_double_union du; + du.d = x; + return (duk_small_uint_t) DUK_DBLUNION_GET_SIGNBIT(&du); +} + +DUK_INTERNAL duk_double_t duk_double_trunc_towards_zero(duk_double_t x) { + /* XXX: optimize */ + duk_small_int_t s = duk_double_signbit(x); + x = DUK_FLOOR(DUK_FABS(x)); /* truncate towards zero */ + if (s) { + x = -x; + } + return x; +} + +DUK_INTERNAL duk_bool_t duk_double_same_sign(duk_double_t x, duk_double_t y) { + 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); +} /* * Round a number upwards to a prime (not usually the nearest one). * @@ -11353,7 +12146,7 @@ DUK_INTERNAL void duk_byteswap_bytes(duk_uint8_t *p, duk_small_uint_t len) { * probe sequence steps in duk_hobject and duk_heap stringtable. */ -/* include removed: duk_internal.h */ +/* #include duk_internal.h -> already included */ /* Awkward inclusion condition: drop out of compilation if not needed by any * call site: object hash part or probing stringtable. @@ -11397,7 +12190,7 @@ DUK_INTERNAL duk_uint32_t duk_util_get_hash_prime(duk_uint32_t size) { } /* prediction: portable variant using doubles if 64-bit values not available */ -#ifdef DUK_USE_64BIT_OPS +#if defined(DUK_USE_64BIT_OPS) curr = (duk_uint32_t) ((((duk_uint64_t) curr) * ((duk_uint64_t) DUK__HASH_SIZE_RATIO)) >> 10); #else /* 32-bit x 11-bit = 43-bit, fits accurately into a double */ @@ -11417,12 +12210,14 @@ DUK_INTERNAL duk_uint32_t duk_util_get_hash_prime(duk_uint32_t size) { } #endif /* DUK_USE_HOBJECT_HASH_PART || DUK_USE_STRTAB_PROBE */ -#line 1 "duk_hobject_class.c" + +/* automatic undefs */ +#undef DUK__HASH_SIZE_RATIO /* * Hobject Ecmascript [[Class]]. */ -/* include removed: duk_internal.h */ +/* #include duk_internal.h -> already included */ #if (DUK_STRIDX_UC_ARGUMENTS > 255) #error constant too large @@ -11469,9 +12264,6 @@ DUK_INTERNAL duk_uint32_t duk_util_get_hash_prime(duk_uint32_t size) { #if (DUK_STRIDX_DEC_ENV > 255) #error constant too large #endif -#if (DUK_STRIDX_UC_BUFFER > 255) -#error constant too large -#endif #if (DUK_STRIDX_UC_POINTER > 255) #error constant too large #endif @@ -11517,23 +12309,23 @@ DUK_INTERNAL duk_uint32_t duk_util_get_hash_prime(duk_uint32_t size) { /* Note: assumes that these string indexes are 8-bit, genstrings.py must ensure that */ DUK_INTERNAL duk_uint8_t duk_class_number_to_stridx[32] = { - DUK_STRIDX_EMPTY_STRING, /* UNUSED, intentionally empty */ - DUK_STRIDX_UC_ARGUMENTS, + DUK_STRIDX_EMPTY_STRING, /* NONE, intentionally empty */ + DUK_STRIDX_UC_OBJECT, DUK_STRIDX_ARRAY, + DUK_STRIDX_UC_FUNCTION, + DUK_STRIDX_UC_ARGUMENTS, DUK_STRIDX_UC_BOOLEAN, DUK_STRIDX_DATE, DUK_STRIDX_UC_ERROR, - DUK_STRIDX_UC_FUNCTION, DUK_STRIDX_JSON, DUK_STRIDX_MATH, DUK_STRIDX_UC_NUMBER, - DUK_STRIDX_UC_OBJECT, DUK_STRIDX_REG_EXP, DUK_STRIDX_UC_STRING, DUK_STRIDX_GLOBAL, + DUK_STRIDX_UC_SYMBOL, DUK_STRIDX_OBJ_ENV, DUK_STRIDX_DEC_ENV, - DUK_STRIDX_UC_BUFFER, DUK_STRIDX_UC_POINTER, DUK_STRIDX_UC_THREAD, DUK_STRIDX_ARRAY_BUFFER, @@ -11550,7 +12342,6 @@ DUK_INTERNAL duk_uint8_t duk_class_number_to_stridx[32] = { DUK_STRIDX_EMPTY_STRING, /* UNUSED, intentionally empty */ DUK_STRIDX_EMPTY_STRING, /* UNUSED, intentionally empty */ }; -#line 1 "duk_alloc_default.c" /* * Default allocation functions. * @@ -11558,7 +12349,7 @@ DUK_INTERNAL duk_uint8_t duk_class_number_to_stridx[32] = { * a NULL or a unique pointer which is a no-op for free. */ -/* include removed: duk_internal.h */ +/* #include duk_internal.h -> already included */ #if defined(DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS) DUK_INTERNAL void *duk_default_alloc_function(void *udata, duk_size_t size) { @@ -11585,20 +12376,19 @@ DUK_INTERNAL void duk_default_free_function(void *udata, void *ptr) { DUK_ANSI_FREE(ptr); } #endif /* DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS */ -#line 1 "duk_api_buffer.c" /* * Buffer */ -/* include removed: duk_internal.h */ +/* #include duk_internal.h -> already included */ -DUK_EXTERNAL void *duk_resize_buffer(duk_context *ctx, duk_idx_t index, duk_size_t new_size) { +DUK_EXTERNAL void *duk_resize_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t new_size) { duk_hthread *thr = (duk_hthread *) ctx; duk_hbuffer_dynamic *h; DUK_ASSERT_CTX_VALID(ctx); - h = (duk_hbuffer_dynamic *) duk_require_hbuffer(ctx, index); + h = (duk_hbuffer_dynamic *) duk_require_hbuffer(ctx, idx); DUK_ASSERT(h != NULL); if (!(DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h))) { @@ -11611,7 +12401,7 @@ DUK_EXTERNAL void *duk_resize_buffer(duk_context *ctx, duk_idx_t index, duk_size return DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h); } -DUK_EXTERNAL void *duk_steal_buffer(duk_context *ctx, duk_idx_t index, duk_size_t *out_size) { +DUK_EXTERNAL void *duk_steal_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size) { duk_hthread *thr = (duk_hthread *) ctx; duk_hbuffer_dynamic *h; void *ptr; @@ -11619,7 +12409,7 @@ DUK_EXTERNAL void *duk_steal_buffer(duk_context *ctx, duk_idx_t index, duk_size_ DUK_ASSERT(ctx != NULL); - h = (duk_hbuffer_dynamic *) duk_require_hbuffer(ctx, index); + h = (duk_hbuffer_dynamic *) duk_require_hbuffer(ctx, idx); DUK_ASSERT(h != NULL); if (!(DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h))) { @@ -11642,13 +12432,13 @@ DUK_EXTERNAL void *duk_steal_buffer(duk_context *ctx, duk_idx_t index, duk_size_ return ptr; } -DUK_EXTERNAL void duk_config_buffer(duk_context *ctx, duk_idx_t index, void *ptr, duk_size_t len) { +DUK_EXTERNAL void duk_config_buffer(duk_context *ctx, duk_idx_t idx, void *ptr, duk_size_t len) { duk_hthread *thr = (duk_hthread *) ctx; duk_hbuffer_external *h; DUK_ASSERT(ctx != NULL); - h = (duk_hbuffer_external *) duk_require_hbuffer(ctx, index); + h = (duk_hbuffer_external *) duk_require_hbuffer(ctx, idx); DUK_ASSERT(h != NULL); if (!DUK_HBUFFER_HAS_EXTERNAL(h)) { @@ -11659,7 +12449,6 @@ DUK_EXTERNAL void duk_config_buffer(duk_context *ctx, duk_idx_t index, void *ptr DUK_HBUFFER_EXTERNAL_SET_DATA_PTR(thr->heap, h, ptr); DUK_HBUFFER_EXTERNAL_SET_SIZE(h, len); } -#line 1 "duk_api_bytecode.c" /* * Bytecode dump/load * @@ -11672,7 +12461,7 @@ DUK_EXTERNAL void duk_config_buffer(duk_context *ctx, duk_idx_t index, void *ptr * validated which is not easy to do with indirect register references etc. */ -/* include removed: duk_internal.h */ +/* #include duk_internal.h -> already included */ #if defined(DUK_USE_BYTECODE_DUMP_SUPPORT) @@ -11700,7 +12489,7 @@ DUK_LOCAL duk_uint8_t *duk__load_buffer_raw(duk_context *ctx, duk_uint8_t *p) { duk_uint8_t *buf; len = DUK_RAW_READ_U32_BE(p); - buf = (duk_uint8_t *) duk_push_fixed_buffer(ctx, (duk_size_t) len); + buf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(ctx, (duk_size_t) len); DUK_ASSERT(buf != NULL); DUK_MEMCPY((void *) buf, (const void *) p, (size_t) len); p += len; @@ -11867,19 +12656,22 @@ DUK_LOCAL duk_uint8_t *duk__dump_formals(duk_hthread *thr, duk_uint8_t *p, duk_b */ varname = DUK_TVAL_GET_STRING(tv_val); DUK_ASSERT(varname != NULL); + DUK_ASSERT(DUK_HSTRING_GET_BYTELEN(varname) >= 1); /* won't be confused with terminator */ DUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= 0x7fffffffUL); /* ensures no overflow */ p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4 + DUK_HSTRING_GET_BYTELEN(varname), p); p = duk__dump_hstring_raw(p, varname); } } + } else { + DUK_DD(DUK_DDPRINT("dumping function without _Formals, emit empty list")); } p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4, p); DUK_RAW_WRITE_U32_BE(p, 0); /* end of _Formals */ return p; } -static duk_uint8_t *duk__dump_func(duk_context *ctx, duk_hcompiledfunction *func, duk_bufwriter_ctx *bw_ctx, duk_uint8_t *p) { +static duk_uint8_t *duk__dump_func(duk_context *ctx, duk_hcompfunc *func, duk_bufwriter_ctx *bw_ctx, duk_uint8_t *p) { duk_hthread *thr; duk_tval *tv, *tv_end; duk_instr_t *ins, *ins_end; @@ -11900,29 +12692,29 @@ static duk_uint8_t *duk__dump_func(duk_context *ctx, duk_hcompiledfunction *func "code=[%p,%p[ (%ld bytes, %ld items)", (void *) func, (void *) p, - (void *) DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE(thr->heap, func), - (void *) DUK_HCOMPILEDFUNCTION_GET_CONSTS_END(thr->heap, func), - (long) DUK_HCOMPILEDFUNCTION_GET_CONSTS_SIZE(thr->heap, func), - (long) DUK_HCOMPILEDFUNCTION_GET_CONSTS_COUNT(thr->heap, func), - (void *) DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE(thr->heap, func), - (void *) DUK_HCOMPILEDFUNCTION_GET_FUNCS_END(thr->heap, func), - (long) DUK_HCOMPILEDFUNCTION_GET_FUNCS_SIZE(thr->heap, func), - (long) DUK_HCOMPILEDFUNCTION_GET_FUNCS_COUNT(thr->heap, func), - (void *) DUK_HCOMPILEDFUNCTION_GET_CODE_BASE(thr->heap, func), - (void *) DUK_HCOMPILEDFUNCTION_GET_CODE_END(thr->heap, func), - (long) DUK_HCOMPILEDFUNCTION_GET_CODE_SIZE(thr->heap, func), - (long) DUK_HCOMPILEDFUNCTION_GET_CODE_COUNT(thr->heap, func))); + (void *) DUK_HCOMPFUNC_GET_CONSTS_BASE(thr->heap, func), + (void *) DUK_HCOMPFUNC_GET_CONSTS_END(thr->heap, func), + (long) DUK_HCOMPFUNC_GET_CONSTS_SIZE(thr->heap, func), + (long) DUK_HCOMPFUNC_GET_CONSTS_COUNT(thr->heap, func), + (void *) DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, func), + (void *) DUK_HCOMPFUNC_GET_FUNCS_END(thr->heap, func), + (long) DUK_HCOMPFUNC_GET_FUNCS_SIZE(thr->heap, func), + (long) DUK_HCOMPFUNC_GET_FUNCS_COUNT(thr->heap, func), + (void *) DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, func), + (void *) DUK_HCOMPFUNC_GET_CODE_END(thr->heap, func), + (long) DUK_HCOMPFUNC_GET_CODE_SIZE(thr->heap, func), + (long) DUK_HCOMPFUNC_GET_CODE_COUNT(thr->heap, func))); DUK_ASSERT(DUK_USE_ESBC_MAX_BYTES <= 0x7fffffffUL); /* ensures no overflow */ - count_instr = (duk_uint32_t) DUK_HCOMPILEDFUNCTION_GET_CODE_COUNT(thr->heap, func); + count_instr = (duk_uint32_t) DUK_HCOMPFUNC_GET_CODE_COUNT(thr->heap, func); p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 3 * 4 + 2 * 2 + 3 * 4 + count_instr * 4, p); /* Fixed header info. */ tmp32 = count_instr; DUK_RAW_WRITE_U32_BE(p, tmp32); - tmp32 = (duk_uint32_t) DUK_HCOMPILEDFUNCTION_GET_CONSTS_COUNT(thr->heap, func); + tmp32 = (duk_uint32_t) DUK_HCOMPFUNC_GET_CONSTS_COUNT(thr->heap, func); DUK_RAW_WRITE_U32_BE(p, tmp32); - tmp32 = (duk_uint32_t) DUK_HCOMPILEDFUNCTION_GET_FUNCS_COUNT(thr->heap, func); + tmp32 = (duk_uint32_t) DUK_HCOMPFUNC_GET_FUNCS_COUNT(thr->heap, func); DUK_RAW_WRITE_U32_BE(p, tmp32); tmp16 = func->nregs; DUK_RAW_WRITE_U16_BE(p, tmp16); @@ -11937,14 +12729,14 @@ static duk_uint8_t *duk__dump_func(duk_context *ctx, duk_hcompiledfunction *func DUK_RAW_WRITE_U32_BE(p, 0); DUK_RAW_WRITE_U32_BE(p, 0); #endif - tmp32 = ((duk_heaphdr *) func)->h_flags & DUK_HEAPHDR_FLAGS_FLAG_MASK; + tmp32 = DUK_HEAPHDR_GET_FLAGS((duk_heaphdr *) func); /* masks flags, only duk_hobject flags */ DUK_RAW_WRITE_U32_BE(p, tmp32); /* Bytecode instructions: endian conversion needed unless * platform is big endian. */ - ins = DUK_HCOMPILEDFUNCTION_GET_CODE_BASE(thr->heap, func); - ins_end = DUK_HCOMPILEDFUNCTION_GET_CODE_END(thr->heap, func); + ins = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, func); + ins_end = DUK_HCOMPFUNC_GET_CODE_END(thr->heap, func); DUK_ASSERT((duk_size_t) (ins_end - ins) == (duk_size_t) count_instr); #if defined(DUK_USE_INTEGER_BE) DUK_MEMCPY((void *) p, (const void *) ins, (size_t) (ins_end - ins)); @@ -11958,8 +12750,8 @@ static duk_uint8_t *duk__dump_func(duk_context *ctx, duk_hcompiledfunction *func #endif /* Constants: variable size encoding. */ - tv = DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE(thr->heap, func); - tv_end = DUK_HCOMPILEDFUNCTION_GET_CONSTS_END(thr->heap, func); + tv = DUK_HCOMPFUNC_GET_CONSTS_BASE(thr->heap, func); + tv_end = DUK_HCOMPFUNC_GET_CONSTS_END(thr->heap, func); while (tv != tv_end) { /* constants are strings or numbers now */ DUK_ASSERT(DUK_TVAL_IS_STRING(tv) || @@ -11983,8 +12775,8 @@ static duk_uint8_t *duk__dump_func(duk_context *ctx, duk_hcompiledfunction *func } /* Inner functions recursively. */ - fn = (duk_hobject **) DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE(thr->heap, func); - fn_end = (duk_hobject **) DUK_HCOMPILEDFUNCTION_GET_FUNCS_END(thr->heap, func); + fn = (duk_hobject **) DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, func); + fn_end = (duk_hobject **) DUK_HCOMPFUNC_GET_FUNCS_END(thr->heap, func); while (fn != fn_end) { /* XXX: This causes recursion up to inner function depth * which is normally not an issue, e.g. mark-and-sweep uses @@ -11992,11 +12784,13 @@ static duk_uint8_t *duk__dump_func(duk_context *ctx, duk_hcompiledfunction *func * this would mean some sort of a work list or just refusing * to serialize deep functions. */ - DUK_ASSERT(DUK_HOBJECT_IS_COMPILEDFUNCTION(*fn)); - p = duk__dump_func(ctx, (duk_hcompiledfunction *) *fn, bw_ctx, p); + DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(*fn)); + p = duk__dump_func(ctx, (duk_hcompfunc *) *fn, bw_ctx, p); fn++; } + /* Lexenv and varenv are not dumped. */ + /* Object extra properties. * * There are some difference between function templates and functions. @@ -12005,9 +12799,15 @@ static duk_uint8_t *duk__dump_func(duk_context *ctx, duk_hcompiledfunction *func */ p = duk__dump_uint32_prop(thr, p, bw_ctx, (duk_hobject *) func, DUK_STRIDX_LENGTH, (duk_uint32_t) func->nargs); +#if defined(DUK_USE_FUNC_NAME_PROPERTY) p = duk__dump_string_prop(thr, p, bw_ctx, (duk_hobject *) func, DUK_STRIDX_NAME); +#endif +#if defined(DUK_USE_FUNC_FILENAME_PROPERTY) p = duk__dump_string_prop(thr, p, bw_ctx, (duk_hobject *) func, DUK_STRIDX_FILE_NAME); +#endif +#if defined(DUK_USE_PC2LINE) p = duk__dump_buffer_prop(thr, p, bw_ctx, (duk_hobject *) func, DUK_STRIDX_INT_PC2LINE); +#endif p = duk__dump_varmap(thr, p, bw_ctx, (duk_hobject *) func); p = duk__dump_formals(thr, p, bw_ctx, (duk_hobject *) func); @@ -12032,7 +12832,7 @@ static duk_uint8_t *duk__dump_func(duk_context *ctx, duk_hcompiledfunction *func static duk_uint8_t *duk__load_func(duk_context *ctx, duk_uint8_t *p, duk_uint8_t *p_end) { duk_hthread *thr; - duk_hcompiledfunction *h_fun; + duk_hcompfunc *h_fun; duk_hbuffer *h_data; duk_size_t data_size; duk_uint32_t count_instr, count_const, count_funcs; @@ -12044,6 +12844,8 @@ static duk_uint8_t *duk__load_func(duk_context *ctx, duk_uint8_t *p, duk_uint8_t duk_idx_t idx_base; duk_tval *tv1; duk_uarridx_t arr_idx; + duk_hobject *func_env; + duk_bool_t need_pop; /* XXX: There's some overlap with duk_js_closure() here, but * seems difficult to share code. Ensure that the final function @@ -12078,13 +12880,13 @@ static duk_uint8_t *duk__load_func(duk_context *ctx, duk_uint8_t *p, duk_uint8_t /* Push function object, init flags etc. This must match * duk_js_push_closure() quite carefully. */ - duk_push_compiledfunction(ctx); - h_fun = duk_get_hcompiledfunction(ctx, -1); + h_fun = duk_push_hcompfunc(ctx); DUK_ASSERT(h_fun != NULL); - DUK_ASSERT(DUK_HOBJECT_IS_COMPILEDFUNCTION((duk_hobject *) h_fun)); - DUK_ASSERT(DUK_HCOMPILEDFUNCTION_GET_DATA(thr->heap, h_fun) == NULL); - DUK_ASSERT(DUK_HCOMPILEDFUNCTION_GET_FUNCS(thr->heap, h_fun) == NULL); - DUK_ASSERT(DUK_HCOMPILEDFUNCTION_GET_BYTECODE(thr->heap, h_fun) == NULL); + DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) h_fun)); + DUK_ASSERT(DUK_HCOMPFUNC_GET_DATA(thr->heap, h_fun) == NULL); + DUK_ASSERT(DUK_HCOMPFUNC_GET_FUNCS(thr->heap, h_fun) == NULL); + DUK_ASSERT(DUK_HCOMPFUNC_GET_BYTECODE(thr->heap, h_fun) == NULL); + DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_fun) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]); h_fun->nregs = DUK_RAW_READ_U16_BE(p); h_fun->nargs = DUK_RAW_READ_U16_BE(p); @@ -12095,25 +12897,25 @@ static duk_uint8_t *duk__load_func(duk_context *ctx, duk_uint8_t *p, duk_uint8_t p += 8; /* skip line info */ #endif - /* duk_hcompiledfunction flags; quite version specific */ + /* duk_hcompfunc flags; quite version specific */ tmp32 = DUK_RAW_READ_U32_BE(p); - DUK_HEAPHDR_SET_FLAGS((duk_heaphdr *) h_fun, tmp32); + DUK_HEAPHDR_SET_FLAGS((duk_heaphdr *) h_fun, tmp32); /* masks flags to only change duk_hobject flags */ /* standard prototype */ DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, &h_fun->obj, thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]); /* assert just a few critical flags */ DUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) h_fun) == DUK_HTYPE_OBJECT); - DUK_ASSERT(!DUK_HOBJECT_HAS_BOUND(&h_fun->obj)); - DUK_ASSERT(DUK_HOBJECT_HAS_COMPILEDFUNCTION(&h_fun->obj)); - DUK_ASSERT(!DUK_HOBJECT_HAS_NATIVEFUNCTION(&h_fun->obj)); + DUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(&h_fun->obj)); + DUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(&h_fun->obj)); + DUK_ASSERT(!DUK_HOBJECT_HAS_NATFUNC(&h_fun->obj)); DUK_ASSERT(!DUK_HOBJECT_HAS_THREAD(&h_fun->obj)); DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARRAY(&h_fun->obj)); DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(&h_fun->obj)); DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(&h_fun->obj)); /* Create function 'data' buffer but don't attach it yet. */ - fun_data = (duk_uint8_t *) duk_push_fixed_buffer(ctx, data_size); + fun_data = (duk_uint8_t *) duk_push_fixed_buffer_nozero(ctx, data_size); DUK_ASSERT(fun_data != NULL); /* Load bytecode instructions. */ @@ -12150,7 +12952,7 @@ static duk_uint8_t *duk__load_func(duk_context *ctx, duk_uint8_t *p, duk_uint8_t duk_double_t val; DUK__ASSERT_LEFT(8); val = DUK_RAW_READ_DOUBLE_BE(p); - DUK_TVAL_SET_NUMBER_CHKFAST(&tv_tmp, val); + DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(&tv_tmp, val); duk_push_tval(ctx, &tv_tmp); break; } @@ -12177,10 +12979,9 @@ static duk_uint8_t *duk__load_func(duk_context *ctx, duk_uint8_t *p, duk_uint8_t * them afterwards. */ - h_data = (duk_hbuffer *) duk_get_hbuffer(ctx, idx_base + 1); - DUK_ASSERT(h_data != NULL); + h_data = (duk_hbuffer *) duk_known_hbuffer(ctx, idx_base + 1); DUK_ASSERT(!DUK_HBUFFER_HAS_DYNAMIC(h_data)); - DUK_HCOMPILEDFUNCTION_SET_DATA(thr->heap, h_fun, h_data); + DUK_HCOMPFUNC_SET_DATA(thr->heap, h_fun, h_data); DUK_HBUFFER_INCREF(thr, h_data); tv1 = duk_get_tval(ctx, idx_base + 2); /* may be NULL if no constants or inner funcs */ @@ -12197,7 +12998,7 @@ static duk_uint8_t *duk__load_func(duk_context *ctx, duk_uint8_t *p, duk_uint8_t tv1 += count_const; } - DUK_HCOMPILEDFUNCTION_SET_FUNCS(thr->heap, h_fun, (duk_hobject **) (void *) q); + DUK_HCOMPFUNC_SET_FUNCS(thr->heap, h_fun, (duk_hobject **) (void *) q); for (n = count_funcs; n > 0; n--) { duk_hobject *h_obj; @@ -12211,7 +13012,7 @@ static duk_uint8_t *duk__load_func(duk_context *ctx, duk_uint8_t *p, duk_uint8_t q += sizeof(duk_hobject *); } - DUK_HCOMPILEDFUNCTION_SET_BYTECODE(thr->heap, h_fun, (duk_instr_t *) (void *) q); + DUK_HCOMPFUNC_SET_BYTECODE(thr->heap, h_fun, (duk_instr_t *) (void *) q); /* The function object is now reachable and refcounts are fine, * so we can pop off all the temporaries. @@ -12222,42 +13023,64 @@ static duk_uint8_t *duk__load_func(duk_context *ctx, duk_uint8_t *p, duk_uint8_t /* Setup function properties. */ tmp32 = DUK_RAW_READ_U32_BE(p); duk_push_u32(ctx, tmp32); - duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_NONE); + duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C); - p = duk__load_string_raw(ctx, p); +#if defined(DUK_USE_FUNC_NAME_PROPERTY) + p = duk__load_string_raw(ctx, p); /* -> [ func funcname ] */ + func_env = thr->builtins[DUK_BIDX_GLOBAL_ENV]; + DUK_ASSERT(func_env != NULL); + need_pop = 0; if (DUK_HOBJECT_HAS_NAMEBINDING((duk_hobject *) h_fun)) { /* Original function instance/template had NAMEBINDING. * Must create a lexical environment on loading to allow * recursive functions like 'function foo() { foo(); }'. */ - duk_hobject *proto; + duk_hobject *new_env; + + new_env = duk_push_object_helper_proto(ctx, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV), + func_env); + DUK_ASSERT(new_env != NULL); + func_env = new_env; - proto = thr->builtins[DUK_BIDX_GLOBAL_ENV]; - (void) duk_push_object_helper_proto(ctx, - DUK_HOBJECT_FLAG_EXTENSIBLE | - DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV), - proto); - duk_dup(ctx, -2); /* -> [ func funcname env funcname ] */ + duk_dup_m2(ctx); /* -> [ func funcname env funcname ] */ duk_dup(ctx, idx_base); /* -> [ func funcname env funcname func ] */ duk_xdef_prop(ctx, -3, DUK_PROPDESC_FLAGS_NONE); /* -> [ func funcname env ] */ - duk_xdef_prop_stridx(ctx, idx_base, DUK_STRIDX_INT_LEXENV, DUK_PROPDESC_FLAGS_WC); - /* since closure has NEWENV, never define DUK_STRIDX_INT_VARENV, as it - * will be ignored anyway - */ + + need_pop = 1; /* Need to pop env, but -after- updating h_fun and increfs. */ } - duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_NONE); + DUK_ASSERT(func_env != NULL); + DUK_HCOMPFUNC_SET_LEXENV(thr->heap, h_fun, func_env); + DUK_HCOMPFUNC_SET_VARENV(thr->heap, h_fun, func_env); + DUK_HOBJECT_INCREF(thr, func_env); + DUK_HOBJECT_INCREF(thr, func_env); + if (need_pop) { + duk_pop(ctx); + } + duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C); +#endif /* DUK_USE_FUNC_NAME_PROPERTY */ +#if defined(DUK_USE_FUNC_FILENAME_PROPERTY) p = duk__load_string_raw(ctx, p); - duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_FILE_NAME, DUK_PROPDESC_FLAGS_WC); + duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_FILE_NAME, DUK_PROPDESC_FLAGS_C); +#endif /* DUK_USE_FUNC_FILENAME_PROPERTY */ - duk_push_object(ctx); - duk_dup(ctx, -2); - duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_CONSTRUCTOR, DUK_PROPDESC_FLAGS_WC); /* func.prototype.constructor = func */ - duk_compact(ctx, -1); - duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_PROTOTYPE, DUK_PROPDESC_FLAGS_W); + if (DUK_HOBJECT_HAS_CONSTRUCTABLE((duk_hobject *) h_fun)) { + /* Restore empty external .prototype only for constructable + * functions. + */ + duk_push_object(ctx); + duk_dup_m2(ctx); + duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_CONSTRUCTOR, DUK_PROPDESC_FLAGS_WC); /* func.prototype.constructor = func */ + duk_compact_m1(ctx); + duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_PROTOTYPE, DUK_PROPDESC_FLAGS_W); + } +#if defined(DUK_USE_PC2LINE) p = duk__load_buffer_raw(ctx, p); - duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_INT_PC2LINE, DUK_PROPDESC_FLAGS_WC); + duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_INT_PC2LINE, DUK_PROPDESC_FLAGS_WC); +#endif /* DUK_USE_PC2LINE */ duk_push_object(ctx); /* _Varmap */ for (;;) { @@ -12271,9 +13094,14 @@ static duk_uint8_t *duk__load_func(duk_context *ctx, duk_uint8_t *p, duk_uint8_t duk_push_u32(ctx, tmp32); duk_put_prop(ctx, -3); } - duk_compact(ctx, -1); - duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_INT_VARMAP, DUK_PROPDESC_FLAGS_NONE); + duk_compact_m1(ctx); + duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_INT_VARMAP, DUK_PROPDESC_FLAGS_NONE); + /* If _Formals wasn't present in the original function, the list + * here will be empty. Same happens if _Formals was present but + * had zero length. We can omit _Formals from the result if its + * length is zero and matches nargs. + */ duk_push_array(ctx); /* _Formals */ for (arr_idx = 0; ; arr_idx++) { /* XXX: awkward */ @@ -12284,8 +13112,12 @@ static duk_uint8_t *duk__load_func(duk_context *ctx, duk_uint8_t *p, duk_uint8_t } duk_put_prop_index(ctx, -2, arr_idx); } - duk_compact(ctx, -1); - duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_INT_FORMALS, DUK_PROPDESC_FLAGS_NONE); + if (arr_idx == 0 && h_fun->nargs == 0) { + duk_pop(ctx); + } else { + duk_compact_m1(ctx); + duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_INT_FORMALS, DUK_PROPDESC_FLAGS_NONE); + } /* Return with final function pushed on stack top. */ DUK_DD(DUK_DDPRINT("final loaded function: %!iT", duk_get_tval(ctx, -1))); @@ -12298,7 +13130,7 @@ static duk_uint8_t *duk__load_func(duk_context *ctx, duk_uint8_t *p, duk_uint8_t DUK_EXTERNAL void duk_dump_function(duk_context *ctx) { duk_hthread *thr; - duk_hcompiledfunction *func; + duk_hcompfunc *func; duk_bufwriter_ctx bw_ctx_alloc; duk_bufwriter_ctx *bw_ctx = &bw_ctx_alloc; duk_uint8_t *p; @@ -12310,9 +13142,9 @@ DUK_EXTERNAL void duk_dump_function(duk_context *ctx) { * lookup the non-bound target function or reject bound functions. * For now, bound functions are rejected. */ - func = duk_require_hcompiledfunction(ctx, -1); + func = duk_require_hcompfunc(ctx, -1); DUK_ASSERT(func != NULL); - DUK_ASSERT(!DUK_HOBJECT_HAS_BOUND(&func->obj)); + DUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(&func->obj)); /* Estimating the result size beforehand would be costly, so * start with a reasonable size and extend as needed. @@ -12327,7 +13159,7 @@ DUK_EXTERNAL void duk_dump_function(duk_context *ctx) { DUK_DD(DUK_DDPRINT("serialized result: %!T", duk_get_tval(ctx, -1))); - duk_remove(ctx, -2); /* [ ... func buf ] -> [ ... buf ] */ + duk_remove_m2(ctx); /* [ ... func buf ] -> [ ... buf ] */ } DUK_EXTERNAL void duk_load_function(duk_context *ctx) { @@ -12363,53 +13195,54 @@ DUK_EXTERNAL void duk_load_function(duk_context *ctx) { goto format_error; } - duk_remove(ctx, -2); /* [ ... buf func ] -> [ ... func ] */ + duk_remove_m2(ctx); /* [ ... buf func ] -> [ ... func ] */ return; format_error: DUK_ERROR_TYPE(thr, DUK_STR_DECODE_FAILED); } -#undef DUK__SER_MARKER -#undef DUK__SER_VERSION -#undef DUK__SER_STRING -#undef DUK__SER_NUMBER -#undef DUK__BYTECODE_INITIAL_ALLOC - #else /* DUK_USE_BYTECODE_DUMP_SUPPORT */ DUK_EXTERNAL void duk_dump_function(duk_context *ctx) { - DUK_ERROR_UNSUPPORTED_DEFMSG((duk_hthread *) ctx); + DUK_ERROR_UNSUPPORTED((duk_hthread *) ctx); } DUK_EXTERNAL void duk_load_function(duk_context *ctx) { - DUK_ERROR_UNSUPPORTED_DEFMSG((duk_hthread *) ctx); + DUK_ERROR_UNSUPPORTED((duk_hthread *) ctx); } #endif /* DUK_USE_BYTECODE_DUMP_SUPPORT */ -#line 1 "duk_api_call.c" + +/* automatic undefs */ +#undef DUK__ASSERT_LEFT +#undef DUK__BYTECODE_INITIAL_ALLOC +#undef DUK__SER_MARKER +#undef DUK__SER_NUMBER +#undef DUK__SER_STRING +#undef DUK__SER_VERSION /* * Calls. * * Protected variants should avoid ever throwing an error. */ -/* include removed: duk_internal.h */ +/* #include duk_internal.h -> already included */ /* Prepare value stack for a method call through an object property. * May currently throw an error e.g. when getting the property. */ -DUK_LOCAL void duk__call_prop_prep_stack(duk_context *ctx, duk_idx_t normalized_obj_index, duk_idx_t nargs) { +DUK_LOCAL void duk__call_prop_prep_stack(duk_context *ctx, duk_idx_t normalized_obj_idx, duk_idx_t nargs) { DUK_ASSERT_CTX_VALID(ctx); - DUK_DDD(DUK_DDDPRINT("duk__call_prop_prep_stack, normalized_obj_index=%ld, nargs=%ld, stacktop=%ld", - (long) normalized_obj_index, (long) nargs, (long) duk_get_top(ctx))); + DUK_DDD(DUK_DDDPRINT("duk__call_prop_prep_stack, normalized_obj_idx=%ld, nargs=%ld, stacktop=%ld", + (long) normalized_obj_idx, (long) nargs, (long) duk_get_top(ctx))); /* [... key arg1 ... argN] */ /* duplicate key */ duk_dup(ctx, -nargs - 1); /* Note: -nargs alone would fail for nargs == 0, this is OK */ - duk_get_prop(ctx, normalized_obj_index); + duk_get_prop(ctx, normalized_obj_idx); DUK_DDD(DUK_DDDPRINT("func: %!T", (duk_tval *) duk_get_tval(ctx, -1))); @@ -12419,7 +13252,7 @@ DUK_LOCAL void duk__call_prop_prep_stack(duk_context *ctx, duk_idx_t normalized_ /* [... func arg1 ... argN] */ - duk_dup(ctx, normalized_obj_index); + duk_dup(ctx, normalized_obj_idx); duk_insert(ctx, -nargs - 1); /* [... func this arg1 ... argN] */ @@ -12436,7 +13269,7 @@ DUK_EXTERNAL void duk_call(duk_context *ctx, duk_idx_t nargs) { idx_func = duk_get_top(ctx) - nargs - 1; if (idx_func < 0 || nargs < 0) { /* note that we can't reliably pop anything here */ - DUK_ERROR_API(thr, DUK_STR_INVALID_CALL_ARGS); + DUK_ERROR_TYPE_INVALID_ARGS(thr); } /* XXX: awkward; we assume there is space for this, overwrite @@ -12463,7 +13296,7 @@ DUK_EXTERNAL void duk_call_method(duk_context *ctx, duk_idx_t nargs) { idx_func = duk_get_top(ctx) - nargs - 2; /* must work for nargs <= 0 */ if (idx_func < 0 || nargs < 0) { /* note that we can't reliably pop anything here */ - DUK_ERROR_API(thr, DUK_STR_INVALID_CALL_ARGS); + DUK_ERROR_TYPE_INVALID_ARGS(thr); } call_flags = 0; /* not protected, respect reclimit, not constructor */ @@ -12473,7 +13306,7 @@ DUK_EXTERNAL void duk_call_method(duk_context *ctx, duk_idx_t nargs) { call_flags); /* call_flags */ } -DUK_EXTERNAL void duk_call_prop(duk_context *ctx, duk_idx_t obj_index, duk_idx_t nargs) { +DUK_EXTERNAL void duk_call_prop(duk_context *ctx, duk_idx_t obj_idx, duk_idx_t nargs) { /* * XXX: if duk_handle_call() took values through indices, this could be * made much more sensible. However, duk_handle_call() needs to fudge @@ -12483,9 +13316,9 @@ DUK_EXTERNAL void duk_call_prop(duk_context *ctx, duk_idx_t obj_index, duk_idx_t DUK_ASSERT_CTX_VALID(ctx); - obj_index = duk_require_normalize_index(ctx, obj_index); /* make absolute */ + obj_idx = duk_require_normalize_index(ctx, obj_idx); /* make absolute */ - duk__call_prop_prep_stack(ctx, obj_index, nargs); + duk__call_prop_prep_stack(ctx, obj_idx, nargs); duk_call_method(ctx, nargs); } @@ -12511,7 +13344,7 @@ DUK_EXTERNAL duk_int_t duk_pcall(duk_context *ctx, duk_idx_t nargs) { * might STILL throw an out-of-memory error or some other internal * fatal error. */ - DUK_ERROR_API(thr, DUK_STR_INVALID_CALL_ARGS); + DUK_ERROR_TYPE_INVALID_ARGS(thr); return DUK_EXEC_ERROR; /* unreachable */ } @@ -12540,7 +13373,7 @@ DUK_EXTERNAL duk_int_t duk_pcall_method(duk_context *ctx, duk_idx_t nargs) { idx_func = duk_get_top(ctx) - nargs - 2; /* must work for nargs <= 0 */ if (idx_func < 0 || nargs < 0) { /* See comments in duk_pcall(). */ - DUK_ERROR_API(thr, DUK_STR_INVALID_CALL_ARGS); + DUK_ERROR_TYPE_INVALID_ARGS(thr); return DUK_EXEC_ERROR; /* unreachable */ } @@ -12553,27 +13386,33 @@ DUK_EXTERNAL duk_int_t duk_pcall_method(duk_context *ctx, duk_idx_t nargs) { return rc; } -DUK_LOCAL duk_ret_t duk__pcall_prop_raw(duk_context *ctx) { - duk_idx_t obj_index; +struct duk__pcall_prop_args { + duk_idx_t obj_idx; duk_idx_t nargs; +}; +typedef struct duk__pcall_prop_args duk__pcall_prop_args; - /* Get the original arguments. Note that obj_index may be a relative - * index so the stack must have the same top when we use it. - */ +DUK_LOCAL duk_ret_t duk__pcall_prop_raw(duk_context *ctx, void *udata) { + duk_idx_t obj_idx; + duk_idx_t nargs; + duk__pcall_prop_args *args; DUK_ASSERT_CTX_VALID(ctx); + DUK_ASSERT(udata != NULL); - obj_index = (duk_idx_t) duk_get_int(ctx, -2); - nargs = (duk_idx_t) duk_get_int(ctx, -1); - duk_pop_2(ctx); + args = (duk__pcall_prop_args *) udata; + obj_idx = args->obj_idx; + nargs = args->nargs; - obj_index = duk_require_normalize_index(ctx, obj_index); /* make absolute */ - duk__call_prop_prep_stack(ctx, obj_index, nargs); + obj_idx = duk_require_normalize_index(ctx, obj_idx); /* make absolute */ + duk__call_prop_prep_stack(ctx, obj_idx, nargs); duk_call_method(ctx, nargs); return 1; } -DUK_EXTERNAL duk_int_t duk_pcall_prop(duk_context *ctx, duk_idx_t obj_index, duk_idx_t nargs) { +DUK_EXTERNAL duk_int_t duk_pcall_prop(duk_context *ctx, duk_idx_t obj_idx, duk_idx_t nargs) { + duk__pcall_prop_args args; + /* * Must be careful to catch errors related to value stack manipulation * and property lookup, not just the call itself. @@ -12581,17 +13420,17 @@ DUK_EXTERNAL duk_int_t duk_pcall_prop(duk_context *ctx, duk_idx_t obj_index, duk DUK_ASSERT_CTX_VALID(ctx); - duk_push_idx(ctx, obj_index); - duk_push_idx(ctx, nargs); + args.obj_idx = obj_idx; + args.nargs = nargs; - /* Inputs: explicit arguments (nargs), +1 for key, +2 for obj_index/nargs passing. - * If the value stack does not contain enough args, an error is thrown; this matches + /* Inputs: explicit arguments (nargs), +1 for key. If the value stack + * does not contain enough args, an error is thrown; this matches * behavior of the other protected call API functions. */ - return duk_safe_call(ctx, duk__pcall_prop_raw, nargs + 1 + 2 /*nargs*/, 1 /*nrets*/); + return duk_safe_call(ctx, duk__pcall_prop_raw, (void *) &args /*udata*/, nargs + 1 /*nargs*/, 1 /*nrets*/); } -DUK_EXTERNAL duk_int_t duk_safe_call(duk_context *ctx, duk_safe_call_function func, duk_idx_t nargs, duk_idx_t nrets) { +DUK_EXTERNAL duk_int_t duk_safe_call(duk_context *ctx, duk_safe_call_function func, void *udata, duk_idx_t nargs, duk_idx_t nrets) { duk_hthread *thr = (duk_hthread *) ctx; duk_int_t rc; @@ -12600,12 +13439,13 @@ DUK_EXTERNAL duk_int_t duk_safe_call(duk_context *ctx, duk_safe_call_function fu if (duk_get_top(ctx) < nargs || nrets < 0) { /* See comments in duk_pcall(). */ - DUK_ERROR_API(thr, DUK_STR_INVALID_CALL_ARGS); + DUK_ERROR_TYPE_INVALID_ARGS(thr); return DUK_EXEC_ERROR; /* unreachable */ } rc = duk_handle_safe_call(thr, /* thread */ func, /* func */ + udata, /* udata */ nargs, /* num_stack_args */ nrets); /* num_stack_res */ @@ -12695,7 +13535,7 @@ DUK_EXTERNAL void duk_new(duk_context *ctx, duk_idx_t nargs) { */ goto not_constructable; } - if (!DUK_HOBJECT_HAS_BOUND(cons)) { + if (!DUK_HOBJECT_HAS_BOUNDFUNC(cons)) { break; } } else if (DUK_TVAL_IS_LIGHTFUNC(tv)) { @@ -12705,12 +13545,12 @@ DUK_EXTERNAL void duk_new(duk_context *ctx, duk_idx_t nargs) { /* Anything else is not constructable. */ goto not_constructable; } - duk_get_prop_stridx(ctx, -1, DUK_STRIDX_INT_TARGET); /* -> [... cons target] */ - duk_remove(ctx, -2); /* -> [... target] */ + duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_INT_TARGET); /* -> [... cons target] */ + duk_remove_m2(ctx); /* -> [... target] */ } DUK_ASSERT(duk_is_callable(ctx, -1)); DUK_ASSERT(duk_is_lightfunc(ctx, -1) || - (duk_get_hobject(ctx, -1) != NULL && !DUK_HOBJECT_HAS_BOUND(duk_get_hobject(ctx, -1)))); + (duk_get_hobject(ctx, -1) != NULL && !DUK_HOBJECT_HAS_BOUNDFUNC(duk_get_hobject(ctx, -1)))); /* [... constructor arg1 ... argN final_cons] */ @@ -12725,7 +13565,7 @@ DUK_EXTERNAL void duk_new(duk_context *ctx, duk_idx_t nargs) { /* [... constructor arg1 ... argN final_cons fallback] */ - duk_get_prop_stridx(ctx, -2, DUK_STRIDX_PROTOTYPE); + duk_get_prop_stridx_short(ctx, -2, DUK_STRIDX_PROTOTYPE); proto = duk_get_hobject(ctx, -1); if (!proto) { DUK_DDD(DUK_DDDPRINT("constructor has no 'prototype' property, or value not an object " @@ -12785,8 +13625,10 @@ DUK_EXTERNAL void duk_new(duk_context *ctx, duk_idx_t nargs) { * object instance or not. */ - if (duk_is_object(ctx, -1)) { - duk_remove(ctx, -2); + if (duk_check_type_mask(ctx, -1, DUK_TYPE_MASK_OBJECT | + DUK_TYPE_MASK_BUFFER | + DUK_TYPE_MASK_LIGHTFUNC)) { + duk_remove_m2(ctx); } else { duk_pop(ctx); } @@ -12797,7 +13639,7 @@ DUK_EXTERNAL void duk_new(duk_context *ctx, duk_idx_t nargs) { * stack reflects the caller which is correct. */ -#ifdef DUK_USE_AUGMENT_ERROR_CREATE +#if defined(DUK_USE_AUGMENT_ERROR_CREATE) duk_hthread_sync_currpc(thr); duk_err_augment_error_create(thr, thr, NULL, 0, 1 /*noblame_fileline*/); #endif @@ -12807,14 +13649,22 @@ DUK_EXTERNAL void duk_new(duk_context *ctx, duk_idx_t nargs) { return; not_constructable: - DUK_ERROR_TYPE(thr, DUK_STR_NOT_CONSTRUCTABLE); +#if defined(DUK_USE_VERBOSE_ERRORS) +#if defined(DUK_USE_PARANOID_ERRORS) + DUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, "%s not constructable", duk_get_type_name(ctx, -1)); +#else + DUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, "%s not constructable", duk_push_string_readable(ctx, -1)); +#endif +#else + DUK_ERROR_TYPE(thr, "not constructable"); +#endif } -DUK_LOCAL duk_ret_t duk__pnew_helper(duk_context *ctx) { - duk_uint_t nargs; +DUK_LOCAL duk_ret_t duk__pnew_helper(duk_context *ctx, void *udata) { + duk_idx_t nargs; - nargs = duk_to_uint(ctx, -1); - duk_pop(ctx); + DUK_ASSERT(udata != NULL); + nargs = *((duk_idx_t *) udata); duk_new(ctx, nargs); return 1; @@ -12833,8 +13683,7 @@ DUK_EXTERNAL duk_int_t duk_pnew(duk_context *ctx, duk_idx_t nargs) { * wrapper. */ - duk_push_uint(ctx, nargs); - rc = duk_safe_call(ctx, duk__pnew_helper, nargs + 2 /*nargs*/, 1 /*nrets*/); + rc = duk_safe_call(ctx, duk__pnew_helper, (void *) &nargs /*udata*/, nargs + 1 /*nargs*/, 1 /*nrets*/); return rc; } @@ -12847,8 +13696,19 @@ DUK_EXTERNAL duk_bool_t duk_is_constructor_call(duk_context *ctx) { DUK_ASSERT_DISABLE(thr->callstack_top >= 0); act = duk_hthread_get_current_activation(thr); - DUK_ASSERT(act != NULL); /* because callstack_top > 0 */ - return ((act->flags & DUK_ACT_FLAG_CONSTRUCT) != 0 ? 1 : 0); + if (act != NULL) { + return ((act->flags & DUK_ACT_FLAG_CONSTRUCT) != 0 ? 1 : 0); + } + return 0; +} + +/* XXX: Make this obsolete by adding a function flag for rejecting a + * non-constructor call automatically? + */ +DUK_INTERNAL void duk_require_constructor_call(duk_context *ctx) { + if (!duk_is_constructor_call(ctx)) { + DUK_ERROR_TYPE((duk_hthread *) ctx, DUK_STR_CONSTRUCT_ONLY); + } } DUK_EXTERNAL duk_bool_t duk_is_strict_call(duk_context *ctx) { @@ -12900,29 +13760,29 @@ DUK_EXTERNAL duk_int_t duk_get_current_magic(duk_context *ctx) { } DUK_ASSERT(func != NULL); - if (DUK_HOBJECT_IS_NATIVEFUNCTION(func)) { - duk_hnativefunction *nf = (duk_hnativefunction *) func; + if (DUK_HOBJECT_IS_NATFUNC(func)) { + duk_hnatfunc *nf = (duk_hnatfunc *) func; return (duk_int_t) nf->magic; } } return 0; } -DUK_EXTERNAL duk_int_t duk_get_magic(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_int_t duk_get_magic(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_tval *tv; duk_hobject *h; DUK_ASSERT_CTX_VALID(ctx); - tv = duk_require_tval(ctx, index); + tv = duk_require_tval(ctx, idx); if (DUK_TVAL_IS_OBJECT(tv)) { h = DUK_TVAL_GET_OBJECT(tv); DUK_ASSERT(h != NULL); - if (!DUK_HOBJECT_HAS_NATIVEFUNCTION(h)) { + if (!DUK_HOBJECT_HAS_NATFUNC(h)) { goto type_error; } - return (duk_int_t) ((duk_hnativefunction *) h)->magic; + return (duk_int_t) ((duk_hnatfunc *) h)->magic; } else if (DUK_TVAL_IS_LIGHTFUNC(tv)) { duk_small_uint_t lf_flags = DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv); return (duk_int_t) DUK_LFUNC_FLAGS_GET_MAGIC(lf_flags); @@ -12934,16 +13794,45 @@ DUK_EXTERNAL duk_int_t duk_get_magic(duk_context *ctx, duk_idx_t index) { return 0; } -DUK_EXTERNAL void duk_set_magic(duk_context *ctx, duk_idx_t index, duk_int_t magic) { - duk_hnativefunction *nf; +DUK_EXTERNAL void duk_set_magic(duk_context *ctx, duk_idx_t idx, duk_int_t magic) { + duk_hnatfunc *nf; DUK_ASSERT_CTX_VALID(ctx); - nf = duk_require_hnativefunction(ctx, index); + nf = duk_require_hnatfunc(ctx, idx); DUK_ASSERT(nf != NULL); nf->magic = (duk_int16_t) magic; } -#line 1 "duk_api_codec.c" + +/* + * Misc helpers + */ + +DUK_INTERNAL void duk_resolve_nonbound_function(duk_context *ctx) { + duk_uint_t sanity; + duk_tval *tv; + + sanity = DUK_HOBJECT_BOUND_CHAIN_SANITY; + do { + tv = DUK_GET_TVAL_NEGIDX(ctx, -1); + if (DUK_TVAL_IS_LIGHTFUNC(tv)) { + /* Lightweight function: never bound, so terminate. */ + break; + } else if (DUK_TVAL_IS_OBJECT(tv)) { + duk_hobject *func; + + func = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(func != NULL); + if (!DUK_HOBJECT_IS_CALLABLE(func) || !DUK_HOBJECT_HAS_BOUNDFUNC(func)) { + break; + } + duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_INT_TARGET); + duk_replace(ctx, -2); + } else { + break; + } + } while (--sanity > 0); +} /* * Encoding and decoding basic formats: hex, base64. * @@ -12952,19 +13841,24 @@ DUK_EXTERNAL void duk_set_magic(duk_context *ctx, duk_idx_t index, duk_int_t mag * Base-64: https://tools.ietf.org/html/rfc4648#section-4 */ -/* include removed: duk_internal.h */ +/* #include duk_internal.h -> already included */ /* Shared handling for encode/decode argument. Fast path handling for * buffer and string values because they're the most common. In particular, * avoid creating a temporary string or buffer when possible. */ -DUK_LOCAL const duk_uint8_t *duk__prep_codec_arg(duk_context *ctx, duk_idx_t index, duk_size_t *out_len) { - DUK_ASSERT(duk_is_valid_index(ctx, index)); /* checked by caller */ - if (duk_is_buffer(ctx, index)) { - return (const duk_uint8_t *) duk_get_buffer(ctx, index, out_len); - } else { - return (const duk_uint8_t *) duk_to_lstring(ctx, index, out_len); +DUK_LOCAL const duk_uint8_t *duk__prep_codec_arg(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len) { + void *ptr; + duk_bool_t isbuffer; + + DUK_ASSERT(duk_is_valid_index(ctx, idx)); /* checked by caller */ + + ptr = duk_get_buffer_data_raw(ctx, idx, out_len, 0 /*throw_flag*/, &isbuffer); + if (isbuffer) { + DUK_ASSERT(*out_len == 0 || ptr != NULL); + return (const duk_uint8_t *) ptr; } + return (const duk_uint8_t *) duk_to_lstring(ctx, idx, out_len); } #if defined(DUK_USE_BASE64_FASTPATH) @@ -13313,7 +14207,7 @@ DUK_LOCAL duk_bool_t duk__base64_decode_helper(const duk_uint8_t *src, duk_size_ } #endif /* DUK_USE_BASE64_FASTPATH */ -DUK_EXTERNAL const char *duk_base64_encode(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL const char *duk_base64_encode(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; const duk_uint8_t *src; duk_size_t srclen; @@ -13327,8 +14221,8 @@ DUK_EXTERNAL const char *duk_base64_encode(duk_context *ctx, duk_idx_t index) { * which makes a copy of the input. */ - index = duk_require_normalize_index(ctx, index); - src = duk__prep_codec_arg(ctx, index, &srclen); + idx = duk_require_normalize_index(ctx, idx); + src = duk__prep_codec_arg(ctx, idx, &srclen); /* Note: for srclen=0, src may be NULL */ /* Computation must not wrap; this limit works for 32-bit size_t: @@ -13340,12 +14234,12 @@ DUK_EXTERNAL const char *duk_base64_encode(duk_context *ctx, duk_idx_t index) { goto type_error; } dstlen = (srclen + 2) / 3 * 4; - dst = (duk_uint8_t *) duk_push_fixed_buffer(ctx, dstlen); + dst = (duk_uint8_t *) duk_push_fixed_buffer_nozero(ctx, dstlen); duk__base64_encode_helper((const duk_uint8_t *) src, srclen, dst); - ret = duk_to_string(ctx, -1); - duk_replace(ctx, index); + ret = duk_buffer_to_string(ctx, -1); /* Safe, result is ASCII. */ + duk_replace(ctx, idx); return ret; type_error: @@ -13353,7 +14247,7 @@ DUK_EXTERNAL const char *duk_base64_encode(duk_context *ctx, duk_idx_t index) { return NULL; /* never here */ } -DUK_EXTERNAL void duk_base64_decode(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL void duk_base64_decode(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; const duk_uint8_t *src; duk_size_t srclen; @@ -13368,8 +14262,8 @@ DUK_EXTERNAL void duk_base64_decode(duk_context *ctx, duk_idx_t index) { * which causes an unnecessary interning. */ - index = duk_require_normalize_index(ctx, index); - src = duk__prep_codec_arg(ctx, index, &srclen); + idx = duk_require_normalize_index(ctx, idx); + src = duk__prep_codec_arg(ctx, idx, &srclen); /* Computation must not wrap, only srclen + 3 is at risk of * wrapping because after that the number gets smaller. @@ -13390,14 +14284,14 @@ DUK_EXTERNAL void duk_base64_decode(duk_context *ctx, duk_idx_t index) { /* XXX: convert to fixed buffer? */ (void) duk_resize_buffer(ctx, -1, (duk_size_t) (dst_final - dst)); - duk_replace(ctx, index); + duk_replace(ctx, idx); return; type_error: DUK_ERROR_TYPE(thr, DUK_STR_DECODE_FAILED); } -DUK_EXTERNAL const char *duk_hex_encode(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL const char *duk_hex_encode(duk_context *ctx, duk_idx_t idx) { const duk_uint8_t *inp; duk_size_t len; duk_size_t i; @@ -13410,12 +14304,12 @@ DUK_EXTERNAL const char *duk_hex_encode(duk_context *ctx, duk_idx_t index) { DUK_ASSERT_CTX_VALID(ctx); - index = duk_require_normalize_index(ctx, index); - inp = duk__prep_codec_arg(ctx, index, &len); + idx = duk_require_normalize_index(ctx, idx); + inp = duk__prep_codec_arg(ctx, idx, &len); DUK_ASSERT(inp != NULL || len == 0); /* Fixed buffer, no zeroing because we'll fill all the data. */ - buf = (duk_uint8_t *) duk_push_buffer_raw(ctx, len * 2, DUK_BUF_FLAG_NOZERO /*flags*/); + buf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(ctx, len * 2); DUK_ASSERT(buf != NULL); #if defined(DUK_USE_HEX_FASTPATH) @@ -13448,12 +14342,12 @@ DUK_EXTERNAL const char *duk_hex_encode(duk_context *ctx, duk_idx_t index) { * caller coerce to string if necessary? */ - ret = duk_to_string(ctx, -1); - duk_replace(ctx, index); + ret = duk_buffer_to_string(ctx, -1); /* Safe, result is ASCII. */ + duk_replace(ctx, idx); return ret; } -DUK_EXTERNAL void duk_hex_decode(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL void duk_hex_decode(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; const duk_uint8_t *inp; duk_size_t len; @@ -13468,8 +14362,8 @@ DUK_EXTERNAL void duk_hex_decode(duk_context *ctx, duk_idx_t index) { DUK_ASSERT_CTX_VALID(ctx); - index = duk_require_normalize_index(ctx, index); - inp = duk__prep_codec_arg(ctx, index, &len); + idx = duk_require_normalize_index(ctx, idx); + inp = duk__prep_codec_arg(ctx, idx, &len); DUK_ASSERT(inp != NULL || len == 0); if (len & 0x01) { @@ -13477,7 +14371,7 @@ DUK_EXTERNAL void duk_hex_decode(duk_context *ctx, duk_idx_t index) { } /* Fixed buffer, no zeroing because we'll fill all the data. */ - buf = (duk_uint8_t *) duk_push_buffer_raw(ctx, len / 2, DUK_BUF_FLAG_NOZERO /*flags*/); + buf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(ctx, len / 2); DUK_ASSERT(buf != NULL); #if defined(DUK_USE_HEX_FASTPATH) @@ -13530,64 +14424,75 @@ DUK_EXTERNAL void duk_hex_decode(duk_context *ctx, duk_idx_t index) { } #endif /* DUK_USE_HEX_FASTPATH */ - duk_replace(ctx, index); + duk_replace(ctx, idx); return; type_error: DUK_ERROR_TYPE(thr, DUK_STR_DECODE_FAILED); } -DUK_EXTERNAL const char *duk_json_encode(duk_context *ctx, duk_idx_t index) { -#ifdef DUK_USE_ASSERTIONS +#if defined(DUK_USE_JSON_SUPPORT) +DUK_EXTERNAL const char *duk_json_encode(duk_context *ctx, duk_idx_t idx) { +#if defined(DUK_USE_ASSERTIONS) duk_idx_t top_at_entry; #endif const char *ret; DUK_ASSERT_CTX_VALID(ctx); -#ifdef DUK_USE_ASSERTIONS +#if defined(DUK_USE_ASSERTIONS) top_at_entry = duk_get_top(ctx); #endif - index = duk_require_normalize_index(ctx, index); + idx = duk_require_normalize_index(ctx, idx); duk_bi_json_stringify_helper(ctx, - index /*idx_value*/, + idx /*idx_value*/, DUK_INVALID_INDEX /*idx_replacer*/, DUK_INVALID_INDEX /*idx_space*/, 0 /*flags*/); DUK_ASSERT(duk_is_string(ctx, -1)); - duk_replace(ctx, index); - ret = duk_get_string(ctx, index); + duk_replace(ctx, idx); + ret = duk_get_string(ctx, idx); DUK_ASSERT(duk_get_top(ctx) == top_at_entry); return ret; } -DUK_EXTERNAL void duk_json_decode(duk_context *ctx, duk_idx_t index) { -#ifdef DUK_USE_ASSERTIONS +DUK_EXTERNAL void duk_json_decode(duk_context *ctx, duk_idx_t idx) { +#if defined(DUK_USE_ASSERTIONS) duk_idx_t top_at_entry; #endif DUK_ASSERT_CTX_VALID(ctx); -#ifdef DUK_USE_ASSERTIONS +#if defined(DUK_USE_ASSERTIONS) top_at_entry = duk_get_top(ctx); #endif - index = duk_require_normalize_index(ctx, index); + idx = duk_require_normalize_index(ctx, idx); duk_bi_json_parse_helper(ctx, - index /*idx_value*/, + idx /*idx_value*/, DUK_INVALID_INDEX /*idx_reviver*/, 0 /*flags*/); - duk_replace(ctx, index); + duk_replace(ctx, idx); DUK_ASSERT(duk_get_top(ctx) == top_at_entry); } -#line 1 "duk_api_compile.c" +#else /* DUK_USE_JSON_SUPPORT */ +DUK_EXTERNAL const char *duk_json_encode(duk_context *ctx, duk_idx_t idx) { + DUK_UNREF(idx); + DUK_ERROR_UNSUPPORTED((duk_hthread *) ctx); +} + +DUK_EXTERNAL void duk_json_decode(duk_context *ctx, duk_idx_t idx) { + DUK_UNREF(idx); + DUK_ERROR_UNSUPPORTED((duk_hthread *) ctx); +} +#endif /* DUK_USE_JSON_SUPPORT */ /* * Compilation and evaluation */ -/* include removed: duk_internal.h */ +/* #include duk_internal.h -> already included */ typedef struct duk__compile_raw_args duk__compile_raw_args; struct duk__compile_raw_args { @@ -13643,14 +14548,15 @@ DUK_EXTERNAL duk_int_t duk_eval_raw(duk_context *ctx, const char *src_buffer, du } /* Helper which can be called both directly and with duk_safe_call(). */ -DUK_LOCAL duk_ret_t duk__do_compile(duk_context *ctx) { +DUK_LOCAL duk_ret_t duk__do_compile(duk_context *ctx, void *udata) { duk_hthread *thr = (duk_hthread *) ctx; duk__compile_raw_args *comp_args; duk_uint_t flags; duk_small_uint_t comp_flags; - duk_hcompiledfunction *h_templ; + duk_hcompfunc *h_templ; DUK_ASSERT_CTX_VALID(ctx); + DUK_ASSERT(udata != NULL); /* Note: strictness is not inherited from the current Duktape/C * context. Otherwise it would not be possible to compile @@ -13659,13 +14565,10 @@ DUK_LOCAL duk_ret_t duk__do_compile(duk_context *ctx) { * for discussion. */ - /* [ ... source? filename? &comp_args ] (depends on flags) */ + /* [ ... source? filename? ] (depends on flags) */ - comp_args = (duk__compile_raw_args *) duk_require_pointer(ctx, -1); + comp_args = (duk__compile_raw_args *) udata; flags = comp_args->flags; - duk_pop(ctx); - - /* [ ... source? filename? ] */ if (flags & DUK_COMPILE_NOFILENAME) { /* Automatic filename: 'eval' or 'input'. */ @@ -13680,11 +14583,7 @@ DUK_LOCAL duk_ret_t duk__do_compile(duk_context *ctx) { h_sourcecode = duk_get_hstring(ctx, -2); if ((flags & DUK_COMPILE_NOSOURCE) || /* args incorrect */ (h_sourcecode == NULL)) { /* e.g. duk_push_string_file_raw() pushed undefined */ - /* XXX: when this error is caused by a nonexistent - * file given to duk_peval_file() or similar, the - * error message is not the best possible. - */ - DUK_ERROR_API(thr, DUK_STR_NO_SOURCECODE); + DUK_ERROR_TYPE(thr, DUK_STR_NO_SOURCECODE); } DUK_ASSERT(h_sourcecode != NULL); comp_args->src_buffer = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_sourcecode); @@ -13714,19 +14613,18 @@ DUK_LOCAL duk_ret_t duk__do_compile(duk_context *ctx) { if (flags & DUK_COMPILE_NOSOURCE) { ; } else { - duk_remove(ctx, -2); + duk_remove_m2(ctx); } /* [ ... func_template ] */ - h_templ = (duk_hcompiledfunction *) duk_get_hobject(ctx, -1); - DUK_ASSERT(h_templ != NULL); + h_templ = (duk_hcompfunc *) duk_known_hobject(ctx, -1); duk_js_push_closure(thr, h_templ, thr->builtins[DUK_BIDX_GLOBAL_ENV], thr->builtins[DUK_BIDX_GLOBAL_ENV], 1 /*add_auto_proto*/); - duk_remove(ctx, -2); /* -> [ ... closure ] */ + duk_remove_m2(ctx); /* -> [ ... closure ] */ /* [ ... closure ] */ @@ -13749,9 +14647,8 @@ DUK_EXTERNAL duk_int_t duk_compile_raw(duk_context *ctx, const char *src_buffer, comp_args->src_buffer = (const duk_uint8_t *) src_buffer; comp_args->src_length = src_length; comp_args->flags = flags; - duk_push_pointer(ctx, (void *) comp_args); - /* [ ... source? filename? &comp_args ] (depends on flags) */ + /* [ ... source? filename? ] (depends on flags) */ if (flags & DUK_COMPILE_SAFE) { duk_int_t rc; @@ -13763,27 +14660,26 @@ DUK_EXTERNAL duk_int_t duk_compile_raw(duk_context *ctx, const char *src_buffer, * directly into flags. */ nargs = flags & 0x07; - DUK_ASSERT(nargs == (1 + - ((flags & DUK_COMPILE_NOSOURCE) ? 0 : 1) + - ((flags & DUK_COMPILE_NOFILENAME) ? 0 : 1))); - rc = duk_safe_call(ctx, duk__do_compile, nargs, nrets); + DUK_ASSERT(nargs == ((flags & DUK_COMPILE_NOSOURCE) ? 0 : 1) + + ((flags & DUK_COMPILE_NOFILENAME) ? 0 : 1)); + rc = duk_safe_call(ctx, duk__do_compile, (void *) comp_args, nargs, nrets); /* [ ... closure ] */ return rc; } - (void) duk__do_compile(ctx); + (void) duk__do_compile(ctx, (void *) comp_args); /* [ ... closure ] */ return DUK_EXEC_SUCCESS; } -#line 1 "duk_api_debug.c" /* * Debugging related API calls */ -/* include removed: duk_internal.h */ +/* #include duk_internal.h -> already included */ +#if defined(DUK_USE_JSON_SUPPORT) DUK_EXTERNAL void duk_push_context_dump(duk_context *ctx) { duk_idx_t idx; duk_idx_t top; @@ -13817,18 +14713,23 @@ DUK_EXTERNAL void duk_push_context_dump(duk_context *ctx) { duk_pop(ctx); DUK_ASSERT(duk_is_string(ctx, -1)); } +#else /* DUK_USE_JSON_SUPPORT */ +DUK_EXTERNAL void duk_push_context_dump(duk_context *ctx) { + DUK_ERROR_UNSUPPORTED((duk_hthread *) ctx); +} +#endif /* DUK_USE_JSON_SUPPORT */ #if defined(DUK_USE_DEBUGGER_SUPPORT) -DUK_EXTERNAL void duk_debugger_attach_custom(duk_context *ctx, - duk_debug_read_function read_cb, - duk_debug_write_function write_cb, - duk_debug_peek_function peek_cb, - duk_debug_read_flush_function read_flush_cb, - duk_debug_write_flush_function write_flush_cb, - duk_debug_request_function request_cb, - duk_debug_detached_function detached_cb, - void *udata) { +DUK_EXTERNAL void duk_debugger_attach(duk_context *ctx, + duk_debug_read_function read_cb, + duk_debug_write_function write_cb, + duk_debug_peek_function peek_cb, + duk_debug_read_flush_function read_flush_cb, + duk_debug_write_flush_function write_flush_cb, + duk_debug_request_function request_cb, + duk_debug_detached_function detached_cb, + void *udata) { duk_hthread *thr = (duk_hthread *) ctx; duk_heap *heap; const char *str; @@ -13858,7 +14759,7 @@ DUK_EXTERNAL void duk_debugger_attach_custom(duk_context *ctx, /* Start in paused state. */ heap->dbg_processing = 0; - heap->dbg_paused = 1; + DUK_HEAP_SET_DEBUGGER_PAUSED(heap); heap->dbg_state_dirty = 1; heap->dbg_force_restart = 0; heap->dbg_step_type = 0; @@ -13937,7 +14838,7 @@ DUK_EXTERNAL duk_bool_t duk_debugger_notify(duk_context *ctx, duk_idx_t nvalues) top = duk_get_top(ctx); if (top < nvalues) { - DUK_ERROR_API(thr, "not enough stack values for notify"); + DUK_ERROR_RANGE(thr, "not enough stack values for notify"); return ret; /* unreachable */ } if (DUK_HEAP_IS_DEBUGGER_ATTACHED(thr->heap)) { @@ -13986,15 +14887,15 @@ DUK_EXTERNAL void duk_debugger_pause(duk_context *ctx) { #else /* DUK_USE_DEBUGGER_SUPPORT */ -DUK_EXTERNAL void duk_debugger_attach_custom(duk_context *ctx, - duk_debug_read_function read_cb, - duk_debug_write_function write_cb, - duk_debug_peek_function peek_cb, - duk_debug_read_flush_function read_flush_cb, - duk_debug_write_flush_function write_flush_cb, - duk_debug_request_function request_cb, - duk_debug_detached_function detached_cb, - void *udata) { +DUK_EXTERNAL void duk_debugger_attach(duk_context *ctx, + duk_debug_read_function read_cb, + duk_debug_write_function write_cb, + duk_debug_peek_function peek_cb, + duk_debug_read_flush_function read_flush_cb, + duk_debug_write_flush_function write_flush_cb, + duk_debug_request_function request_cb, + duk_debug_detached_function detached_cb, + void *udata) { DUK_ASSERT_CTX_VALID(ctx); DUK_UNREF(read_cb); DUK_UNREF(write_cb); @@ -14004,12 +14905,12 @@ DUK_EXTERNAL void duk_debugger_attach_custom(duk_context *ctx, DUK_UNREF(request_cb); DUK_UNREF(detached_cb); DUK_UNREF(udata); - DUK_ERROR_API((duk_hthread *) ctx, "no debugger support"); + DUK_ERROR_TYPE((duk_hthread *) ctx, "no debugger support"); } DUK_EXTERNAL void duk_debugger_detach(duk_context *ctx) { DUK_ASSERT_CTX_VALID(ctx); - DUK_ERROR_API((duk_hthread *) ctx, "no debugger support"); + DUK_ERROR_TYPE((duk_hthread *) ctx, "no debugger support"); } DUK_EXTERNAL void duk_debugger_cooperate(duk_context *ctx) { @@ -14025,7 +14926,7 @@ DUK_EXTERNAL duk_bool_t duk_debugger_notify(duk_context *ctx, duk_idx_t nvalues) top = duk_get_top(ctx); if (top < nvalues) { - DUK_ERROR_API((duk_hthread *) ctx, "not enough stack values for notify"); + DUK_ERROR_RANGE_INVALID_COUNT((duk_hthread *) ctx); return 0; /* unreachable */ } @@ -14041,12 +14942,11 @@ DUK_EXTERNAL void duk_debugger_pause(duk_context *ctx) { } #endif /* DUK_USE_DEBUGGER_SUPPORT */ -#line 1 "duk_api_heap.c" /* * Heap creation and destruction */ -/* include removed: duk_internal.h */ +/* #include duk_internal.h -> already included */ typedef struct duk_internal_thread_state duk_internal_thread_state; @@ -14205,24 +15105,19 @@ DUK_EXTERNAL void duk_set_global_object(duk_context *ctx) { * same (initial) built-ins. */ - (void) duk_push_object_helper(ctx, - DUK_HOBJECT_FLAG_EXTENSIBLE | - DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJENV), - -1); /* no prototype, updated below */ - - duk_dup(ctx, -2); - duk_dup(ctx, -3); - - /* [ ... new_glob new_env new_glob new_glob ] */ + h_env = duk_push_object_helper(ctx, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJENV), + -1); /* no prototype, updated below */ + DUK_ASSERT(h_env != NULL); - duk_xdef_prop_stridx(thr, -3, DUK_STRIDX_INT_TARGET, DUK_PROPDESC_FLAGS_NONE); - duk_xdef_prop_stridx(thr, -2, DUK_STRIDX_INT_THIS, DUK_PROPDESC_FLAGS_NONE); + duk_dup_m2(ctx); + duk_dup_m3(ctx); + duk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_INT_TARGET, DUK_PROPDESC_FLAGS_NONE); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_THIS, DUK_PROPDESC_FLAGS_NONE); /* [ ... new_glob new_env ] */ - h_env = duk_get_hobject(ctx, -1); - DUK_ASSERT(h_env != NULL); - h_prev_env = thr->builtins[DUK_BIDX_GLOBAL_ENV]; thr->builtins[DUK_BIDX_GLOBAL_ENV] = h_env; DUK_HOBJECT_INCREF(thr, h_env); @@ -14236,65 +15131,257 @@ DUK_EXTERNAL void duk_set_global_object(duk_context *ctx) { /* [ ... ] */ } -#line 1 "duk_api_logging.c" /* - * Logging - * - * Current logging primitive is a sprintf-style log which is convenient - * for most C code. Another useful primitive would be to log N arguments - * from value stack (like the Ecmascript binding does). + * Inspection */ -/* include removed: duk_internal.h */ +/* #include duk_internal.h -> already included */ -DUK_EXTERNAL void duk_log_va(duk_context *ctx, duk_int_t level, const char *fmt, va_list ap) { - /* stridx_logfunc[] must be static to allow initializer with old compilers like BCC */ - static const duk_uint16_t stridx_logfunc[6] = { - DUK_STRIDX_LC_TRACE, DUK_STRIDX_LC_DEBUG, DUK_STRIDX_LC_INFO, - DUK_STRIDX_LC_WARN, DUK_STRIDX_LC_ERROR, DUK_STRIDX_LC_FATAL - }; +/* For footprint efficient multiple value setting: arrays are much better than + * varargs, format string with parsing is often better than string pointer arrays. + */ +DUK_LOCAL void duk__inspect_multiple_uint(duk_context *ctx, const char *fmt, duk_int_t *vals) { + duk_int_t val; + const char *p; + const char *p_curr; + duk_size_t len; - DUK_ASSERT_CTX_VALID(ctx); + for (p = fmt;;) { + len = DUK_STRLEN(p); + p_curr = p; + p += len + 1; + if (len == 0) { + /* Double NUL (= empty key) terminates. */ + break; + } + val = *vals++; + if (val >= 0) { + /* Negative values are markers to skip key. */ + duk_push_string(ctx, p_curr); + duk_push_uint(ctx, val); + duk_put_prop(ctx, -3); + } + } +} + +/* Raw helper to extract internal information / statistics about a value. + * The return value is an object with properties that are version specific. + * The properties must not expose anything that would lead to security + * issues (e.g. exposing compiled function 'data' buffer might be an issue). + * Currently only counts and sizes and such are given so there shouldn't + * be security implications. + */ + +#define DUK__IDX_TYPE 0 +#define DUK__IDX_ITAG 1 +#define DUK__IDX_REFC 2 +#define DUK__IDX_HBYTES 3 +#define DUK__IDX_CLASS 4 +#define DUK__IDX_PBYTES 5 +#define DUK__IDX_ESIZE 6 +#define DUK__IDX_ENEXT 7 +#define DUK__IDX_ASIZE 8 +#define DUK__IDX_HSIZE 9 +#define DUK__IDX_BCBYTES 10 +#define DUK__IDX_DBYTES 11 +#define DUK__IDX_TSTATE 12 +#define DUK__IDX_VARIANT 13 + +DUK_EXTERNAL void duk_inspect_value(duk_context *ctx, duk_idx_t idx) { + duk_hthread *thr = (duk_hthread *) ctx; + duk_tval *tv; + duk_heaphdr *h; + /* The temporary values should be in an array rather than individual + * variables which (in practice) ensures that the compiler won't map + * them to registers and emit a lot of unnecessary shuffling code. + */ + duk_int_t vals[14]; + + DUK_UNREF(thr); + + tv = duk_get_tval_or_unused(ctx, idx); + h = (DUK_TVAL_IS_HEAP_ALLOCATED(tv) ? DUK_TVAL_GET_HEAPHDR(tv) : NULL); + + /* Assume two's complement and set everything to -1. */ + DUK_MEMSET((void *) &vals, (int) 0xff, sizeof(vals)); + DUK_ASSERT(vals[DUK__IDX_TYPE] == -1); /* spot check one */ + + duk_push_bare_object(ctx); - if (level < 0) { - level = 0; - } else if (level > (int) (sizeof(stridx_logfunc) / sizeof(duk_uint16_t)) - 1) { - level = (int) (sizeof(stridx_logfunc) / sizeof(duk_uint16_t)) - 1; + vals[DUK__IDX_TYPE] = duk_get_type_tval(tv); + vals[DUK__IDX_ITAG] = (duk_uint_t) DUK_TVAL_GET_TAG(tv); + + if (h == NULL) { + goto finish; } + duk_push_pointer(ctx, (void *) h); + duk_put_prop_string(ctx, -2, "hptr"); - duk_push_hobject_bidx(ctx, DUK_BIDX_LOGGER_CONSTRUCTOR); - duk_get_prop_stridx(ctx, -1, DUK_STRIDX_CLOG); - duk_get_prop_stridx(ctx, -1, stridx_logfunc[level]); - duk_dup(ctx, -2); +#if 0 + /* Covers a lot of information, e.g. buffer and string variants. */ + duk_push_uint(ctx, (duk_uint_t) DUK_HEAPHDR_GET_FLAGS(h)); + duk_put_prop_string(ctx, -2, "hflags"); +#endif + +#if defined(DUK_USE_REFERENCE_COUNTING) + vals[DUK__IDX_REFC] = (duk_int_t) DUK_HEAPHDR_GET_REFCOUNT(h); +#endif + vals[DUK__IDX_VARIANT] = 0; + + /* Heaphdr size and additional allocation size, followed by + * type specific stuff (with varying value count). + */ + switch ((duk_small_int_t) DUK_HEAPHDR_GET_TYPE(h)) { + case DUK_HTYPE_STRING: { + duk_hstring *h_str = (duk_hstring *) h; + vals[DUK__IDX_HBYTES] = (duk_int_t) (sizeof(duk_hstring) + DUK_HSTRING_GET_BYTELEN(h_str) + 1); +#if defined(DUK_USE_HSTRING_EXTDATA) + if (DUK_HSTRING_HAS_EXTDATA(h_str)) { + vals[DUK__IDX_VARIANT] = 1; + } +#endif + break; + } + case DUK_HTYPE_OBJECT: { + duk_hobject *h_obj = (duk_hobject *) h; - /* [ ... Logger clog logfunc clog ] */ + /* XXX: variants here are maybe pointless; class is enough? */ + if (DUK_HOBJECT_IS_ARRAY(h_obj)) { + vals[DUK__IDX_HBYTES] = sizeof(duk_harray); + } else if (DUK_HOBJECT_IS_COMPFUNC(h_obj)) { + vals[DUK__IDX_HBYTES] = sizeof(duk_hcompfunc); + } else if (DUK_HOBJECT_IS_NATFUNC(h_obj)) { + vals[DUK__IDX_HBYTES] = sizeof(duk_hnatfunc); + } else if (DUK_HOBJECT_IS_THREAD(h_obj)) { + vals[DUK__IDX_HBYTES] = sizeof(duk_hthread); + vals[DUK__IDX_TSTATE] = ((duk_hthread *) h_obj)->state; +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) + } else if (DUK_HOBJECT_IS_BUFOBJ(h_obj)) { + vals[DUK__IDX_HBYTES] = sizeof(duk_hbufobj); + /* XXX: some size information */ +#endif + } else { + vals[DUK__IDX_HBYTES] = (duk_small_uint_t) sizeof(duk_hobject); + } - duk_push_vsprintf(ctx, fmt, ap); + vals[DUK__IDX_CLASS] = (duk_int_t) DUK_HOBJECT_GET_CLASS_NUMBER(h_obj); + vals[DUK__IDX_PBYTES] = (duk_int_t) DUK_HOBJECT_P_ALLOC_SIZE(h_obj), + vals[DUK__IDX_ESIZE] = (duk_int_t) DUK_HOBJECT_GET_ESIZE(h_obj); + vals[DUK__IDX_ENEXT] = (duk_int_t) DUK_HOBJECT_GET_ENEXT(h_obj); + vals[DUK__IDX_ASIZE] = (duk_int_t) DUK_HOBJECT_GET_ASIZE(h_obj); + vals[DUK__IDX_HSIZE] = (duk_int_t) DUK_HOBJECT_GET_HSIZE(h_obj); - /* [ ... Logger clog logfunc clog(=this) msg ] */ + /* Note: e_next indicates the number of gc-reachable entries + * in the entry part, and also indicates the index where the + * next new property would be inserted. It does *not* indicate + * the number of non-NULL keys present in the object. That + * value could be counted separately but requires a pass through + * the key list. + */ - duk_call_method(ctx, 1 /*nargs*/); + if (DUK_HOBJECT_IS_COMPFUNC(h_obj)) { + duk_hbuffer *h_data = (duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA(thr->heap, (duk_hcompfunc *) h_obj); + vals[DUK__IDX_BCBYTES] = (duk_int_t) (h_data ? DUK_HBUFFER_GET_SIZE(h_data) : 0); + } + break; + } + case DUK_HTYPE_BUFFER: { + duk_hbuffer *h_buf = (duk_hbuffer *) h; - /* [ ... Logger clog res ] */ + if (DUK_HBUFFER_HAS_DYNAMIC(h_buf)) { + if (DUK_HBUFFER_HAS_EXTERNAL(h_buf)) { + vals[DUK__IDX_VARIANT] = 2; /* buffer variant 2: external */ + vals[DUK__IDX_HBYTES] = (duk_uint_t) (sizeof(duk_hbuffer_external)); + } else { + /* When alloc_size == 0 the second allocation may not + * actually exist. + */ + vals[DUK__IDX_VARIANT] = 1; /* buffer variant 1: dynamic */ + vals[DUK__IDX_HBYTES] = (duk_uint_t) (sizeof(duk_hbuffer_dynamic)); + } + vals[DUK__IDX_DBYTES] = (duk_uint_t) (DUK_HBUFFER_GET_SIZE(h_buf)); + } else { + DUK_ASSERT(vals[DUK__IDX_VARIANT] == 0); /* buffer variant 0: fixed */ + vals[DUK__IDX_HBYTES] = (duk_uint_t) (sizeof(duk_hbuffer_fixed) + DUK_HBUFFER_GET_SIZE(h_buf)); + } + break; + } + } - duk_pop_3(ctx); + finish: + duk__inspect_multiple_uint(ctx, + "type" "\x00" "itag" "\x00" "refc" "\x00" "hbytes" "\x00" "class" "\x00" + "pbytes" "\x00" "esize" "\x00" "enext" "\x00" "asize" "\x00" "hsize" "\x00" + "bcbytes" "\x00" "dbytes" "\x00" "tstate" "\x00" "variant" "\x00" "\x00", + (duk_int_t *) &vals); } -DUK_EXTERNAL void duk_log(duk_context *ctx, duk_int_t level, const char *fmt, ...) { - va_list ap; +DUK_EXTERNAL void duk_inspect_callstack_entry(duk_context *ctx, duk_int_t level) { + duk_hthread *thr = (duk_hthread *) ctx; + duk_activation *act; + duk_uint_fast32_t pc; + duk_uint_fast32_t line; DUK_ASSERT_CTX_VALID(ctx); - va_start(ap, fmt); - duk_log_va(ctx, level, fmt, ap); - va_end(ap); + /* -1 = top callstack entry, callstack[callstack_top - 1] + * -callstack_top = bottom callstack entry, callstack[0] + */ + if (level >= 0 || -level > (duk_int_t) thr->callstack_top) { + duk_push_undefined(ctx); + return; + } + duk_push_bare_object(ctx); + DUK_ASSERT(level >= -((duk_int_t) thr->callstack_top) && level <= -1); + + act = thr->callstack + thr->callstack_top + level; + /* Relevant PC is just before current one because PC is + * post-incremented. This should match what error augment + * code does. + */ + pc = duk_hthread_get_act_prev_pc(thr, act); + + duk_push_tval(ctx, &act->tv_func); + + duk_push_uint(ctx, (duk_uint_t) pc); + duk_put_prop_stridx_short(ctx, -3, DUK_STRIDX_PC); + +#if defined(DUK_USE_PC2LINE) + line = duk_hobject_pc2line_query(ctx, -1, pc); +#else + line = 0; +#endif + duk_push_uint(ctx, (duk_uint_t) line); + duk_put_prop_stridx_short(ctx, -3, DUK_STRIDX_LINE_NUMBER); + + duk_put_prop_stridx_short(ctx, -2, DUK_STRIDX_LC_FUNCTION); + /* Providing access to e.g. act->lex_env would be dangerous: these + * internal structures must never be accessible to the application. + * Duktape relies on them having consistent data, and this consistency + * is only asserted for, not checked for. + */ } -#line 1 "duk_api_memory.c" + +/* automatic undefs */ +#undef DUK__IDX_ASIZE +#undef DUK__IDX_BCBYTES +#undef DUK__IDX_CLASS +#undef DUK__IDX_DBYTES +#undef DUK__IDX_ENEXT +#undef DUK__IDX_ESIZE +#undef DUK__IDX_HBYTES +#undef DUK__IDX_HSIZE +#undef DUK__IDX_ITAG +#undef DUK__IDX_PBYTES +#undef DUK__IDX_REFC +#undef DUK__IDX_TSTATE +#undef DUK__IDX_TYPE +#undef DUK__IDX_VARIANT /* * Memory calls. */ -/* include removed: duk_internal.h */ +/* #include duk_internal.h -> already included */ DUK_EXTERNAL void *duk_alloc_raw(duk_context *ctx, duk_size_t size) { duk_hthread *thr = (duk_hthread *) ctx; @@ -14371,34 +15458,24 @@ DUK_EXTERNAL void duk_get_memory_functions(duk_context *ctx, duk_memory_function } DUK_EXTERNAL void duk_gc(duk_context *ctx, duk_uint_t flags) { -#ifdef DUK_USE_MARK_AND_SWEEP duk_hthread *thr = (duk_hthread *) ctx; duk_heap *heap; + duk_small_uint_t ms_flags; - DUK_UNREF(flags); - - /* NULL accepted */ - if (!ctx) { - return; - } DUK_ASSERT_CTX_VALID(ctx); heap = thr->heap; DUK_ASSERT(heap != NULL); DUK_D(DUK_DPRINT("mark-and-sweep requested by application")); - duk_heap_mark_and_sweep(heap, 0); -#else - DUK_D(DUK_DPRINT("mark-and-sweep requested by application but mark-and-sweep not enabled, ignoring")); - DUK_UNREF(ctx); - DUK_UNREF(flags); -#endif + DUK_ASSERT(DUK_GC_COMPACT == DUK_MS_FLAG_EMERGENCY); /* Compact flag is 1:1 with emergency flag which forces compaction. */ + ms_flags = (duk_small_uint_t) flags; + duk_heap_mark_and_sweep(heap, ms_flags); } -#line 1 "duk_api_object.c" /* * Object handling: property access and other support functions. */ -/* include removed: duk_internal.h */ +/* #include duk_internal.h -> already included */ /* * Property handling @@ -14408,7 +15485,7 @@ DUK_EXTERNAL void duk_gc(duk_context *ctx, duk_uint_t flags) { * defineProperty, getOwnPropertyDescriptor). */ -DUK_EXTERNAL duk_bool_t duk_get_prop(duk_context *ctx, duk_idx_t obj_index) { +DUK_EXTERNAL duk_bool_t duk_get_prop(duk_context *ctx, duk_idx_t obj_idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_tval *tv_obj; duk_tval *tv_key; @@ -14420,55 +15497,67 @@ DUK_EXTERNAL duk_bool_t duk_get_prop(duk_context *ctx, duk_idx_t obj_index) { * resize is not necessary for a property get right now. */ - tv_obj = duk_require_tval(ctx, obj_index); + tv_obj = duk_require_tval(ctx, obj_idx); tv_key = duk_require_tval(ctx, -1); rc = duk_hobject_getprop(thr, tv_obj, tv_key); DUK_ASSERT(rc == 0 || rc == 1); /* a value is left on stack regardless of rc */ - duk_remove(ctx, -2); /* remove key */ + duk_remove_m2(ctx); /* remove key */ return rc; /* 1 if property found, 0 otherwise */ } -DUK_EXTERNAL duk_bool_t duk_get_prop_string(duk_context *ctx, duk_idx_t obj_index, const char *key) { +DUK_EXTERNAL duk_bool_t duk_get_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key) { DUK_ASSERT_CTX_VALID(ctx); DUK_ASSERT(key != NULL); - obj_index = duk_require_normalize_index(ctx, obj_index); + obj_idx = duk_require_normalize_index(ctx, obj_idx); duk_push_string(ctx, key); - return duk_get_prop(ctx, obj_index); + return duk_get_prop(ctx, obj_idx); +} + +DUK_EXTERNAL duk_bool_t duk_get_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len) { + DUK_ASSERT_CTX_VALID(ctx); + DUK_ASSERT(key != NULL); + + obj_idx = duk_require_normalize_index(ctx, obj_idx); + duk_push_lstring(ctx, key, key_len); + return duk_get_prop(ctx, obj_idx); } -DUK_EXTERNAL duk_bool_t duk_get_prop_index(duk_context *ctx, duk_idx_t obj_index, duk_uarridx_t arr_index) { +DUK_EXTERNAL duk_bool_t duk_get_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx) { DUK_ASSERT_CTX_VALID(ctx); - obj_index = duk_require_normalize_index(ctx, obj_index); - duk_push_uarridx(ctx, arr_index); - return duk_get_prop(ctx, obj_index); + obj_idx = duk_require_normalize_index(ctx, obj_idx); + duk_push_uarridx(ctx, arr_idx); + return duk_get_prop(ctx, obj_idx); } -DUK_INTERNAL duk_bool_t duk_get_prop_stridx(duk_context *ctx, duk_idx_t obj_index, duk_small_int_t stridx) { +DUK_INTERNAL duk_bool_t duk_get_prop_stridx(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx) { duk_hthread *thr = (duk_hthread *) ctx; DUK_ASSERT_CTX_VALID(ctx); - DUK_ASSERT_DISABLE(stridx >= 0); - DUK_ASSERT(stridx < DUK_HEAP_NUM_STRINGS); + DUK_ASSERT_STRIDX_VALID(stridx); DUK_UNREF(thr); - obj_index = duk_require_normalize_index(ctx, obj_index); + obj_idx = duk_require_normalize_index(ctx, obj_idx); duk_push_hstring(ctx, DUK_HTHREAD_GET_STRING(thr, stridx)); - return duk_get_prop(ctx, obj_index); + return duk_get_prop(ctx, obj_idx); +} + +DUK_INTERNAL duk_bool_t duk_get_prop_stridx_short_raw(duk_context *ctx, duk_uint_t packed_args) { + return duk_get_prop_stridx(ctx, (duk_idx_t) (duk_int16_t) (packed_args >> 16), + (duk_small_uint_t) (packed_args & 0xffffUL)); } -DUK_INTERNAL duk_bool_t duk_get_prop_stridx_boolean(duk_context *ctx, duk_idx_t obj_index, duk_small_int_t stridx, duk_bool_t *out_has_prop) { +DUK_INTERNAL duk_bool_t duk_get_prop_stridx_boolean(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_bool_t *out_has_prop) { duk_bool_t rc; DUK_ASSERT_CTX_VALID(ctx); - DUK_ASSERT_DISABLE(stridx >= 0); - DUK_ASSERT(stridx < DUK_HEAP_NUM_STRINGS); + DUK_ASSERT_STRIDX_VALID(stridx); - rc = duk_get_prop_stridx(ctx, obj_index, stridx); + rc = duk_get_prop_stridx(ctx, obj_idx, stridx); if (out_has_prop) { *out_has_prop = rc; } @@ -14496,6 +15585,7 @@ DUK_LOCAL duk_bool_t duk__put_prop_shared(duk_context *ctx, duk_idx_t obj_idx, d */ DUK_ASSERT((idx_key == -2 && (idx_key ^ 1) == -1) || (idx_key == -1 && (idx_key ^ 1) == -2)); + /* XXX: Direct access; faster validation. */ tv_obj = duk_require_tval(ctx, obj_idx); tv_key = duk_require_tval(ctx, idx_key); tv_val = duk_require_tval(ctx, idx_key ^ 1); @@ -14526,6 +15616,15 @@ DUK_EXTERNAL duk_bool_t duk_put_prop_string(duk_context *ctx, duk_idx_t obj_idx, return duk__put_prop_shared(ctx, obj_idx, -1); } +DUK_EXTERNAL duk_bool_t duk_put_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len) { + DUK_ASSERT_CTX_VALID(ctx); + DUK_ASSERT(key != NULL); + + obj_idx = duk_normalize_index(ctx, obj_idx); + (void) duk_push_lstring(ctx, key, key_len); + return duk__put_prop_shared(ctx, obj_idx, -1); +} + DUK_EXTERNAL duk_bool_t duk_put_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx) { DUK_ASSERT_CTX_VALID(ctx); @@ -14534,12 +15633,11 @@ DUK_EXTERNAL duk_bool_t duk_put_prop_index(duk_context *ctx, duk_idx_t obj_idx, return duk__put_prop_shared(ctx, obj_idx, -1); } -DUK_INTERNAL duk_bool_t duk_put_prop_stridx(duk_context *ctx, duk_idx_t obj_idx, duk_small_int_t stridx) { +DUK_INTERNAL duk_bool_t duk_put_prop_stridx(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx) { duk_hthread *thr = (duk_hthread *) ctx; DUK_ASSERT_CTX_VALID(ctx); - DUK_ASSERT_DISABLE(stridx >= 0); - DUK_ASSERT(stridx < DUK_HEAP_NUM_STRINGS); + DUK_ASSERT_STRIDX_VALID(stridx); DUK_UNREF(thr); obj_idx = duk_require_normalize_index(ctx, obj_idx); @@ -14547,7 +15645,12 @@ DUK_INTERNAL duk_bool_t duk_put_prop_stridx(duk_context *ctx, duk_idx_t obj_idx, return duk__put_prop_shared(ctx, obj_idx, -1); } -DUK_EXTERNAL duk_bool_t duk_del_prop(duk_context *ctx, duk_idx_t obj_index) { +DUK_INTERNAL duk_bool_t duk_put_prop_stridx_short_raw(duk_context *ctx, duk_uint_t packed_args) { + return duk_put_prop_stridx(ctx, (duk_idx_t) (duk_int16_t) (packed_args >> 16), + (duk_small_uint_t) (packed_args & 0xffffUL)); +} + +DUK_EXTERNAL duk_bool_t duk_del_prop(duk_context *ctx, duk_idx_t obj_idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_tval *tv_obj; duk_tval *tv_key; @@ -14560,7 +15663,7 @@ DUK_EXTERNAL duk_bool_t duk_del_prop(duk_context *ctx, duk_idx_t obj_index) { * resize is not necessary for a property delete right now. */ - tv_obj = duk_require_tval(ctx, obj_index); + tv_obj = duk_require_tval(ctx, obj_idx); tv_key = duk_require_tval(ctx, -1); throw_flag = duk_is_strict_call(ctx); @@ -14571,37 +15674,52 @@ DUK_EXTERNAL duk_bool_t duk_del_prop(duk_context *ctx, duk_idx_t obj_index) { return rc; } -DUK_EXTERNAL duk_bool_t duk_del_prop_string(duk_context *ctx, duk_idx_t obj_index, const char *key) { +DUK_EXTERNAL duk_bool_t duk_del_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key) { DUK_ASSERT_CTX_VALID(ctx); DUK_ASSERT(key != NULL); - obj_index = duk_require_normalize_index(ctx, obj_index); + obj_idx = duk_require_normalize_index(ctx, obj_idx); duk_push_string(ctx, key); - return duk_del_prop(ctx, obj_index); + return duk_del_prop(ctx, obj_idx); +} + +DUK_EXTERNAL duk_bool_t duk_del_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len) { + DUK_ASSERT_CTX_VALID(ctx); + DUK_ASSERT(key != NULL); + + obj_idx = duk_require_normalize_index(ctx, obj_idx); + duk_push_lstring(ctx, key, key_len); + return duk_del_prop(ctx, obj_idx); } -DUK_EXTERNAL duk_bool_t duk_del_prop_index(duk_context *ctx, duk_idx_t obj_index, duk_uarridx_t arr_index) { +DUK_EXTERNAL duk_bool_t duk_del_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx) { DUK_ASSERT_CTX_VALID(ctx); - obj_index = duk_require_normalize_index(ctx, obj_index); - duk_push_uarridx(ctx, arr_index); - return duk_del_prop(ctx, obj_index); + obj_idx = duk_require_normalize_index(ctx, obj_idx); + duk_push_uarridx(ctx, arr_idx); + return duk_del_prop(ctx, obj_idx); } -DUK_INTERNAL duk_bool_t duk_del_prop_stridx(duk_context *ctx, duk_idx_t obj_index, duk_small_int_t stridx) { +DUK_INTERNAL duk_bool_t duk_del_prop_stridx(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx) { duk_hthread *thr = (duk_hthread *) ctx; DUK_ASSERT_CTX_VALID(ctx); - DUK_ASSERT_DISABLE(stridx >= 0); - DUK_ASSERT(stridx < DUK_HEAP_NUM_STRINGS); + DUK_ASSERT_STRIDX_VALID(stridx); DUK_UNREF(thr); - obj_index = duk_require_normalize_index(ctx, obj_index); + obj_idx = duk_require_normalize_index(ctx, obj_idx); duk_push_hstring(ctx, DUK_HTHREAD_GET_STRING(thr, stridx)); - return duk_del_prop(ctx, obj_index); + return duk_del_prop(ctx, obj_idx); +} + +#if 0 +DUK_INTERNAL duk_bool_t duk_del_prop_stridx_short_raw(duk_context *ctx, duk_uint_t packed_args) { + return duk_del_prop_stridx(ctx, (duk_idx_t) (duk_int16_t) (packed_args >> 16), + (duk_small_uint_t) (packed_args & 0xffffUL)); } +#endif -DUK_EXTERNAL duk_bool_t duk_has_prop(duk_context *ctx, duk_idx_t obj_index) { +DUK_EXTERNAL duk_bool_t duk_has_prop(duk_context *ctx, duk_idx_t obj_idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_tval *tv_obj; duk_tval *tv_key; @@ -14613,7 +15731,7 @@ DUK_EXTERNAL duk_bool_t duk_has_prop(duk_context *ctx, duk_idx_t obj_index) { * resize is not necessary for a property existence check right now. */ - tv_obj = duk_require_tval(ctx, obj_index); + tv_obj = duk_require_tval(ctx, obj_idx); tv_key = duk_require_tval(ctx, -1); rc = duk_hobject_hasprop(thr, tv_obj, tv_key); @@ -14623,51 +15741,66 @@ DUK_EXTERNAL duk_bool_t duk_has_prop(duk_context *ctx, duk_idx_t obj_index) { return rc; /* 1 if property found, 0 otherwise */ } -DUK_EXTERNAL duk_bool_t duk_has_prop_string(duk_context *ctx, duk_idx_t obj_index, const char *key) { +DUK_EXTERNAL duk_bool_t duk_has_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key) { DUK_ASSERT_CTX_VALID(ctx); DUK_ASSERT(key != NULL); - obj_index = duk_require_normalize_index(ctx, obj_index); + obj_idx = duk_require_normalize_index(ctx, obj_idx); duk_push_string(ctx, key); - return duk_has_prop(ctx, obj_index); + return duk_has_prop(ctx, obj_idx); +} + +DUK_EXTERNAL duk_bool_t duk_has_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len) { + DUK_ASSERT_CTX_VALID(ctx); + DUK_ASSERT(key != NULL); + + obj_idx = duk_require_normalize_index(ctx, obj_idx); + duk_push_lstring(ctx, key, key_len); + return duk_has_prop(ctx, obj_idx); } -DUK_EXTERNAL duk_bool_t duk_has_prop_index(duk_context *ctx, duk_idx_t obj_index, duk_uarridx_t arr_index) { +DUK_EXTERNAL duk_bool_t duk_has_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx) { DUK_ASSERT_CTX_VALID(ctx); - obj_index = duk_require_normalize_index(ctx, obj_index); - duk_push_uarridx(ctx, arr_index); - return duk_has_prop(ctx, obj_index); + obj_idx = duk_require_normalize_index(ctx, obj_idx); + duk_push_uarridx(ctx, arr_idx); + return duk_has_prop(ctx, obj_idx); } -DUK_INTERNAL duk_bool_t duk_has_prop_stridx(duk_context *ctx, duk_idx_t obj_index, duk_small_int_t stridx) { +DUK_INTERNAL duk_bool_t duk_has_prop_stridx(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx) { duk_hthread *thr = (duk_hthread *) ctx; DUK_ASSERT_CTX_VALID(ctx); - DUK_ASSERT_DISABLE(stridx >= 0); - DUK_ASSERT(stridx < DUK_HEAP_NUM_STRINGS); + DUK_ASSERT_STRIDX_VALID(stridx); DUK_UNREF(thr); - obj_index = duk_require_normalize_index(ctx, obj_index); + obj_idx = duk_require_normalize_index(ctx, obj_idx); duk_push_hstring(ctx, DUK_HTHREAD_GET_STRING(thr, stridx)); - return duk_has_prop(ctx, obj_index); + return duk_has_prop(ctx, obj_idx); } -/* Define own property without inheritance looks and such. This differs from +#if 0 +DUK_INTERNAL duk_bool_t duk_has_prop_stridx_short_raw(duk_context *ctx, duk_uint_t packed_args) { + return duk_has_prop_stridx(ctx, (duk_idx_t) (duk_int16_t) (packed_args >> 16), + (duk_small_uint_t) (packed_args & 0xffffUL)); +} +#endif + +/* Define own property without inheritance lookups and such. This differs from * [[DefineOwnProperty]] because special behaviors (like Array 'length') are * not invoked by this method. The caller must be careful to invoke any such * behaviors if necessary. */ -DUK_INTERNAL void duk_xdef_prop(duk_context *ctx, duk_idx_t obj_index, duk_small_uint_t desc_flags) { +DUK_INTERNAL void duk_xdef_prop(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t desc_flags) { duk_hthread *thr = (duk_hthread *) ctx; duk_hobject *obj; duk_hstring *key; DUK_ASSERT_CTX_VALID(ctx); - obj = duk_require_hobject(ctx, obj_index); + obj = duk_require_hobject(ctx, obj_idx); DUK_ASSERT(obj != NULL); - key = duk_to_hstring(ctx, -2); + key = duk_to_property_key_hstring(ctx, -2); DUK_ASSERT(key != NULL); DUK_ASSERT(duk_require_tval(ctx, -1) != NULL); @@ -14676,29 +15809,28 @@ DUK_INTERNAL void duk_xdef_prop(duk_context *ctx, duk_idx_t obj_index, duk_small duk_pop(ctx); /* pop key */ } -DUK_INTERNAL void duk_xdef_prop_index(duk_context *ctx, duk_idx_t obj_index, duk_uarridx_t arr_index, duk_small_uint_t desc_flags) { +DUK_INTERNAL void duk_xdef_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx, duk_small_uint_t desc_flags) { duk_hthread *thr = (duk_hthread *) ctx; duk_hobject *obj; DUK_ASSERT_CTX_VALID(ctx); - obj = duk_require_hobject(ctx, obj_index); + obj = duk_require_hobject(ctx, obj_idx); DUK_ASSERT(obj != NULL); - duk_hobject_define_property_internal_arridx(thr, obj, arr_index, desc_flags); + duk_hobject_define_property_internal_arridx(thr, obj, arr_idx, desc_flags); /* value popped by call */ } -DUK_INTERNAL void duk_xdef_prop_stridx(duk_context *ctx, duk_idx_t obj_index, duk_small_int_t stridx, duk_small_uint_t desc_flags) { +DUK_INTERNAL void duk_xdef_prop_stridx(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_uint_t desc_flags) { duk_hthread *thr = (duk_hthread *) ctx; duk_hobject *obj; duk_hstring *key; DUK_ASSERT_CTX_VALID(ctx); - DUK_ASSERT_DISABLE(stridx >= 0); - DUK_ASSERT(stridx < DUK_HEAP_NUM_STRINGS); + DUK_ASSERT_STRIDX_VALID(stridx); - obj = duk_require_hobject(ctx, obj_index); + obj = duk_require_hobject(ctx, obj_idx); DUK_ASSERT(obj != NULL); key = DUK_HTHREAD_GET_STRING(thr, stridx); DUK_ASSERT(key != NULL); @@ -14708,18 +15840,22 @@ DUK_INTERNAL void duk_xdef_prop_stridx(duk_context *ctx, duk_idx_t obj_index, du /* value popped by call */ } -DUK_INTERNAL void duk_xdef_prop_stridx_builtin(duk_context *ctx, duk_idx_t obj_index, duk_small_int_t stridx, duk_small_int_t builtin_idx, duk_small_uint_t desc_flags) { +DUK_INTERNAL void duk_xdef_prop_stridx_short_raw(duk_context *ctx, duk_uint_t packed_args) { + duk_xdef_prop_stridx(ctx, (duk_idx_t) (duk_int8_t) (packed_args >> 24), + (duk_small_uint_t) (packed_args >> 8) & 0xffffUL, + (duk_small_uint_t) (packed_args & 0xffL)); +} + +DUK_INTERNAL void duk_xdef_prop_stridx_builtin(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_int_t builtin_idx, duk_small_uint_t desc_flags) { duk_hthread *thr = (duk_hthread *) ctx; duk_hobject *obj; duk_hstring *key; DUK_ASSERT_CTX_VALID(ctx); - DUK_ASSERT_DISABLE(stridx >= 0); - DUK_ASSERT(stridx < DUK_HEAP_NUM_STRINGS); - DUK_ASSERT_DISABLE(builtin_idx >= 0); - DUK_ASSERT(builtin_idx < DUK_NUM_BUILTINS); + DUK_ASSERT_STRIDX_VALID(stridx); + DUK_ASSERT_BIDX_VALID(builtin_idx); - obj = duk_require_hobject(ctx, obj_index); + obj = duk_require_hobject(ctx, obj_idx); DUK_ASSERT(obj != NULL); key = DUK_HTHREAD_GET_STRING(thr, stridx); DUK_ASSERT(key != NULL); @@ -14734,15 +15870,23 @@ DUK_INTERNAL void duk_xdef_prop_stridx_builtin(duk_context *ctx, duk_idx_t obj_i * object creation code, function instance creation code, and Function.prototype.bind(). */ -DUK_INTERNAL void duk_xdef_prop_stridx_thrower(duk_context *ctx, duk_idx_t obj_index, duk_small_int_t stridx, duk_small_uint_t desc_flags) { - duk_hthread *thr = (duk_hthread *) ctx; - duk_hobject *obj = duk_require_hobject(ctx, obj_index); - duk_hobject *thrower = thr->builtins[DUK_BIDX_TYPE_ERROR_THROWER]; - duk_hobject_define_accessor_internal(thr, obj, DUK_HTHREAD_GET_STRING(thr, stridx), thrower, thrower, desc_flags); +DUK_INTERNAL void duk_xdef_prop_stridx_thrower(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx) { + obj_idx = duk_require_normalize_index(ctx, obj_idx); + duk_push_hstring_stridx(ctx, stridx); + duk_push_hobject_bidx(ctx, DUK_BIDX_TYPE_ERROR_THROWER); + duk_dup_top(ctx); + duk_def_prop(ctx, obj_idx, DUK_DEFPROP_HAVE_SETTER | DUK_DEFPROP_HAVE_GETTER | DUK_DEFPROP_FORCE); /* attributes always 0 */ +} + +/* Object.getOwnPropertyDescriptor() equivalent C binding. */ +DUK_EXTERNAL void duk_get_prop_desc(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t flags) { + DUK_UNREF(flags); /* no flags defined yet */ + + duk_hobject_object_get_own_property_descriptor(ctx, obj_idx); /* [ ... key ] -> [ ... desc ] */ } /* Object.defineProperty() equivalent C binding. */ -DUK_EXTERNAL void duk_def_prop(duk_context *ctx, duk_idx_t obj_index, duk_uint_t flags) { +DUK_EXTERNAL void duk_def_prop(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t flags) { duk_hthread *thr = (duk_hthread *) ctx; duk_idx_t idx_base; duk_hobject *obj; @@ -14755,7 +15899,7 @@ DUK_EXTERNAL void duk_def_prop(duk_context *ctx, duk_idx_t obj_index, duk_uint_t DUK_ASSERT_CTX_VALID(ctx); - obj = duk_require_hobject(ctx, obj_index); + obj = duk_require_hobject(ctx, obj_idx); is_data_desc = flags & (DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_HAVE_WRITABLE); is_acc_desc = flags & (DUK_DEFPROP_HAVE_GETTER | DUK_DEFPROP_HAVE_SETTER); @@ -14772,7 +15916,7 @@ DUK_EXTERNAL void duk_def_prop(duk_context *ctx, duk_idx_t obj_index, duk_uint_t duk_require_type_mask(ctx, idx_base, DUK_TYPE_MASK_UNDEFINED | DUK_TYPE_MASK_OBJECT | DUK_TYPE_MASK_LIGHTFUNC); - set = duk_get_hobject_or_lfunc_coerce(ctx, idx_base); + set = duk_get_hobject_promote_lfunc(ctx, idx_base); if (set != NULL && !DUK_HOBJECT_IS_CALLABLE(set)) { goto fail_not_callable; } @@ -14784,7 +15928,7 @@ DUK_EXTERNAL void duk_def_prop(duk_context *ctx, duk_idx_t obj_index, duk_uint_t duk_require_type_mask(ctx, idx_base, DUK_TYPE_MASK_UNDEFINED | DUK_TYPE_MASK_OBJECT | DUK_TYPE_MASK_LIGHTFUNC); - get = duk_get_hobject_or_lfunc_coerce(ctx, idx_base); + get = duk_get_hobject_promote_lfunc(ctx, idx_base); if (get != NULL && !DUK_HOBJECT_IS_CALLABLE(get)) { goto fail_not_callable; } @@ -14798,7 +15942,8 @@ DUK_EXTERNAL void duk_def_prop(duk_context *ctx, duk_idx_t obj_index, duk_uint_t } else { idx_value = (duk_idx_t) -1; } - key = duk_require_hstring(ctx, idx_base); + key = duk_to_property_key_hstring(ctx, idx_base); + DUK_ASSERT(key != NULL); duk_require_valid_index(ctx, idx_base); @@ -14808,7 +15953,8 @@ DUK_EXTERNAL void duk_def_prop(duk_context *ctx, duk_idx_t obj_index, duk_uint_t key, idx_value, get, - set); + set, + 1 /*throw_flag*/); /* Clean up stack */ @@ -14834,26 +15980,30 @@ DUK_EXTERNAL void duk_def_prop(duk_context *ctx, duk_idx_t obj_index, duk_uint_t * and are not exposed through the API. */ -DUK_EXTERNAL void duk_compact(duk_context *ctx, duk_idx_t obj_index) { +DUK_EXTERNAL void duk_compact(duk_context *ctx, duk_idx_t obj_idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_hobject *obj; DUK_ASSERT_CTX_VALID(ctx); - obj = duk_get_hobject(ctx, obj_index); + obj = duk_get_hobject(ctx, obj_idx); if (obj) { /* Note: this may fail, caller should protect the call if necessary */ duk_hobject_compact_props(thr, obj); } } +DUK_INTERNAL void duk_compact_m1(duk_context *ctx) { + duk_compact(ctx, -1); +} + /* XXX: the duk_hobject_enum.c stack APIs should be reworked */ -DUK_EXTERNAL void duk_enum(duk_context *ctx, duk_idx_t obj_index, duk_uint_t enum_flags) { +DUK_EXTERNAL void duk_enum(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t enum_flags) { DUK_ASSERT_CTX_VALID(ctx); - duk_dup(ctx, obj_index); - duk_require_hobject_or_lfunc_coerce(ctx, -1); + duk_dup(ctx, obj_idx); + duk_require_hobject_promote_mask(ctx, -1, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER); duk_hobject_enumerator_create(ctx, enum_flags); /* [target] -> [enum] */ } @@ -14869,31 +16019,34 @@ DUK_EXTERNAL duk_bool_t duk_next(duk_context *ctx, duk_idx_t enum_index, duk_boo * Helpers for writing multiple properties */ -DUK_EXTERNAL void duk_put_function_list(duk_context *ctx, duk_idx_t obj_index, const duk_function_list_entry *funcs) { +DUK_EXTERNAL void duk_put_function_list(duk_context *ctx, duk_idx_t obj_idx, const duk_function_list_entry *funcs) { const duk_function_list_entry *ent = funcs; DUK_ASSERT_CTX_VALID(ctx); - obj_index = duk_require_normalize_index(ctx, obj_index); + obj_idx = duk_require_normalize_index(ctx, obj_idx); if (ent != NULL) { while (ent->key != NULL) { duk_push_c_function(ctx, ent->value, ent->nargs); - duk_put_prop_string(ctx, obj_index, ent->key); + duk_put_prop_string(ctx, obj_idx, ent->key); ent++; } } } -DUK_EXTERNAL void duk_put_number_list(duk_context *ctx, duk_idx_t obj_index, const duk_number_list_entry *numbers) { +DUK_EXTERNAL void duk_put_number_list(duk_context *ctx, duk_idx_t obj_idx, const duk_number_list_entry *numbers) { const duk_number_list_entry *ent = numbers; + duk_tval *tv; DUK_ASSERT_CTX_VALID(ctx); - obj_index = duk_require_normalize_index(ctx, obj_index); + obj_idx = duk_require_normalize_index(ctx, obj_idx); if (ent != NULL) { while (ent->key != NULL) { - duk_push_number(ctx, ent->value); - duk_put_prop_string(ctx, obj_index, ent->key); + tv = ((duk_hthread *) ctx)->valstack_top++; + DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv)); /* value stack init policy */ + DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv, ent->value); /* no need for decref/incref */ + duk_put_prop_string(ctx, obj_idx, ent->key); ent++; } } @@ -14914,7 +16067,22 @@ DUK_EXTERNAL duk_bool_t duk_get_global_string(duk_context *ctx, const char *key) duk_push_hobject(ctx, thr->builtins[DUK_BIDX_GLOBAL]); ret = duk_get_prop_string(ctx, -1, key); - duk_remove(ctx, -2); + duk_remove_m2(ctx); + return ret; +} + +DUK_EXTERNAL duk_bool_t duk_get_global_lstring(duk_context *ctx, const char *key, duk_size_t key_len) { + duk_hthread *thr = (duk_hthread *) ctx; + duk_bool_t ret; + + DUK_ASSERT_CTX_VALID(ctx); + DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL); + + /* XXX: direct implementation */ + + duk_push_hobject(ctx, thr->builtins[DUK_BIDX_GLOBAL]); + ret = duk_get_prop_lstring(ctx, -1, key, key_len); + duk_remove_m2(ctx); return ret; } @@ -14934,11 +16102,27 @@ DUK_EXTERNAL duk_bool_t duk_put_global_string(duk_context *ctx, const char *key) return ret; } +DUK_EXTERNAL duk_bool_t duk_put_global_lstring(duk_context *ctx, const char *key, duk_size_t key_len) { + duk_hthread *thr = (duk_hthread *) ctx; + duk_bool_t ret; + + DUK_ASSERT_CTX_VALID(ctx); + DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL); + + /* XXX: direct implementation */ + + duk_push_hobject(ctx, thr->builtins[DUK_BIDX_GLOBAL]); + duk_insert(ctx, -2); + ret = duk_put_prop_lstring(ctx, -2, key, key_len); /* [ ... global val ] -> [ ... global ] */ + duk_pop(ctx); + return ret; +} + /* * Object prototype */ -DUK_EXTERNAL void duk_get_prototype(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL void duk_get_prototype(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_hobject *obj; duk_hobject *proto; @@ -14946,7 +16130,7 @@ DUK_EXTERNAL void duk_get_prototype(duk_context *ctx, duk_idx_t index) { DUK_ASSERT_CTX_VALID(ctx); DUK_UNREF(thr); - obj = duk_require_hobject(ctx, index); + obj = duk_require_hobject(ctx, idx); DUK_ASSERT(obj != NULL); /* XXX: shared helper for duk_push_hobject_or_undefined()? */ @@ -14958,14 +16142,14 @@ DUK_EXTERNAL void duk_get_prototype(duk_context *ctx, duk_idx_t index) { } } -DUK_EXTERNAL void duk_set_prototype(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL void duk_set_prototype(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_hobject *obj; duk_hobject *proto; DUK_ASSERT_CTX_VALID(ctx); - obj = duk_require_hobject(ctx, index); + obj = duk_require_hobject(ctx, idx); DUK_ASSERT(obj != NULL); duk_require_type_mask(ctx, -1, DUK_TYPE_MASK_UNDEFINED | DUK_TYPE_MASK_OBJECT); @@ -14988,23 +16172,36 @@ DUK_EXTERNAL void duk_set_prototype(duk_context *ctx, duk_idx_t index) { * Object finalizer */ +#if defined(DUK_USE_FINALIZER_SUPPORT) /* XXX: these could be implemented as macros calling an internal function * directly. * XXX: same issue as with Duktape.fin: there's no way to delete the property * now (just set it to undefined). */ -DUK_EXTERNAL void duk_get_finalizer(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL void duk_get_finalizer(duk_context *ctx, duk_idx_t idx) { DUK_ASSERT_CTX_VALID(ctx); - duk_get_prop_stridx(ctx, index, DUK_STRIDX_INT_FINALIZER); + duk_get_prop_stridx(ctx, idx, DUK_STRIDX_INT_FINALIZER); } -DUK_EXTERNAL void duk_set_finalizer(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL void duk_set_finalizer(duk_context *ctx, duk_idx_t idx) { DUK_ASSERT_CTX_VALID(ctx); - duk_put_prop_stridx(ctx, index, DUK_STRIDX_INT_FINALIZER); + duk_put_prop_stridx(ctx, idx, DUK_STRIDX_INT_FINALIZER); +} +#else /* DUK_USE_FINALIZER_SUPPORT */ +DUK_EXTERNAL void duk_get_finalizer(duk_context *ctx, duk_idx_t idx) { + DUK_ASSERT_CTX_VALID(ctx); + DUK_UNREF(idx); + DUK_ERROR_UNSUPPORTED((duk_hthread *) ctx); +} + +DUK_EXTERNAL void duk_set_finalizer(duk_context *ctx, duk_idx_t idx) { + DUK_ASSERT_CTX_VALID(ctx); + DUK_UNREF(idx); + DUK_ERROR_UNSUPPORTED((duk_hthread *) ctx); } -#line 1 "duk_api_stack.c" +#endif /* DUK_USE_FINALIZER_SUPPORT */ /* * API calls related to general value stack manipulation: resizing the value * stack, pushing and popping values, type checking and reading values, @@ -15017,7 +16214,7 @@ DUK_EXTERNAL void duk_set_finalizer(duk_context *ctx, duk_idx_t index) { /* XXX: repetition of stack pre-checks -> helper or macro or inline */ /* XXX: shared api error strings, and perhaps even throw code for rare cases? */ -/* include removed: duk_internal.h */ +/* #include duk_internal.h -> already included */ /* * Forward declarations @@ -15029,7 +16226,7 @@ DUK_LOCAL_DECL duk_idx_t duk__push_c_function_raw(duk_context *ctx, duk_c_functi * Global state for working around missing variadic macros */ -#ifndef DUK_USE_VARIADIC_MACROS +#if !defined(DUK_USE_VARIADIC_MACROS) DUK_EXTERNAL const char *duk_api_global_filename = NULL; DUK_EXTERNAL duk_int_t duk_api_global_line = 0; #endif @@ -15038,6 +16235,35 @@ DUK_EXTERNAL duk_int_t duk_api_global_line = 0; * Misc helpers */ +#if !defined(DUK_USE_PACKED_TVAL) +DUK_LOCAL const duk_uint_t duk__type_from_tag[] = { + DUK_TYPE_NUMBER, + DUK_TYPE_NUMBER, /* fastint */ + DUK_TYPE_UNDEFINED, + DUK_TYPE_NULL, + DUK_TYPE_BOOLEAN, + DUK_TYPE_POINTER, + DUK_TYPE_LIGHTFUNC, + DUK_TYPE_NONE, + DUK_TYPE_STRING, + DUK_TYPE_OBJECT, + DUK_TYPE_BUFFER, +}; +DUK_LOCAL const duk_uint_t duk__type_mask_from_tag[] = { + DUK_TYPE_MASK_NUMBER, + DUK_TYPE_MASK_NUMBER, /* fastint */ + DUK_TYPE_MASK_UNDEFINED, + DUK_TYPE_MASK_NULL, + DUK_TYPE_MASK_BOOLEAN, + DUK_TYPE_MASK_POINTER, + DUK_TYPE_MASK_LIGHTFUNC, + DUK_TYPE_MASK_NONE, + DUK_TYPE_MASK_STRING, + DUK_TYPE_MASK_OBJECT, + DUK_TYPE_MASK_BUFFER, +}; +#endif /* !DUK_USE_PACKED_TVAL */ + /* Check that there's room to push one value. */ #if defined(DUK_USE_VALSTACK_UNSAFE) /* Faster but value stack overruns are memory unsafe. */ @@ -15047,14 +16273,14 @@ DUK_EXTERNAL duk_int_t duk_api_global_line = 0; #else #define DUK__CHECK_SPACE() do { \ if (DUK_UNLIKELY(thr->valstack_top >= thr->valstack_end)) { \ - DUK_ERROR_API(thr, DUK_STR_PUSH_BEYOND_ALLOC_STACK); \ + DUK_ERROR_RANGE_PUSH_BEYOND(thr); \ } \ } while (0) #endif -DUK_LOCAL_DECL duk_heaphdr *duk__get_tagged_heaphdr_raw(duk_context *ctx, duk_idx_t index, duk_uint_t tag); +DUK_LOCAL_DECL duk_heaphdr *duk__get_tagged_heaphdr_raw(duk_context *ctx, duk_idx_t idx, duk_uint_t tag); -DUK_LOCAL duk_int_t duk__api_coerce_d2i(duk_context *ctx, duk_idx_t index, duk_bool_t require) { +DUK_LOCAL duk_int_t duk__api_coerce_d2i(duk_context *ctx, duk_idx_t idx, duk_bool_t require) { duk_hthread *thr; duk_tval *tv; duk_small_int_t c; @@ -15062,10 +16288,8 @@ DUK_LOCAL duk_int_t duk__api_coerce_d2i(duk_context *ctx, duk_idx_t index, duk_b thr = (duk_hthread *) ctx; - tv = duk_get_tval(ctx, index); - if (tv == NULL) { - goto error_notnumber; - } + tv = duk_get_tval_or_unused(ctx, idx); + DUK_ASSERT(tv != NULL); /* * Special cases like NaN and +/- Infinity are handled explicitly @@ -15112,16 +16336,14 @@ DUK_LOCAL duk_int_t duk__api_coerce_d2i(duk_context *ctx, duk_idx_t index, duk_b } } - error_notnumber: - if (require) { - DUK_ERROR_REQUIRE_TYPE_INDEX(thr, index, "number", DUK_STR_NOT_NUMBER); + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "number", DUK_STR_NOT_NUMBER); /* not reachable */ } return 0; } -DUK_LOCAL duk_uint_t duk__api_coerce_d2ui(duk_context *ctx, duk_idx_t index, duk_bool_t require) { +DUK_LOCAL duk_uint_t duk__api_coerce_d2ui(duk_context *ctx, duk_idx_t idx, duk_bool_t require) { duk_hthread *thr; duk_tval *tv; duk_small_int_t c; @@ -15131,10 +16353,8 @@ DUK_LOCAL duk_uint_t duk__api_coerce_d2ui(duk_context *ctx, duk_idx_t index, duk thr = (duk_hthread *) ctx; - tv = duk_get_tval(ctx, index); - if (tv == NULL) { - goto error_notnumber; - } + tv = duk_get_tval_or_unused(ctx, idx); + DUK_ASSERT(tv != NULL); #if defined(DUK_USE_FASTINT) if (DUK_TVAL_IS_FASTINT(tv)) { @@ -15169,10 +16389,8 @@ DUK_LOCAL duk_uint_t duk__api_coerce_d2ui(duk_context *ctx, duk_idx_t index, duk } } - error_notnumber: - if (require) { - DUK_ERROR_REQUIRE_TYPE_INDEX(thr, index, "number", DUK_STR_NOT_NUMBER); + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "number", DUK_STR_NOT_NUMBER); /* not reachable */ } return 0; @@ -15187,10 +16405,10 @@ DUK_LOCAL duk_uint_t duk__api_coerce_d2ui(duk_context *ctx, duk_idx_t index, duk * There's some repetition because of this; keep the functions in sync. */ -DUK_EXTERNAL duk_idx_t duk_normalize_index(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_idx_t duk_normalize_index(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_uidx_t vs_size; - duk_uidx_t uindex; + duk_uidx_t uidx; DUK_ASSERT_CTX_VALID(ctx); DUK_ASSERT(DUK_INVALID_INDEX < 0); @@ -15206,27 +16424,27 @@ DUK_EXTERNAL duk_idx_t duk_normalize_index(duk_context *ctx, duk_idx_t index) { vs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom); DUK_ASSERT_DISABLE(vs_size >= 0); /* unsigned */ - if (index < 0) { - uindex = vs_size + (duk_uidx_t) index; + if (idx < 0) { + uidx = vs_size + (duk_uidx_t) idx; } else { /* since index non-negative */ - DUK_ASSERT(index != DUK_INVALID_INDEX); - uindex = (duk_uidx_t) index; + DUK_ASSERT(idx != DUK_INVALID_INDEX); + uidx = (duk_uidx_t) idx; } /* DUK_INVALID_INDEX won't be accepted as a valid index. */ DUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size); - if (DUK_LIKELY(uindex < vs_size)) { - return (duk_idx_t) uindex; + if (DUK_LIKELY(uidx < vs_size)) { + return (duk_idx_t) uidx; } return DUK_INVALID_INDEX; } -DUK_EXTERNAL duk_idx_t duk_require_normalize_index(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_idx_t duk_require_normalize_index(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_uidx_t vs_size; - duk_uidx_t uindex; + duk_uidx_t uidx; DUK_ASSERT_CTX_VALID(ctx); DUK_ASSERT(DUK_INVALID_INDEX < 0); @@ -15235,27 +16453,27 @@ DUK_EXTERNAL duk_idx_t duk_require_normalize_index(duk_context *ctx, duk_idx_t i vs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom); DUK_ASSERT_DISABLE(vs_size >= 0); /* unsigned */ - if (index < 0) { - uindex = vs_size + (duk_uidx_t) index; + if (idx < 0) { + uidx = vs_size + (duk_uidx_t) idx; } else { - DUK_ASSERT(index != DUK_INVALID_INDEX); - uindex = (duk_uidx_t) index; + DUK_ASSERT(idx != DUK_INVALID_INDEX); + uidx = (duk_uidx_t) idx; } /* DUK_INVALID_INDEX won't be accepted as a valid index. */ DUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size); - if (DUK_LIKELY(uindex < vs_size)) { - return (duk_idx_t) uindex; + if (DUK_LIKELY(uidx < vs_size)) { + return (duk_idx_t) uidx; } - DUK_ERROR_API_INDEX(thr, index); + DUK_ERROR_RANGE_INDEX(thr, idx); return 0; /* unreachable */ } -DUK_INTERNAL duk_tval *duk_get_tval(duk_context *ctx, duk_idx_t index) { +DUK_INTERNAL duk_tval *duk_get_tval(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_uidx_t vs_size; - duk_uidx_t uindex; + duk_uidx_t uidx; DUK_ASSERT_CTX_VALID(ctx); DUK_ASSERT(DUK_INVALID_INDEX < 0); @@ -15264,26 +16482,43 @@ DUK_INTERNAL duk_tval *duk_get_tval(duk_context *ctx, duk_idx_t index) { vs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom); DUK_ASSERT_DISABLE(vs_size >= 0); /* unsigned */ - if (index < 0) { - uindex = vs_size + (duk_uidx_t) index; + if (idx < 0) { + uidx = vs_size + (duk_uidx_t) idx; } else { - DUK_ASSERT(index != DUK_INVALID_INDEX); - uindex = (duk_uidx_t) index; + DUK_ASSERT(idx != DUK_INVALID_INDEX); + uidx = (duk_uidx_t) idx; } /* DUK_INVALID_INDEX won't be accepted as a valid index. */ DUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size); - if (DUK_LIKELY(uindex < vs_size)) { - return thr->valstack_bottom + uindex; + if (DUK_LIKELY(uidx < vs_size)) { + return thr->valstack_bottom + uidx; } return NULL; } -DUK_INTERNAL duk_tval *duk_require_tval(duk_context *ctx, duk_idx_t index) { +/* Variant of duk_get_tval() which is guaranteed to return a valid duk_tval + * pointer. When duk_get_tval() would return NULL, this variant returns a + * pointer to a duk_tval with tag DUK_TAG_UNUSED. This allows the call site + * to avoid an unnecessary NULL check which sometimes leads to better code. + * The return duk_tval is read only (at least for the UNUSED value). + */ +DUK_LOCAL const duk_tval_unused duk__const_tval_unused = DUK_TVAL_UNUSED_INITIALIZER(); + +DUK_INTERNAL duk_tval *duk_get_tval_or_unused(duk_context *ctx, duk_idx_t idx) { + duk_tval *tv; + tv = duk_get_tval(ctx, idx); + if (tv != NULL) { + return tv; + } + return (duk_tval *) DUK_LOSE_CONST(&duk__const_tval_unused); +} + +DUK_INTERNAL duk_tval *duk_require_tval(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_uidx_t vs_size; - duk_uidx_t uindex; + duk_uidx_t uidx; DUK_ASSERT_CTX_VALID(ctx); DUK_ASSERT(DUK_INVALID_INDEX < 0); @@ -15293,40 +16528,40 @@ DUK_INTERNAL duk_tval *duk_require_tval(duk_context *ctx, duk_idx_t index) { DUK_ASSERT_DISABLE(vs_size >= 0); /* unsigned */ /* Use unsigned arithmetic to optimize comparison. */ - if (index < 0) { - uindex = vs_size + (duk_uidx_t) index; + if (idx < 0) { + uidx = vs_size + (duk_uidx_t) idx; } else { - DUK_ASSERT(index != DUK_INVALID_INDEX); - uindex = (duk_uidx_t) index; + DUK_ASSERT(idx != DUK_INVALID_INDEX); + uidx = (duk_uidx_t) idx; } /* DUK_INVALID_INDEX won't be accepted as a valid index. */ DUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size); - if (DUK_LIKELY(uindex < vs_size)) { - return thr->valstack_bottom + uindex; + if (DUK_LIKELY(uidx < vs_size)) { + return thr->valstack_bottom + uidx; } - DUK_ERROR_API_INDEX(thr, index); + DUK_ERROR_RANGE_INDEX(thr, idx); return NULL; } /* Non-critical. */ -DUK_EXTERNAL duk_bool_t duk_is_valid_index(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_bool_t duk_is_valid_index(duk_context *ctx, duk_idx_t idx) { DUK_ASSERT_CTX_VALID(ctx); DUK_ASSERT(DUK_INVALID_INDEX < 0); - return (duk_normalize_index(ctx, index) >= 0); + return (duk_normalize_index(ctx, idx) >= 0); } /* Non-critical. */ -DUK_EXTERNAL void duk_require_valid_index(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL void duk_require_valid_index(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; DUK_ASSERT_CTX_VALID(ctx); DUK_ASSERT(DUK_INVALID_INDEX < 0); - if (duk_normalize_index(ctx, index) < 0) { - DUK_ERROR_API_INDEX(thr, index); + if (duk_normalize_index(ctx, idx) < 0) { + DUK_ERROR_RANGE_INDEX(thr, idx); return; /* unreachable */ } } @@ -15343,15 +16578,31 @@ DUK_EXTERNAL duk_idx_t duk_get_top(duk_context *ctx) { return (duk_idx_t) (thr->valstack_top - thr->valstack_bottom); } +/* Internal helper to get current top but to require a minimum top value + * (TypeError if not met). + */ +DUK_INTERNAL duk_idx_t duk_get_top_require_min(duk_context *ctx, duk_idx_t min_top) { + duk_hthread *thr = (duk_hthread *) ctx; + duk_idx_t ret; + + DUK_ASSERT_CTX_VALID(ctx); + + ret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom); + if (ret < min_top) { + DUK_ERROR_TYPE_INVALID_ARGS(thr); + } + return ret; +} + /* Set stack top within currently allocated range, but don't reallocate. * This is performance critical especially for call handling, so whenever * changing, profile and look at generated code. */ -DUK_EXTERNAL void duk_set_top(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL void duk_set_top(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_uidx_t vs_size; duk_uidx_t vs_limit; - duk_uidx_t uindex; + duk_uidx_t uidx; duk_tval *tv; DUK_ASSERT_CTX_VALID(ctx); @@ -15362,16 +16613,16 @@ DUK_EXTERNAL void duk_set_top(duk_context *ctx, duk_idx_t index) { vs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom); vs_limit = (duk_uidx_t) (thr->valstack_end - thr->valstack_bottom); - if (index < 0) { + if (idx < 0) { /* Negative indices are always within allocated stack but * must not go below zero index. */ - uindex = vs_size + (duk_uidx_t) index; + uidx = vs_size + (duk_uidx_t) idx; } else { /* Positive index can be higher than valstack top but must * not go above allocated stack (equality is OK). */ - uindex = (duk_uidx_t) index; + uidx = (duk_uidx_t) idx; } /* DUK_INVALID_INDEX won't be accepted as a valid index. */ @@ -15379,15 +16630,15 @@ DUK_EXTERNAL void duk_set_top(duk_context *ctx, duk_idx_t index) { DUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_limit); #if defined(DUK_USE_VALSTACK_UNSAFE) - DUK_ASSERT(uindex <= vs_limit); + DUK_ASSERT(uidx <= vs_limit); DUK_UNREF(vs_limit); #else - if (DUK_UNLIKELY(uindex > vs_limit)) { - DUK_ERROR_API_INDEX(thr, index); + if (DUK_UNLIKELY(uidx > vs_limit)) { + DUK_ERROR_RANGE_INDEX(thr, idx); return; /* unreachable */ } #endif - DUK_ASSERT(uindex <= vs_limit); + DUK_ASSERT(uidx <= vs_limit); /* Handle change in value stack top. Respect value stack * initialization policy: 'undefined' above top. Note that @@ -15395,37 +16646,42 @@ DUK_EXTERNAL void duk_set_top(duk_context *ctx, duk_idx_t index) { * so must relookup after DECREF. */ - if (uindex >= vs_size) { + if (uidx >= vs_size) { /* Stack size increases or stays the same. */ #if defined(DUK_USE_ASSERTIONS) duk_uidx_t count; - count = uindex - vs_size; + count = uidx - vs_size; while (count != 0) { count--; tv = thr->valstack_top + count; DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv)); } #endif - thr->valstack_top = thr->valstack_bottom + uindex; + thr->valstack_top = thr->valstack_bottom + uidx; } else { /* Stack size decreases. */ #if defined(DUK_USE_REFERENCE_COUNTING) duk_uidx_t count; + duk_tval *tv_end; - count = vs_size - uindex; + count = vs_size - uidx; DUK_ASSERT(count > 0); - while (count > 0) { - count--; - tv = --thr->valstack_top; /* tv -> value just before prev top value; must relookup */ + tv = thr->valstack_top; + tv_end = tv - count; + DUK_ASSERT(tv > tv_end); /* Because count > 0. */ + do { + tv--; DUK_ASSERT(tv >= thr->valstack_bottom); - DUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv); /* side effects */ - } + DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, tv); + } while (tv != tv_end); + thr->valstack_top = tv_end; + DUK_REFZERO_CHECK_FAST(thr); #else /* DUK_USE_REFERENCE_COUNTING */ duk_uidx_t count; duk_tval *tv_end; - count = vs_size - uindex; + count = vs_size - uidx; tv = thr->valstack_top; tv_end = tv - count; DUK_ASSERT(tv > tv_end); @@ -15444,7 +16700,7 @@ DUK_EXTERNAL duk_idx_t duk_get_top_index(duk_context *ctx) { DUK_ASSERT_CTX_VALID(ctx); - ret = ((duk_idx_t) (thr->valstack_top - thr->valstack_bottom)) - 1; + ret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom) - 1; if (DUK_UNLIKELY(ret < 0)) { /* Return invalid index; if caller uses this without checking * in another API call, the index won't map to a valid stack @@ -15455,15 +16711,28 @@ DUK_EXTERNAL duk_idx_t duk_get_top_index(duk_context *ctx) { return ret; } +/* Internal variant: call assumes there is at least one element on the value + * stack frame; this is only asserted for. + */ +DUK_INTERNAL duk_idx_t duk_get_top_index_unsafe(duk_context *ctx) { + duk_hthread *thr = (duk_hthread *) ctx; + duk_idx_t ret; + + DUK_ASSERT_CTX_VALID(ctx); + + ret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom) - 1; + return ret; +} + DUK_EXTERNAL duk_idx_t duk_require_top_index(duk_context *ctx) { duk_hthread *thr = (duk_hthread *) ctx; duk_idx_t ret; DUK_ASSERT_CTX_VALID(ctx); - ret = ((duk_idx_t) (thr->valstack_top - thr->valstack_bottom)) - 1; + ret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom) - 1; if (DUK_UNLIKELY(ret < 0)) { - DUK_ERROR_API_INDEX(thr, -1); + DUK_ERROR_RANGE_INDEX(thr, -1); return 0; /* unreachable */ } return ret; @@ -15496,7 +16765,7 @@ DUK_LOCAL duk_bool_t duk__resize_valstack(duk_context *ctx, duk_size_t new_size) duk_ptrdiff_t old_bottom_offset; duk_ptrdiff_t old_top_offset; duk_ptrdiff_t old_end_offset_post; -#ifdef DUK_USE_DEBUG +#if defined(DUK_USE_DEBUG) duk_ptrdiff_t old_end_offset_pre; duk_tval *old_valstack_pre; duk_tval *old_valstack_post; @@ -15517,7 +16786,7 @@ DUK_LOCAL duk_bool_t duk__resize_valstack(duk_context *ctx, duk_size_t new_size) /* get pointer offsets for tweaking below */ old_bottom_offset = (((duk_uint8_t *) thr->valstack_bottom) - ((duk_uint8_t *) thr->valstack)); old_top_offset = (((duk_uint8_t *) thr->valstack_top) - ((duk_uint8_t *) thr->valstack)); -#ifdef DUK_USE_DEBUG +#if defined(DUK_USE_DEBUG) old_end_offset_pre = (((duk_uint8_t *) thr->valstack_end) - ((duk_uint8_t *) thr->valstack)); /* not very useful, used for debugging */ old_valstack_pre = thr->valstack; #endif @@ -15563,7 +16832,7 @@ DUK_LOCAL duk_bool_t duk__resize_valstack(duk_context *ctx, duk_size_t new_size) /* success, fixup pointers */ old_end_offset_post = (((duk_uint8_t *) thr->valstack_end) - ((duk_uint8_t *) thr->valstack)); /* must be computed after realloc */ -#ifdef DUK_USE_DEBUG +#if defined(DUK_USE_DEBUG) old_valstack_post = thr->valstack; #endif thr->valstack = new_valstack; @@ -15579,7 +16848,7 @@ DUK_LOCAL duk_bool_t duk__resize_valstack(duk_context *ctx, duk_size_t new_size) DUK_ASSERT(thr->valstack_end >= thr->valstack_top); /* useful for debugging */ -#ifdef DUK_USE_DEBUG +#if defined(DUK_USE_DEBUG) if (old_end_offset_pre != old_end_offset_post) { DUK_D(DUK_DPRINT("valstack was resized during valstack_resize(), probably by mark-and-sweep; " "end offset changed: %lu -> %lu", @@ -15711,7 +16980,7 @@ duk_bool_t duk_valstack_resize_raw(duk_context *ctx, DUK_DD(DUK_DDPRINT("valstack resize failed")); if (throw_flag) { - DUK_ERROR_ALLOC_DEFMSG(thr); + DUK_ERROR_ALLOC_FAILED(thr); } else { return 0; } @@ -15809,16 +17078,16 @@ DUK_EXTERNAL void duk_require_stack_top(duk_context *ctx, duk_idx_t top) { * Basic stack manipulation: swap, dup, insert, replace, etc */ -DUK_EXTERNAL void duk_swap(duk_context *ctx, duk_idx_t index1, duk_idx_t index2) { +DUK_EXTERNAL void duk_swap(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2) { duk_tval *tv1; duk_tval *tv2; duk_tval tv_tmp; DUK_ASSERT_CTX_VALID(ctx); - tv1 = duk_require_tval(ctx, index1); + tv1 = duk_require_tval(ctx, idx1); DUK_ASSERT(tv1 != NULL); - tv2 = duk_require_tval(ctx, index2); + tv2 = duk_require_tval(ctx, idx2); DUK_ASSERT(tv2 != NULL); /* If tv1==tv2 this is a NOP, no check is needed */ @@ -15827,13 +17096,13 @@ DUK_EXTERNAL void duk_swap(duk_context *ctx, duk_idx_t index1, duk_idx_t index2) DUK_TVAL_SET_TVAL(tv2, &tv_tmp); } -DUK_EXTERNAL void duk_swap_top(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL void duk_swap_top(duk_context *ctx, duk_idx_t idx) { DUK_ASSERT_CTX_VALID(ctx); - duk_swap(ctx, index, -1); + duk_swap(ctx, idx, -1); } -DUK_EXTERNAL void duk_dup(duk_context *ctx, duk_idx_t from_index) { +DUK_EXTERNAL void duk_dup(duk_context *ctx, duk_idx_t from_idx) { duk_hthread *thr; duk_tval *tv_from; duk_tval *tv_to; @@ -15842,7 +17111,7 @@ DUK_EXTERNAL void duk_dup(duk_context *ctx, duk_idx_t from_index) { thr = (duk_hthread *) ctx; DUK__CHECK_SPACE(); - tv_from = duk_require_tval(ctx, from_index); + tv_from = duk_require_tval(ctx, from_idx); tv_to = thr->valstack_top++; DUK_ASSERT(tv_from != NULL); DUK_ASSERT(tv_to != NULL); @@ -15851,6 +17120,9 @@ DUK_EXTERNAL void duk_dup(duk_context *ctx, duk_idx_t from_index) { } DUK_EXTERNAL void duk_dup_top(duk_context *ctx) { +#if defined(DUK_USE_PREFER_SIZE) + duk_dup(ctx, -1); +#else duk_hthread *thr; duk_tval *tv_from; duk_tval *tv_to; @@ -15860,7 +17132,7 @@ DUK_EXTERNAL void duk_dup_top(duk_context *ctx) { DUK__CHECK_SPACE(); if (thr->valstack_top - thr->valstack_bottom <= 0) { - DUK_ERROR_API_INDEX(thr, -1); + DUK_ERROR_RANGE_INDEX(thr, -1); return; /* unreachable */ } tv_from = thr->valstack_top - 1; @@ -15869,9 +17141,29 @@ DUK_EXTERNAL void duk_dup_top(duk_context *ctx) { DUK_ASSERT(tv_to != NULL); DUK_TVAL_SET_TVAL(tv_to, tv_from); DUK_TVAL_INCREF(thr, tv_to); /* no side effects */ +#endif +} + +DUK_INTERNAL void duk_dup_0(duk_context *ctx) { + duk_dup(ctx, 0); +} +DUK_INTERNAL void duk_dup_1(duk_context *ctx) { + duk_dup(ctx, 1); +} +DUK_INTERNAL void duk_dup_2(duk_context *ctx) { + duk_dup(ctx, 2); +} +DUK_INTERNAL void duk_dup_m2(duk_context *ctx) { + duk_dup(ctx, -2); +} +DUK_INTERNAL void duk_dup_m3(duk_context *ctx) { + duk_dup(ctx, -3); +} +DUK_INTERNAL void duk_dup_m4(duk_context *ctx) { + duk_dup(ctx, -4); } -DUK_EXTERNAL void duk_insert(duk_context *ctx, duk_idx_t to_index) { +DUK_EXTERNAL void duk_insert(duk_context *ctx, duk_idx_t to_idx) { duk_tval *p; duk_tval *q; duk_tval tv_tmp; @@ -15879,7 +17171,7 @@ DUK_EXTERNAL void duk_insert(duk_context *ctx, duk_idx_t to_index) { DUK_ASSERT_CTX_VALID(ctx); - p = duk_require_tval(ctx, to_index); + p = duk_require_tval(ctx, to_idx); DUK_ASSERT(p != NULL); q = duk_require_tval(ctx, -1); DUK_ASSERT(q != NULL); @@ -15894,8 +17186,8 @@ DUK_EXTERNAL void duk_insert(duk_context *ctx, duk_idx_t to_index) { nbytes = (duk_size_t) (((duk_uint8_t *) q) - ((duk_uint8_t *) p)); /* Note: 'q' is top-1 */ - DUK_DDD(DUK_DDDPRINT("duk_insert: to_index=%ld, p=%p, q=%p, nbytes=%lu", - (long) to_index, (void *) p, (void *) q, (unsigned long) nbytes)); + DUK_DDD(DUK_DDDPRINT("duk_insert: to_idx=%ld, p=%p, q=%p, nbytes=%lu", + (long) to_idx, (void *) p, (void *) q, (unsigned long) nbytes)); /* No net refcount changes. */ @@ -15911,7 +17203,7 @@ DUK_EXTERNAL void duk_insert(duk_context *ctx, duk_idx_t to_index) { } } -DUK_EXTERNAL void duk_replace(duk_context *ctx, duk_idx_t to_index) { +DUK_EXTERNAL void duk_replace(duk_context *ctx, duk_idx_t to_idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_tval *tv1; duk_tval *tv2; @@ -15921,7 +17213,7 @@ DUK_EXTERNAL void duk_replace(duk_context *ctx, duk_idx_t to_index) { tv1 = duk_require_tval(ctx, -1); DUK_ASSERT(tv1 != NULL); - tv2 = duk_require_tval(ctx, to_index); + tv2 = duk_require_tval(ctx, to_idx); DUK_ASSERT(tv2 != NULL); /* For tv1 == tv2, both pointing to stack top, the end result @@ -15934,7 +17226,7 @@ DUK_EXTERNAL void duk_replace(duk_context *ctx, duk_idx_t to_index) { DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */ } -DUK_EXTERNAL void duk_copy(duk_context *ctx, duk_idx_t from_index, duk_idx_t to_index) { +DUK_EXTERNAL void duk_copy(duk_context *ctx, duk_idx_t from_idx, duk_idx_t to_idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_tval *tv1; duk_tval *tv2; @@ -15942,27 +17234,27 @@ DUK_EXTERNAL void duk_copy(duk_context *ctx, duk_idx_t from_index, duk_idx_t to_ DUK_ASSERT_CTX_VALID(ctx); DUK_UNREF(thr); /* w/o refcounting */ - tv1 = duk_require_tval(ctx, from_index); + tv1 = duk_require_tval(ctx, from_idx); DUK_ASSERT(tv1 != NULL); - tv2 = duk_require_tval(ctx, to_index); + tv2 = duk_require_tval(ctx, to_idx); DUK_ASSERT(tv2 != NULL); /* For tv1 == tv2, this is a no-op (no explicit check needed). */ DUK_TVAL_SET_TVAL_UPDREF(thr, tv2, tv1); /* side effects */ } -DUK_EXTERNAL void duk_remove(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL void duk_remove(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_tval *p; duk_tval *q; -#ifdef DUK_USE_REFERENCE_COUNTING +#if defined(DUK_USE_REFERENCE_COUNTING) duk_tval tv_tmp; #endif duk_size_t nbytes; DUK_ASSERT_CTX_VALID(ctx); - p = duk_require_tval(ctx, index); + p = duk_require_tval(ctx, idx); DUK_ASSERT(p != NULL); q = duk_require_tval(ctx, -1); DUK_ASSERT(q != NULL); @@ -15975,7 +17267,7 @@ DUK_EXTERNAL void duk_remove(duk_context *ctx, duk_idx_t index) { * => [ ... | x | x | q ] [ ... ] */ -#ifdef DUK_USE_REFERENCE_COUNTING +#if defined(DUK_USE_REFERENCE_COUNTING) /* use a temp: decref only when valstack reachable values are correct */ DUK_TVAL_SET_TVAL(&tv_tmp, p); #endif @@ -15986,11 +17278,15 @@ DUK_EXTERNAL void duk_remove(duk_context *ctx, duk_idx_t index) { DUK_TVAL_SET_UNDEFINED(q); thr->valstack_top--; -#ifdef DUK_USE_REFERENCE_COUNTING +#if defined(DUK_USE_REFERENCE_COUNTING) DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */ #endif } +DUK_INTERNAL_DECL void duk_remove_m2(duk_context *ctx) { + duk_remove(ctx, -2); +} + /* * Stack slice primitives */ @@ -16011,13 +17307,13 @@ DUK_EXTERNAL void duk_xcopymove_raw(duk_context *to_ctx, duk_context *from_ctx, DUK_ASSERT(from_ctx != NULL); if (to_ctx == from_ctx) { - DUK_ERROR_API(to_thr, DUK_STR_INVALID_CONTEXT); + DUK_ERROR_TYPE(to_thr, DUK_STR_INVALID_CONTEXT); return; } if ((count < 0) || (count > (duk_idx_t) to_thr->valstack_max)) { /* Maximum value check ensures 'nbytes' won't wrap below. */ - DUK_ERROR_API(to_thr, DUK_STR_INVALID_COUNT); + DUK_ERROR_RANGE_INVALID_COUNT(to_thr); return; } @@ -16027,11 +17323,11 @@ DUK_EXTERNAL void duk_xcopymove_raw(duk_context *to_ctx, duk_context *from_ctx, } DUK_ASSERT(to_thr->valstack_top <= to_thr->valstack_end); if ((duk_size_t) ((duk_uint8_t *) to_thr->valstack_end - (duk_uint8_t *) to_thr->valstack_top) < nbytes) { - DUK_ERROR_API(to_thr, DUK_STR_PUSH_BEYOND_ALLOC_STACK); + DUK_ERROR_RANGE_PUSH_BEYOND(to_thr); } src = (void *) ((duk_uint8_t *) from_thr->valstack_top - nbytes); if (src < (void *) from_thr->valstack_bottom) { - DUK_ERROR_API(to_thr, DUK_STR_INVALID_COUNT); + DUK_ERROR_RANGE_INVALID_COUNT(to_thr); } /* copy values (no overlap even if to_ctx == from_ctx; that's not @@ -16068,42 +17364,41 @@ DUK_EXTERNAL void duk_xcopymove_raw(duk_context *to_ctx, duk_context *from_ctx, * Get/require */ -DUK_EXTERNAL void duk_require_undefined(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL void duk_require_undefined(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_tval *tv; DUK_ASSERT_CTX_VALID(ctx); - tv = duk_get_tval(ctx, index); - if (tv && DUK_TVAL_IS_UNDEFINED(tv)) { - return; + tv = duk_get_tval_or_unused(ctx, idx); + DUK_ASSERT(tv != NULL); + if (!DUK_TVAL_IS_UNDEFINED(tv)) { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "undefined", DUK_STR_NOT_UNDEFINED); } - DUK_ERROR_REQUIRE_TYPE_INDEX(thr, index, "undefined", DUK_STR_NOT_UNDEFINED); - return; /* not reachable */ } -DUK_EXTERNAL void duk_require_null(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL void duk_require_null(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_tval *tv; DUK_ASSERT_CTX_VALID(ctx); - tv = duk_get_tval(ctx, index); - if (tv && DUK_TVAL_IS_NULL(tv)) { - return; + tv = duk_get_tval_or_unused(ctx, idx); + DUK_ASSERT(tv != NULL); + if (!DUK_TVAL_IS_NULL(tv)) { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "null", DUK_STR_NOT_NULL); } - DUK_ERROR_REQUIRE_TYPE_INDEX(thr, index, "null", DUK_STR_NOT_NULL); - return; /* not reachable */ } -DUK_EXTERNAL duk_bool_t duk_get_boolean(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_bool_t duk_get_boolean(duk_context *ctx, duk_idx_t idx) { duk_bool_t ret = 0; /* default: false */ duk_tval *tv; DUK_ASSERT_CTX_VALID(ctx); - tv = duk_get_tval(ctx, index); - if (tv && DUK_TVAL_IS_BOOLEAN(tv)) { + tv = duk_get_tval_or_unused(ctx, idx); + DUK_ASSERT(tv != NULL); + if (DUK_TVAL_IS_BOOLEAN(tv)) { ret = DUK_TVAL_GET_BOOLEAN(tv); } @@ -16111,91 +17406,92 @@ DUK_EXTERNAL duk_bool_t duk_get_boolean(duk_context *ctx, duk_idx_t index) { return ret; } -DUK_EXTERNAL duk_bool_t duk_require_boolean(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_bool_t duk_require_boolean(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_tval *tv; + duk_bool_t ret; DUK_ASSERT_CTX_VALID(ctx); - tv = duk_get_tval(ctx, index); - if (tv && DUK_TVAL_IS_BOOLEAN(tv)) { - duk_bool_t ret = DUK_TVAL_GET_BOOLEAN(tv); - DUK_ASSERT(ret == 0 || ret == 1); - return ret; + tv = duk_get_tval_or_unused(ctx, idx); + DUK_ASSERT(tv != NULL); + if (!DUK_TVAL_IS_BOOLEAN(tv)) { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "boolean", DUK_STR_NOT_BOOLEAN); } - DUK_ERROR_REQUIRE_TYPE_INDEX(thr, index, "boolean", DUK_STR_NOT_BOOLEAN); - return 0; /* not reachable */ + ret = DUK_TVAL_GET_BOOLEAN(tv); + DUK_ASSERT(ret == 0 || ret == 1); + return ret; } -DUK_EXTERNAL duk_double_t duk_get_number(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_double_t duk_get_number(duk_context *ctx, duk_idx_t idx) { duk_double_union ret; duk_tval *tv; DUK_ASSERT_CTX_VALID(ctx); ret.d = DUK_DOUBLE_NAN; /* default: NaN */ - tv = duk_get_tval(ctx, index); - if (tv && DUK_TVAL_IS_NUMBER(tv)) { + tv = duk_get_tval_or_unused(ctx, idx); + DUK_ASSERT(tv != NULL); + if (DUK_TVAL_IS_NUMBER(tv)) { ret.d = DUK_TVAL_GET_NUMBER(tv); } - /* - * Number should already be in NaN-normalized form, but let's - * normalize anyway. + /* 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_DBLUNION_NORMALIZE_NAN_CHECK(&ret); + DUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&ret)); return ret.d; } -DUK_EXTERNAL duk_double_t duk_require_number(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_double_t duk_require_number(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_tval *tv; + duk_double_union ret; DUK_ASSERT_CTX_VALID(ctx); - tv = duk_get_tval(ctx, index); - if (tv && DUK_TVAL_IS_NUMBER(tv)) { - duk_double_union ret; - ret.d = DUK_TVAL_GET_NUMBER(tv); + tv = duk_get_tval_or_unused(ctx, idx); + DUK_ASSERT(tv != NULL); + if (!DUK_TVAL_IS_NUMBER(tv)) { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "number", DUK_STR_NOT_NUMBER); + } - /* - * Number should already be in NaN-normalized form, - * but let's normalize anyway. - */ + ret.d = DUK_TVAL_GET_NUMBER(tv); - DUK_DBLUNION_NORMALIZE_NAN_CHECK(&ret); - return ret.d; - } - DUK_ERROR_REQUIRE_TYPE_INDEX(thr, index, "number", DUK_STR_NOT_NUMBER); - return DUK_DOUBLE_NAN; /* not reachable */ + /* 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_int_t duk_get_int(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_int_t duk_get_int(duk_context *ctx, duk_idx_t idx) { /* Custom coercion for API */ DUK_ASSERT_CTX_VALID(ctx); - return (duk_int_t) duk__api_coerce_d2i(ctx, index, 0 /*require*/); + return (duk_int_t) duk__api_coerce_d2i(ctx, idx, 0 /*require*/); } -DUK_EXTERNAL duk_uint_t duk_get_uint(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_uint_t duk_get_uint(duk_context *ctx, duk_idx_t idx) { /* Custom coercion for API */ DUK_ASSERT_CTX_VALID(ctx); - return (duk_uint_t) duk__api_coerce_d2ui(ctx, index, 0 /*require*/); + return (duk_uint_t) duk__api_coerce_d2ui(ctx, idx, 0 /*require*/); } -DUK_EXTERNAL duk_int_t duk_require_int(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_int_t duk_require_int(duk_context *ctx, duk_idx_t idx) { /* Custom coercion for API */ DUK_ASSERT_CTX_VALID(ctx); - return (duk_int_t) duk__api_coerce_d2i(ctx, index, 1 /*require*/); + return (duk_int_t) duk__api_coerce_d2i(ctx, idx, 1 /*require*/); } -DUK_EXTERNAL duk_uint_t duk_require_uint(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_uint_t duk_require_uint(duk_context *ctx, duk_idx_t idx) { /* Custom coercion for API */ DUK_ASSERT_CTX_VALID(ctx); - return (duk_uint_t) duk__api_coerce_d2ui(ctx, index, 1 /*require*/); + return (duk_uint_t) duk__api_coerce_d2ui(ctx, idx, 1 /*require*/); } -DUK_EXTERNAL const char *duk_get_lstring(duk_context *ctx, duk_idx_t index, duk_size_t *out_len) { +DUK_EXTERNAL const char *duk_get_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len) { const char *ret; duk_tval *tv; @@ -16207,8 +17503,9 @@ DUK_EXTERNAL const char *duk_get_lstring(duk_context *ctx, duk_idx_t index, duk_ *out_len = 0; } - tv = duk_get_tval(ctx, index); - if (tv && DUK_TVAL_IS_STRING(tv)) { + tv = duk_get_tval_or_unused(ctx, idx); + DUK_ASSERT(tv != NULL); + if (DUK_TVAL_IS_STRING(tv)) { /* Here we rely on duk_hstring instances always being zero * terminated even if the actual string is not. */ @@ -16223,87 +17520,125 @@ DUK_EXTERNAL const char *duk_get_lstring(duk_context *ctx, duk_idx_t index, duk_ return ret; } -DUK_EXTERNAL const char *duk_require_lstring(duk_context *ctx, duk_idx_t index, duk_size_t *out_len) { - duk_hthread *thr = (duk_hthread *) ctx; - const char *ret; +DUK_EXTERNAL const char *duk_require_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len) { + duk_hstring *h; DUK_ASSERT_CTX_VALID(ctx); - /* Note: this check relies on the fact that even a zero-size string - * has a non-NULL pointer. - */ - ret = duk_get_lstring(ctx, index, out_len); - if (ret) { - return ret; + h = duk_require_hstring(ctx, idx); + DUK_ASSERT(h != NULL); + if (out_len) { + *out_len = DUK_HSTRING_GET_BYTELEN(h); + } + return (const char *) DUK_HSTRING_GET_DATA(h); +} + +DUK_INTERNAL const char *duk_require_lstring_notsymbol(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len) { + duk_hstring *h; + + DUK_ASSERT_CTX_VALID(ctx); + + h = duk_require_hstring_notsymbol(ctx, idx); + DUK_ASSERT(h != NULL); + if (out_len) { + *out_len = DUK_HSTRING_GET_BYTELEN(h); + } + return (const char *) DUK_HSTRING_GET_DATA(h); +} + +DUK_EXTERNAL const char *duk_get_string(duk_context *ctx, duk_idx_t idx) { + DUK_ASSERT_CTX_VALID(ctx); + + return duk_get_lstring(ctx, idx, NULL); +} + +DUK_INTERNAL const char *duk_get_string_notsymbol(duk_context *ctx, duk_idx_t idx) { + duk_hstring *h; + + DUK_ASSERT_CTX_VALID(ctx); + + h = duk_get_hstring_notsymbol(ctx, idx); + if (h) { + return (const char *) DUK_HSTRING_GET_DATA(h); + } else { + return NULL; } - DUK_ERROR_REQUIRE_TYPE_INDEX(thr, index, "string", DUK_STR_NOT_STRING); - return NULL; /* not reachable */ } -DUK_EXTERNAL const char *duk_get_string(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL const char *duk_require_string(duk_context *ctx, duk_idx_t idx) { DUK_ASSERT_CTX_VALID(ctx); - return duk_get_lstring(ctx, index, NULL); + return duk_require_lstring(ctx, idx, NULL); } -DUK_EXTERNAL const char *duk_require_string(duk_context *ctx, duk_idx_t index) { +DUK_INTERNAL const char *duk_require_string_notsymbol(duk_context *ctx, duk_idx_t idx) { + duk_hstring *h; + DUK_ASSERT_CTX_VALID(ctx); - return duk_require_lstring(ctx, index, NULL); + h = duk_require_hstring_notsymbol(ctx, idx); + DUK_ASSERT(h != NULL); + return (const char *) DUK_HSTRING_GET_DATA(h); } -DUK_EXTERNAL void *duk_get_pointer(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL void *duk_get_pointer(duk_context *ctx, duk_idx_t idx) { duk_tval *tv; + void *p; DUK_ASSERT_CTX_VALID(ctx); - tv = duk_get_tval(ctx, index); - if (tv && DUK_TVAL_IS_POINTER(tv)) { - void *p = DUK_TVAL_GET_POINTER(tv); /* may be NULL */ - return (void *) p; + tv = duk_get_tval_or_unused(ctx, idx); + DUK_ASSERT(tv != NULL); + if (!DUK_TVAL_IS_POINTER(tv)) { + return NULL; } - return NULL; + p = DUK_TVAL_GET_POINTER(tv); /* may be NULL */ + return p; } -DUK_EXTERNAL void *duk_require_pointer(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL void *duk_require_pointer(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_tval *tv; + void *p; DUK_ASSERT_CTX_VALID(ctx); /* Note: here we must be wary of the fact that a pointer may be * valid and be a NULL. */ - tv = duk_get_tval(ctx, index); - if (tv && DUK_TVAL_IS_POINTER(tv)) { - void *p = DUK_TVAL_GET_POINTER(tv); /* may be NULL */ - return (void *) p; + tv = duk_get_tval_or_unused(ctx, idx); + DUK_ASSERT(tv != NULL); + if (!DUK_TVAL_IS_POINTER(tv)) { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "pointer", DUK_STR_NOT_POINTER); } - DUK_ERROR_REQUIRE_TYPE_INDEX(thr, index, "pointer", DUK_STR_NOT_POINTER); - return NULL; /* not reachable */ + p = DUK_TVAL_GET_POINTER(tv); /* may be NULL */ + return p; } #if 0 /*unused*/ -DUK_INTERNAL void *duk_get_voidptr(duk_context *ctx, duk_idx_t index) { +DUK_INTERNAL void *duk_get_voidptr(duk_context *ctx, duk_idx_t idx) { duk_tval *tv; + duk_heaphdr *h; DUK_ASSERT_CTX_VALID(ctx); - tv = duk_get_tval(ctx, index); - if (tv && DUK_TVAL_IS_HEAP_ALLOCATED(tv)) { - duk_heaphdr *h = DUK_TVAL_GET_HEAPHDR(tv); - DUK_ASSERT(h != NULL); - return (void *) h; + tv = duk_get_tval_or_unused(ctx, idx); + DUK_ASSERT(tv != NULL); + if (!DUK_TVAL_IS_HEAP_ALLOCATED(tv)) { + return NULL; } - return NULL; + h = DUK_TVAL_GET_HEAPHDR(tv); + DUK_ASSERT(h != NULL); + return (void *) h; } #endif -DUK_LOCAL void *duk__get_buffer_helper(duk_context *ctx, duk_idx_t index, duk_size_t *out_size, duk_bool_t throw_flag) { +DUK_LOCAL void *duk__get_buffer_helper(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, duk_bool_t throw_flag) { duk_hthread *thr = (duk_hthread *) ctx; duk_tval *tv; + duk_hbuffer *h; DUK_ASSERT_CTX_VALID(ctx); DUK_UNREF(thr); @@ -16312,90 +17647,105 @@ DUK_LOCAL void *duk__get_buffer_helper(duk_context *ctx, duk_idx_t index, duk_si *out_size = 0; } - tv = duk_get_tval(ctx, index); - if (tv && DUK_TVAL_IS_BUFFER(tv)) { - duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv); - DUK_ASSERT(h != NULL); - if (out_size) { - *out_size = DUK_HBUFFER_GET_SIZE(h); + tv = duk_get_tval_or_unused(ctx, idx); + DUK_ASSERT(tv != NULL); + if (!DUK_TVAL_IS_BUFFER(tv)) { + if (throw_flag) { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "buffer", DUK_STR_NOT_BUFFER); } - return (void *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h); /* may be NULL (but only if size is 0) */ + return NULL; } - if (throw_flag) { - DUK_ERROR_REQUIRE_TYPE_INDEX(thr, index, "buffer", DUK_STR_NOT_BUFFER); + h = DUK_TVAL_GET_BUFFER(tv); + DUK_ASSERT(h != NULL); + if (out_size) { + *out_size = DUK_HBUFFER_GET_SIZE(h); } - return NULL; + return (void *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h); /* may be NULL (but only if size is 0) */ } -DUK_EXTERNAL void *duk_get_buffer(duk_context *ctx, duk_idx_t index, duk_size_t *out_size) { - return duk__get_buffer_helper(ctx, index, out_size, 0 /*throw_flag*/); +DUK_EXTERNAL void *duk_get_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size) { + return duk__get_buffer_helper(ctx, idx, out_size, 0 /*throw_flag*/); } -DUK_EXTERNAL void *duk_require_buffer(duk_context *ctx, duk_idx_t index, duk_size_t *out_size) { - return duk__get_buffer_helper(ctx, index, out_size, 1 /*throw_flag*/); +DUK_EXTERNAL void *duk_require_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size) { + return duk__get_buffer_helper(ctx, idx, out_size, 1 /*throw_flag*/); } -DUK_LOCAL void *duk__get_buffer_data_helper(duk_context *ctx, duk_idx_t index, duk_size_t *out_size, duk_bool_t throw_flag) { +/* Get the active buffer data area for a plain buffer or a buffer object. + * Return NULL if the the value is not a buffer. Note that a buffer may + * have a NULL data pointer when its size is zero, the optional 'out_isbuffer' + * argument allows caller to detect this reliably. + */ +DUK_INTERNAL void *duk_get_buffer_data_raw(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, duk_bool_t throw_flag, duk_bool_t *out_isbuffer) { duk_hthread *thr = (duk_hthread *) ctx; duk_tval *tv; DUK_ASSERT_CTX_VALID(ctx); DUK_UNREF(thr); + if (out_isbuffer != NULL) { + *out_isbuffer = 0; + } if (out_size != NULL) { *out_size = 0; } - tv = duk_get_tval(ctx, index); - if (tv == NULL) { - goto fail; - } + tv = duk_get_tval_or_unused(ctx, idx); + DUK_ASSERT(tv != NULL); if (DUK_TVAL_IS_BUFFER(tv)) { duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv); DUK_ASSERT(h != NULL); - if (out_size) { + if (out_size != NULL) { *out_size = DUK_HBUFFER_GET_SIZE(h); } + if (out_isbuffer != NULL) { + *out_isbuffer = 1; + } return (void *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h); /* may be NULL (but only if size is 0) */ - } else if (DUK_TVAL_IS_OBJECT(tv)) { + } +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) + else if (DUK_TVAL_IS_OBJECT(tv)) { duk_hobject *h = DUK_TVAL_GET_OBJECT(tv); DUK_ASSERT(h != NULL); - if (DUK_HOBJECT_IS_BUFFEROBJECT(h)) { + if (DUK_HOBJECT_IS_BUFOBJ(h)) { /* XXX: this is probably a useful shared helper: for a - * duk_hbufferobject, get a validated buffer pointer/length. + * duk_hbufobj, get a validated buffer pointer/length. */ - duk_hbufferobject *h_bufobj = (duk_hbufferobject *) h; - DUK_ASSERT_HBUFFEROBJECT_VALID(h_bufobj); + duk_hbufobj *h_bufobj = (duk_hbufobj *) h; + DUK_ASSERT_HBUFOBJ_VALID(h_bufobj); if (h_bufobj->buf != NULL && - DUK_HBUFFEROBJECT_VALID_SLICE(h_bufobj)) { + DUK_HBUFOBJ_VALID_SLICE(h_bufobj)) { duk_uint8_t *p; p = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf); if (out_size != NULL) { *out_size = (duk_size_t) h_bufobj->length; } + if (out_isbuffer != NULL) { + *out_isbuffer = 1; + } return (void *) (p + h_bufobj->offset); } /* if slice not fully valid, treat as error */ } } +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ - fail: if (throw_flag) { - DUK_ERROR_REQUIRE_TYPE_INDEX(thr, index, "buffer", DUK_STR_NOT_BUFFER); + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "buffer", DUK_STR_NOT_BUFFER); } return NULL; } -DUK_EXTERNAL void *duk_get_buffer_data(duk_context *ctx, duk_idx_t index, duk_size_t *out_size) { - return duk__get_buffer_data_helper(ctx, index, out_size, 0 /*throw_flag*/); +DUK_EXTERNAL void *duk_get_buffer_data(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size) { + return duk_get_buffer_data_raw(ctx, idx, out_size, 0 /*throw_flag*/, NULL); } -DUK_EXTERNAL void *duk_require_buffer_data(duk_context *ctx, duk_idx_t index, duk_size_t *out_size) { - return duk__get_buffer_data_helper(ctx, index, out_size, 1 /*throw_flag*/); +DUK_EXTERNAL void *duk_require_buffer_data(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size) { + return duk_get_buffer_data_raw(ctx, idx, out_size, 1 /*throw_flag*/, NULL); } /* Raw helper for getting a value from the stack, checking its tag. @@ -16403,290 +17753,301 @@ DUK_EXTERNAL void *duk_require_buffer_data(duk_context *ctx, duk_idx_t index, du * tag in the packed representation. */ -DUK_LOCAL duk_heaphdr *duk__get_tagged_heaphdr_raw(duk_context *ctx, duk_idx_t index, duk_uint_t tag) { +DUK_LOCAL duk_heaphdr *duk__get_tagged_heaphdr_raw(duk_context *ctx, duk_idx_t idx, duk_uint_t tag) { duk_tval *tv; + duk_heaphdr *ret; DUK_ASSERT_CTX_VALID(ctx); - tv = duk_get_tval(ctx, index); - if (tv && (DUK_TVAL_GET_TAG(tv) == tag)) { - duk_heaphdr *ret; - ret = DUK_TVAL_GET_HEAPHDR(tv); - DUK_ASSERT(ret != NULL); /* tagged null pointers should never occur */ - return ret; + tv = duk_get_tval_or_unused(ctx, idx); + DUK_ASSERT(tv != NULL); + if (DUK_TVAL_GET_TAG(tv) != tag) { + return (duk_heaphdr *) NULL; } - return (duk_heaphdr *) NULL; + ret = DUK_TVAL_GET_HEAPHDR(tv); + DUK_ASSERT(ret != NULL); /* tagged null pointers should never occur */ + return ret; + } -DUK_INTERNAL duk_hstring *duk_get_hstring(duk_context *ctx, duk_idx_t index) { - return (duk_hstring *) duk__get_tagged_heaphdr_raw(ctx, index, DUK_TAG_STRING); +DUK_INTERNAL duk_hstring *duk_get_hstring(duk_context *ctx, duk_idx_t idx) { + return (duk_hstring *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_STRING); } -DUK_INTERNAL duk_hstring *duk_require_hstring(duk_context *ctx, duk_idx_t index) { - duk_heaphdr *h; - h = duk__get_tagged_heaphdr_raw(ctx, index, DUK_TAG_STRING); +DUK_INTERNAL duk_hstring *duk_get_hstring_notsymbol(duk_context *ctx, duk_idx_t idx) { + duk_hstring *res = (duk_hstring *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_STRING); + if (res && DUK_HSTRING_HAS_SYMBOL(res)) { + return NULL; + } + return res; +} + +DUK_INTERNAL duk_hstring *duk_require_hstring(duk_context *ctx, duk_idx_t idx) { + duk_hstring *h; + h = (duk_hstring *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_STRING); if (h == NULL) { - DUK_ERROR_REQUIRE_TYPE_INDEX(ctx, index, "string", DUK_STR_NOT_STRING); + DUK_ERROR_REQUIRE_TYPE_INDEX(ctx, idx, "string", DUK_STR_NOT_STRING); + } + return h; +} + +DUK_INTERNAL duk_hstring *duk_require_hstring_notsymbol(duk_context *ctx, duk_idx_t idx) { + duk_hstring *h; + h = (duk_hstring *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_STRING); + if (h == NULL || DUK_HSTRING_HAS_SYMBOL(h)) { + DUK_ERROR_REQUIRE_TYPE_INDEX(ctx, idx, "string", DUK_STR_NOT_STRING); } - return (duk_hstring *) h; + return h; } -DUK_INTERNAL duk_hobject *duk_get_hobject(duk_context *ctx, duk_idx_t index) { - return (duk_hobject *) duk__get_tagged_heaphdr_raw(ctx, index, DUK_TAG_OBJECT); +DUK_INTERNAL duk_hobject *duk_get_hobject(duk_context *ctx, duk_idx_t idx) { + return (duk_hobject *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_OBJECT); } -DUK_INTERNAL duk_hobject *duk_require_hobject(duk_context *ctx, duk_idx_t index) { - duk_heaphdr *h; - h = duk__get_tagged_heaphdr_raw(ctx, index, DUK_TAG_OBJECT); +DUK_INTERNAL duk_hobject *duk_require_hobject(duk_context *ctx, duk_idx_t idx) { + duk_hobject *h; + h = (duk_hobject *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_OBJECT); if (h == NULL) { - DUK_ERROR_REQUIRE_TYPE_INDEX(ctx, index, "object", DUK_STR_NOT_OBJECT); + DUK_ERROR_REQUIRE_TYPE_INDEX(ctx, idx, "object", DUK_STR_NOT_OBJECT); } - return (duk_hobject *) h; + return h; } -DUK_INTERNAL duk_hbuffer *duk_get_hbuffer(duk_context *ctx, duk_idx_t index) { - return (duk_hbuffer *) duk__get_tagged_heaphdr_raw(ctx, index, DUK_TAG_BUFFER); +DUK_INTERNAL duk_hbuffer *duk_get_hbuffer(duk_context *ctx, duk_idx_t idx) { + return (duk_hbuffer *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_BUFFER); } -DUK_INTERNAL duk_hbuffer *duk_require_hbuffer(duk_context *ctx, duk_idx_t index) { - duk_heaphdr *h; - h = duk__get_tagged_heaphdr_raw(ctx, index, DUK_TAG_BUFFER); +DUK_INTERNAL duk_hbuffer *duk_require_hbuffer(duk_context *ctx, duk_idx_t idx) { + duk_hbuffer *h; + h = (duk_hbuffer *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_BUFFER); if (h == NULL) { - DUK_ERROR_REQUIRE_TYPE_INDEX(ctx, index, "buffer", DUK_STR_NOT_BUFFER); + DUK_ERROR_REQUIRE_TYPE_INDEX(ctx, idx, "buffer", DUK_STR_NOT_BUFFER); } - return (duk_hbuffer *) h; + return h; } -DUK_INTERNAL duk_hthread *duk_get_hthread(duk_context *ctx, duk_idx_t index) { - duk_hobject *h = (duk_hobject *) duk__get_tagged_heaphdr_raw(ctx, index, DUK_TAG_OBJECT); +DUK_INTERNAL duk_hthread *duk_get_hthread(duk_context *ctx, duk_idx_t idx) { + duk_hobject *h = (duk_hobject *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_OBJECT); if (h != NULL && !DUK_HOBJECT_IS_THREAD(h)) { h = NULL; } return (duk_hthread *) h; } -DUK_INTERNAL duk_hthread *duk_require_hthread(duk_context *ctx, duk_idx_t index) { +DUK_INTERNAL duk_hthread *duk_require_hthread(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; - duk_hobject *h = (duk_hobject *) duk__get_tagged_heaphdr_raw(ctx, index, DUK_TAG_OBJECT); + duk_hobject *h = (duk_hobject *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_OBJECT); if (!(h != NULL && DUK_HOBJECT_IS_THREAD(h))) { - DUK_ERROR_REQUIRE_TYPE_INDEX(thr, index, "thread", DUK_STR_NOT_THREAD); + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "thread", DUK_STR_NOT_THREAD); } return (duk_hthread *) h; } -DUK_INTERNAL duk_hcompiledfunction *duk_get_hcompiledfunction(duk_context *ctx, duk_idx_t index) { - duk_hobject *h = (duk_hobject *) duk__get_tagged_heaphdr_raw(ctx, index, DUK_TAG_OBJECT); - if (h != NULL && !DUK_HOBJECT_IS_COMPILEDFUNCTION(h)) { +DUK_INTERNAL duk_hcompfunc *duk_get_hcompfunc(duk_context *ctx, duk_idx_t idx) { + duk_hobject *h = (duk_hobject *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_OBJECT); + if (h != NULL && !DUK_HOBJECT_IS_COMPFUNC(h)) { h = NULL; } - return (duk_hcompiledfunction *) h; + return (duk_hcompfunc *) h; } -DUK_INTERNAL duk_hcompiledfunction *duk_require_hcompiledfunction(duk_context *ctx, duk_idx_t index) { +DUK_INTERNAL duk_hcompfunc *duk_require_hcompfunc(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; - duk_hobject *h = (duk_hobject *) duk__get_tagged_heaphdr_raw(ctx, index, DUK_TAG_OBJECT); - if (!(h != NULL && DUK_HOBJECT_IS_COMPILEDFUNCTION(h))) { - DUK_ERROR_REQUIRE_TYPE_INDEX(thr, index, "compiledfunction", DUK_STR_NOT_COMPILEDFUNCTION); + duk_hobject *h = (duk_hobject *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_OBJECT); + if (!(h != NULL && DUK_HOBJECT_IS_COMPFUNC(h))) { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "compiledfunction", DUK_STR_NOT_COMPFUNC); } - return (duk_hcompiledfunction *) h; + return (duk_hcompfunc *) h; } -DUK_INTERNAL duk_hnativefunction *duk_get_hnativefunction(duk_context *ctx, duk_idx_t index) { - duk_hobject *h = (duk_hobject *) duk__get_tagged_heaphdr_raw(ctx, index, DUK_TAG_OBJECT); - if (h != NULL && !DUK_HOBJECT_IS_NATIVEFUNCTION(h)) { +DUK_INTERNAL duk_hnatfunc *duk_get_hnatfunc(duk_context *ctx, duk_idx_t idx) { + duk_hobject *h = (duk_hobject *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_OBJECT); + if (h != NULL && !DUK_HOBJECT_IS_NATFUNC(h)) { h = NULL; } - return (duk_hnativefunction *) h; + return (duk_hnatfunc *) h; } -DUK_INTERNAL duk_hnativefunction *duk_require_hnativefunction(duk_context *ctx, duk_idx_t index) { +DUK_INTERNAL duk_hnatfunc *duk_require_hnatfunc(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; - duk_hobject *h = (duk_hobject *) duk__get_tagged_heaphdr_raw(ctx, index, DUK_TAG_OBJECT); - if (!(h != NULL && DUK_HOBJECT_IS_NATIVEFUNCTION(h))) { - DUK_ERROR_REQUIRE_TYPE_INDEX(thr, index, "nativefunction", DUK_STR_NOT_NATIVEFUNCTION); + duk_hobject *h = (duk_hobject *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_OBJECT); + if (!(h != NULL && DUK_HOBJECT_IS_NATFUNC(h))) { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "nativefunction", DUK_STR_NOT_NATFUNC); } - return (duk_hnativefunction *) h; + return (duk_hnatfunc *) h; } -DUK_EXTERNAL duk_c_function duk_get_c_function(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_c_function duk_get_c_function(duk_context *ctx, duk_idx_t idx) { duk_tval *tv; duk_hobject *h; - duk_hnativefunction *f; + duk_hnatfunc *f; DUK_ASSERT_CTX_VALID(ctx); - tv = duk_get_tval(ctx, index); - if (!tv) { - return NULL; - } + tv = duk_get_tval_or_unused(ctx, idx); + DUK_ASSERT(tv != NULL); if (!DUK_TVAL_IS_OBJECT(tv)) { return NULL; } h = DUK_TVAL_GET_OBJECT(tv); DUK_ASSERT(h != NULL); - if (!DUK_HOBJECT_IS_NATIVEFUNCTION(h)) { + if (!DUK_HOBJECT_IS_NATFUNC(h)) { return NULL; } - DUK_ASSERT(DUK_HOBJECT_HAS_NATIVEFUNCTION(h)); - f = (duk_hnativefunction *) h; + DUK_ASSERT(DUK_HOBJECT_HAS_NATFUNC(h)); + f = (duk_hnatfunc *) h; return f->func; } -DUK_EXTERNAL duk_c_function duk_require_c_function(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_c_function duk_require_c_function(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_c_function ret; DUK_ASSERT_CTX_VALID(ctx); - ret = duk_get_c_function(ctx, index); + ret = duk_get_c_function(ctx, idx); if (!ret) { - DUK_ERROR_REQUIRE_TYPE_INDEX(thr, index, "nativefunction", DUK_STR_NOT_NATIVEFUNCTION); + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "nativefunction", DUK_STR_NOT_NATFUNC); } return ret; } -DUK_EXTERNAL void duk_require_function(duk_context *ctx, duk_idx_t index) { - if (!duk_is_function(ctx, index)) { - DUK_ERROR_REQUIRE_TYPE_INDEX((duk_hthread *) ctx, index, "function", DUK_STR_NOT_FUNCTION); +DUK_EXTERNAL void duk_require_function(duk_context *ctx, duk_idx_t idx) { + if (!duk_is_function(ctx, idx)) { + DUK_ERROR_REQUIRE_TYPE_INDEX((duk_hthread *) ctx, idx, "function", DUK_STR_NOT_FUNCTION); + } +} + +DUK_INTERNAL_DECL void duk_require_constructable(duk_context *ctx, duk_idx_t idx) { + duk_hobject *h; + + h = duk_require_hobject_accept_mask(ctx, idx, DUK_TYPE_MASK_LIGHTFUNC); + if (h != NULL && !DUK_HOBJECT_HAS_CONSTRUCTABLE(h)) { + DUK_ERROR_REQUIRE_TYPE_INDEX((duk_hthread *) ctx, idx, "constructable", DUK_STR_NOT_CONSTRUCTABLE); } + /* Lightfuncs (h == NULL) are constructable. */ } -DUK_EXTERNAL duk_context *duk_get_context(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_context *duk_get_context(duk_context *ctx, duk_idx_t idx) { DUK_ASSERT_CTX_VALID(ctx); - return (duk_context *) duk_get_hthread(ctx, index); + return (duk_context *) duk_get_hthread(ctx, idx); } -DUK_EXTERNAL duk_context *duk_require_context(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_context *duk_require_context(duk_context *ctx, duk_idx_t idx) { DUK_ASSERT_CTX_VALID(ctx); - return (duk_context *) duk_require_hthread(ctx, index); + return (duk_context *) duk_require_hthread(ctx, idx); } -DUK_EXTERNAL void *duk_get_heapptr(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL void *duk_get_heapptr(duk_context *ctx, duk_idx_t idx) { duk_tval *tv; void *ret; DUK_ASSERT_CTX_VALID(ctx); - tv = duk_get_tval(ctx, index); - if (tv && DUK_TVAL_IS_HEAP_ALLOCATED(tv)) { - ret = (void *) DUK_TVAL_GET_HEAPHDR(tv); - DUK_ASSERT(ret != NULL); - return ret; + tv = duk_get_tval_or_unused(ctx, idx); + DUK_ASSERT(tv != NULL); + if (!DUK_TVAL_IS_HEAP_ALLOCATED(tv)) { + return (void *) NULL; } - return (void *) NULL; + ret = (void *) DUK_TVAL_GET_HEAPHDR(tv); + DUK_ASSERT(ret != NULL); + return ret; } -DUK_EXTERNAL void *duk_require_heapptr(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL void *duk_require_heapptr(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_tval *tv; void *ret; DUK_ASSERT_CTX_VALID(ctx); - tv = duk_require_tval(ctx, index); + tv = duk_get_tval_or_unused(ctx, idx); DUK_ASSERT(tv != NULL); - if (DUK_TVAL_IS_HEAP_ALLOCATED(tv)) { - ret = (void *) DUK_TVAL_GET_HEAPHDR(tv); - DUK_ASSERT(ret != NULL); - return ret; + if (!DUK_TVAL_IS_HEAP_ALLOCATED(tv)) { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "heapobject", DUK_STR_UNEXPECTED_TYPE); } - DUK_ERROR_REQUIRE_TYPE_INDEX(thr, index, "heapobject", DUK_STR_UNEXPECTED_TYPE); - return (void *) NULL; /* not reachable */ -} - -#if 0 -/* This would be pointless: we'd return NULL for both lightfuncs and - * unexpected types. - */ -DUK_INTERNAL duk_hobject *duk_get_hobject_or_lfunc(duk_context *ctx, duk_idx_t index) { + ret = (void *) DUK_TVAL_GET_HEAPHDR(tv); + DUK_ASSERT(ret != NULL); + return ret; } -#endif -/* Useful for internal call sites where we either expect an object (function) - * or a lightfunc. Accepts an object (returned as is) or a lightfunc (coerced - * to an object). Return value is NULL if value is neither an object nor a - * lightfunc. - */ -DUK_INTERNAL duk_hobject *duk_get_hobject_or_lfunc_coerce(duk_context *ctx, duk_idx_t index) { - duk_tval *tv; +/* Internal helper for getting/requiring a duk_hobject with possible promotion. */ +DUK_LOCAL duk_hobject *duk__get_hobject_promote_mask_raw(duk_context *ctx, duk_idx_t idx, duk_uint_t type_mask) { + duk_uint_t val_mask; + duk_hobject *res; DUK_ASSERT_CTX_VALID(ctx); - tv = duk_require_tval(ctx, index); - DUK_ASSERT(tv != NULL); - if (DUK_TVAL_IS_OBJECT(tv)) { - return DUK_TVAL_GET_OBJECT(tv); - } else if (DUK_TVAL_IS_LIGHTFUNC(tv)) { - duk_to_object(ctx, index); - return duk_require_hobject(ctx, index); + res = duk_get_hobject(ctx, idx); /* common case, not promoted */ + if (res != NULL) { + DUK_ASSERT(res != NULL); + return res; + } + + val_mask = duk_get_type_mask(ctx, idx); + if (val_mask & type_mask) { + if (type_mask & DUK_TYPE_MASK_PROMOTE) { + res = duk_to_hobject(ctx, idx); + DUK_ASSERT(res != NULL); + return res; + } else { + return NULL; /* accept without promoting */ + } } + if (type_mask & DUK_TYPE_MASK_THROW) { + DUK_ERROR_REQUIRE_TYPE_INDEX((duk_hthread *) ctx, idx, "object", DUK_STR_NOT_OBJECT); + } return NULL; } -/* Useful for internal call sites where we either expect an object (function) - * or a lightfunc. Returns NULL for a lightfunc. +/* Get a duk_hobject * at 'idx'; if the value is not an object but matches the + * supplied 'type_mask', promote it to an object and return the duk_hobject *. + * This is useful for call sites which want an object but also accept a plain + * buffer and/or a lightfunc which gets automatically promoted to an object. + * Return value is NULL if value is neither an object nor a plain type allowed + * by the mask. */ -DUK_INTERNAL duk_hobject *duk_require_hobject_or_lfunc(duk_context *ctx, duk_idx_t index) { - duk_hthread *thr = (duk_hthread *) ctx; - duk_tval *tv; - - DUK_ASSERT_CTX_VALID(ctx); - - tv = duk_require_tval(ctx, index); - DUK_ASSERT(tv != NULL); - if (DUK_TVAL_IS_OBJECT(tv)) { - return DUK_TVAL_GET_OBJECT(tv); - } else if (DUK_TVAL_IS_LIGHTFUNC(tv)) { - return NULL; - } - DUK_ERROR_REQUIRE_TYPE_INDEX(thr, index, "object", DUK_STR_NOT_OBJECT); - return NULL; /* not reachable */ +DUK_INTERNAL duk_hobject *duk_get_hobject_promote_mask(duk_context *ctx, duk_idx_t idx, duk_uint_t type_mask) { + return duk__get_hobject_promote_mask_raw(ctx, idx, type_mask | DUK_TYPE_MASK_PROMOTE); } -/* Useful for internal call sites where we either expect an object (function) - * or a lightfunc. Accepts an object (returned as is) or a lightfunc (coerced - * to an object). Return value is never NULL. +/* Like duk_get_hobject_promote_mask() but throw a TypeError instead of + * returning a NULL. */ -DUK_INTERNAL duk_hobject *duk_require_hobject_or_lfunc_coerce(duk_context *ctx, duk_idx_t index) { - duk_hthread *thr = (duk_hthread *) ctx; - duk_tval *tv; - - DUK_ASSERT_CTX_VALID(ctx); +DUK_INTERNAL duk_hobject *duk_require_hobject_promote_mask(duk_context *ctx, duk_idx_t idx, duk_uint_t type_mask) { + return duk__get_hobject_promote_mask_raw(ctx, idx, type_mask | DUK_TYPE_MASK_THROW | DUK_TYPE_MASK_PROMOTE); +} - tv = duk_require_tval(ctx, index); - if (DUK_TVAL_IS_OBJECT(tv)) { - return DUK_TVAL_GET_OBJECT(tv); - } else if (DUK_TVAL_IS_LIGHTFUNC(tv)) { - duk_to_object(ctx, index); - return duk_require_hobject(ctx, index); - } - DUK_ERROR_REQUIRE_TYPE_INDEX(thr, index, "object", DUK_STR_NOT_OBJECT); - return NULL; /* not reachable */ +/* Require a duk_hobject * at 'idx'; if the value is not an object but matches the + * supplied 'type_mask', return a NULL instead. Otherwise throw a TypeError. + */ +DUK_INTERNAL duk_hobject *duk_require_hobject_accept_mask(duk_context *ctx, duk_idx_t idx, duk_uint_t type_mask) { + return duk__get_hobject_promote_mask_raw(ctx, idx, type_mask | DUK_TYPE_MASK_THROW); } -DUK_INTERNAL duk_hobject *duk_get_hobject_with_class(duk_context *ctx, duk_idx_t index, duk_small_uint_t classnum) { +DUK_INTERNAL duk_hobject *duk_get_hobject_with_class(duk_context *ctx, duk_idx_t idx, duk_small_uint_t classnum) { duk_hobject *h; DUK_ASSERT_CTX_VALID(ctx); DUK_ASSERT_DISABLE(classnum >= 0); /* unsigned */ DUK_ASSERT(classnum <= DUK_HOBJECT_CLASS_MAX); - h = (duk_hobject *) duk__get_tagged_heaphdr_raw(ctx, index, DUK_TAG_OBJECT); + h = (duk_hobject *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_OBJECT); if (h != NULL && DUK_HOBJECT_GET_CLASS_NUMBER(h) != classnum) { h = NULL; } return h; } -DUK_INTERNAL duk_hobject *duk_require_hobject_with_class(duk_context *ctx, duk_idx_t index, duk_small_uint_t classnum) { +DUK_INTERNAL duk_hobject *duk_require_hobject_with_class(duk_context *ctx, duk_idx_t idx, duk_small_uint_t classnum) { duk_hthread *thr; duk_hobject *h; @@ -16695,26 +18056,24 @@ DUK_INTERNAL duk_hobject *duk_require_hobject_with_class(duk_context *ctx, duk_i DUK_ASSERT(classnum <= DUK_HOBJECT_CLASS_MAX); thr = (duk_hthread *) ctx; - h = (duk_hobject *) duk__get_tagged_heaphdr_raw(ctx, index, DUK_TAG_OBJECT); + h = (duk_hobject *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_OBJECT); if (!(h != NULL && DUK_HOBJECT_GET_CLASS_NUMBER(h) == classnum)) { duk_hstring *h_class; h_class = DUK_HTHREAD_GET_STRING(thr, DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(classnum)); DUK_UNREF(h_class); - DUK_ERROR_REQUIRE_TYPE_INDEX(thr, index, (const char *) DUK_HSTRING_GET_DATA(h_class), DUK_STR_UNEXPECTED_TYPE); + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, (const char *) DUK_HSTRING_GET_DATA(h_class), DUK_STR_UNEXPECTED_TYPE); } return h; } -DUK_EXTERNAL duk_size_t duk_get_length(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_size_t duk_get_length(duk_context *ctx, duk_idx_t idx) { duk_tval *tv; DUK_ASSERT_CTX_VALID(ctx); - tv = duk_get_tval(ctx, index); - if (!tv) { - return 0; - } + tv = duk_get_tval_or_unused(ctx, idx); + DUK_ASSERT(tv != NULL); switch (DUK_TVAL_GET_TAG(tv)) { case DUK_TAG_UNDEFINED: @@ -16722,16 +18081,29 @@ DUK_EXTERNAL duk_size_t duk_get_length(duk_context *ctx, duk_idx_t index) { case DUK_TAG_BOOLEAN: case DUK_TAG_POINTER: return 0; +#if defined(DUK_USE_PREFER_SIZE) + /* All of these types (besides object) have a virtual, non-configurable + * .length property which is within size_t range so we can just look it + * up without specific type checks. + */ + case DUK_TAG_STRING: + case DUK_TAG_BUFFER: + case DUK_TAG_LIGHTFUNC: { + duk_size_t ret; + duk_get_prop_stridx(ctx, idx, DUK_STRIDX_LENGTH); + ret = (duk_size_t) duk_to_number_m1(ctx); + duk_pop(ctx); + return ret; + } +#else /* DUK_USE_PREFER_SIZE */ case DUK_TAG_STRING: { duk_hstring *h = DUK_TVAL_GET_STRING(tv); DUK_ASSERT(h != NULL); + if (DUK_HSTRING_HAS_SYMBOL(h)) { + return 0; + } return (duk_size_t) DUK_HSTRING_GET_CHARLEN(h); } - case DUK_TAG_OBJECT: { - duk_hobject *h = DUK_TVAL_GET_OBJECT(tv); - DUK_ASSERT(h != NULL); - return (duk_size_t) duk_hobject_get_length((duk_hthread *) ctx, h); - } case DUK_TAG_BUFFER: { duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv); DUK_ASSERT(h != NULL); @@ -16742,31 +18114,83 @@ DUK_EXTERNAL duk_size_t duk_get_length(duk_context *ctx, duk_idx_t index) { lf_flags = DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv); return (duk_size_t) DUK_LFUNC_FLAGS_GET_LENGTH(lf_flags); } +#endif /* DUK_USE_PREFER_SIZE */ + case DUK_TAG_OBJECT: { + duk_hobject *h = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(h != NULL); + return (duk_size_t) duk_hobject_get_length((duk_hthread *) ctx, h); + } #if defined(DUK_USE_FASTINT) case DUK_TAG_FASTINT: #endif default: - /* number */ - DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv)); - DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv)); + /* number or 'unused' */ + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv) || DUK_TVAL_IS_UNUSED(tv)); return 0; } DUK_UNREACHABLE(); } -DUK_INTERNAL void duk_set_length(duk_context *ctx, duk_idx_t index, duk_size_t length) { +/* + * duk_known_xxx() helpers + * + * Used internally when we're 100% sure that a certain index is valid and + * contains an object of a certain type. For example, if we duk_push_object() + * we can then safely duk_known_hobject(ctx, -1). These helpers just assert + * for the index and type, and if the assumptions are not valid, memory unsafe + * behavior happens. + */ + +DUK_LOCAL duk_heaphdr *duk__known_heaphdr(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; - duk_hobject *h; + duk_tval *tv; + duk_heaphdr *h; DUK_ASSERT_CTX_VALID(ctx); - - h = duk_get_hobject(ctx, index); - if (!h) { - return; + if (idx < 0) { + tv = thr->valstack_top + idx; + } else { + tv = thr->valstack_bottom + idx; } + DUK_ASSERT(tv >= thr->valstack_bottom); + DUK_ASSERT(tv < thr->valstack_top); + h = DUK_TVAL_GET_HEAPHDR(tv); + DUK_ASSERT(h != NULL); + return h; +} + +DUK_INTERNAL duk_hstring *duk_known_hstring(duk_context *ctx, duk_idx_t idx) { + DUK_ASSERT(duk_get_hstring(ctx, idx) != NULL); + return (duk_hstring *) duk__known_heaphdr(ctx, idx); +} + +DUK_INTERNAL duk_hobject *duk_known_hobject(duk_context *ctx, duk_idx_t idx) { + DUK_ASSERT(duk_get_hobject(ctx, idx) != NULL); + return (duk_hobject *) duk__known_heaphdr(ctx, idx); +} + +DUK_INTERNAL duk_hbuffer *duk_known_hbuffer(duk_context *ctx, duk_idx_t idx) { + DUK_ASSERT(duk_get_hbuffer(ctx, idx) != NULL); + return (duk_hbuffer *) duk__known_heaphdr(ctx, idx); +} + +DUK_INTERNAL duk_hcompfunc *duk_known_hcompfunc(duk_context *ctx, duk_idx_t idx) { + DUK_ASSERT(duk_get_hcompfunc(ctx, idx) != NULL); + return (duk_hcompfunc *) duk__known_heaphdr(ctx, idx); +} - duk_hobject_set_length(thr, h, (duk_uint32_t) length); /* XXX: typing */ +DUK_INTERNAL duk_hnatfunc *duk_known_hnatfunc(duk_context *ctx, duk_idx_t idx) { + DUK_ASSERT(duk_get_hnatfunc(ctx, idx) != NULL); + return (duk_hnatfunc *) duk__known_heaphdr(ctx, idx); +} + +DUK_EXTERNAL void duk_set_length(duk_context *ctx, duk_idx_t idx, duk_size_t len) { + DUK_ASSERT_CTX_VALID(ctx); + + idx = duk_normalize_index(ctx, idx); + duk_push_uint(ctx, (duk_uint_t) len); + duk_put_prop_stridx(ctx, idx, DUK_STRIDX_LENGTH); } /* @@ -16779,14 +18203,14 @@ DUK_INTERNAL void duk_set_length(duk_context *ctx, duk_idx_t index, duk_size_t l /* E5 Section 8.12.8 */ -DUK_LOCAL duk_bool_t duk__defaultvalue_coerce_attempt(duk_context *ctx, duk_idx_t index, duk_small_int_t func_stridx) { - if (duk_get_prop_stridx(ctx, index, func_stridx)) { +DUK_LOCAL duk_bool_t duk__defaultvalue_coerce_attempt(duk_context *ctx, duk_idx_t idx, duk_small_int_t func_stridx) { + if (duk_get_prop_stridx(ctx, idx, func_stridx)) { /* [ ... func ] */ if (duk_is_callable(ctx, -1)) { - duk_dup(ctx, index); /* -> [ ... func this ] */ + duk_dup(ctx, idx); /* -> [ ... func this ] */ duk_call_method(ctx, 0); /* -> [ ... retval ] */ if (duk_is_primitive(ctx, -1)) { - duk_replace(ctx, index); + duk_replace(ctx, idx); return 1; } /* [ ... retval ]; popped below */ @@ -16796,86 +18220,113 @@ DUK_LOCAL duk_bool_t duk__defaultvalue_coerce_attempt(duk_context *ctx, duk_idx_ return 0; } -DUK_EXTERNAL void duk_to_defaultvalue(duk_context *ctx, duk_idx_t index, duk_int_t hint) { - duk_hthread *thr = (duk_hthread *) ctx; - duk_hobject *obj; - /* inline initializer for coercers[] is not allowed by old compilers like BCC */ - duk_small_int_t coercers[2]; - - DUK_ASSERT_CTX_VALID(ctx); - DUK_ASSERT(thr != NULL); - - coercers[0] = DUK_STRIDX_VALUE_OF; - coercers[1] = DUK_STRIDX_TO_STRING; - - index = duk_require_normalize_index(ctx, index); - obj = duk_require_hobject_or_lfunc(ctx, index); - - if (hint == DUK_HINT_NONE) { - if (obj != NULL && DUK_HOBJECT_GET_CLASS_NUMBER(obj) == DUK_HOBJECT_CLASS_DATE) { - hint = DUK_HINT_STRING; - } else { - hint = DUK_HINT_NUMBER; - } - } - - if (hint == DUK_HINT_STRING) { - coercers[0] = DUK_STRIDX_TO_STRING; - coercers[1] = DUK_STRIDX_VALUE_OF; - } - - if (duk__defaultvalue_coerce_attempt(ctx, index, coercers[0])) { - return; - } - - if (duk__defaultvalue_coerce_attempt(ctx, index, coercers[1])) { - return; - } - - DUK_ERROR_TYPE(thr, DUK_STR_DEFAULTVALUE_COERCE_FAILED); -} - -DUK_EXTERNAL void duk_to_undefined(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL void duk_to_undefined(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_tval *tv; DUK_ASSERT_CTX_VALID(ctx); DUK_UNREF(thr); - tv = duk_require_tval(ctx, index); + tv = duk_require_tval(ctx, idx); DUK_ASSERT(tv != NULL); DUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv); /* side effects */ } -DUK_EXTERNAL void duk_to_null(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL void duk_to_null(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_tval *tv; DUK_ASSERT_CTX_VALID(ctx); DUK_UNREF(thr); - tv = duk_require_tval(ctx, index); + tv = duk_require_tval(ctx, idx); DUK_ASSERT(tv != NULL); DUK_TVAL_SET_NULL_UPDREF(thr, tv); /* side effects */ } /* E5 Section 9.1 */ -DUK_EXTERNAL void duk_to_primitive(duk_context *ctx, duk_idx_t index, duk_int_t hint) { +DUK_EXTERNAL void duk_to_primitive(duk_context *ctx, duk_idx_t idx, duk_int_t hint) { + duk_hthread *thr = (duk_hthread *) ctx; + /* inline initializer for coercers[] is not allowed by old compilers like BCC */ + duk_small_int_t coercers[2]; + duk_small_uint_t class_number; + DUK_ASSERT_CTX_VALID(ctx); DUK_ASSERT(hint == DUK_HINT_NONE || hint == DUK_HINT_NUMBER || hint == DUK_HINT_STRING); - index = duk_require_normalize_index(ctx, index); + idx = duk_require_normalize_index(ctx, idx); + + if (!duk_check_type_mask(ctx, idx, DUK_TYPE_MASK_OBJECT | + DUK_TYPE_MASK_LIGHTFUNC | + DUK_TYPE_MASK_BUFFER)) { + /* Any other values stay as is. */ + DUK_ASSERT(!duk_is_buffer(ctx, idx)); /* duk_to_string() relies on this behavior */ + return; + } + + class_number = duk_get_class_number(ctx, idx); + + /* XXX: Symbol objects normally coerce via the ES2015-revised ToPrimitive() + * algorithm which consults value[@@toPrimitive] and avoids calling + * .valueOf() and .toString(). Before that is implemented, special + * case Symbol objects to behave as if they had the default @@toPrimitive + * algorithm of E6 Section 19.4.3.4, i.e. return the plain symbol value + * with no further side effects. + */ + + if (class_number == DUK_HOBJECT_CLASS_SYMBOL) { + duk_hobject *h_obj; + duk_hstring *h_str; + + /* XXX: pretty awkward, index based API for internal value access? */ + h_obj = duk_known_hobject(ctx, idx); + h_str = duk_hobject_get_internal_value_string(thr->heap, h_obj); + if (h_str) { + duk_push_hstring(ctx, h_str); + duk_replace(ctx, idx); + return; + } + } + + + /* Objects are coerced based on E5 specification. + * Lightfuncs are coerced because they behave like + * objects even if they're internally a primitive + * type. Same applies to plain buffers, which behave + * like ArrayBuffer objects since Duktape 2.x. + */ + + coercers[0] = DUK_STRIDX_VALUE_OF; + coercers[1] = DUK_STRIDX_TO_STRING; + + if (hint == DUK_HINT_NONE) { + if (class_number == DUK_HOBJECT_CLASS_DATE) { + hint = DUK_HINT_STRING; + } else { + hint = DUK_HINT_NUMBER; + } + } + + if (hint == DUK_HINT_STRING) { + coercers[0] = DUK_STRIDX_TO_STRING; + coercers[1] = DUK_STRIDX_VALUE_OF; + } + + if (duk__defaultvalue_coerce_attempt(ctx, idx, coercers[0])) { + DUK_ASSERT(!duk_is_buffer(ctx, idx)); /* duk_to_string() relies on this behavior */ + return; + } - if (!duk_check_type_mask(ctx, index, DUK_TYPE_MASK_OBJECT | - DUK_TYPE_MASK_LIGHTFUNC)) { - /* everything except object stay as is */ + if (duk__defaultvalue_coerce_attempt(ctx, idx, coercers[1])) { + DUK_ASSERT(!duk_is_buffer(ctx, idx)); /* duk_to_string() relies on this behavior */ return; } - duk_to_defaultvalue(ctx, index, hint); + + DUK_ERROR_TYPE(thr, DUK_STR_TOPRIMITIVE_FAILED); } /* E5 Section 9.2 */ -DUK_EXTERNAL duk_bool_t duk_to_boolean(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_bool_t duk_to_boolean(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_tval *tv; duk_bool_t val; @@ -16883,135 +18334,155 @@ DUK_EXTERNAL duk_bool_t duk_to_boolean(duk_context *ctx, duk_idx_t index) { DUK_ASSERT_CTX_VALID(ctx); DUK_UNREF(thr); - index = duk_require_normalize_index(ctx, index); - - tv = duk_require_tval(ctx, index); + idx = duk_require_normalize_index(ctx, idx); + tv = DUK_GET_TVAL_POSIDX(ctx, idx); DUK_ASSERT(tv != NULL); val = duk_js_toboolean(tv); DUK_ASSERT(val == 0 || val == 1); - /* Note: no need to re-lookup tv, conversion is side effect free */ + /* Note: no need to re-lookup tv, conversion is side effect free. */ DUK_ASSERT(tv != NULL); DUK_TVAL_SET_BOOLEAN_UPDREF(thr, tv, val); /* side effects */ return val; } -DUK_EXTERNAL duk_double_t duk_to_number(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_double_t duk_to_number(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_tval *tv; duk_double_t d; DUK_ASSERT_CTX_VALID(ctx); - tv = duk_require_tval(ctx, index); + /* XXX: No need to normalize; the whole operation could be inlined here to + * avoid 'tv' re-lookup. + */ + idx = duk_require_normalize_index(ctx, idx); + tv = DUK_GET_TVAL_POSIDX(ctx, idx); DUK_ASSERT(tv != NULL); - /* XXX: fastint? */ - d = duk_js_tonumber(thr, tv); + d = duk_js_tonumber(thr, tv); /* XXX: fastint coercion? now result will always be a non-fastint */ - /* Note: need to re-lookup because ToNumber() may have side effects */ - tv = duk_require_tval(ctx, index); + /* ToNumber() may have side effects so must relookup 'tv'. */ + tv = DUK_GET_TVAL_POSIDX(ctx, idx); DUK_TVAL_SET_NUMBER_UPDREF(thr, tv, d); /* side effects */ return d; } +DUK_INTERNAL duk_double_t duk_to_number_m1(duk_context *ctx) { + return duk_to_number(ctx, -1); +} +DUK_INTERNAL duk_double_t duk_to_number_m2(duk_context *ctx) { + return duk_to_number(ctx, -2); +} + +DUK_INTERNAL duk_double_t duk_to_number_tval(duk_context *ctx, duk_tval *tv) { + duk_double_t res; + + DUK_ASSERT_CTX_VALID(ctx); + + duk_push_tval(ctx, tv); + res = duk_to_number(ctx, -1); + duk_pop(ctx); + return res; +} + /* XXX: combine all the integer conversions: they share everything * but the helper function for coercion. */ typedef duk_double_t (*duk__toint_coercer)(duk_hthread *thr, duk_tval *tv); -DUK_LOCAL duk_double_t duk__to_int_uint_helper(duk_context *ctx, duk_idx_t index, duk__toint_coercer coerce_func) { +DUK_LOCAL duk_double_t duk__to_int_uint_helper(duk_context *ctx, duk_idx_t idx, duk__toint_coercer coerce_func) { duk_hthread *thr = (duk_hthread *) ctx; duk_tval *tv; duk_double_t d; DUK_ASSERT_CTX_VALID(ctx); - tv = duk_require_tval(ctx, index); + tv = duk_require_tval(ctx, idx); DUK_ASSERT(tv != NULL); d = coerce_func(thr, tv); /* XXX: fastint? */ /* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */ - tv = duk_require_tval(ctx, index); + tv = duk_require_tval(ctx, idx); DUK_TVAL_SET_NUMBER_UPDREF(thr, tv, d); /* side effects */ return d; } -DUK_EXTERNAL duk_int_t duk_to_int(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_int_t duk_to_int(duk_context *ctx, duk_idx_t idx) { /* Value coercion (in stack): ToInteger(), E5 Section 9.4 * API return value coercion: custom */ DUK_ASSERT_CTX_VALID(ctx); - (void) duk__to_int_uint_helper(ctx, index, duk_js_tointeger); - return (duk_int_t) duk__api_coerce_d2i(ctx, index, 0 /*require*/); + (void) duk__to_int_uint_helper(ctx, idx, duk_js_tointeger); + return (duk_int_t) duk__api_coerce_d2i(ctx, idx, 0 /*require*/); } -DUK_EXTERNAL duk_uint_t duk_to_uint(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_uint_t duk_to_uint(duk_context *ctx, duk_idx_t idx) { /* Value coercion (in stack): ToInteger(), E5 Section 9.4 * API return value coercion: custom */ DUK_ASSERT_CTX_VALID(ctx); - (void) duk__to_int_uint_helper(ctx, index, duk_js_tointeger); - return (duk_uint_t) duk__api_coerce_d2ui(ctx, index, 0 /*require*/); + (void) duk__to_int_uint_helper(ctx, idx, duk_js_tointeger); + return (duk_uint_t) duk__api_coerce_d2ui(ctx, idx, 0 /*require*/); } -DUK_EXTERNAL duk_int32_t duk_to_int32(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_int32_t duk_to_int32(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_tval *tv; duk_int32_t ret; DUK_ASSERT_CTX_VALID(ctx); - tv = duk_require_tval(ctx, index); + tv = duk_require_tval(ctx, idx); DUK_ASSERT(tv != NULL); ret = duk_js_toint32(thr, tv); /* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */ - tv = duk_require_tval(ctx, index); - DUK_TVAL_SET_FASTINT_I32_UPDREF(thr, tv, ret); /* side effects */ + tv = duk_require_tval(ctx, idx); + DUK_TVAL_SET_I32_UPDREF(thr, tv, ret); /* side effects */ return ret; } -DUK_EXTERNAL duk_uint32_t duk_to_uint32(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_uint32_t duk_to_uint32(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_tval *tv; duk_uint32_t ret; DUK_ASSERT_CTX_VALID(ctx); - tv = duk_require_tval(ctx, index); + tv = duk_require_tval(ctx, idx); DUK_ASSERT(tv != NULL); ret = duk_js_touint32(thr, tv); /* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */ - tv = duk_require_tval(ctx, index); - DUK_TVAL_SET_FASTINT_U32_UPDREF(thr, tv, ret); /* side effects */ + tv = duk_require_tval(ctx, idx); + DUK_TVAL_SET_U32_UPDREF(thr, tv, ret); /* side effects */ return ret; } -DUK_EXTERNAL duk_uint16_t duk_to_uint16(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_uint16_t duk_to_uint16(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_tval *tv; duk_uint16_t ret; DUK_ASSERT_CTX_VALID(ctx); - tv = duk_require_tval(ctx, index); + tv = duk_require_tval(ctx, idx); DUK_ASSERT(tv != NULL); ret = duk_js_touint16(thr, tv); /* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */ - tv = duk_require_tval(ctx, index); - DUK_TVAL_SET_FASTINT_U32_UPDREF(thr, tv, ret); /* side effects */ + tv = duk_require_tval(ctx, idx); + DUK_TVAL_SET_U32_UPDREF(thr, tv, ret); /* side effects */ return ret; } #if defined(DUK_USE_BUFFEROBJECT_SUPPORT) /* Special coercion for Uint8ClampedArray. */ -DUK_INTERNAL duk_uint8_t duk_to_uint8clamped(duk_context *ctx, duk_idx_t index) { +DUK_INTERNAL duk_uint8_t duk_to_uint8clamped(duk_context *ctx, duk_idx_t idx) { duk_double_t d; duk_double_t t; duk_uint8_t ret; @@ -17021,7 +18492,7 @@ DUK_INTERNAL duk_uint8_t duk_to_uint8clamped(duk_context *ctx, duk_idx_t index) * directly. */ - d = duk_to_number(ctx, index); + d = duk_to_number(ctx, idx); if (d <= 0.0) { return 0; } else if (d >= 255) { @@ -17046,35 +18517,37 @@ DUK_INTERNAL duk_uint8_t duk_to_uint8clamped(duk_context *ctx, duk_idx_t index) } #endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ -DUK_EXTERNAL const char *duk_to_lstring(duk_context *ctx, duk_idx_t index, duk_size_t *out_len) { +DUK_EXTERNAL const char *duk_to_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len) { DUK_ASSERT_CTX_VALID(ctx); - (void) duk_to_string(ctx, index); - return duk_require_lstring(ctx, index, out_len); + (void) duk_to_string(ctx, idx); + DUK_ASSERT(duk_is_string(ctx, idx)); + return duk_require_lstring(ctx, idx, out_len); } -DUK_LOCAL duk_ret_t duk__safe_to_string_raw(duk_context *ctx) { +DUK_LOCAL duk_ret_t duk__safe_to_string_raw(duk_context *ctx, void *udata) { DUK_ASSERT_CTX_VALID(ctx); + DUK_UNREF(udata); duk_to_string(ctx, -1); return 1; } -DUK_EXTERNAL const char *duk_safe_to_lstring(duk_context *ctx, duk_idx_t index, duk_size_t *out_len) { +DUK_EXTERNAL const char *duk_safe_to_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len) { DUK_ASSERT_CTX_VALID(ctx); - index = duk_require_normalize_index(ctx, index); + idx = duk_require_normalize_index(ctx, idx); /* We intentionally ignore the duk_safe_call() return value and only * check the output type. This way we don't also need to check that * the returned value is indeed a string in the success case. */ - duk_dup(ctx, index); - (void) duk_safe_call(ctx, duk__safe_to_string_raw, 1 /*nargs*/, 1 /*nrets*/); + duk_dup(ctx, idx); + (void) duk_safe_call(ctx, duk__safe_to_string_raw, NULL /*udata*/, 1 /*nargs*/, 1 /*nrets*/); if (!duk_is_string(ctx, -1)) { /* Error: try coercing error to string once. */ - (void) duk_safe_call(ctx, duk__safe_to_string_raw, 1 /*nargs*/, 1 /*nrets*/); + (void) duk_safe_call(ctx, duk__safe_to_string_raw, NULL /*udata*/, 1 /*nargs*/, 1 /*nrets*/); if (!duk_is_string(ctx, -1)) { /* Double error */ duk_pop(ctx); @@ -17083,72 +18556,129 @@ DUK_EXTERNAL const char *duk_safe_to_lstring(duk_context *ctx, duk_idx_t index, ; } } else { + /* String; may be a symbol, accepted. */ ; } DUK_ASSERT(duk_is_string(ctx, -1)); - DUK_ASSERT(duk_get_string(ctx, -1) != NULL); - duk_replace(ctx, index); - return duk_get_lstring(ctx, index, out_len); + duk_replace(ctx, idx); + DUK_ASSERT(duk_get_string(ctx, idx) != NULL); + return duk_get_lstring(ctx, idx, out_len); } -#if defined(DUK_USE_DEBUGGER_SUPPORT) /* only needed by debugger for now */ -DUK_INTERNAL duk_hstring *duk_safe_to_hstring(duk_context *ctx, duk_idx_t index) { - (void) duk_safe_to_string(ctx, index); - DUK_ASSERT(duk_is_string(ctx, index)); - DUK_ASSERT(duk_get_hstring(ctx, index) != NULL); - return duk_get_hstring(ctx, index); -} -#endif - -/* Coerce top into Object.prototype.toString() output. */ -DUK_INTERNAL void duk_to_object_class_string_top(duk_context *ctx) { - duk_hthread *thr; - duk_uint_t typemask; - duk_hstring *h_strclass; +DUK_INTERNAL duk_hstring *duk_to_property_key_hstring(duk_context *ctx, duk_idx_t idx) { + duk_hstring *h; DUK_ASSERT_CTX_VALID(ctx); - thr = (duk_hthread *) ctx; - DUK_UNREF(thr); - - typemask = duk_get_type_mask(ctx, -1); - if (typemask & DUK_TYPE_MASK_UNDEFINED) { - h_strclass = DUK_HTHREAD_STRING_UC_UNDEFINED(thr); - } else if (typemask & DUK_TYPE_MASK_NULL) { - h_strclass = DUK_HTHREAD_STRING_UC_NULL(thr); - } else { - duk_hobject *h_obj; - - duk_to_object(ctx, -1); - h_obj = duk_get_hobject(ctx, -1); - DUK_ASSERT(h_obj != NULL); - h_strclass = DUK_HOBJECT_GET_CLASS_STRING(thr->heap, h_obj); + duk_to_primitive(ctx, idx, DUK_HINT_STRING); /* needed for e.g. Symbol objects */ + h = duk_get_hstring(ctx, idx); + if (h == NULL) { + /* The "is string?" check may seem unnecessary, but as things + * are duk_to_hstring() invokes ToString() which fails for + * symbols. But since symbols are already strings for Duktape + * C API, we check for that before doing the coercion. + */ + h = duk_to_hstring(ctx, idx); } - DUK_ASSERT(h_strclass != NULL); + DUK_ASSERT(h != NULL); + return h; +} - duk_pop(ctx); - duk_push_sprintf(ctx, "[object %s]", (const char *) DUK_HSTRING_GET_DATA(h_strclass)); +#if defined(DUK_USE_DEBUGGER_SUPPORT) /* only needed by debugger for now */ +DUK_INTERNAL duk_hstring *duk_safe_to_hstring(duk_context *ctx, duk_idx_t idx) { + (void) duk_safe_to_string(ctx, idx); + DUK_ASSERT(duk_is_string(ctx, idx)); + DUK_ASSERT(duk_get_hstring(ctx, idx) != NULL); + return duk_known_hstring(ctx, idx); } +#endif -#if !defined(DUK_USE_PARANOID_ERRORS) -DUK_INTERNAL void duk_push_hobject_class_string(duk_context *ctx, duk_hobject *h) { +/* Push Object.prototype.toString() output for 'tv'. */ +DUK_INTERNAL void duk_push_class_string_tval(duk_context *ctx, duk_tval *tv) { duk_hthread *thr; + duk_small_uint_t stridx; duk_hstring *h_strclass; DUK_ASSERT_CTX_VALID(ctx); - DUK_ASSERT(h != NULL); thr = (duk_hthread *) ctx; DUK_UNREF(thr); - h_strclass = DUK_HOBJECT_GET_CLASS_STRING(thr->heap, h); + switch (DUK_TVAL_GET_TAG(tv)) { + case DUK_TAG_UNUSED: /* Treat like 'undefined', shouldn't happen. */ + case DUK_TAG_UNDEFINED: { + stridx = DUK_STRIDX_UC_UNDEFINED; + break; + } + case DUK_TAG_NULL: { + stridx = DUK_STRIDX_UC_NULL; + break; + } + case DUK_TAG_BOOLEAN: { + stridx = DUK_STRIDX_UC_BOOLEAN; + break; + } + case DUK_TAG_POINTER: { + stridx = DUK_STRIDX_UC_POINTER; + break; + } + case DUK_TAG_LIGHTFUNC: { + stridx = DUK_STRIDX_UC_FUNCTION; + break; + } + case DUK_TAG_STRING: { + duk_hstring *h; + h = DUK_TVAL_GET_STRING(tv); + DUK_ASSERT(h != NULL); + if (DUK_HSTRING_HAS_SYMBOL(h)) { + stridx = DUK_STRIDX_UC_SYMBOL; + } else { + stridx = DUK_STRIDX_UC_STRING; + } + break; + } + case DUK_TAG_OBJECT: { + duk_hobject *h; + duk_small_uint_t classnum; + + h = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(h != NULL); + classnum = DUK_HOBJECT_GET_CLASS_NUMBER(h); + stridx = DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(classnum); + + /* XXX: This is not entirely correct anymore; in ES2015 the + * default lookup should use @@toStringTag to come up with + * e.g. [object Symbol], [object Uint8Array], etc. See + * ES2015 Section 19.1.3.6. The downside of implementing that + * directly is that the @@toStringTag lookup may have side + * effects, so all call sites must be checked for that. + * Some may need a side-effect free lookup, e.g. avoiding + * getters which are not typical. + */ + break; + } + case DUK_TAG_BUFFER: { + stridx = DUK_STRIDX_UINT8_ARRAY; + break; + } +#if defined(DUK_USE_FASTINT) + case DUK_TAG_FASTINT: + /* Fall through to generic number case. */ +#endif + default: { + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv)); /* number (maybe fastint) */ + stridx = DUK_STRIDX_UC_NUMBER; + break; + } + } + h_strclass = DUK_HTHREAD_GET_STRING(thr, stridx); DUK_ASSERT(h_strclass != NULL); + duk_push_sprintf(ctx, "[object %s]", (const char *) DUK_HSTRING_GET_DATA(h_strclass)); } -#endif /* !DUK_USE_PARANOID_ERRORS */ /* XXX: other variants like uint, u32 etc */ -DUK_INTERNAL duk_int_t duk_to_int_clamped_raw(duk_context *ctx, duk_idx_t index, duk_int_t minval, duk_int_t maxval, duk_bool_t *out_clamped) { +DUK_INTERNAL duk_int_t duk_to_int_clamped_raw(duk_context *ctx, duk_idx_t idx, duk_int_t minval, duk_int_t maxval, duk_bool_t *out_clamped) { duk_hthread *thr = (duk_hthread *) ctx; duk_tval *tv; duk_tval tv_tmp; @@ -17158,7 +18688,7 @@ DUK_INTERNAL duk_int_t duk_to_int_clamped_raw(duk_context *ctx, duk_idx_t index, DUK_ASSERT_CTX_VALID(ctx); - tv = duk_require_tval(ctx, index); + tv = duk_require_tval(ctx, idx); DUK_ASSERT(tv != NULL); d = duk_js_tointeger(thr, tv); /* E5 Section 9.4, ToInteger() */ @@ -17180,12 +18710,12 @@ DUK_INTERNAL duk_int_t duk_to_int_clamped_raw(duk_context *ctx, duk_idx_t index, /* 'd' and 'res' agree here */ /* Relookup in case duk_js_tointeger() ends up e.g. coercing an object. */ - tv = duk_get_tval(ctx, index); + tv = duk_get_tval(ctx, idx); DUK_ASSERT(tv != NULL); /* not popped by side effect */ DUK_TVAL_SET_TVAL(&tv_tmp, tv); #if defined(DUK_USE_FASTINT) #if (DUK_INT_MAX <= 0x7fffffffL) - DUK_TVAL_SET_FASTINT_I32(tv, res); + DUK_TVAL_SET_I32(tv, res); #else /* Clamping needed if duk_int_t is 64 bits. */ if (res >= DUK_FASTINT_MIN && res <= DUK_FASTINT_MAX) { @@ -17211,25 +18741,24 @@ DUK_INTERNAL duk_int_t duk_to_int_clamped_raw(duk_context *ctx, duk_idx_t index, return res; } -DUK_INTERNAL duk_int_t duk_to_int_clamped(duk_context *ctx, duk_idx_t index, duk_idx_t minval, duk_idx_t maxval) { +DUK_INTERNAL duk_int_t duk_to_int_clamped(duk_context *ctx, duk_idx_t idx, duk_idx_t minval, duk_idx_t maxval) { duk_bool_t dummy; - return duk_to_int_clamped_raw(ctx, index, minval, maxval, &dummy); + return duk_to_int_clamped_raw(ctx, idx, minval, maxval, &dummy); } -DUK_INTERNAL duk_int_t duk_to_int_check_range(duk_context *ctx, duk_idx_t index, duk_int_t minval, duk_int_t maxval) { - return duk_to_int_clamped_raw(ctx, index, minval, maxval, NULL); /* out_clamped==NULL -> RangeError if outside range */ +DUK_INTERNAL duk_int_t duk_to_int_check_range(duk_context *ctx, duk_idx_t idx, duk_int_t minval, duk_int_t maxval) { + return duk_to_int_clamped_raw(ctx, idx, minval, maxval, NULL); /* out_clamped==NULL -> RangeError if outside range */ } -DUK_EXTERNAL const char *duk_to_string(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL const char *duk_to_string(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_tval *tv; DUK_ASSERT_CTX_VALID(ctx); DUK_UNREF(thr); - index = duk_require_normalize_index(ctx, index); - - tv = duk_require_tval(ctx, index); + idx = duk_require_normalize_index(ctx, idx); + tv = DUK_GET_TVAL_POSIDX(ctx, idx); DUK_ASSERT(tv != NULL); switch (DUK_TVAL_GET_TAG(tv)) { @@ -17250,23 +18779,36 @@ DUK_EXTERNAL const char *duk_to_string(duk_context *ctx, duk_idx_t index) { break; } case DUK_TAG_STRING: { - /* nop */ + /* Nop for actual strings, TypeError for Symbols. + * Because various internals rely on ToString() coercion of + * internal strings, -allow- (NOP) string coercion for hidden + * symbols. + */ +#if 1 + duk_hstring *h; + h = DUK_TVAL_GET_STRING(tv); + DUK_ASSERT(h != NULL); + if (DUK_HSTRING_HAS_SYMBOL(h)) { + DUK_ERROR_TYPE((duk_hthread *) ctx, DUK_STR_CANNOT_STRING_COERCE_SYMBOL); + } else { + goto skip_replace; + } +#else goto skip_replace; +#endif } + case DUK_TAG_BUFFER: /* Go through Uint8Array.prototype.toString() for coercion. */ case DUK_TAG_OBJECT: { - duk_to_primitive(ctx, index, DUK_HINT_STRING); - return duk_to_string(ctx, index); /* Note: recursive call */ - } - case DUK_TAG_BUFFER: { - duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv); - - /* Note: this allows creation of internal strings. */ - - DUK_ASSERT(h != NULL); - duk_push_lstring(ctx, - (const char *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h), - (duk_size_t) DUK_HBUFFER_GET_SIZE(h)); - break; + /* Plain buffers: go through ArrayBuffer.prototype.toString() + * for coercion. + * + * Symbol objects: duk_to_primitive() results in a plain symbol + * value, and duk_to_string() then causes a TypeError. + */ + duk_to_primitive(ctx, idx, DUK_HINT_STRING); + DUK_ASSERT(!duk_is_buffer(ctx, idx)); /* ToPrimitive() must guarantee */ + DUK_ASSERT(!duk_is_object(ctx, idx)); + return duk_to_string(ctx, idx); /* Note: recursive call */ } case DUK_TAG_POINTER: { void *ptr = DUK_TVAL_GET_POINTER(tv); @@ -17302,22 +18844,59 @@ DUK_EXTERNAL const char *duk_to_string(duk_context *ctx, duk_idx_t index) { } } - duk_replace(ctx, index); + duk_replace(ctx, idx); skip_replace: - return duk_require_string(ctx, index); + DUK_ASSERT(duk_is_string(ctx, idx)); + return duk_require_string(ctx, idx); } -DUK_INTERNAL duk_hstring *duk_to_hstring(duk_context *ctx, duk_idx_t index) { +DUK_INTERNAL duk_hstring *duk_to_hstring(duk_context *ctx, duk_idx_t idx) { duk_hstring *ret; DUK_ASSERT_CTX_VALID(ctx); - duk_to_string(ctx, index); - ret = duk_get_hstring(ctx, index); + duk_to_string(ctx, idx); + ret = duk_get_hstring(ctx, idx); DUK_ASSERT(ret != NULL); return ret; } -DUK_EXTERNAL void *duk_to_buffer_raw(duk_context *ctx, duk_idx_t index, duk_size_t *out_size, duk_uint_t mode) { +DUK_INTERNAL duk_hstring *duk_to_hstring_m1(duk_context *ctx) { + return duk_to_hstring(ctx, -1); +} + +DUK_INTERNAL duk_hstring *duk_to_hstring_acceptsymbol(duk_context *ctx, duk_idx_t idx) { + duk_hstring *ret; + DUK_ASSERT_CTX_VALID(ctx); + ret = duk_get_hstring(ctx, idx); + if (ret && DUK_HSTRING_HAS_SYMBOL(ret)) { + return ret; + } + return duk_to_hstring(ctx, idx); +} + +/* Convert a plain buffer or any buffer object into a string, using the buffer + * bytes 1:1 in the internal string representation. For views the active byte + * slice (not element slice interpreted as an initializer) is used. This is + * necessary in Duktape 2.x because ToString(plainBuffer) no longer creates a + * string with the same bytes as in the buffer but rather (usually) + * '[object ArrayBuffer]'. + */ +DUK_EXTERNAL const char *duk_buffer_to_string(duk_context *ctx, duk_idx_t idx) { + void *ptr_src; + duk_size_t len; + const char *res; + + idx = duk_require_normalize_index(ctx, idx); + + ptr_src = duk_require_buffer_data(ctx, idx, &len); + DUK_ASSERT(ptr_src != NULL || len == 0); + + res = duk_push_lstring(ctx, (const char *) ptr_src, len); + duk_replace(ctx, idx); + return res; +} + +DUK_EXTERNAL void *duk_to_buffer_raw(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, duk_uint_t mode) { duk_hthread *thr = (duk_hthread *) ctx; duk_hbuffer *h_buf; const duk_uint8_t *src_data; @@ -17327,9 +18906,9 @@ DUK_EXTERNAL void *duk_to_buffer_raw(duk_context *ctx, duk_idx_t index, duk_size DUK_ASSERT_CTX_VALID(ctx); DUK_UNREF(thr); - index = duk_require_normalize_index(ctx, index); + idx = duk_require_normalize_index(ctx, idx); - h_buf = duk_get_hbuffer(ctx, index); + h_buf = duk_get_hbuffer(ctx, idx); if (h_buf != NULL) { /* Buffer is kept as is, with the fixed/dynamic nature of the * buffer only changed if requested. An external buffer @@ -17355,10 +18934,10 @@ DUK_EXTERNAL void *duk_to_buffer_raw(duk_context *ctx, duk_idx_t index, duk_size } else { /* Non-buffer value is first ToString() coerced, then converted * to a buffer (fixed buffer is used unless a dynamic buffer is - * explicitly requested). + * explicitly requested). Symbols are rejected with a TypeError. + * XXX: C API could maybe allow symbol-to-buffer coercion? */ - - src_data = (const duk_uint8_t *) duk_to_lstring(ctx, index, &src_size); + src_data = (const duk_uint8_t *) duk_to_lstring(ctx, idx, &src_size); } dst_data = (duk_uint8_t *) duk_push_buffer(ctx, src_size, (mode == DUK_BUF_MODE_DYNAMIC) /*dynamic*/); @@ -17370,7 +18949,7 @@ DUK_EXTERNAL void *duk_to_buffer_raw(duk_context *ctx, duk_idx_t index, duk_size */ DUK_MEMCPY((void *) dst_data, (const void *) src_data, (size_t) src_size); } - duk_replace(ctx, index); + duk_replace(ctx, idx); skip_copy: if (out_size) { @@ -17379,15 +18958,14 @@ DUK_EXTERNAL void *duk_to_buffer_raw(duk_context *ctx, duk_idx_t index, duk_size return dst_data; } -DUK_EXTERNAL void *duk_to_pointer(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL void *duk_to_pointer(duk_context *ctx, duk_idx_t idx) { duk_tval *tv; void *res; DUK_ASSERT_CTX_VALID(ctx); - index = duk_require_normalize_index(ctx, index); - - tv = duk_require_tval(ctx, index); + idx = duk_require_normalize_index(ctx, idx); + tv = DUK_GET_TVAL_POSIDX(ctx, idx); DUK_ASSERT(tv != NULL); switch (DUK_TVAL_GET_TAG(tv)) { @@ -17426,11 +19004,51 @@ DUK_EXTERNAL void *duk_to_pointer(duk_context *ctx, duk_idx_t index) { } duk_push_pointer(ctx, res); - duk_replace(ctx, index); + duk_replace(ctx, idx); return res; } -DUK_EXTERNAL void duk_to_object(duk_context *ctx, duk_idx_t index) { +DUK_LOCAL void duk__push_func_from_lightfunc(duk_context *ctx, duk_c_function func, duk_small_uint_t lf_flags) { + duk_idx_t nargs; + duk_uint_t flags = 0; /* shared flags for a subset of types */ + duk_small_uint_t lf_len; + duk_hnatfunc *nf; + + nargs = (duk_idx_t) DUK_LFUNC_FLAGS_GET_NARGS(lf_flags); + if (nargs == DUK_LFUNC_NARGS_VARARGS) { + nargs = (duk_idx_t) DUK_VARARGS; + } + + flags = DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_CONSTRUCTABLE | + DUK_HOBJECT_FLAG_NATFUNC | + DUK_HOBJECT_FLAG_NEWENV | + DUK_HOBJECT_FLAG_STRICT | + DUK_HOBJECT_FLAG_NOTAIL | + /* DUK_HOBJECT_FLAG_EXOTIC_DUKFUNC: omitted here intentionally */ + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION); + (void) duk__push_c_function_raw(ctx, func, nargs, flags); + + lf_len = DUK_LFUNC_FLAGS_GET_LENGTH(lf_flags); + if ((duk_idx_t) lf_len != nargs) { + /* Explicit length is only needed if it differs from 'nargs'. */ + duk_push_int(ctx, (duk_int_t) lf_len); + duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_NONE); + } + +#if defined(DUK_USE_FUNC_NAME_PROPERTY) + duk_push_lightfunc_name_raw(ctx, func, lf_flags); + duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C); +#endif + + nf = duk_known_hnatfunc(ctx, -1); + nf->magic = (duk_int16_t) DUK_LFUNC_FLAGS_GET_MAGIC(lf_flags); + + /* Enable DUKFUNC exotic behavior once properties are set up. */ + DUK_HOBJECT_SET_EXOTIC_DUKFUNC((duk_hobject *) nf); +} + +DUK_EXTERNAL void duk_to_object(duk_context *ctx, duk_idx_t idx) { duk_hthread *thr = (duk_hthread *) ctx; duk_tval *tv; duk_uint_t flags = 0; /* shared flags for a subset of types */ @@ -17438,12 +19056,14 @@ DUK_EXTERNAL void duk_to_object(duk_context *ctx, duk_idx_t index) { DUK_ASSERT_CTX_VALID(ctx); - index = duk_require_normalize_index(ctx, index); - - tv = duk_require_tval(ctx, index); + idx = duk_require_normalize_index(ctx, idx); + tv = DUK_GET_TVAL_POSIDX(ctx, idx); DUK_ASSERT(tv != NULL); switch (DUK_TVAL_GET_TAG(tv)) { +#if !defined(DUK_USE_BUFFEROBJECT_SUPPORT) + case DUK_TAG_BUFFER: /* With no bufferobject support, don't object coerce. */ +#endif case DUK_TAG_UNDEFINED: case DUK_TAG_NULL: { DUK_ERROR_TYPE(thr, DUK_STR_NOT_OBJECT_COERCIBLE); @@ -17456,47 +19076,42 @@ DUK_EXTERNAL void duk_to_object(duk_context *ctx, duk_idx_t index) { goto create_object; } case DUK_TAG_STRING: { - flags = DUK_HOBJECT_FLAG_EXTENSIBLE | - DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ | - DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_STRING); - proto = DUK_BIDX_STRING_PROTOTYPE; + duk_hstring *h; + h = DUK_TVAL_GET_STRING(tv); + DUK_ASSERT(h != NULL); + if (DUK_HSTRING_HAS_SYMBOL(h)) { + flags = DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_SYMBOL); + proto = DUK_BIDX_SYMBOL_PROTOTYPE; + } else { + flags = DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_STRING); + proto = DUK_BIDX_STRING_PROTOTYPE; + } goto create_object; } case DUK_TAG_OBJECT: { /* nop */ break; } +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) case DUK_TAG_BUFFER: { - /* A plain buffer coerces to a Duktape.Buffer because it's the - * object counterpart of the plain buffer value. But it might - * still make more sense to produce an ArrayBuffer here? + /* A plain buffer object coerces to a full ArrayBuffer which + * is not fully transparent behavior (ToObject() should be a + * nop for an object). This behavior matches lightfuncs which + * also coerce to an equivalent Function object. There are + * also downsides to defining ToObject(plainBuffer) as a no-op; + * for example duk_to_hobject() could result in a NULL pointer. */ + duk_hbuffer *h_buf; - duk_hbufferobject *h_bufobj; - duk_hbuffer *h_val; - - h_val = DUK_TVAL_GET_BUFFER(tv); - DUK_ASSERT(h_val != NULL); - - h_bufobj = duk_push_bufferobject_raw(ctx, - DUK_HOBJECT_FLAG_EXTENSIBLE | - DUK_HOBJECT_FLAG_BUFFEROBJECT | - DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_BUFFER), - DUK_BIDX_BUFFER_PROTOTYPE); - DUK_ASSERT(h_bufobj != NULL); - DUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE((duk_hobject *) h_bufobj)); - DUK_ASSERT(DUK_HOBJECT_IS_BUFFEROBJECT((duk_hobject *) h_bufobj)); - - h_bufobj->buf = h_val; - DUK_HBUFFER_INCREF(thr, h_val); - DUK_ASSERT(h_bufobj->offset == 0); - h_bufobj->length = (duk_uint_t) DUK_HBUFFER_GET_SIZE(h_val); - DUK_ASSERT(h_bufobj->shift == 0); - DUK_ASSERT(h_bufobj->elem_type == DUK_HBUFFEROBJECT_ELEM_UINT8); - - DUK_ASSERT_HBUFFEROBJECT_VALID(h_bufobj); + h_buf = DUK_TVAL_GET_BUFFER(tv); + DUK_ASSERT(h_buf != NULL); + duk_hbufobj_push_uint8array_from_plain(thr, h_buf); goto replace_value; } +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ case DUK_TAG_POINTER: { flags = DUK_HOBJECT_FLAG_EXTENSIBLE | DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_POINTER); @@ -17506,50 +19121,18 @@ DUK_EXTERNAL void duk_to_object(duk_context *ctx, duk_idx_t index) { case DUK_TAG_LIGHTFUNC: { /* Lightfunc coerces to a Function instance with concrete * properties. Since 'length' is virtual for Duktape/C - * functions, don't need to define that. + * functions, don't need to define that. The result is made + * extensible to mimic what happens to strings in object + * coercion: * - * The result is made extensible to mimic what happens to - * strings: * > Object.isExtensible(Object('foo')) * true */ duk_small_uint_t lf_flags; - duk_idx_t nargs; - duk_small_uint_t lf_len; duk_c_function func; - duk_hnativefunction *nf; DUK_TVAL_GET_LIGHTFUNC(tv, func, lf_flags); - - nargs = (duk_idx_t) DUK_LFUNC_FLAGS_GET_NARGS(lf_flags); - if (nargs == DUK_LFUNC_NARGS_VARARGS) { - nargs = (duk_idx_t) DUK_VARARGS; - } - flags = DUK_HOBJECT_FLAG_EXTENSIBLE | - DUK_HOBJECT_FLAG_CONSTRUCTABLE | - DUK_HOBJECT_FLAG_NATIVEFUNCTION | - DUK_HOBJECT_FLAG_NEWENV | - DUK_HOBJECT_FLAG_STRICT | - DUK_HOBJECT_FLAG_NOTAIL | - /* DUK_HOBJECT_FLAG_EXOTIC_DUKFUNC: omitted here intentionally */ - DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION); - (void) duk__push_c_function_raw(ctx, func, nargs, flags); - - lf_len = DUK_LFUNC_FLAGS_GET_LENGTH(lf_flags); - if ((duk_idx_t) lf_len != nargs) { - /* Explicit length is only needed if it differs from 'nargs'. */ - duk_push_int(ctx, (duk_int_t) lf_len); - duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_NONE); - } - duk_push_lightfunc_name(ctx, tv); - duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_NONE); - - nf = duk_get_hnativefunction(ctx, -1); - DUK_ASSERT(nf != NULL); - nf->magic = (duk_int16_t) DUK_LFUNC_FLAGS_GET_MAGIC(lf_flags); - - /* Enable DUKFUNC exotic behavior once properties are set up. */ - DUK_HOBJECT_SET_EXOTIC_DUKFUNC((duk_hobject *) nf); + duk__push_func_from_lightfunc(ctx, func, lf_flags); goto replace_value; } #if defined(DUK_USE_FASTINT) @@ -17564,6 +19147,7 @@ DUK_EXTERNAL void duk_to_object(duk_context *ctx, duk_idx_t index) { goto create_object; } } + DUK_ASSERT(duk_is_object(ctx, idx)); return; create_object: @@ -17576,49 +19160,53 @@ DUK_EXTERNAL void duk_to_object(duk_context *ctx, duk_idx_t index) { * String and buffer special behaviors are already enabled which is not * ideal, but a write to the internal value is not affected by them. */ - duk_dup(ctx, index); - duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE); + duk_dup(ctx, idx); + duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE); replace_value: - duk_replace(ctx, index); + duk_replace(ctx, idx); + DUK_ASSERT(duk_is_object(ctx, idx)); +} + +DUK_INTERNAL duk_hobject *duk_to_hobject(duk_context *ctx, duk_idx_t idx) { + duk_hobject *ret; + DUK_ASSERT_CTX_VALID(ctx); + duk_to_object(ctx, idx); + ret = duk_known_hobject(ctx, idx); + return ret; } /* * Type checking */ -DUK_LOCAL duk_bool_t duk__tag_check(duk_context *ctx, duk_idx_t index, duk_small_uint_t tag) { +DUK_LOCAL duk_bool_t duk__tag_check(duk_context *ctx, duk_idx_t idx, duk_small_uint_t tag) { duk_tval *tv; - tv = duk_get_tval(ctx, index); - if (!tv) { - return 0; - } + tv = duk_get_tval_or_unused(ctx, idx); + DUK_ASSERT(tv != NULL); return (DUK_TVAL_GET_TAG(tv) == tag); } -DUK_LOCAL duk_bool_t duk__obj_flag_any_default_false(duk_context *ctx, duk_idx_t index, duk_uint_t flag_mask) { +DUK_LOCAL duk_bool_t duk__obj_flag_any_default_false(duk_context *ctx, duk_idx_t idx, duk_uint_t flag_mask) { duk_hobject *obj; DUK_ASSERT_CTX_VALID(ctx); - obj = duk_get_hobject(ctx, index); + obj = duk_get_hobject(ctx, idx); if (obj) { return (DUK_HEAPHDR_CHECK_FLAG_BITS((duk_heaphdr *) obj, flag_mask) ? 1 : 0); } return 0; } -DUK_EXTERNAL duk_int_t duk_get_type(duk_context *ctx, duk_idx_t index) { - duk_tval *tv; - - DUK_ASSERT_CTX_VALID(ctx); +DUK_INTERNAL duk_int_t duk_get_type_tval(duk_tval *tv) { + DUK_ASSERT(tv != NULL); - tv = duk_get_tval(ctx, index); - if (!tv) { - return DUK_TYPE_NONE; - } +#if defined(DUK_USE_PACKED_TVAL) switch (DUK_TVAL_GET_TAG(tv)) { + case DUK_TAG_UNUSED: + return DUK_TYPE_NONE; case DUK_TAG_UNDEFINED: return DUK_TYPE_UNDEFINED; case DUK_TAG_NULL: @@ -17644,7 +19232,22 @@ DUK_EXTERNAL duk_int_t duk_get_type(duk_context *ctx, duk_idx_t index) { DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv)); return DUK_TYPE_NUMBER; } - DUK_UNREACHABLE(); +#else /* DUK_USE_PACKED_TVAL */ + DUK_ASSERT(DUK_TVAL_IS_VALID_TAG(tv)); + DUK_ASSERT(sizeof(duk__type_from_tag) / sizeof(duk_uint_t) == DUK_TAG_MAX - DUK_TAG_MIN + 1); + return (duk_int_t) duk__type_from_tag[DUK_TVAL_GET_TAG(tv) - DUK_TAG_MIN]; +#endif /* DUK_USE_PACKED_TVAL */ +} + +DUK_EXTERNAL duk_int_t duk_get_type(duk_context *ctx, duk_idx_t idx) { + duk_tval *tv; + + DUK_ASSERT_CTX_VALID(ctx); + + tv = duk_get_tval_or_unused(ctx, idx); + DUK_ASSERT(tv != NULL); + + return duk_get_type_tval(tv); } #if defined(DUK_USE_VERBOSE_ERRORS) && defined(DUK_USE_PARANOID_ERRORS) @@ -17661,10 +19264,10 @@ DUK_LOCAL const char *duk__type_names[] = { "lightfunc" }; -DUK_INTERNAL const char *duk_get_type_name(duk_context *ctx, duk_idx_t index) { +DUK_INTERNAL const char *duk_get_type_name(duk_context *ctx, duk_idx_t idx) { duk_int_t type_tag; - type_tag = duk_get_type(ctx, index); + type_tag = duk_get_type(ctx, idx); DUK_ASSERT(type_tag >= DUK_TYPE_MIN && type_tag <= DUK_TYPE_MAX); DUK_ASSERT(DUK_TYPE_MIN == 0 && sizeof(duk__type_names) / sizeof(const char *) == DUK_TYPE_MAX + 1); @@ -17672,22 +19275,43 @@ DUK_INTERNAL const char *duk_get_type_name(duk_context *ctx, duk_idx_t index) { } #endif -DUK_EXTERNAL duk_bool_t duk_check_type(duk_context *ctx, duk_idx_t index, duk_int_t type) { - DUK_ASSERT_CTX_VALID(ctx); +DUK_INTERNAL duk_small_uint_t duk_get_class_number(duk_context *ctx, duk_idx_t idx) { + duk_tval *tv; + duk_hobject *obj; - return (duk_get_type(ctx, index) == type) ? 1 : 0; -} + tv = duk_get_tval_or_unused(ctx, idx); + DUK_ASSERT(tv != NULL); -DUK_EXTERNAL duk_uint_t duk_get_type_mask(duk_context *ctx, duk_idx_t index) { - duk_tval *tv; + switch (DUK_TVAL_GET_TAG(tv)) { + case DUK_TAG_OBJECT: + obj = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(obj != NULL); + return DUK_HOBJECT_GET_CLASS_NUMBER(obj); + case DUK_TAG_BUFFER: + /* Buffers behave like Uint8Array objects. */ + return DUK_HOBJECT_CLASS_UINT8ARRAY; + case DUK_TAG_LIGHTFUNC: + /* Lightfuncs behave like Function objects. */ + return DUK_HOBJECT_CLASS_FUNCTION; + default: + /* Primitive or UNUSED, no class number. */ + return DUK_HOBJECT_CLASS_NONE; + } +} +DUK_EXTERNAL duk_bool_t duk_check_type(duk_context *ctx, duk_idx_t idx, duk_int_t type) { DUK_ASSERT_CTX_VALID(ctx); - tv = duk_get_tval(ctx, index); - if (!tv) { - return DUK_TYPE_MASK_NONE; - } + return (duk_get_type(ctx, idx) == type) ? 1 : 0; +} + +DUK_INTERNAL duk_uint_t duk_get_type_mask_tval(duk_tval *tv) { + DUK_ASSERT(tv != NULL); + +#if defined(DUK_USE_PACKED_TVAL) switch (DUK_TVAL_GET_TAG(tv)) { + case DUK_TAG_UNUSED: + return DUK_TYPE_MASK_NONE; case DUK_TAG_UNDEFINED: return DUK_TYPE_MASK_UNDEFINED; case DUK_TAG_NULL: @@ -17713,15 +19337,30 @@ DUK_EXTERNAL duk_uint_t duk_get_type_mask(duk_context *ctx, duk_idx_t index) { DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv)); return DUK_TYPE_MASK_NUMBER; } - DUK_UNREACHABLE(); +#else /* DUK_USE_PACKED_TVAL */ + DUK_ASSERT(DUK_TVAL_IS_VALID_TAG(tv)); + DUK_ASSERT(sizeof(duk__type_mask_from_tag) / sizeof(duk_uint_t) == DUK_TAG_MAX - DUK_TAG_MIN + 1); + return (duk_int_t) duk__type_mask_from_tag[DUK_TVAL_GET_TAG(tv) - DUK_TAG_MIN]; +#endif /* DUK_USE_PACKED_TVAL */ } -DUK_EXTERNAL duk_bool_t duk_check_type_mask(duk_context *ctx, duk_idx_t index, duk_uint_t mask) { +DUK_EXTERNAL duk_uint_t duk_get_type_mask(duk_context *ctx, duk_idx_t idx) { + duk_tval *tv; + + DUK_ASSERT_CTX_VALID(ctx); + + tv = duk_get_tval_or_unused(ctx, idx); + DUK_ASSERT(tv != NULL); + + return duk_get_type_mask_tval(tv); +} + +DUK_EXTERNAL duk_bool_t duk_check_type_mask(duk_context *ctx, duk_idx_t idx, duk_uint_t mask) { duk_hthread *thr = (duk_hthread *) ctx; DUK_ASSERT_CTX_VALID(ctx); - if (duk_get_type_mask(ctx, index) & mask) { + if (duk_get_type_mask(ctx, idx) & mask) { return 1; } if (mask & DUK_TYPE_MASK_THROW) { @@ -17731,36 +19370,22 @@ DUK_EXTERNAL duk_bool_t duk_check_type_mask(duk_context *ctx, duk_idx_t index, d return 0; } -DUK_EXTERNAL duk_bool_t duk_is_undefined(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_bool_t duk_is_undefined(duk_context *ctx, duk_idx_t idx) { DUK_ASSERT_CTX_VALID(ctx); - return duk__tag_check(ctx, index, DUK_TAG_UNDEFINED); + return duk__tag_check(ctx, idx, DUK_TAG_UNDEFINED); } -DUK_EXTERNAL duk_bool_t duk_is_null(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_bool_t duk_is_null(duk_context *ctx, duk_idx_t idx) { DUK_ASSERT_CTX_VALID(ctx); - return duk__tag_check(ctx, index, DUK_TAG_NULL); + return duk__tag_check(ctx, idx, DUK_TAG_NULL); } -DUK_EXTERNAL duk_bool_t duk_is_null_or_undefined(duk_context *ctx, duk_idx_t index) { - duk_tval *tv; - duk_small_uint_t tag; - +DUK_EXTERNAL duk_bool_t duk_is_boolean(duk_context *ctx, duk_idx_t idx) { DUK_ASSERT_CTX_VALID(ctx); - - tv = duk_get_tval(ctx, index); - if (!tv) { - return 0; - } - tag = DUK_TVAL_GET_TAG(tv); - return (tag == DUK_TAG_UNDEFINED) || (tag == DUK_TAG_NULL); + return duk__tag_check(ctx, idx, DUK_TAG_BOOLEAN); } -DUK_EXTERNAL duk_bool_t duk_is_boolean(duk_context *ctx, duk_idx_t index) { - DUK_ASSERT_CTX_VALID(ctx); - return duk__tag_check(ctx, index, DUK_TAG_BOOLEAN); -} - -DUK_EXTERNAL duk_bool_t duk_is_number(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_bool_t duk_is_number(duk_context *ctx, duk_idx_t idx) { duk_tval *tv; DUK_ASSERT_CTX_VALID(ctx); @@ -17770,16 +19395,14 @@ DUK_EXTERNAL duk_bool_t duk_is_number(duk_context *ctx, duk_idx_t index) { * tag in the 8-byte representation. */ - /* XXX: shorter version for 12-byte representation? */ + /* XXX: shorter version for unpacked representation? */ - tv = duk_get_tval(ctx, index); - if (!tv) { - return 0; - } + tv = duk_get_tval_or_unused(ctx, idx); + DUK_ASSERT(tv != NULL); return DUK_TVAL_IS_NUMBER(tv); } -DUK_EXTERNAL duk_bool_t duk_is_nan(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_bool_t duk_is_nan(duk_context *ctx, 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 @@ -17790,101 +19413,149 @@ DUK_EXTERNAL duk_bool_t duk_is_nan(duk_context *ctx, duk_idx_t index) { DUK_ASSERT_CTX_VALID(ctx); - tv = duk_get_tval(ctx, index); - if (!tv || !DUK_TVAL_IS_NUMBER(tv)) { + tv = duk_get_tval_or_unused(ctx, idx); + DUK_ASSERT(tv != NULL); + + /* XXX: for packed duk_tval an explicit "is number" check is unnecessary */ + if (!DUK_TVAL_IS_NUMBER(tv)) { return 0; } return DUK_ISNAN(DUK_TVAL_GET_NUMBER(tv)); } -DUK_EXTERNAL duk_bool_t duk_is_string(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_bool_t duk_is_string(duk_context *ctx, duk_idx_t idx) { DUK_ASSERT_CTX_VALID(ctx); - return duk__tag_check(ctx, index, DUK_TAG_STRING); + return duk__tag_check(ctx, idx, DUK_TAG_STRING); } -DUK_EXTERNAL duk_bool_t duk_is_object(duk_context *ctx, duk_idx_t index) { +DUK_INTERNAL duk_bool_t duk_is_string_notsymbol(duk_context *ctx, duk_idx_t idx) { DUK_ASSERT_CTX_VALID(ctx); - return duk__tag_check(ctx, index, DUK_TAG_OBJECT); + return duk_get_hstring_notsymbol(ctx, idx) != NULL; } -DUK_EXTERNAL duk_bool_t duk_is_buffer(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_bool_t duk_is_object(duk_context *ctx, duk_idx_t idx) { DUK_ASSERT_CTX_VALID(ctx); - return duk__tag_check(ctx, index, DUK_TAG_BUFFER); + return duk__tag_check(ctx, idx, DUK_TAG_OBJECT); } -DUK_EXTERNAL duk_bool_t duk_is_pointer(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_bool_t duk_is_buffer(duk_context *ctx, duk_idx_t idx) { DUK_ASSERT_CTX_VALID(ctx); - return duk__tag_check(ctx, index, DUK_TAG_POINTER); + return duk__tag_check(ctx, idx, DUK_TAG_BUFFER); } -DUK_EXTERNAL duk_bool_t duk_is_lightfunc(duk_context *ctx, duk_idx_t index) { +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_EXTERNAL duk_bool_t duk_is_buffer_data(duk_context *ctx, duk_idx_t idx) { + duk_tval *tv; + DUK_ASSERT_CTX_VALID(ctx); - return duk__tag_check(ctx, index, DUK_TAG_LIGHTFUNC); + + tv = duk_get_tval_or_unused(ctx, idx); + DUK_ASSERT(tv != NULL); + if (DUK_TVAL_IS_BUFFER(tv)) { + return 1; + } else if (DUK_TVAL_IS_OBJECT(tv)) { + duk_hobject *h = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(h != NULL); + if (DUK_HOBJECT_IS_BUFOBJ(h)) { + return 1; + } + } + return 0; +} +#else /* DUK_USE_BUFFEROBJECT_SUPPORT */ +DUK_EXTERNAL duk_bool_t duk_is_buffer_data(duk_context *ctx, duk_idx_t idx) { + DUK_ASSERT_CTX_VALID(ctx); + + return duk_is_buffer(ctx, idx); +} + +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +DUK_EXTERNAL duk_bool_t duk_is_pointer(duk_context *ctx, duk_idx_t idx) { + DUK_ASSERT_CTX_VALID(ctx); + return duk__tag_check(ctx, idx, DUK_TAG_POINTER); +} + +DUK_EXTERNAL duk_bool_t duk_is_lightfunc(duk_context *ctx, duk_idx_t idx) { + DUK_ASSERT_CTX_VALID(ctx); + return duk__tag_check(ctx, idx, DUK_TAG_LIGHTFUNC); +} + +DUK_EXTERNAL duk_bool_t duk_is_symbol(duk_context *ctx, duk_idx_t idx) { + duk_hstring *h; + + DUK_ASSERT_CTX_VALID(ctx); + h = duk_get_hstring(ctx, idx); + if (h != NULL && DUK_HSTRING_HAS_SYMBOL(h)) { + return 1; + } + return 0; } -DUK_EXTERNAL duk_bool_t duk_is_array(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_bool_t duk_is_array(duk_context *ctx, duk_idx_t idx) { duk_hobject *obj; DUK_ASSERT_CTX_VALID(ctx); - obj = duk_get_hobject(ctx, index); + obj = duk_get_hobject(ctx, idx); if (obj) { return (DUK_HOBJECT_GET_CLASS_NUMBER(obj) == DUK_HOBJECT_CLASS_ARRAY ? 1 : 0); } return 0; } -DUK_EXTERNAL duk_bool_t duk_is_function(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_bool_t duk_is_function(duk_context *ctx, duk_idx_t idx) { duk_tval *tv; DUK_ASSERT_CTX_VALID(ctx); - tv = duk_get_tval(ctx, index); - if (tv && DUK_TVAL_IS_LIGHTFUNC(tv)) { + tv = duk_get_tval_or_unused(ctx, idx); + if (DUK_TVAL_IS_LIGHTFUNC(tv)) { return 1; } return duk__obj_flag_any_default_false(ctx, - index, - DUK_HOBJECT_FLAG_COMPILEDFUNCTION | - DUK_HOBJECT_FLAG_NATIVEFUNCTION | - DUK_HOBJECT_FLAG_BOUND); + idx, + DUK_HOBJECT_FLAG_COMPFUNC | + DUK_HOBJECT_FLAG_NATFUNC | + DUK_HOBJECT_FLAG_BOUNDFUNC); } -DUK_EXTERNAL duk_bool_t duk_is_c_function(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_bool_t duk_is_c_function(duk_context *ctx, duk_idx_t idx) { DUK_ASSERT_CTX_VALID(ctx); return duk__obj_flag_any_default_false(ctx, - index, - DUK_HOBJECT_FLAG_NATIVEFUNCTION); + idx, + DUK_HOBJECT_FLAG_NATFUNC); } -DUK_EXTERNAL duk_bool_t duk_is_ecmascript_function(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_bool_t duk_is_ecmascript_function(duk_context *ctx, duk_idx_t idx) { DUK_ASSERT_CTX_VALID(ctx); return duk__obj_flag_any_default_false(ctx, - index, - DUK_HOBJECT_FLAG_COMPILEDFUNCTION); + idx, + DUK_HOBJECT_FLAG_COMPFUNC); } -DUK_EXTERNAL duk_bool_t duk_is_bound_function(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_bool_t duk_is_bound_function(duk_context *ctx, duk_idx_t idx) { DUK_ASSERT_CTX_VALID(ctx); return duk__obj_flag_any_default_false(ctx, - index, - DUK_HOBJECT_FLAG_BOUND); + idx, + DUK_HOBJECT_FLAG_BOUNDFUNC); } -DUK_EXTERNAL duk_bool_t duk_is_thread(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_bool_t duk_is_thread(duk_context *ctx, duk_idx_t idx) { DUK_ASSERT_CTX_VALID(ctx); return duk__obj_flag_any_default_false(ctx, - index, + idx, DUK_HOBJECT_FLAG_THREAD); } -DUK_EXTERNAL duk_bool_t duk_is_fixed_buffer(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_bool_t duk_is_fixed_buffer(duk_context *ctx, duk_idx_t idx) { duk_tval *tv; DUK_ASSERT_CTX_VALID(ctx); - tv = duk_get_tval(ctx, index); - if (tv && DUK_TVAL_IS_BUFFER(tv)) { + tv = duk_get_tval_or_unused(ctx, idx); + DUK_ASSERT(tv != NULL); + if (DUK_TVAL_IS_BUFFER(tv)) { duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv); DUK_ASSERT(h != NULL); return (DUK_HBUFFER_HAS_DYNAMIC(h) ? 0 : 1); @@ -17892,13 +19563,14 @@ DUK_EXTERNAL duk_bool_t duk_is_fixed_buffer(duk_context *ctx, duk_idx_t index) { return 0; } -DUK_EXTERNAL duk_bool_t duk_is_dynamic_buffer(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_bool_t duk_is_dynamic_buffer(duk_context *ctx, duk_idx_t idx) { duk_tval *tv; DUK_ASSERT_CTX_VALID(ctx); - tv = duk_get_tval(ctx, index); - if (tv && DUK_TVAL_IS_BUFFER(tv)) { + tv = duk_get_tval_or_unused(ctx, idx); + DUK_ASSERT(tv != NULL); + if (DUK_TVAL_IS_BUFFER(tv)) { duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv); DUK_ASSERT(h != NULL); return (DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h) ? 1 : 0); @@ -17906,13 +19578,14 @@ DUK_EXTERNAL duk_bool_t duk_is_dynamic_buffer(duk_context *ctx, duk_idx_t index) return 0; } -DUK_EXTERNAL duk_bool_t duk_is_external_buffer(duk_context *ctx, duk_idx_t index) { +DUK_EXTERNAL duk_bool_t duk_is_external_buffer(duk_context *ctx, duk_idx_t idx) { duk_tval *tv; DUK_ASSERT_CTX_VALID(ctx); - tv = duk_get_tval(ctx, index); - if (tv && DUK_TVAL_IS_BUFFER(tv)) { + tv = duk_get_tval_or_unused(ctx, idx); + DUK_ASSERT(tv != NULL); + if (DUK_TVAL_IS_BUFFER(tv)) { duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv); DUK_ASSERT(h != NULL); return (DUK_HBUFFER_HAS_DYNAMIC(h) && DUK_HBUFFER_HAS_EXTERNAL(h) ? 1 : 0); @@ -17920,14 +19593,14 @@ DUK_EXTERNAL duk_bool_t duk_is_external_buffer(duk_context *ctx, duk_idx_t index return 0; } -DUK_EXTERNAL duk_errcode_t duk_get_error_code(duk_c |