summaryrefslogtreecommitdiff
path: root/content/handlers/javascript
diff options
context:
space:
mode:
Diffstat (limited to 'content/handlers/javascript')
-rw-r--r--content/handlers/javascript/duktape/duk_config.h120
-rw-r--r--content/handlers/javascript/duktape/duktape.c6038
-rw-r--r--content/handlers/javascript/duktape/duktape.h108
3 files changed, 3974 insertions, 2292 deletions
diff --git a/content/handlers/javascript/duktape/duk_config.h b/content/handlers/javascript/duktape/duk_config.h
index 7ee0b13ba..40df0fe8e 100644
--- a/content/handlers/javascript/duktape/duk_config.h
+++ b/content/handlers/javascript/duktape/duk_config.h
@@ -218,12 +218,6 @@
#define DUK_F_UNIX
#endif
-/* C++ */
-#undef DUK_F_CPP
-#if defined(__cplusplus)
-#define DUK_F_CPP
-#endif
-
/* Intel x86 (32-bit), x64 (64-bit) or x32 (64-bit but 32-bit pointers),
* define only one of DUK_F_X86, DUK_F_X64, DUK_F_X32.
* https://sites.google.com/site/x32abi/
@@ -301,6 +295,12 @@
#define DUK_F_CLANG
#endif
+/* C++ */
+#undef DUK_F_CPP
+#if defined(__cplusplus)
+#define DUK_F_CPP
+#endif
+
/* C99 or above */
#undef DUK_F_C99
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
@@ -836,9 +836,7 @@
#include <stdint.h>
#endif
-#if defined(DUK_F_CPP)
-#include <exception> /* std::exception */
-#endif
+/* <exception> is only included if needed, based on DUK_USE_xxx flags. */
/*
* Architecture autodetection
@@ -850,13 +848,16 @@
#if !defined(DUK_USE_BYTEORDER)
#define DUK_USE_BYTEORDER 1
#endif
-/* XXX: This is technically not guaranteed because it's possible to configure
- * an x86 to require aligned accesses with Alignment Check (AC) flag.
+
+#define DUK_USE_PACKED_TVAL
+
+/* FreeBSD, -m32, and clang prior to 5.0 has union aliasing issues which
+ * break duk_tval copying. Disable packed duk_tval automatically.
*/
-#if !defined(DUK_USE_ALIGN_BY)
-#define DUK_USE_ALIGN_BY 1
+#if defined(DUK_F_FREEBSD) && defined(DUK_F_X86) && \
+ defined(__clang__) && defined(__clang_major__) && (__clang_major__ < 5)
+#undef DUK_USE_PACKED_TVAL
#endif
-#define DUK_USE_PACKED_TVAL
#define DUK_F_PACKED_TVAL_PROVIDED
#elif defined(DUK_F_X64)
/* --- x64 --- */
@@ -864,12 +865,6 @@
#if !defined(DUK_USE_BYTEORDER)
#define DUK_USE_BYTEORDER 1
#endif
-/* XXX: This is technically not guaranteed because it's possible to configure
- * an x86 to require aligned accesses with Alignment Check (AC) flag.
- */
-#if !defined(DUK_USE_ALIGN_BY)
-#define DUK_USE_ALIGN_BY 1
-#endif
#undef DUK_USE_PACKED_TVAL
#define DUK_F_PACKED_TVAL_PROVIDED
#elif defined(DUK_F_X32)
@@ -878,48 +873,30 @@
#if !defined(DUK_USE_BYTEORDER)
#define DUK_USE_BYTEORDER 1
#endif
-/* XXX: This is technically not guaranteed because it's possible to configure
- * an x86 to require aligned accesses with Alignment Check (AC) flag.
- */
-#if !defined(DUK_USE_ALIGN_BY)
-#define DUK_USE_ALIGN_BY 1
-#endif
#define DUK_USE_PACKED_TVAL
#define DUK_F_PACKED_TVAL_PROVIDED
#elif defined(DUK_F_ARM32)
/* --- ARM 32-bit --- */
#define DUK_USE_ARCH_STRING "arm32"
/* Byte order varies, so rely on autodetect. */
-#if !defined(DUK_USE_ALIGN_BY)
-#define DUK_USE_ALIGN_BY 8
-#endif
#define DUK_USE_PACKED_TVAL
#define DUK_F_PACKED_TVAL_PROVIDED
#elif defined(DUK_F_ARM64)
/* --- ARM 64-bit --- */
#define DUK_USE_ARCH_STRING "arm64"
/* Byte order varies, so rely on autodetect. */
-#if !defined(DUK_USE_ALIGN_BY)
-#define DUK_USE_ALIGN_BY 8
-#endif
#undef DUK_USE_PACKED_TVAL
#define DUK_F_PACKED_TVAL_PROVIDED
#elif defined(DUK_F_MIPS32)
/* --- MIPS 32-bit --- */
#define DUK_USE_ARCH_STRING "mips32"
/* MIPS byte order varies so rely on autodetection. */
-#if !defined(DUK_USE_ALIGN_BY)
-#define DUK_USE_ALIGN_BY 8
-#endif
#define DUK_USE_PACKED_TVAL
#define DUK_F_PACKED_TVAL_PROVIDED
#elif defined(DUK_F_MIPS64)
/* --- MIPS 64-bit --- */
#define DUK_USE_ARCH_STRING "mips64"
/* MIPS byte order varies so rely on autodetection. */
-#if !defined(DUK_USE_ALIGN_BY)
-#define DUK_USE_ALIGN_BY 8
-#endif
#undef DUK_USE_PACKED_TVAL
#define DUK_F_PACKED_TVAL_PROVIDED
#elif defined(DUK_F_PPC32)
@@ -928,9 +905,6 @@
#if !defined(DUK_USE_BYTEORDER)
#define DUK_USE_BYTEORDER 3
#endif
-#if !defined(DUK_USE_ALIGN_BY)
-#define DUK_USE_ALIGN_BY 8
-#endif
#define DUK_USE_PACKED_TVAL
#define DUK_F_PACKED_TVAL_PROVIDED
#elif defined(DUK_F_PPC64)
@@ -939,39 +913,24 @@
#if !defined(DUK_USE_BYTEORDER)
#define DUK_USE_BYTEORDER 3
#endif
-#if !defined(DUK_USE_ALIGN_BY)
-#define DUK_USE_ALIGN_BY 8
-#endif
#undef DUK_USE_PACKED_TVAL
#define DUK_F_PACKED_TVAL_PROVIDED
#elif defined(DUK_F_SPARC32)
/* --- SPARC 32-bit --- */
#define DUK_USE_ARCH_STRING "sparc32"
/* SPARC byte order varies so rely on autodetection. */
-#if !defined(DUK_USE_ALIGN_BY)
-#define DUK_USE_ALIGN_BY 8
-#endif
#define DUK_USE_PACKED_TVAL
#define DUK_F_PACKED_TVAL_PROVIDED
#elif defined(DUK_F_SPARC64)
/* --- SPARC 64-bit --- */
#define DUK_USE_ARCH_STRING "sparc64"
/* SPARC byte order varies so rely on autodetection. */
-#if !defined(DUK_USE_ALIGN_BY)
-#define DUK_USE_ALIGN_BY 8
-#endif
#undef DUK_USE_PACKED_TVAL
#define DUK_F_PACKED_TVAL_PROVIDED
#elif defined(DUK_F_SUPERH)
/* --- SuperH --- */
#define DUK_USE_ARCH_STRING "sh"
/* Byte order varies, rely on autodetection. */
-/* Based on 'make checkalign' there are no alignment requirements on
- * Linux SH4, but align by 4 is probably a good basic default.
- */
-#if !defined(DUK_USE_ALIGN_BY)
-#define DUK_USE_ALIGN_BY 4
-#endif
#define DUK_USE_PACKED_TVAL
#define DUK_F_PACKED_TVAL_PROVIDED
#elif defined(DUK_F_M68K)
@@ -980,9 +939,6 @@
#if !defined(DUK_USE_BYTEORDER)
#define DUK_USE_BYTEORDER 3
#endif
-#if !defined(DUK_USE_ALIGN_BY)
-#define DUK_USE_ALIGN_BY 8
-#endif
#define DUK_USE_PACKED_TVAL
#define DUK_F_PACKED_TVAL_PROVIDED
#elif defined(DUK_F_EMSCRIPTEN)
@@ -991,9 +947,6 @@
#if !defined(DUK_USE_BYTEORDER)
#define DUK_USE_BYTEORDER 1
#endif
-#if !defined(DUK_USE_ALIGN_BY)
-#define DUK_USE_ALIGN_BY 8
-#endif
#undef DUK_USE_PACKED_TVAL
#define DUK_F_PACKED_TVAL_PROVIDED
#else
@@ -2540,10 +2493,13 @@ typedef struct duk_hthread duk_context;
*
* Assume unaligned accesses are not supported unless specifically allowed
* in the target platform. Some platforms may support unaligned accesses
- * but alignment to 4 or 8 may still be desirable.
+ * but alignment to 4 or 8 may still be desirable. Note that unaligned
+ * accesses (and even pointers) relative to natural alignment (regardless
+ * of target alignment) are technically undefined behavior and thus
+ * compiler/architecture specific.
*/
-/* If not provided, use safe default for alignment. */
+/* If not forced, use safe default for alignment. */
#if !defined(DUK_USE_ALIGN_BY)
#define DUK_USE_ALIGN_BY 8
#endif
@@ -2595,6 +2551,7 @@ typedef struct duk_hthread duk_context;
*/
#define DUK_CAUSE_SEGFAULT() do { *((volatile duk_uint32_t *) NULL) = (duk_uint32_t) 0xdeadbeefUL; } while (0)
#endif
+
#if !defined(DUK_UNREF)
/* Macro for suppressing warnings for potentially unreferenced variables.
* The variables can be actually unreferenced or unreferenced in some
@@ -2604,9 +2561,24 @@ typedef struct duk_hthread duk_context;
*/
#define DUK_UNREF(x) do { (void) (x); } while (0)
#endif
-#if !defined(DUK_NORETURN)
+
+/* Fillin for DUK_NORETURN; DUK_WO_NORETURN() is used to insert dummy
+ * dummy statements after noreturn calls to silence harmless compiler
+ * warnings, e.g.:
+ *
+ * DUK_ERROR_TYPE(thr, "aiee");
+ * DUK_WO_NORETURN(return 0;);
+ *
+ * Statements inside DUK_WO_NORETURN() must NEVER be actually reachable,
+ * and they're only included to satisfy the compiler.
+ */
+#if defined(DUK_NORETURN)
+#define DUK_WO_NORETURN(stmt) do { } while (0)
+#else
#define DUK_NORETURN(decl) decl
+#define DUK_WO_NORETURN(stmt) do { stmt } while (0)
#endif
+
#if !defined(DUK_UNREACHABLE)
/* Don't know how to declare unreachable point, so don't do it; this
* may cause some spurious compilation warnings (e.g. "variable used
@@ -2614,6 +2586,7 @@ typedef struct duk_hthread duk_context;
*/
#define DUK_UNREACHABLE() do { } while (0)
#endif
+
#if !defined(DUK_LOSE_CONST)
/* Convert any input pointer into a "void *", losing a const qualifier.
* This is not fully portable because casting through duk_uintptr_t may
@@ -2781,8 +2754,8 @@ typedef struct duk_hthread duk_context;
#if defined(DUK_F_PACKED_TVAL_POSSIBLE)
#define DUK_USE_PACKED_TVAL
#endif
-
#undef DUK_F_PACKED_TVAL_POSSIBLE
+
#endif /* DUK_F_PACKED_TVAL_PROVIDED */
/* Object property allocation layout has implications for memory and code
* footprint and generated code size/speed. The best layout also depends
@@ -2817,6 +2790,7 @@ typedef struct duk_hthread duk_context;
* Autogenerated defaults
*/
+#undef DUK_USE_ALLOW_UNDEFINED_BEHAVIOR
#define DUK_USE_ARRAY_BUILTIN
#define DUK_USE_ARRAY_FASTPATH
#define DUK_USE_ARRAY_PROP_FASTPATH
@@ -2825,6 +2799,7 @@ typedef struct duk_hthread duk_context;
#define DUK_USE_AUGMENT_ERROR_THROW
#define DUK_USE_AVOID_PLATFORM_FUNCPTRS
#define DUK_USE_BASE64_FASTPATH
+#define DUK_USE_BASE64_SUPPORT
#define DUK_USE_BOOLEAN_BUILTIN
#define DUK_USE_BUFFEROBJECT_SUPPORT
#undef DUK_USE_BUFLEN16
@@ -2902,6 +2877,7 @@ typedef struct duk_hthread duk_context;
#undef DUK_USE_HEAPPTR_DEC16
#undef DUK_USE_HEAPPTR_ENC16
#define DUK_USE_HEX_FASTPATH
+#define DUK_USE_HEX_SUPPORT
#define DUK_USE_HOBJECT_ARRAY_ABANDON_LIMIT 2
#define DUK_USE_HOBJECT_ARRAY_FAST_RESIZE_LIMIT 9
#define DUK_USE_HOBJECT_ARRAY_MINGROW_ADD 16
@@ -2932,11 +2908,10 @@ typedef struct duk_hthread duk_context;
#define DUK_USE_JX
#define DUK_USE_LEXER_SLIDING_WINDOW
#undef DUK_USE_LIGHTFUNC_BUILTINS
+#define DUK_USE_LITCACHE_SIZE 256
#define DUK_USE_MARK_AND_SWEEP_RECLIMIT 256
#define DUK_USE_MATH_BUILTIN
#define DUK_USE_NATIVE_CALL_RECLIMIT 1000
-#define DUK_USE_NONSTD_ARRAY_CONCAT_TRAILER
-#define DUK_USE_NONSTD_ARRAY_MAP_TRAILER
#define DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT
#undef DUK_USE_NONSTD_FUNC_CALLER_PROPERTY
#undef DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY
@@ -3018,6 +2993,15 @@ typedef struct duk_hthread duk_context;
/* __OVERRIDE_DEFINES__ */
/*
+ * Conditional includes
+ */
+
+#if defined(DUK_F_CPP) && defined(DUK_USE_CPP_EXCEPTIONS)
+#include <exception> /* std::exception */
+#include <stdexcept> /* std::runtime_error */
+#endif
+
+/*
* Date provider selection
*
* User may define DUK_USE_DATE_GET_NOW() etc directly, in which case we'll
diff --git a/content/handlers/javascript/duktape/duktape.c b/content/handlers/javascript/duktape/duktape.c
index dbebee282..6224aa2c6 100644
--- a/content/handlers/javascript/duktape/duktape.c
+++ b/content/handlers/javascript/duktape/duktape.c
@@ -1,7 +1,5 @@
-/* Omit from static analysis. */
-#ifndef __clang_analyzer__
/*
- * Single source autogenerated distributable for Duktape 2.2.1.
+ * Single source autogenerated distributable for Duktape 2.3.0.
*
* Git commit external (external).
* Git branch external.
@@ -18,7 +16,7 @@
*
* (http://opensource.org/licenses/MIT)
*
-* Copyright (c) 2013-2017 by Duktape authors (see AUTHORS.rst)
+* Copyright (c) 2013-2018 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
@@ -89,6 +87,14 @@
* * Steven Don (https://github.com/shdon)
* * Simon Stone (https://github.com/sstone1)
* * \J. McC. (https://github.com/jmhmccr)
+* * Jakub Nowakowski (https://github.com/jimvonmoon)
+* * Tommy Nguyen (https://github.com/tn0502)
+* * Fabrice Fontaine (https://github.com/ffontaine)
+* * Christopher Hiller (https://github.com/boneskull)
+* * Gonzalo Diethelm (https://github.com/gonzus)
+* * Michal Kasperek (https://github.com/michalkas)
+* * Andrew Janke (https://github.com/apjanke)
+* * Steve Fan (https://github.com/stevefan1999)
*
* Other contributions
* ===================
@@ -127,6 +133,8 @@
* * https://github.com/chris-y
* * Laurent Zubiaur (https://github.com/lzubiaur)
* * Neil Kolban (https://github.com/nkolban)
+* * Wilhelm Wanecek (https://github.com/wanecek)
+* * Andrew Janke (https://github.com/apjanke)
*
* If you are accidentally missing from this list, send me an e-mail
* (``sami.vaarala@iki.fi``) and I'll fix the omission.
@@ -665,20 +673,32 @@ struct duk_jmpbuf {
#endif /* DUK_JMPBUF_H_INCLUDED */
/* #include duk_exception.h */
/*
- * Exception for Duktape internal throws when C++ exceptions are used
+ * Exceptions for Duktape internal throws when C++ exceptions are used
* for long control transfers.
- *
- * Doesn't inherit from any exception base class to minimize the chance
- * that user code would accidentally catch this exception.
*/
#if !defined(DUK_EXCEPTION_H_INCLUDED)
#define DUK_EXCEPTION_H_INCLUDED
#if defined(DUK_USE_CPP_EXCEPTIONS)
+/* Internal exception used as a setjmp-longjmp replacement. User code should
+ * NEVER see or catch this exception, so it doesn't inherit from any base
+ * class which should minimize the chance of user code accidentally catching
+ * the exception.
+ */
class duk_internal_exception {
/* intentionally empty */
};
+
+/* Fatal error, thrown as a specific C++ exception with C++ exceptions
+ * enabled. It is unsafe to continue; doing so may cause crashes or memory
+ * leaks. This is intended to be either uncaught, or caught by user code
+ * aware of the "unsafe to continue" semantics.
+ */
+class duk_fatal_exception : public virtual std::runtime_error {
+ public:
+ duk_fatal_exception(const char *message) : std::runtime_error(message) {}
+};
#endif
#endif /* DUK_EXCEPTION_H_INCLUDED */
@@ -729,8 +749,9 @@ struct duk_breakpoint;
struct duk_activation;
struct duk_catcher;
-struct duk_strcache;
struct duk_ljstate;
+struct duk_strcache_entry;
+struct duk_litcache_entry;
struct duk_strtab_entry;
#if defined(DUK_USE_DEBUG)
@@ -789,8 +810,9 @@ typedef struct duk_breakpoint duk_breakpoint;
typedef struct duk_activation duk_activation;
typedef struct duk_catcher duk_catcher;
-typedef struct duk_strcache duk_strcache;
typedef struct duk_ljstate duk_ljstate;
+typedef struct duk_strcache_entry duk_strcache_entry;
+typedef struct duk_litcache_entry duk_litcache_entry;
typedef struct duk_strtab_entry duk_strtab_entry;
#if defined(DUK_USE_DEBUG)
@@ -1401,7 +1423,7 @@ typedef struct {
#if 0
DUK_INTERNAL_DECL duk_double_t duk_tval_get_number_unpacked(duk_tval *tv);
#endif
-DUK_INTERNAL_DECL DUK_INLINE duk_double_t duk_tval_get_number_unpacked_fastint(duk_tval *tv);
+DUK_INTERNAL_DECL duk_double_t duk_tval_get_number_unpacked_fastint(duk_tval *tv);
#endif
#endif /* DUK_USE_PACKED_TVAL */
@@ -1443,7 +1465,7 @@ DUK_INTERNAL_DECL DUK_INLINE duk_double_t duk_tval_get_number_unpacked_fastint(d
#define DUK_FASTINT_MAX (DUK_I64_CONSTANT(0x7fffffffffff))
#define DUK_FASTINT_BITS 48
-DUK_INTERNAL_DECL DUK_INLINE void duk_tval_set_number_chkfast_fast(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
@@ -1687,278 +1709,290 @@ DUK_INTERNAL_DECL void duk_tval_set_number_chkfast_slow(duk_tval *tv, duk_double
#define DUK_STRIDX_OWN_KEYS 75 /* '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 76 /* 'setPrototypeOf' */
+#define DUK_STRIDX_WELLKNOWN_SYMBOL_TO_PRIMITIVE 76 /* '\x81Symbol.toPrimitive\xff' */
+#define DUK_HEAP_STRING_WELLKNOWN_SYMBOL_TO_PRIMITIVE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WELLKNOWN_SYMBOL_TO_PRIMITIVE)
+#define DUK_HTHREAD_STRING_WELLKNOWN_SYMBOL_TO_PRIMITIVE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WELLKNOWN_SYMBOL_TO_PRIMITIVE)
+#define DUK_STRIDX_WELLKNOWN_SYMBOL_HAS_INSTANCE 77 /* '\x81Symbol.hasInstance\xff' */
+#define DUK_HEAP_STRING_WELLKNOWN_SYMBOL_HAS_INSTANCE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WELLKNOWN_SYMBOL_HAS_INSTANCE)
+#define DUK_HTHREAD_STRING_WELLKNOWN_SYMBOL_HAS_INSTANCE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WELLKNOWN_SYMBOL_HAS_INSTANCE)
+#define DUK_STRIDX_WELLKNOWN_SYMBOL_TO_STRING_TAG 78 /* '\x81Symbol.toStringTag\xff' */
+#define DUK_HEAP_STRING_WELLKNOWN_SYMBOL_TO_STRING_TAG(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WELLKNOWN_SYMBOL_TO_STRING_TAG)
+#define DUK_HTHREAD_STRING_WELLKNOWN_SYMBOL_TO_STRING_TAG(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WELLKNOWN_SYMBOL_TO_STRING_TAG)
+#define DUK_STRIDX_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE 79 /* '\x81Symbol.isConcatSpreadable\xff' */
+#define DUK_HEAP_STRING_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE)
+#define DUK_HTHREAD_STRING_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE)
+#define DUK_STRIDX_SET_PROTOTYPE_OF 80 /* '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__ 77 /* '__proto__' */
+#define DUK_STRIDX___PROTO__ 81 /* '__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_TO_STRING 78 /* 'toString' */
+#define DUK_STRIDX_TO_STRING 82 /* '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 79 /* 'toJSON' */
+#define DUK_STRIDX_TO_JSON 83 /* '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 80 /* 'type' */
+#define DUK_STRIDX_TYPE 84 /* '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 81 /* 'data' */
+#define DUK_STRIDX_DATA 85 /* '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 82 /* 'length' */
+#define DUK_STRIDX_LENGTH 86 /* '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_SET 83 /* 'set' */
+#define DUK_STRIDX_SET 87 /* '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 84 /* 'stack' */
+#define DUK_STRIDX_STACK 88 /* '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 85 /* 'pc' */
+#define DUK_STRIDX_PC 89 /* '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 86 /* 'lineNumber' */
+#define DUK_STRIDX_LINE_NUMBER 90 /* '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 87 /* '\x82Tracedata' */
+#define DUK_STRIDX_INT_TRACEDATA 91 /* '\x82Tracedata' */
#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 88 /* 'name' */
+#define DUK_STRIDX_NAME 92 /* '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 89 /* 'fileName' */
+#define DUK_STRIDX_FILE_NAME 93 /* '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_POINTER 90 /* 'pointer' */
+#define DUK_STRIDX_LC_POINTER 94 /* '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_TARGET 91 /* '\x82Target' */
+#define DUK_STRIDX_INT_TARGET 95 /* '\x82Target' */
#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_NEXT 92 /* '\x82Next' */
+#define DUK_STRIDX_INT_NEXT 96 /* '\x82Next' */
#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 93 /* '\x82Bytecode' */
+#define DUK_STRIDX_INT_BYTECODE 97 /* '\x82Bytecode' */
#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 94 /* '\x82Formals' */
+#define DUK_STRIDX_INT_FORMALS 98 /* '\x82Formals' */
#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 95 /* '\x82Varmap' */
+#define DUK_STRIDX_INT_VARMAP 99 /* '\x82Varmap' */
#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_SOURCE 96 /* '\x82Source' */
+#define DUK_STRIDX_INT_SOURCE 100 /* '\x82Source' */
#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 97 /* '\x82Pc2line' */
+#define DUK_STRIDX_INT_PC2LINE 101 /* '\x82Pc2line' */
#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_MAP 98 /* '\x82Map' */
+#define DUK_STRIDX_INT_MAP 102 /* '\x82Map' */
#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_VARENV 99 /* '\x82Varenv' */
+#define DUK_STRIDX_INT_VARENV 103 /* '\x82Varenv' */
#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 100 /* '\x82Finalizer' */
+#define DUK_STRIDX_INT_FINALIZER 104 /* '\x82Finalizer' */
#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_VALUE 101 /* '\x82Value' */
+#define DUK_STRIDX_INT_VALUE 105 /* '\x82Value' */
#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_COMPILE 102 /* '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 103 /* '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 104 /* '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 105 /* '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_ENV 106 /* '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 107 /* '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 108 /* '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 109 /* '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 110 /* '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_JSON_EXT_UNDEFINED 111 /* '{"_undef":true}' */
+#define DUK_STRIDX_JSON_EXT_UNDEFINED 115 /* '{"_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 112 /* '{"_nan":true}' */
+#define DUK_STRIDX_JSON_EXT_NAN 116 /* '{"_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 113 /* '{"_inf":true}' */
+#define DUK_STRIDX_JSON_EXT_POSINF 117 /* '{"_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 114 /* '{"_ninf":true}' */
+#define DUK_STRIDX_JSON_EXT_NEGINF 118 /* '{"_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 115 /* '{"_func":true}' */
+#define DUK_STRIDX_JSON_EXT_FUNCTION1 119 /* '{"_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 116 /* '{_func:true}' */
+#define DUK_STRIDX_JSON_EXT_FUNCTION2 120 /* '{_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 117 /* 'break' */
+#define DUK_STRIDX_BREAK 121 /* '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 118 /* 'case' */
+#define DUK_STRIDX_CASE 122 /* '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 119 /* 'catch' */
+#define DUK_STRIDX_CATCH 123 /* '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 120 /* 'continue' */
+#define DUK_STRIDX_CONTINUE 124 /* '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 121 /* 'debugger' */
+#define DUK_STRIDX_DEBUGGER 125 /* '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 122 /* 'default' */
+#define DUK_STRIDX_DEFAULT 126 /* '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 123 /* 'delete' */
+#define DUK_STRIDX_DELETE 127 /* '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 124 /* 'do' */
+#define DUK_STRIDX_DO 128 /* '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 125 /* 'else' */
+#define DUK_STRIDX_ELSE 129 /* '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 126 /* 'finally' */
+#define DUK_STRIDX_FINALLY 130 /* '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 127 /* 'for' */
+#define DUK_STRIDX_FOR 131 /* '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 128 /* 'function' */
+#define DUK_STRIDX_LC_FUNCTION 132 /* '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 129 /* 'if' */
+#define DUK_STRIDX_IF 133 /* '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 130 /* 'in' */
+#define DUK_STRIDX_IN 134 /* '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 131 /* 'instanceof' */
+#define DUK_STRIDX_INSTANCEOF 135 /* '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 132 /* 'new' */
+#define DUK_STRIDX_NEW 136 /* '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 133 /* 'return' */
+#define DUK_STRIDX_RETURN 137 /* '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 134 /* 'switch' */
+#define DUK_STRIDX_SWITCH 138 /* '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 135 /* 'this' */
+#define DUK_STRIDX_THIS 139 /* '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 136 /* 'throw' */
+#define DUK_STRIDX_THROW 140 /* '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 137 /* 'try' */
+#define DUK_STRIDX_TRY 141 /* '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 138 /* 'typeof' */
+#define DUK_STRIDX_TYPEOF 142 /* '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 139 /* 'var' */
+#define DUK_STRIDX_VAR 143 /* '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 140 /* 'const' */
+#define DUK_STRIDX_CONST 144 /* '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 141 /* 'void' */
+#define DUK_STRIDX_VOID 145 /* '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 142 /* 'while' */
+#define DUK_STRIDX_WHILE 146 /* '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 143 /* 'with' */
+#define DUK_STRIDX_WITH 147 /* '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 144 /* 'class' */
+#define DUK_STRIDX_CLASS 148 /* '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 145 /* 'enum' */
+#define DUK_STRIDX_ENUM 149 /* '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 146 /* 'export' */
+#define DUK_STRIDX_EXPORT 150 /* '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 147 /* 'extends' */
+#define DUK_STRIDX_EXTENDS 151 /* '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 148 /* 'import' */
+#define DUK_STRIDX_IMPORT 152 /* '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 149 /* 'super' */
+#define DUK_STRIDX_SUPER 153 /* '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 150 /* 'null' */
+#define DUK_STRIDX_LC_NULL 154 /* '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 151 /* 'true' */
+#define DUK_STRIDX_TRUE 155 /* '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 152 /* 'false' */
+#define DUK_STRIDX_FALSE 156 /* '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 153 /* 'implements' */
+#define DUK_STRIDX_IMPLEMENTS 157 /* '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 154 /* 'interface' */
+#define DUK_STRIDX_INTERFACE 158 /* '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 155 /* 'let' */
+#define DUK_STRIDX_LET 159 /* '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 156 /* 'package' */
+#define DUK_STRIDX_PACKAGE 160 /* '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 157 /* 'private' */
+#define DUK_STRIDX_PRIVATE 161 /* '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 158 /* 'protected' */
+#define DUK_STRIDX_PROTECTED 162 /* '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 159 /* 'public' */
+#define DUK_STRIDX_PUBLIC 163 /* '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 160 /* 'static' */
+#define DUK_STRIDX_STATIC 164 /* '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 161 /* 'yield' */
+#define DUK_STRIDX_YIELD 165 /* '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 162
-#define DUK_STRIDX_START_RESERVED 117
-#define DUK_STRIDX_START_STRICT_RESERVED 153
-#define DUK_STRIDX_END_RESERVED 162 /* exclusive endpoint */
+#define DUK_HEAP_NUM_STRINGS 166
+#define DUK_STRIDX_START_RESERVED 121
+#define DUK_STRIDX_START_STRICT_RESERVED 157
+#define DUK_STRIDX_END_RESERVED 166 /* 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[892];
+DUK_INTERNAL_DECL const duk_uint8_t duk_strings_data[967];
#endif /* !DUK_SINGLE_FILE */
-#define DUK_STRDATA_MAX_STRLEN 17
-#define DUK_STRDATA_DATA_LENGTH 892
+#define DUK_STRDATA_MAX_STRLEN 27
+#define DUK_STRDATA_DATA_LENGTH 967
#endif /* DUK_USE_ROM_STRINGS */
#if defined(DUK_USE_ROM_OBJECTS)
@@ -1975,6 +2009,8 @@ 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_global_object_parse_int(duk_context *ctx);
+DUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_parse_float(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_thread_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_proxy_constructor(duk_context *ctx);
@@ -1985,8 +2021,6 @@ 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);
DUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_is_nan(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_is_finite(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_decode_uri(duk_context *ctx);
@@ -2058,6 +2092,7 @@ DUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_startswith_endswith(duk_cont
DUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_includes(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_check_shared(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_number_prototype_to_string(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_number_prototype_to_locale_string(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_number_prototype_value_of(duk_context *ctx);
@@ -2140,7 +2175,7 @@ DUK_INTERNAL_DECL duk_ret_t duk_bi_textdecoder_prototype_shared_getter(duk_conte
DUK_INTERNAL_DECL duk_ret_t duk_bi_textdecoder_prototype_decode(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_performance_now(duk_context *ctx);
#if !defined(DUK_SINGLE_FILE)
-DUK_INTERNAL_DECL const duk_c_function duk_bi_native_functions[176];
+DUK_INTERNAL_DECL const duk_c_function duk_bi_native_functions[177];
#endif /* !DUK_SINGLE_FILE */
#define DUK_BIDX_GLOBAL 0
#define DUK_BIDX_GLOBAL_ENV 1
@@ -2195,22 +2230,22 @@ DUK_INTERNAL_DECL const duk_c_function duk_bi_native_functions[176];
#define DUK_BIDX_NODEJS_BUFFER_PROTOTYPE 50
#define DUK_NUM_BUILTINS 51
#define DUK_NUM_BIDX_BUILTINS 51
-#define DUK_NUM_ALL_BUILTINS 76
+#define DUK_NUM_ALL_BUILTINS 78
#if defined(DUK_USE_DOUBLE_LE)
#if !defined(DUK_SINGLE_FILE)
-DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[3972];
+DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[4116];
#endif /* !DUK_SINGLE_FILE */
-#define DUK_BUILTINS_DATA_LENGTH 3972
+#define DUK_BUILTINS_DATA_LENGTH 4116
#elif defined(DUK_USE_DOUBLE_BE)
#if !defined(DUK_SINGLE_FILE)
-DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[3972];
+DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[4116];
#endif /* !DUK_SINGLE_FILE */
-#define DUK_BUILTINS_DATA_LENGTH 3972
+#define DUK_BUILTINS_DATA_LENGTH 4116
#elif defined(DUK_USE_DOUBLE_ME)
#if !defined(DUK_SINGLE_FILE)
-DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[3972];
+DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[4116];
#endif /* !DUK_SINGLE_FILE */
-#define DUK_BUILTINS_DATA_LENGTH 3972
+#define DUK_BUILTINS_DATA_LENGTH 4116
#else
#error invalid endianness defines
#endif
@@ -2535,12 +2570,13 @@ struct duk_bufwriter_ctx {
(bw_ctx)->p += duk__enc_len; \
} while (0)
/* XXX: add temporary duk__p pointer here too; sharing */
+/* XXX: avoid unsafe variants */
#define DUK_BW_WRITE_RAW_BYTES(thr,bw_ctx,valptr,valsz) do { \
const void *duk__valptr; \
duk_size_t duk__valsz; \
duk__valptr = (const void *) (valptr); \
duk__valsz = (duk_size_t) (valsz); \
- DUK_MEMCPY((void *) ((bw_ctx)->p), duk__valptr, duk__valsz); \
+ duk_memcpy_unsafe((void *) ((bw_ctx)->p), duk__valptr, duk__valsz); \
(bw_ctx)->p += duk__valsz; \
} while (0)
#define DUK_BW_WRITE_RAW_CSTRING(thr,bw_ctx,val) do { \
@@ -2548,31 +2584,31 @@ struct duk_bufwriter_ctx {
duk_size_t duk__val_len; \
duk__val = (const duk_uint8_t *) (val); \
duk__val_len = DUK_STRLEN((const char *) duk__val); \
- DUK_MEMCPY((void *) ((bw_ctx)->p), (const void *) duk__val, duk__val_len); \
+ duk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) duk__val, duk__val_len); \
(bw_ctx)->p += duk__val_len; \
} while (0)
#define DUK_BW_WRITE_RAW_HSTRING(thr,bw_ctx,val) do { \
duk_size_t duk__val_len; \
duk__val_len = DUK_HSTRING_GET_BYTELEN((val)); \
- DUK_MEMCPY((void *) ((bw_ctx)->p), (const void *) DUK_HSTRING_GET_DATA((val)), duk__val_len); \
+ duk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HSTRING_GET_DATA((val)), duk__val_len); \
(bw_ctx)->p += duk__val_len; \
} while (0)
#define DUK_BW_WRITE_RAW_HBUFFER(thr,bw_ctx,val) do { \
duk_size_t duk__val_len; \
duk__val_len = DUK_HBUFFER_GET_SIZE((val)); \
- DUK_MEMCPY((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \
+ duk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \
(bw_ctx)->p += duk__val_len; \
} while (0)
#define DUK_BW_WRITE_RAW_HBUFFER_FIXED(thr,bw_ctx,val) do { \
duk_size_t duk__val_len; \
duk__val_len = DUK_HBUFFER_FIXED_GET_SIZE((val)); \
- DUK_MEMCPY((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_FIXED_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \
+ duk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_FIXED_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \
(bw_ctx)->p += duk__val_len; \
} while (0)
#define DUK_BW_WRITE_RAW_HBUFFER_DYNAMIC(thr,bw_ctx,val) do { \
duk_size_t duk__val_len; \
duk__val_len = DUK_HBUFFER_DYNAMIC_GET_SIZE((val)); \
- DUK_MEMCPY((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \
+ duk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \
(bw_ctx)->p += duk__val_len; \
} while (0)
@@ -2636,13 +2672,14 @@ struct duk_bufwriter_ctx {
DUK_BW_WRITE_RAW_CESU8((thr), (bw_ctx), (cp)); \
} while (0)
/* XXX: add temporary duk__p pointer here too; sharing */
+/* XXX: avoid unsafe */
#define DUK_BW_WRITE_ENSURE_BYTES(thr,bw_ctx,valptr,valsz) do { \
const void *duk__valptr; \
duk_size_t duk__valsz; \
duk__valptr = (const void *) (valptr); \
duk__valsz = (duk_size_t) (valsz); \
DUK_BW_ENSURE((thr), (bw_ctx), duk__valsz); \
- DUK_MEMCPY((void *) ((bw_ctx)->p), duk__valptr, duk__valsz); \
+ duk_memcpy_unsafe((void *) ((bw_ctx)->p), duk__valptr, duk__valsz); \
(bw_ctx)->p += duk__valsz; \
} while (0)
#define DUK_BW_WRITE_ENSURE_CSTRING(thr,bw_ctx,val) do { \
@@ -2651,35 +2688,35 @@ struct duk_bufwriter_ctx {
duk__val = (const duk_uint8_t *) (val); \
duk__val_len = DUK_STRLEN((const char *) duk__val); \
DUK_BW_ENSURE((thr), (bw_ctx), duk__val_len); \
- DUK_MEMCPY((void *) ((bw_ctx)->p), (const void *) duk__val, duk__val_len); \
+ duk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) duk__val, duk__val_len); \
(bw_ctx)->p += duk__val_len; \
} while (0)
#define DUK_BW_WRITE_ENSURE_HSTRING(thr,bw_ctx,val) do { \
duk_size_t duk__val_len; \
duk__val_len = DUK_HSTRING_GET_BYTELEN((val)); \
DUK_BW_ENSURE((thr), (bw_ctx), duk__val_len); \
- DUK_MEMCPY((void *) ((bw_ctx)->p), (const void *) DUK_HSTRING_GET_DATA((val)), duk__val_len); \
+ duk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HSTRING_GET_DATA((val)), duk__val_len); \
(bw_ctx)->p += duk__val_len; \
} while (0)
#define DUK_BW_WRITE_ENSURE_HBUFFER(thr,bw_ctx,val) do { \
duk_size_t duk__val_len; \
duk__val_len = DUK_HBUFFER_GET_SIZE((val)); \
DUK_BW_ENSURE((thr), (bw_ctx), duk__val_len); \
- DUK_MEMCPY((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \
+ duk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \
(bw_ctx)->p += duk__val_len; \
} while (0)
#define DUK_BW_WRITE_ENSURE_HBUFFER_FIXED(thr,bw_ctx,val) do { \
duk_size_t duk__val_len; \
duk__val_len = DUK_HBUFFER_FIXED_GET_SIZE((val)); \
DUK_BW_ENSURE((thr), (bw_ctx), duk__val_len); \
- DUK_MEMCPY((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_FIXED_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \
+ duk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_FIXED_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \
(bw_ctx)->p += duk__val_len; \
} while (0)
#define DUK_BW_WRITE_ENSURE_HBUFFER_DYNAMIC(thr,bw_ctx,val) do { \
duk_size_t duk__val_len; \
duk__val_len = DUK_HBUFFER_DYNAMIC_GET_SIZE((val)); \
DUK_BW_ENSURE((thr), (bw_ctx), duk__val_len); \
- DUK_MEMCPY((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \
+ duk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \
(bw_ctx)->p += duk__val_len; \
} while (0)
@@ -2708,10 +2745,6 @@ DUK_INTERNAL_DECL const duk_int8_t duk_hex_dectab[256];
DUK_INTERNAL_DECL const duk_int16_t duk_hex_dectab_shift4[256];
DUK_INTERNAL_DECL const duk_uint16_t duk_hex_enctab[256];
#endif
-#if defined(DUK_USE_BASE64_FASTPATH)
-DUK_INTERNAL_DECL const duk_uint8_t duk_base64_enctab[64];
-DUK_INTERNAL_DECL const duk_int8_t duk_base64_dectab[256];
-#endif
#endif /* !DUK_SINGLE_FILE */
/* Note: assumes that duk_util_probe_steps size is 32 */
@@ -2755,17 +2788,138 @@ 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_DECL void duk_byteswap_bytes(duk_uint8_t *p, duk_small_uint_t len);
#endif
+/* memcpy(), memmove() etc wrappers. The plain variants like duk_memcpy()
+ * assume C99+ and 'src' and 'dst' pointers must be non-NULL even when the
+ * operation size is zero. The unsafe variants like duk_memcpy_safe() deal
+ * with the zero size case explicitly, and allow NULL pointers in that case
+ * (which is undefined behavior in C99+). For the majority of actual targets
+ * a NULL pointer with a zero length is fine in practice. These wrappers are
+ * macros to force inlining; because there are hundreds of call sites, even a
+ * few extra bytes per call site adds up to ~1kB footprint.
+ */
+#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)
+#define duk_memcpy(dst,src,len) do { \
+ void *duk__dst = (dst); \
+ const void *duk__src = (src); \
+ duk_size_t duk__len = (len); \
+ DUK_ASSERT(duk__dst != NULL || duk__len == 0U); \
+ DUK_ASSERT(duk__src != NULL || duk__len == 0U); \
+ (void) DUK_MEMCPY(duk__dst, duk__src, (size_t) duk__len); \
+ } while (0)
+#define duk_memcpy_unsafe(dst,src,len) duk_memcpy((dst), (src), (len))
+#define duk_memmove(dst,src,len) do { \
+ void *duk__dst = (dst); \
+ const void *duk__src = (src); \
+ duk_size_t duk__len = (len); \
+ DUK_ASSERT(duk__dst != NULL || duk__len == 0U); \
+ DUK_ASSERT(duk__src != NULL || duk__len == 0U); \
+ (void) DUK_MEMMOVE(duk__dst, duk__src, (size_t) duk__len); \
+ } while (0)
+#define duk_memmove_unsafe(dst,src,len) duk_memmove((dst), (src), (len))
+#define duk_memset(dst,val,len) do { \
+ void *duk__dst = (dst); \
+ duk_small_int_t duk__val = (val); \
+ duk_size_t duk__len = (len); \
+ DUK_ASSERT(duk__dst != NULL || duk__len == 0U); \
+ (void) DUK_MEMSET(duk__dst, duk__val, (size_t) duk__len); \
+ } while (0)
+#define duk_memset_unsafe(dst,val,len) duk_memset((dst), (val), (len))
+#define duk_memzero(dst,len) do { \
+ void *duk__dst = (dst); \
+ duk_size_t duk__len = (len); \
+ DUK_ASSERT(duk__dst != NULL || duk__len == 0U); \
+ (void) DUK_MEMZERO(duk__dst, (size_t) duk__len); \
+ } while (0)
+#define duk_memzero_unsafe(dst,len) duk_memzero((dst), (len))
+#else /* DUK_USE_ALLOW_UNDEFINED_BEHAVIOR */
+#define duk_memcpy(dst,src,len) do { \
+ void *duk__dst = (dst); \
+ const void *duk__src = (src); \
+ duk_size_t duk__len = (len); \
+ DUK_ASSERT(duk__dst != NULL); \
+ DUK_ASSERT(duk__src != NULL); \
+ (void) DUK_MEMCPY(duk__dst, duk__src, (size_t) duk__len); \
+ } while (0)
+#define duk_memcpy_unsafe(dst,src,len) do { \
+ void *duk__dst = (dst); \
+ const void *duk__src = (src); \
+ duk_size_t duk__len = (len); \
+ DUK_ASSERT(duk__dst != NULL || duk__len == 0U); \
+ DUK_ASSERT(duk__src != NULL || duk__len == 0U); \
+ if (DUK_LIKELY(duk__len > 0U)) { \
+ DUK_ASSERT(duk__dst != NULL); \
+ DUK_ASSERT(duk__src != NULL); \
+ (void) DUK_MEMCPY(duk__dst, duk__src, (size_t) duk__len); \
+ } \
+ } while (0)
+#define duk_memmove(dst,src,len) do { \
+ void *duk__dst = (dst); \
+ const void *duk__src = (src); \
+ duk_size_t duk__len = (len); \
+ DUK_ASSERT(duk__dst != NULL); \
+ DUK_ASSERT(duk__src != NULL); \
+ (void) DUK_MEMMOVE(duk__dst, duk__src, (size_t) duk__len); \
+ } while (0)
+#define duk_memmove_unsafe(dst,src,len) do { \
+ void *duk__dst = (dst); \
+ const void *duk__src = (src); \
+ duk_size_t duk__len = (len); \
+ DUK_ASSERT(duk__dst != NULL || duk__len == 0U); \
+ DUK_ASSERT(duk__src != NULL || duk__len == 0U); \
+ if (DUK_LIKELY(duk__len > 0U)) { \
+ DUK_ASSERT(duk__dst != NULL); \
+ DUK_ASSERT(duk__src != NULL); \
+ (void) DUK_MEMMOVE(duk__dst, duk__src, (size_t) duk__len); \
+ } \
+ } while (0)
+#define duk_memset(dst,val,len) do { \
+ void *duk__dst = (dst); \
+ duk_small_int_t duk__val = (val); \
+ duk_size_t duk__len = (len); \
+ DUK_ASSERT(duk__dst != NULL); \
+ (void) DUK_MEMSET(duk__dst, duk__val, (size_t) duk__len); \
+ } while (0)
+#define duk_memset_unsafe(dst,val,len) do { \
+ void *duk__dst = (dst); \
+ duk_small_int_t duk__val = (val); \
+ duk_size_t duk__len = (len); \
+ DUK_ASSERT(duk__dst != NULL || duk__len == 0U); \
+ if (DUK_LIKELY(duk__len > 0U)) { \
+ DUK_ASSERT(duk__dst != NULL); \
+ (void) DUK_MEMSET(duk__dst, duk__val, (size_t) duk__len); \
+ } \
+ } while (0)
+#define duk_memzero(dst,len) do { \
+ void *duk__dst = (dst); \
+ duk_size_t duk__len = (len); \
+ DUK_ASSERT(duk__dst != NULL); \
+ (void) DUK_MEMZERO(duk__dst, (size_t) duk__len); \
+ } while (0)
+#define duk_memzero_unsafe(dst,len) do { \
+ void *duk__dst = (dst); \
+ duk_size_t duk__len = (len); \
+ DUK_ASSERT(duk__dst != NULL || duk__len == 0U); \
+ if (DUK_LIKELY(duk__len > 0U)) { \
+ DUK_ASSERT(duk__dst != NULL); \
+ (void) DUK_MEMZERO(duk__dst, (size_t) duk__len); \
+ } \
+ } while (0)
+#endif /* DUK_USE_ALLOW_UNDEFINED_BEHAVIOR */
+
+DUK_INTERNAL_DECL duk_small_int_t duk_memcmp(const void *s1, const void *s2, duk_size_t len);
+DUK_INTERNAL_DECL duk_small_int_t duk_memcmp_unsafe(const void *s1, const void *s2, duk_size_t len);
+
DUK_INTERNAL_DECL duk_bool_t duk_is_whole_get_int32_nonegzero(duk_double_t x, duk_int32_t *ival);
DUK_INTERNAL_DECL duk_bool_t duk_is_whole_get_int32(duk_double_t x, duk_int32_t *ival);
DUK_INTERNAL_DECL duk_bool_t duk_double_is_anyinf(duk_double_t x);
@@ -2780,6 +2934,33 @@ DUK_INTERNAL_DECL duk_double_t duk_double_trunc_towards_zero(duk_double_t x);
DUK_INTERNAL_DECL duk_bool_t duk_double_same_sign(duk_double_t x, duk_double_t y);
DUK_INTERNAL_DECL duk_double_t duk_double_fmin(duk_double_t x, duk_double_t y);
DUK_INTERNAL_DECL duk_double_t duk_double_fmax(duk_double_t x, duk_double_t y);
+DUK_INTERNAL_DECL duk_bool_t duk_double_is_finite(duk_double_t x);
+DUK_INTERNAL_DECL duk_bool_t duk_double_is_integer(duk_double_t x);
+DUK_INTERNAL_DECL duk_bool_t duk_double_is_safe_integer(duk_double_t x);
+
+DUK_INTERNAL_DECL duk_double_t duk_double_div(duk_double_t x, duk_double_t y);
+DUK_INTERNAL_DECL duk_int_t duk_double_to_int_t(duk_double_t x);
+DUK_INTERNAL_DECL duk_uint_t duk_double_to_uint_t(duk_double_t x);
+DUK_INTERNAL_DECL duk_int32_t duk_double_to_int32_t(duk_double_t x);
+DUK_INTERNAL_DECL duk_uint32_t duk_double_to_uint32_t(duk_double_t x);
+DUK_INTERNAL_DECL duk_float_t duk_double_to_float_t(duk_double_t x);
+
+/*
+ * Miscellaneous
+ */
+
+/* Example: x = 0x10 = 0b00010000
+ * x - 1 = 0x0f = 0b00001111
+ * x & (x - 1) == 0
+ *
+ * x = 0x07 = 0b00000111
+ * x - 1 = 0x06 = 0b00000110
+ * x & (x - 1) != 0
+ *
+ * However, incorrectly true for x == 0 so check for that explicitly.
+ */
+#define DUK_IS_POWER_OF_TWO(x) \
+ ((x) != 0U && ((x) & ((x) - 1U)) == 0U)
#endif /* DUK_UTIL_H_INCLUDED */
/* #include duk_strings.h */
@@ -2952,7 +3133,7 @@ DUK_INTERNAL_DECL duk_double_t duk_double_fmax(duk_double_t x, duk_double_t y);
#endif /* DUK_ERRMSG_H_INCLUDED */
/* #include duk_js_bytecode.h */
/*
- * Ecmascript bytecode
+ * ECMAScript bytecode
*/
#if !defined(DUK_JS_BYTECODE_H_INCLUDED)
@@ -3824,7 +4005,7 @@ struct duk_lexer_codepoint {
duk_int_t line;
};
-/* Lexer context. Same context is used for Ecmascript and Regexp parsing. */
+/* Lexer context. Same context is used for ECMAScript and Regexp parsing. */
struct duk_lexer_ctx {
#if defined(DUK_USE_LEXER_SLIDING_WINDOW)
duk_lexer_codepoint *window; /* unicode code points, window[0] is always next, points to 'buffer' */
@@ -3874,13 +4055,13 @@ DUK_INTERNAL_DECL void duk_lexer_parse_re_ranges(duk_lexer_ctx *lex_ctx, duk_re_
#endif /* DUK_LEXER_H_INCLUDED */
/* #include duk_js_compiler.h */
/*
- * Ecmascript compiler.
+ * ECMAScript compiler.
*/
#if !defined(DUK_JS_COMPILER_H_INCLUDED)
#define DUK_JS_COMPILER_H_INCLUDED
-/* ecmascript compiler limits */
+/* ECMAScript compiler limits */
#define DUK_COMPILER_TOKEN_LIMIT 100000000L /* 1e8: protects against deeply nested inner functions */
/* maximum loopcount for peephole optimization */
@@ -4062,6 +4243,7 @@ struct duk_compiler_func {
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 */
+ duk_uint8_t allow_regexp_in_adv; /* allow RegExp literal on next advance() call */
};
struct duk_compiler_ctx {
@@ -4219,9 +4401,6 @@ DUK_INTERNAL_DECL void duk_regexp_match_force_global(duk_hthread *thr); /* hack
/* XXX: macro for shared header fields (avoids some padding issues) */
-#if (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_MSVC_PRAGMA)
-#pragma pack(push, 8)
-#endif
struct duk_heaphdr {
duk_uint32_t h_flags;
@@ -4267,16 +4446,7 @@ struct duk_heaphdr {
#if defined(DUK_USE_HEAPPTR16)
duk_uint16_t h_extra16;
#endif
-}
-#if (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_GCC_ATTR)
-__attribute__ ((aligned (8)))
-#elif (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_CLANG_ATTR)
-__attribute__ ((aligned (8)))
-#endif
-;
-#if (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_MSVC_PRAGMA)
-#pragma pack(pop)
-#endif
+};
struct duk_heaphdr_string {
/* 16 bits would be enough for shared heaphdr flags and duk_hstring
@@ -5196,7 +5366,7 @@ struct duk_heaphdr_string {
#if defined(DUK_USE_REFERENCE_COUNTING)
#if defined(DUK_USE_FINALIZER_SUPPORT)
DUK_INTERNAL_DECL void duk_refzero_check_slow(duk_hthread *thr);
-DUK_INTERNAL_DECL DUK_INLINE void duk_refzero_check_fast(duk_hthread *thr);
+DUK_INTERNAL_DECL void duk_refzero_check_fast(duk_hthread *thr);
#endif
DUK_INTERNAL_DECL void duk_heaphdr_refcount_finalize_norz(duk_heap *heap, duk_heaphdr *hdr);
DUK_INTERNAL_DECL void duk_hobject_refcount_finalize_norz(duk_heap *heap, duk_hobject *h);
@@ -5251,8 +5421,8 @@ DUK_INTERNAL_DECL void duk_heaphdr_decref_norz(duk_hthread *thr, duk_heaphdr *h)
/* Current convention is to use duk_size_t for value stack sizes and global indices,
* and duk_idx_t for local frame indices.
*/
-DUK_INTERNAL_DECL DUK_INLINE void duk_valstack_grow_check_throw(duk_hthread *thr, duk_size_t min_bytes);
-DUK_INTERNAL_DECL DUK_INLINE duk_bool_t duk_valstack_grow_check_nothrow(duk_hthread *thr, duk_size_t min_bytes);
+DUK_INTERNAL_DECL void duk_valstack_grow_check_throw(duk_hthread *thr, duk_size_t min_bytes);
+DUK_INTERNAL_DECL duk_bool_t duk_valstack_grow_check_nothrow(duk_hthread *thr, duk_size_t min_bytes);
DUK_INTERNAL_DECL void duk_valstack_shrink_check_nothrow(duk_hthread *thr, duk_bool_t snug);
DUK_INTERNAL_DECL void duk_copy_tvals_incref(duk_hthread *thr, duk_tval *tv_dst, duk_tval *tv_src, duk_size_t count);
@@ -5373,10 +5543,12 @@ DUK_INTERNAL_DECL duk_hobject *duk_to_hobject(duk_hthread *thr, duk_idx_t idx);
DUK_INTERNAL_DECL duk_double_t duk_to_number_m1(duk_hthread *thr);
DUK_INTERNAL_DECL duk_double_t duk_to_number_m2(duk_hthread *thr);
+DUK_INTERNAL_DECL duk_bool_t duk_to_boolean_top_pop(duk_hthread *thr);
+
#if defined(DUK_USE_DEBUGGER_SUPPORT) /* only needed by debugger for now */
DUK_INTERNAL_DECL duk_hstring *duk_safe_to_hstring(duk_hthread *thr, duk_idx_t idx);
#endif
-DUK_INTERNAL_DECL void duk_push_class_string_tval(duk_hthread *thr, duk_tval *tv);
+DUK_INTERNAL_DECL void duk_push_class_string_tval(duk_hthread *thr, duk_tval *tv, duk_bool_t avoid_side_effects);
DUK_INTERNAL_DECL duk_int_t duk_to_int_clamped_raw(duk_hthread *thr, 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_hthread *thr, duk_idx_t idx, duk_int_t minval, duk_int_t maxval);
@@ -5514,6 +5686,8 @@ DUK_INTERNAL_DECL void duk_xdef_prop_stridx_builtin(duk_hthread *thr, duk_idx_t
DUK_INTERNAL_DECL void duk_xdef_prop_stridx_thrower(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx); /* [] -> [] */
+DUK_INTERNAL_DECL duk_bool_t duk_get_method_stridx(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t stridx);
+
DUK_INTERNAL_DECL void duk_pack(duk_hthread *thr, duk_idx_t count);
DUK_INTERNAL_DECL duk_idx_t duk_unpack_array_like(duk_hthread *thr, duk_idx_t idx);
#if 0
@@ -5550,6 +5724,10 @@ DUK_INTERNAL_DECL void duk_concat_2(duk_hthread *thr);
DUK_INTERNAL_DECL duk_int_t duk_pcall_method_flags(duk_hthread *thr, duk_idx_t nargs, duk_small_uint_t call_flags);
+#if defined(DUK_USE_SYMBOL_BUILTIN)
+DUK_INTERNAL_DECL void duk_to_primitive_ordinary(duk_hthread *thr, duk_idx_t idx, duk_int_t hint);
+#endif
+
/* 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,
* using these macro results in faster and smaller code than duk_get_tval().
@@ -5588,7 +5766,7 @@ DUK_INTERNAL_DECL duk_double_t duk_time_get_monotonic_time(duk_hthread *thr);
* strings used as internal property names and raw buffers converted to
* strings. In such cases the 'clen' field contains an inaccurate value.
*
- * Ecmascript requires support for 32-bit long strings. However, since each
+ * ECMAScript requires support for 32-bit long strings. However, since each
* 16-bit codepoint can take 3 bytes in CESU-8, this representation can only
* support about 1.4G codepoint long strings in extreme cases. This is not
* really a practical issue.
@@ -5612,12 +5790,15 @@ DUK_INTERNAL_DECL duk_double_t duk_time_get_monotonic_time(duk_hthread *thr);
#define DUK_HSTRING_MAX_BYTELEN (0x7fffffffUL)
#endif
-/* XXX: could add flags for "is valid CESU-8" (Ecmascript compatible strings),
+/* XXX: could add flags for "is valid CESU-8" (ECMAScript compatible strings),
* "is valid UTF-8", "is valid extended UTF-8" (internal strings are not,
* regexp bytecode is), and "contains non-BMP characters". These are not
* needed right now.
*/
+/* With lowmem builds the high 16 bits of duk_heaphdr are used for other
+ * purposes, so this leaves 7 duk_heaphdr flags and 9 duk_hstring flags.
+ */
#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_SYMBOL DUK_HEAPHDR_USER_FLAG(2) /* string is a symbol (invalid utf-8) */
@@ -5626,6 +5807,7 @@ DUK_INTERNAL_DECL duk_double_t duk_time_get_monotonic_time(duk_hthread *thr);
#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_FLAG_PINNED_LITERAL DUK_HEAPHDR_USER_FLAG(8) /* string is a literal, and pinned */
#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)
@@ -5635,6 +5817,7 @@ DUK_INTERNAL_DECL duk_double_t duk_time_get_monotonic_time(duk_hthread *thr);
#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)
#define DUK_HSTRING_HAS_EXTDATA(x) DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EXTDATA)
+#define DUK_HSTRING_HAS_PINNED_LITERAL(x) DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_PINNED_LITERAL)
#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)
@@ -5644,6 +5827,7 @@ DUK_INTERNAL_DECL duk_double_t duk_time_get_monotonic_time(duk_hthread *thr);
#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)
#define DUK_HSTRING_SET_EXTDATA(x) DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EXTDATA)
+#define DUK_HSTRING_SET_PINNED_LITERAL(x) DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_PINNED_LITERAL)
#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)
@@ -5653,6 +5837,7 @@ DUK_INTERNAL_DECL duk_double_t duk_time_get_monotonic_time(duk_hthread *thr);
#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)
#define DUK_HSTRING_CLEAR_EXTDATA(x) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EXTDATA)
+#define DUK_HSTRING_CLEAR_PINNED_LITERAL(x) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_PINNED_LITERAL)
#if 0 /* Slightly smaller code without explicit flag, but explicit flag
* is very useful when 'clen' is dropped.
@@ -5745,9 +5930,6 @@ DUK_INTERNAL_DECL duk_double_t duk_time_get_monotonic_time(duk_hthread *thr);
* Misc
*/
-#if (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_MSVC_PRAGMA)
-#pragma pack(push, 8)
-#endif
struct duk_hstring {
/* Smaller heaphdr than for other objects, because strings are held
* in string intern table which requires no link pointers. Much of
@@ -5792,16 +5974,7 @@ struct duk_hstring {
* for strings, but fields above should guarantee alignment-by-4
* (but not alignment-by-8).
*/
-}
-#if (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_GCC_ATTR)
-__attribute__ ((aligned (8)))
-#elif (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_CLANG_ATTR)
-__attribute__ ((aligned (8)))
-#endif
-;
-#if (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_MSVC_PRAGMA)
-#pragma pack(pop)
-#endif
+};
/* The external string struct is defined even when the feature is inactive. */
struct duk_hstring_external {
@@ -5832,12 +6005,12 @@ DUK_INTERNAL_DECL void duk_hstring_init_charlen(duk_hstring *h);
/*
* Heap object representation.
*
- * Heap objects are used for Ecmascript objects, arrays, and functions,
+ * Heap objects are used for ECMAScript objects, arrays, and functions,
* but also for internal control like declarative and object environment
* records. Compiled functions, native functions, and threads are also
* objects but with an extended C struct.
*
- * Objects provide the required Ecmascript semantics and exotic behaviors
+ * Objects provide the required ECMAScript semantics and exotic behaviors
* especially for property access.
*
* Properties are stored in three conceptual parts:
@@ -6466,7 +6639,7 @@ DUK_INTERNAL_DECL void duk_hstring_init_charlen(duk_hstring *h);
#define DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY 10000L
/*
- * Ecmascript [[Class]]
+ * ECMAScript [[Class]]
*/
/* range check not necessary because all 4-bit values are mapped */
@@ -6829,9 +7002,9 @@ DUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype(duk_hthread *thr);
#endif /* DUK_HOBJECT_H_INCLUDED */
/* #include duk_hcompfunc.h */
/*
- * Heap compiled function (Ecmascript function) representation.
+ * Heap compiled function (ECMAScript function) representation.
*
- * There is a single data buffer containing the Ecmascript function's
+ * There is a single data buffer containing the ECMAScript function's
* bytecode, constants, and inner functions.
*/
@@ -7222,7 +7395,8 @@ struct duk_hboundfunc {
} while (0)
/* Get the current data pointer (caller must ensure buf != NULL) as a
- * duk_uint8_t ptr.
+ * duk_uint8_t ptr. Note that the result may be NULL if the underlying
+ * buffer has zero size and is not a fixed buffer.
*/
#define DUK_HBUFOBJ_GET_SLICE_BASE(heap,h) \
(DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \
@@ -7540,14 +7714,14 @@ struct duk_activation {
duk_instr_t *curr_pc; /* next instruction to execute (points to 'func' bytecode, stable pointer), NULL for native calls */
/* bottom_byteoff and retval_byteoff are only used for book-keeping
- * of Ecmascript-initiated calls, to allow returning to an Ecmascript
+ * of ECMAScript-initiated calls, to allow returning to an ECMAScript
* function properly.
*/
/* Bottom of valstack for this activation, used to reset
* valstack_bottom on return; offset is absolute. There's
* no need to track 'top' because native call handling deals
- * with that using locals, and for Ecmascript returns 'nregs'
+ * with that using locals, and for ECMAScript returns 'nregs'
* indicates the necessary top.
*/
duk_size_t bottom_byteoff;
@@ -7712,13 +7886,13 @@ DUK_INTERNAL_DECL void duk_hthread_create_builtin_objects(duk_hthread *thr);
DUK_INTERNAL_DECL duk_bool_t duk_hthread_init_stacks(duk_heap *heap, duk_hthread *thr);
DUK_INTERNAL_DECL void duk_hthread_terminate(duk_hthread *thr);
-DUK_INTERNAL_DECL DUK_INLINE duk_activation *duk_hthread_activation_alloc(duk_hthread *thr);
+DUK_INTERNAL_DECL duk_activation *duk_hthread_activation_alloc(duk_hthread *thr);
DUK_INTERNAL_DECL void duk_hthread_activation_free(duk_hthread *thr, duk_activation *act);
DUK_INTERNAL_DECL void duk_hthread_activation_unwind_norz(duk_hthread *thr);
DUK_INTERNAL_DECL void duk_hthread_activation_unwind_reuse_norz(duk_hthread *thr);
DUK_INTERNAL_DECL duk_activation *duk_hthread_get_activation_for_level(duk_hthread *thr, duk_int_t level);
-DUK_INTERNAL_DECL DUK_INLINE duk_catcher *duk_hthread_catcher_alloc(duk_hthread *thr);
+DUK_INTERNAL_DECL duk_catcher *duk_hthread_catcher_alloc(duk_hthread *thr);
DUK_INTERNAL_DECL void duk_hthread_catcher_free(duk_hthread *thr, duk_catcher *cat);
DUK_INTERNAL_DECL void duk_hthread_catcher_unwind_norz(duk_hthread *thr, duk_activation *act);
DUK_INTERNAL_DECL void duk_hthread_catcher_unwind_nolexenv_norz(duk_hthread *thr, duk_activation *act);
@@ -7931,7 +8105,7 @@ struct duk_hobjenv {
#define DUK_HBUFFER_EXTERNAL_GET_SIZE(x) DUK_HBUFFER_GET_SIZE((duk_hbuffer *) (x))
#define DUK_HBUFFER_EXTERNAL_SET_SIZE(x,v) DUK_HBUFFER_SET_SIZE((duk_hbuffer *) (x), (v))
-#define DUK_HBUFFER_FIXED_GET_DATA_PTR(heap,x) ((duk_uint8_t *) (((duk_hbuffer_fixed *) (x)) + 1))
+#define DUK_HBUFFER_FIXED_GET_DATA_PTR(heap,x) ((duk_uint8_t *) (((duk_hbuffer_fixed *) (void *) (x)) + 1))
#if defined(DUK_USE_HEAPPTR16)
#define DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap,x) \
@@ -7986,7 +8160,7 @@ struct duk_hobjenv {
DUK_HBUFFER_EXTERNAL_GET_DATA_PTR((heap), (duk_hbuffer_external *) (x)) : \
DUK_HBUFFER_DYNAMIC_GET_DATA_PTR((heap), (duk_hbuffer_dynamic *) (x)) \
) : \
- DUK_HBUFFER_FIXED_GET_DATA_PTR((heap), (duk_hbuffer_fixed *) (x)) \
+ DUK_HBUFFER_FIXED_GET_DATA_PTR((heap), (duk_hbuffer_fixed *) (void *) (x)) \
)
#else
/* Without heap pointer compression duk_hbuffer_dynamic and duk_hbuffer_external
@@ -7995,7 +8169,7 @@ struct duk_hobjenv {
#define DUK_HBUFFER_GET_DATA_PTR(heap,x) ( \
DUK_HBUFFER_HAS_DYNAMIC((x)) ? \
DUK_HBUFFER_DYNAMIC_GET_DATA_PTR((heap), (duk_hbuffer_dynamic *) (x)) : \
- DUK_HBUFFER_FIXED_GET_DATA_PTR((heap), (duk_hbuffer_fixed *) (x)) \
+ DUK_HBUFFER_FIXED_GET_DATA_PTR((heap), (duk_hbuffer_fixed *) (void *) (x)) \
)
#endif
@@ -8069,7 +8243,10 @@ struct duk_hbuffer_fixed {
#if (DUK_USE_ALIGN_BY == 4)
duk_uint32_t dummy_for_align4;
#elif (DUK_USE_ALIGN_BY == 8)
- duk_double_t dummy_for_align8;
+ duk_double_t dummy_for_align8_1;
+#if defined(DUK_USE_64BIT_OPS)
+ duk_uint64_t dummy_for_align8_2;
+#endif
#elif (DUK_USE_ALIGN_BY == 1)
/* no extra padding */
#else
@@ -8484,7 +8661,7 @@ struct duk_breakpoint {
* Thus, string caches are now at the heap level now.
*/
-struct duk_strcache {
+struct duk_strcache_entry {
duk_hstring *h;
duk_uint32_t bidx;
duk_uint32_t cidx;
@@ -8516,6 +8693,15 @@ struct duk_ljstate {
} while (0)
/*
+ * Literal intern cache
+ */
+
+struct duk_litcache_entry {
+ const duk_uint8_t *addr;
+ duk_hstring *h;
+};
+
+/*
* Main heap structure
*/
@@ -8741,7 +8927,15 @@ struct duk_heap {
/* String access cache (codepoint offset -> byte offset) for fast string
* character looping; 'weak' reference which needs special handling in GC.
*/
- duk_strcache strcache[DUK_HEAP_STRCACHE_SIZE];
+ duk_strcache_entry strcache[DUK_HEAP_STRCACHE_SIZE];
+
+#if defined(DUK_USE_LITCACHE_SIZE)
+ /* Literal intern cache. When enabled, strings interned as literals
+ * (e.g. duk_push_literal()) will be pinned and cached for the lifetime
+ * of the heap.
+ */
+ duk_litcache_entry litcache[DUK_USE_LITCACHE_SIZE];
+#endif
/* Built-in strings. */
#if defined(DUK_USE_ROM_STRINGS)
@@ -8773,6 +8967,9 @@ struct duk_heap {
duk_int_t stats_strtab_resize_check;
duk_int_t stats_strtab_resize_grow;
duk_int_t stats_strtab_resize_shrink;
+ duk_int_t stats_strtab_litcache_hit;
+ duk_int_t stats_strtab_litcache_miss;
+ duk_int_t stats_strtab_litcache_pin;
duk_int_t stats_object_realloc_props;
duk_int_t stats_object_abandon_array;
duk_int_t stats_getownpropdesc_count;
@@ -8833,6 +9030,9 @@ DUK_INTERNAL_DECL void duk_heap_switch_thread(duk_heap *heap, duk_hthread *new_t
DUK_INTERNAL_DECL duk_hstring *duk_heap_strtable_intern(duk_heap *heap, const duk_uint8_t *str, duk_uint32_t blen);
DUK_INTERNAL_DECL duk_hstring *duk_heap_strtable_intern_checked(duk_hthread *thr, const duk_uint8_t *str, duk_uint32_t len);
+#if defined(DUK_USE_LITCACHE_SIZE)
+DUK_INTERNAL_DECL duk_hstring *duk_heap_strtable_intern_literal_checked(duk_hthread *thr, const duk_uint8_t *str, duk_uint32_t blen);
+#endif
DUK_INTERNAL_DECL duk_hstring *duk_heap_strtable_intern_u32(duk_heap *heap, duk_uint32_t val);
DUK_INTERNAL_DECL duk_hstring *duk_heap_strtable_intern_u32_checked(duk_hthread *thr, duk_uint32_t val);
#if defined(DUK_USE_REFERENCE_COUNTING)
@@ -9234,8 +9434,8 @@ DUK_INTERNAL_DECL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb);
* Error codes: defined in duktape.h
*
* Error codes are used as a shorthand to throw exceptions from inside
- * the implementation. The appropriate Ecmascript object is constructed
- * based on the code. Ecmascript code throws objects directly. The error
+ * the implementation. The appropriate ECMAScript object is constructed
+ * based on the code. ECMAScript code throws objects directly. The error
* codes are defined in the public API header because they are also used
* by calling code.
*/
@@ -9637,7 +9837,7 @@ DUK_INTERNAL_DECL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb);
#if defined(DUK_USE_ASSERTIONS)
#define DUK_ASSERT_SET_GARBAGE(ptr,size) do { \
- DUK_MEMSET((void *) (ptr), 0x5a, size); \
+ duk_memset_unsafe((void *) (ptr), 0x5a, size); \
} while (0)
#else
#define DUK_ASSERT_SET_GARBAGE(ptr,size) do {} while (0)
@@ -9915,13 +10115,13 @@ DUK_INTERNAL_DECL duk_hobject *duk_error_prototype_from_code(duk_hthread *thr, d
* Automatically generated by extract_chars.py, do not edit!
*/
-extern const duk_uint8_t duk_unicode_ids_noa[1036];
+extern const duk_uint8_t duk_unicode_ids_noa[1063];
#else
/*
* Automatically generated by extract_chars.py, do not edit!
*/
-extern const duk_uint8_t duk_unicode_ids_noabmp[625];
+extern const duk_uint8_t duk_unicode_ids_noabmp[626];
#endif
#if defined(DUK_USE_SOURCE_NONBMP)
@@ -9943,13 +10143,13 @@ extern const duk_uint8_t duk_unicode_ids_m_let_noabmp[24];
* Automatically generated by extract_chars.py, do not edit!
*/
-extern const duk_uint8_t duk_unicode_idp_m_ids_noa[530];
+extern const duk_uint8_t duk_unicode_idp_m_ids_noa[549];
#else
/*
* Automatically generated by extract_chars.py, do not edit!
*/
-extern const duk_uint8_t duk_unicode_idp_m_ids_noabmp[357];
+extern const duk_uint8_t duk_unicode_idp_m_ids_noabmp[358];
#endif
/*
@@ -10090,7 +10290,7 @@ typedef struct {
#endif /* DUK_JSON_H_INCLUDED */
/* #include duk_js.h */
/*
- * Ecmascript execution, support primitives.
+ * ECMAScript execution, support primitives.
*/
#if !defined(DUK_JS_H_INCLUDED)
@@ -10134,6 +10334,9 @@ DUK_INTERNAL_DECL duk_small_int_t duk_js_buffer_compare(duk_heap *heap, duk_hbuf
#endif
DUK_INTERNAL_DECL duk_bool_t duk_js_compare_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_t flags);
DUK_INTERNAL_DECL duk_bool_t duk_js_instanceof(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y);
+#if defined(DUK_USE_SYMBOL_BUILTIN)
+DUK_INTERNAL_DECL duk_bool_t duk_js_instanceof_ordinary(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y);
+#endif
DUK_INTERNAL_DECL duk_bool_t duk_js_in(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y);
DUK_INTERNAL_DECL duk_small_uint_t duk_js_typeof_stridx(duk_tval *tv_x);
@@ -10202,7 +10405,7 @@ DUK_INTERNAL_DECL void duk_js_execute_bytecode(duk_hthread *exec_thr);
/* #include duk_numconv.h */
/*
* Number-to-string conversion. The semantics of these is very tightly
- * bound with the Ecmascript semantics required for call sites.
+ * bound with the ECMAScript semantics required for call sites.
*/
#if !defined(DUK_NUMCONV_H_INCLUDED)
@@ -10235,9 +10438,13 @@ DUK_INTERNAL_DECL void duk_js_execute_bytecode(duk_hthread *exec_thr);
/* Maximum exponent value when parsing numbers. This is not strictly
* compliant as there should be no upper limit, but as we parse the
- * exponent without a bigint, impose some limit.
+ * exponent without a bigint, impose some limit. The limit should be
+ * small enough that multiplying it (or limit-1 to be precise) won't
+ * overflow signed 32-bit integer range. Exponent is only parsed with
+ * radix 10, but with maximum radix (36) a safe limit is:
+ * (10000000*36).toString(16) -> '15752a00'
*/
-#define DUK_S2N_MAX_EXPONENT 1000000000
+#define DUK_S2N_MAX_EXPONENT 10000000L
/* Trim white space (= allow leading and trailing whitespace) */
#define DUK_S2N_FLAG_TRIM_WHITE (1U << 0)
@@ -10508,7 +10715,7 @@ DUK_INTERNAL void duk_debug_log(duk_int_t level, const char *file, duk_int_t lin
va_start(ap, fmt);
- DUK_MEMZERO((void *) buf, (size_t) DUK__DEBUG_BUFSIZE);
+ duk_memzero((void *) buf, (size_t) DUK__DEBUG_BUFSIZE);
duk_debug_vsnprintf(buf, DUK__DEBUG_BUFSIZE - 1, fmt, ap);
arg_level = (long) level;
@@ -10539,7 +10746,7 @@ DUK_INTERNAL void duk_debug_log(const char *fmt, ...) {
va_start(ap, fmt);
- DUK_MEMZERO((void *) buf, (size_t) DUK__DEBUG_BUFSIZE);
+ duk_memzero((void *) buf, (size_t) DUK__DEBUG_BUFSIZE);
duk_debug_vsnprintf(buf, DUK__DEBUG_BUFSIZE - 1, fmt, ap);
arg_level = (long) duk_debug_level_stash;
@@ -10579,7 +10786,7 @@ DUK_INTERNAL void duk_debug_log(const char *fmt, ...) {
#if defined(DUK_USE_ROM_STRINGS)
#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[892] = {
+DUK_INTERNAL const duk_uint8_t duk_strings_data[967] = {
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,
@@ -10601,36 +10808,40 @@ DUK_INTERNAL const duk_uint8_t duk_strings_data[892] = {
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,137,64,247,175,9,19,155,41,198,130,155,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,39,220,228,193,19,18,101,220,227,
-73,121,167,115,129,196,200,39,12,136,220,225,93,22,1,114,62,231,42,8,176,
-15,62,231,36,234,68,68,70,231,30,45,37,161,164,38,231,24,7,159,115,149,4,
-72,218,171,115,133,67,64,180,100,145,54,231,42,5,208,135,19,152,244,44,133,
-67,95,73,164,145,143,5,18,2,100,65,35,30,76,241,117,134,70,212,103,37,204,
-16,72,154,218,130,77,196,145,63,127,123,106,141,25,11,189,243,169,198,132,
-251,235,119,247,182,154,6,239,124,234,113,161,62,250,221,253,237,164,52,
-187,223,58,156,104,79,190,187,127,123,105,168,105,119,190,117,56,208,159,
-125,118,254,246,209,104,209,111,124,234,113,161,62,250,205,253,162,209,162,
-249,212,227,66,125,244,161,137,0,162,8,18,33,68,9,136,232,19,155,52,54,132,
-64,200,26,24,196,137,198,66,130,139,153,134,69,146,100,16,220,66,46,68,57,
-80,208,45,120,25,93,20,22,141,20,208,230,137,5,18,26,164,54,83,3,68,71,20,
-109,37,141,18,78,145,105,165,100,76,71,36,206,137,22,103,139,172,57,199,6,
-158,30,71,20,117,4,74,39,54,83,37,92,129,150,199,66,200,75,34,103,40,150,9,
-72,132,109,24,98,93,238,140,206,75,204,141,28,140,134,61,209,153,101,71,
-146,36,109,22,178,78,52,33,74,5,200,138,67,30,178,48,141,156,146,134,204,
-145,40,4,65,172,147,59,192,37,0,196,59,226,138,130,100,75,226,233,144,83,
-32,204,250,5,104,17,165,48,77,2,46,16,69,140,
+231,146,51,192,204,73,140,224,145,221,102,241,68,196,169,248,30,75,12,11,
+151,242,233,187,143,138,24,137,162,164,255,253,63,3,201,97,129,114,254,92,
+112,75,136,108,166,6,136,159,255,167,224,121,44,48,46,95,203,166,238,74,
+113,67,77,201,128,223,255,223,224,121,44,48,46,95,203,145,46,9,205,16,39,
+201,62,36,0,192,21,147,255,238,145,39,199,197,211,116,240,242,113,197,78,
+214,211,226,233,187,107,105,19,119,37,56,161,166,52,221,212,201,205,36,240,
+242,16,96,152,12,178,52,211,56,228,73,150,83,0,148,39,137,75,67,73,198,209,
+129,36,85,185,201,196,2,32,193,48,17,160,97,16,84,44,156,104,24,67,189,200,
+108,201,19,238,114,96,137,137,50,238,113,164,188,211,185,192,226,100,19,
+134,68,110,112,174,139,0,185,31,115,149,4,88,7,159,115,146,117,34,34,35,
+115,143,22,146,208,210,19,115,140,3,207,185,202,130,36,109,85,185,194,161,
+160,90,50,72,155,115,149,2,232,67,137,204,122,22,66,161,175,164,210,72,199,
+130,137,1,50,32,145,143,38,120,186,195,35,106,51,146,230,8,36,77,109,65,38,
+226,72,159,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 configure.py with --rom-support
#else /* DUK_USE_ROM_OBJECTS */
-/* native functions: 176 */
-DUK_INTERNAL const duk_c_function duk_bi_native_functions[176] = {
+/* native functions: 177 */
+DUK_INTERNAL const duk_c_function duk_bi_native_functions[177] = {
NULL,
duk_bi_array_constructor,
duk_bi_array_constructor_is_array,
@@ -10723,6 +10934,7 @@ DUK_INTERNAL const duk_c_function duk_bi_native_functions[176] = {
duk_bi_nodejs_buffer_tojson,
duk_bi_nodejs_buffer_tostring,
duk_bi_nodejs_buffer_write,
+ duk_bi_number_check_shared,
duk_bi_number_constructor,
duk_bi_number_prototype_to_exponential,
duk_bi_number_prototype_to_fixed,
@@ -10809,556 +11021,577 @@ DUK_INTERNAL const duk_c_function duk_bi_native_functions[176] = {
duk_bi_uint8array_plainof,
};
#if defined(DUK_USE_DOUBLE_LE)
-DUK_INTERNAL const duk_uint8_t duk_builtins_data[3972] = {
-144,148,105,223,160,68,52,228,62,12,104,200,165,132,52,167,194,138,105,242,
-252,57,28,211,57,18,64,52,238,62,44,138,111,171,241,164,19,87,125,30,33,
+DUK_INTERNAL const duk_uint8_t duk_builtins_data[4116] = {
+144,148,105,224,32,68,52,228,62,12,104,200,165,132,52,167,194,138,105,243,
+124,57,28,211,57,18,64,52,238,126,44,138,111,171,241,164,19,87,129,30,33,
167,16,145,159,8,211,136,9,225,42,5,240,145,139,163,163,8,211,136,10,228,
64,211,19,132,140,93,29,56,70,156,64,119,34,66,146,36,104,137,194,70,46,
142,172,35,78,32,47,146,195,102,11,240,145,139,163,175,8,211,136,9,228,240,
242,112,145,139,163,179,8,211,136,8,237,34,130,118,49,116,118,225,26,48,0,
-1,80,29,201,158,46,183,39,135,147,132,140,93,16,132,76,66,33,8,66,16,132,
-33,8,66,34,33,154,112,0,1,73,247,35,79,91,237,198,174,192,47,31,23,95,17,
-13,51,19,35,93,68,216,209,128,0,10,192,174,79,15,32,248,8,196,24,8,107,192,
-0,5,98,118,27,94,0,0,43,19,227,94,0,0,43,20,46,215,128,0,10,197,28,198,188,
-0,0,86,41,100,53,224,0,2,177,79,85,175,0,0,21,138,154,45,120,0,0,172,85,
-217,107,192,0,5,98,182,243,86,193,106,52,127,66,249,50,94,124,35,68,225,
-146,49,13,31,170,23,201,146,243,224,200,39,12,145,136,67,134,11,49,0,0,0,0,
-0,0,3,225,255,51,0,0,0,0,0,0,3,193,255,47,18,1,172,19,120,71,10,25,196,136,
-113,162,156,136,199,42,57,204,144,115,132,240,149,2,248,72,197,209,58,2,
-185,16,52,196,225,35,23,68,233,14,228,72,82,68,141,17,56,72,197,209,58,130,
-249,44,54,96,191,9,24,186,39,88,79,39,135,147,132,140,93,19,176,35,180,138,
-9,216,197,209,59,82,79,31,40,242,1,248,58,42,96,121,14,232,94,62,46,190,15,
-38,31,145,33,86,65,76,242,150,143,69,48,242,179,79,45,56,243,51,207,53,64,
-243,116,79,57,72,243,180,207,61,80,243,245,79,65,88,244,34,249,50,94,124,
-35,68,225,146,39,163,23,201,146,243,224,200,39,12,145,61,40,183,146,37,116,
-88,6,136,158,244,241,174,230,202,80,135,130,50,39,16,217,231,208,20,240,70,
-68,225,86,224,79,60,64,84,75,141,7,27,157,32,66,37,194,161,168,153,51,132,
-9,25,4,225,147,180,138,50,196,18,25,4,225,147,180,138,5,215,49,238,105,27,
-60,185,2,72,209,56,100,237,34,140,193,4,136,209,56,100,237,34,129,117,204,
-123,154,70,207,50,64,98,72,64,121,51,68,8,163,73,33,1,228,208,16,0,65,112,
-152,56,196,159,31,23,77,211,195,201,199,23,150,73,169,234,34,24,49,39,199,
-89,188,124,92,242,70,120,224,201,33,69,15,155,163,196,64,153,137,62,58,205,
-227,226,231,146,51,199,26,6,18,92,130,64,192,148,144,102,240,23,129,133,18,
-2,100,224,160,56,100,42,26,78,62,46,121,35,60,112,216,32,50,21,13,39,31,23,
-60,145,154,9,46,18,1,36,64,47,148,64,98,196,132,201,57,68,132,95,18,84,141,
-159,9,121,145,178,67,155,46,73,2,17,46,72,128,89,7,199,32,66,37,194,197,
-217,35,120,228,131,17,46,18,243,35,100,128,172,156,98,2,40,152,151,32,130,
-166,36,248,235,55,143,139,158,72,207,28,150,24,23,46,92,130,80,72,151,21,0,
-100,213,103,229,245,8,186,190,144,24,78,136,24,94,152,3,142,9,113,214,111,
-31,23,60,145,158,57,164,13,68,184,248,186,110,158,30,78,56,188,226,10,62,
-46,121,35,60,113,18,225,27,70,18,32,10,201,208,32,134,214,208,200,84,52,
-156,49,39,50,71,107,107,152,129,13,173,161,144,168,105,57,34,78,100,142,
-214,215,49,16,134,214,210,220,229,81,252,49,39,50,71,107,107,158,65,13,173,
-165,185,202,163,249,34,78,100,142,214,215,60,146,12,16,28,128,62,175,42,6,
-143,36,136,16,64,90,242,135,192,129,67,71,147,62,65,5,215,231,214,6,215,62,
-180,8,49,1,3,162,92,4,98,12,41,14,67,40,106,229,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,192,163,11,23,51,130,56,35,
-193,56,100,243,31,6,150,46,103,4,225,147,143,114,27,63,57,241,200,169,194,
-133,42,166,175,240,6,23,240,0,97,28,17,224,39,233,32,80,142,8,240,78,25,56,
-9,250,136,22,39,12,156,123,144,217,240,19,245,18,6,19,154,32,79,214,124,14,
-134,140,151,227,139,237,52,11,88,37,62,33,163,37,248,226,251,77,32,213,184,
-64,89,56,39,49,224,137,61,196,5,96,38,35,251,200,15,18,61,96,17,62,40,6,
-145,1,17,31,228,64,89,45,2,39,205,0,178,122,209,63,162,2,101,64,202,113,67,
-77,247,64,92,221,197,186,196,143,4,9,19,208,1,25,187,139,112,128,178,113,
-110,177,35,193,2,68,244,0,46,110,229,30,242,71,130,4,137,232,4,35,55,113,
-110,16,22,78,81,239,36,120,32,72,158,128,64,147,138,25,249,0,52,72,242,2,
-127,2,5,74,96,140,229,203,34,103,250,154,4,17,163,151,44,137,159,234,105,4,
-33,162,93,6,73,123,13,1,165,64,202,113,251,33,6,64,14,71,78,20,101,213,207,
-4,194,207,2,12,162,0,158,176,23,218,168,23,66,64,255,255,255,255,255,255,
-239,127,19,214,33,187,85,2,232,72,0,32,0,0,0,0,0,0,25,136,0,0,0,0,0,0,31,
-15,228,122,247,73,19,69,73,180,134,149,13,68,241,0,0,0,0,0,0,3,193,252,143,
-90,67,2,104,169,54,144,210,161,168,158,32,0,0,0,0,0,0,120,127,142,73,78,20,
-0,0,0,0,0,0,0,0,8,58,189,233,24,77,217,24,93,240,1,230,238,21,23,32,247,68,
-13,155,184,75,189,205,35,102,128,47,114,64,185,187,143,137,4,137,33,205,
-222,17,6,96,48,87,130,50,37,114,1,246,147,21,143,224,54,186,213,128,114,90,
-112,164,0,0,0,0,0,0,124,63,226,117,119,128,25,55,112,96,153,57,41,197,13,
-53,224,65,147,119,38,134,19,146,156,80,211,94,5,194,94,6,37,55,113,110,16,
-22,78,12,19,39,37,56,161,166,188,14,74,110,226,220,32,44,156,154,24,78,74,
-113,67,77,120,32,97,175,4,28,61,224,133,172,186,70,22,248,1,204,73,242,104,
-97,47,128,44,196,159,11,69,175,152,32,35,100,33,142,49,39,218,76,69,237,22,
-190,96,128,141,144,136,32,196,159,24,230,204,246,66,40,179,18,125,164,196,
-206,185,179,61,144,140,28,196,159,6,9,146,200,71,20,98,79,180,152,135,208,
-76,150,66,64,99,18,124,24,49,100,36,137,49,39,218,76,67,232,49,100,37,8,49,
-39,195,186,145,149,144,150,44,196,159,105,49,31,174,164,101,100,38,10,49,
-39,198,33,180,153,37,100,38,141,49,39,218,76,76,234,27,73,146,86,66,112,
-163,18,124,145,4,230,142,86,66,120,211,18,125,164,197,46,144,78,104,229,
-100,40,15,49,39,198,33,107,68,136,39,52,114,178,20,73,24,147,237,38,38,117,
-11,90,36,65,57,163,149,144,164,68,196,159,38,134,19,46,105,56,226,150,68,
-157,160,3,200,147,228,208,194,92,32,124,137,62,49,11,90,36,65,57,163,149,
-178,166,74,68,159,105,49,51,168,90,209,34,9,205,28,173,149,65,82,36,249,34,
-9,205,28,173,175,170,54,68,159,105,49,75,164,19,154,57,91,95,88,84,137,62,
-49,13,164,201,43,111,235,141,145,39,218,76,76,234,27,73,146,86,223,216,17,
-34,79,135,117,35,43,115,236,139,145,39,218,76,71,235,169,25,91,159,104,60,
-137,62,12,19,37,178,182,42,68,159,105,49,15,160,153,45,149,193,18,36,248,
-199,54,103,182,190,232,185,18,125,164,196,206,185,179,61,181,247,133,200,
-147,225,104,181,243,4,4,109,191,190,58,68,159,105,49,23,180,90,249,130,2,
-54,223,224,67,152,147,230,8,8,217,12,16,121,18,124,193,1,27,101,131,131,56,
-7,38,193,198,72,0,0,0,0,0,0,0,0,198,231,240,134,39,63,136,151,95,63,136,49,
-89,252,66,98,243,248,133,96,132,185,5,224,32,36,201,41,248,200,213,249,0,
-131,64,7,39,192,218,148,124,137,74,216,231,198,227,141,182,124,78,40,217,
-231,197,227,4,213,227,192,159,72,10,5,21,218,138,120,74,129,124,36,98,232,
-228,74,81,62,160,20,10,107,181,21,114,32,105,137,194,70,46,142,68,165,19,
-235,1,64,170,187,81,119,34,66,146,36,104,137,194,70,46,142,68,165,19,236,1,
-64,174,187,81,95,37,134,204,23,225,35,23,71,34,82,137,246,128,160,89,93,
-168,167,147,195,201,194,70,46,142,68,165,19,238,1,64,182,187,81,71,105,20,
-19,177,139,163,145,41,68,16,7,6,15,82,70,72,115,96,0,0,0,0,32,93,105,160,
-91,60,149,195,200,194,8,134,149,216,114,1,128,83,192,144,8,194,195,16,12,
-168,110,20,120,12,141,22,16,120,12,100,22,12,120,28,78,99,192,41,224,136,
-115,36,14,100,197,213,245,193,48,189,112,40,2,237,96,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,28,1,204,178,10,14,38,78,44,141,52,207,31,0,0,21,64,129,100,180,8,148,
-145,92,203,176,160,226,100,226,200,211,76,241,240,0,1,84,2,131,137,147,142,
-41,100,73,199,192,0,5,88,6,13,10,82,70,62,0,0,42,66,88,115,18,124,67,103,
-177,69,49,130,12,73,242,136,108,246,40,165,177,6,36,248,134,207,71,90,138,
-99,68,152,147,229,16,217,232,235,81,75,130,12,73,241,13,158,158,149,20,199,
-9,49,39,202,33,179,211,210,162,151,69,24,147,225,86,224,79,79,74,138,94,20,
-98,79,133,91,129,61,109,74,41,124,60,137,62,33,179,216,166,216,193,18,36,
-249,68,54,123,20,218,216,137,18,124,67,103,163,173,77,177,162,100,73,242,
-136,108,244,117,169,181,193,18,36,248,134,207,79,74,155,99,132,200,147,229,
-16,217,233,233,83,107,162,164,73,240,171,112,39,167,165,77,175,10,145,39,
-194,173,192,158,182,165,54,191,153,51,72,71,161,196,201,45,167,146,59,68,
-89,24,70,206,0,0,0,0,0,0,7,129,249,153,51,104,71,161,196,201,45,167,146,59,
-68,89,24,70,206,0,0,0,0,0,0,7,129,249,153,51,136,71,161,196,201,45,167,146,
-59,68,89,24,70,206,0,0,0,0,0,0,7,129,249,153,51,168,71,161,196,201,45,167,
-146,59,68,89,24,70,206,0,0,0,0,0,0,0,2,1,153,51,200,71,161,196,201,45,167,
-146,59,68,89,24,70,206,0,0,0,0,0,0,0,2,1,153,51,232,71,161,196,201,45,167,
-146,59,68,89,24,70,206,0,0,0,0,0,0,0,130,1,153,52,8,71,161,196,201,45,167,
-146,59,68,89,24,70,206,0,0,0,0,0,0,0,130,1,153,52,40,71,161,196,201,45,167,
-146,59,68,89,24,70,206,0,0,0,0,0,0,0,130,1,153,52,72,71,161,196,201,45,167,
-146,59,68,89,24,70,206,0,0,0,0,0,0,1,2,1,135,52,102,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,123,
-102,53,155,80,2,21,11,94,201,128,196,133,0,185,80,32,56,156,199,130,36,160,
-72,16,78,126,54,48,5,146,208,34,82,72,1,109,20,76,155,120,28,34,1,225,32,
-52,171,138,69,133,95,130,160,4,234,219,163,161,0,89,86,214,238,197,172,9,0,
-31,86,221,40,29,231,63,95,200,69,220,199,225,122,183,27,72,144,63,160,138,
-217,81,197,125,207,195,117,110,54,142,129,32,7,114,147,10,189,229,237,159,
-130,235,209,0,96,181,17,83,236,132,37,0,63,101,8,207,71,107,74,6,105,219,
-251,52,245,7,49,248,94,202,17,158,148,12,211,183,246,105,234,15,99,242,159,
-129,228,176,192,185,127,46,155,185,41,197,13,55,38,3,127,255,20,138,160,
-192,25,106,8,8,1,58,90,130,64,128,146,27,168,37,8,9,129,186,130,96,160,152,
-27,165,171,64,32,131,25,234,10,64,65,17,11,212,19,133,18,243,167,165,163,
-32,24,157,45,65,64,6,75,191,80,80,66,149,110,116,117,5,8,41,240,247,79,72,
-188,8,134,81,122,84,1,173,198,212,20,48,139,113,180,181,5,36,42,220,109,29,
-13,65,74,6,192,95,76,188,6,196,55,78,188,6,247,91,86,136,26,32,104,220,205,
-72,1,98,234,52,122,130,136,18,72,51,117,68,3,146,27,168,40,161,37,8,207,80,
-81,129,204,13,212,20,112,179,141,26,45,65,75,112,20,43,193,25,19,66,128,
-153,78,40,105,144,92,104,152,131,124,27,253,128,0,10,116,3,68,146,163,9,
-128,0,10,102,3,138,145,137,27,60,0,0,82,129,7,2,4,16,7,2,70,143,178,203,
-164,237,35,14,25,10,134,147,143,139,158,72,207,28,54,77,47,109,13,55,113,
-120,96,196,159,29,102,241,241,115,201,25,227,131,36,133,20,62,110,143,17,
-16,113,137,62,62,46,155,167,135,147,142,47,44,151,79,221,64,98,37,194,94,
-100,108,144,21,147,140,73,168,228,19,17,124,73,82,54,124,37,230,70,201,14,
-108,185,36,155,14,243,243,83,212,69,131,132,4,12,137,114,168,37,166,145,7,
-10,4,28,200,14,12,40,56,153,56,178,52,211,60,124,0,0,85,0,160,226,100,227,
-138,89,18,113,240,0,1,86,1,131,66,148,145,143,128,0,10,144,93,134,0,0,43,
-80,17,42,4,17,136,49,73,19,49,134,16,143,67,137,146,91,79,36,118,136,178,
-48,141,156,0,0,0,0,0,0,15,3,243,49,135,16,143,67,137,146,91,79,36,118,136,
-178,48,141,156,0,0,0,0,0,0,15,3,245,20,5,173,194,227,214,4,55,0,0,21,196,7,
-122,192,134,241,197,192,0,5,121,25,140,64,132,122,28,76,146,218,121,35,180,
-69,145,132,108,224,0,0,0,0,0,0,120,31,153,140,72,132,122,28,76,146,218,121,
-35,180,69,145,132,108,224,0,0,0,0,0,0,0,32,25,140,80,132,122,28,76,146,218,
-121,35,180,69,145,132,108,224,0,0,0,0,0,0,0,32,25,140,88,132,122,28,76,146,
-218,121,35,180,69,145,132,108,224,0,0,0,0,0,0,8,32,25,140,96,132,122,28,76,
-146,218,121,35,180,69,145,132,108,224,0,0,0,0,0,0,8,32,25,140,104,132,122,
-28,76,146,218,121,35,180,69,145,132,108,224,0,0,0,0,0,0,8,32,25,140,112,
-132,122,28,76,146,218,121,35,180,69,145,132,108,224,0,0,0,0,0,0,16,32,16,
-113,225,0,48,156,209,2,122,244,5,34,92,35,68,225,161,166,218,16,33,18,224,
-104,82,146,59,50,5,7,19,39,22,70,154,103,215,32,28,78,99,193,18,80,70,131,
-165,1,205,34,8,35,68,225,161,166,239,255,4,12,70,137,195,39,248,73,7,78,3,
-154,102,16,70,137,195,67,77,223,248,1,74,9,129,125,255,130,9,65,154,232,
-147,161,115,59,255,5,64,195,32,156,50,126,197,14,2,3,107,173,213,0,
+1,82,29,201,158,46,183,39,135,147,132,140,93,16,132,76,66,33,8,66,16,132,
+33,8,66,26,179,233,97,167,60,150,34,33,154,112,0,1,75,247,35,79,95,237,198,
+174,200,47,31,23,95,17,13,51,19,35,93,68,216,209,128,0,10,208,174,79,15,32,
+248,8,196,24,8,107,192,0,5,106,118,27,94,0,0,43,83,227,94,0,0,43,84,46,215,
+128,0,10,213,28,198,188,0,0,86,169,100,53,224,0,2,181,79,85,175,0,0,21,170,
+154,45,120,0,0,173,85,217,107,192,0,5,106,182,243,86,193,106,52,127,130,
+249,50,94,124,35,68,225,146,49,13,31,186,23,201,146,243,224,200,39,12,145,
+136,67,134,19,49,0,0,0,0,0,0,3,225,255,51,0,0,0,0,0,0,3,193,255,47,18,1,
+172,19,120,71,10,25,196,136,113,162,156,136,199,42,57,204,144,115,132,240,
+149,2,248,72,197,209,58,2,185,16,52,196,225,35,23,68,233,14,228,72,82,68,
+141,17,56,72,197,209,58,130,249,44,54,96,191,9,24,186,39,88,79,39,135,147,
+132,140,93,19,176,35,180,138,9,216,197,209,59,82,79,35,40,242,65,248,58,42,
+96,121,14,232,94,62,46,190,15,42,31,145,33,86,65,76,242,214,143,73,48,242,
+243,79,49,56,243,115,207,57,64,243,180,79,61,72,243,244,207,65,80,244,53,
+79,69,88,244,98,30,8,200,156,67,102,120,241,79,4,100,78,21,110,4,207,32,47,
+147,37,231,194,52,78,25,34,122,81,124,153,47,62,12,130,112,201,19,211,139,
+121,34,87,69,128,104,137,239,83,18,238,108,165,2,162,92,104,56,220,233,1,8,
+151,10,134,162,100,206,16,18,50,9,195,39,105,20,101,136,18,25,4,225,147,
+180,138,5,215,49,238,105,27,60,185,1,36,104,156,50,118,145,70,96,129,34,52,
+78,25,59,72,160,93,115,30,230,145,179,204,144,12,73,8,15,38,104,128,138,52,
+146,16,30,77,1,0,2,11,132,193,198,36,248,248,186,110,158,30,78,56,188,194,
+70,183,170,136,48,98,79,142,179,120,248,185,228,140,241,193,146,66,138,31,
+55,71,138,128,153,137,62,58,205,227,226,231,146,51,199,26,6,18,92,146,64,
+96,74,72,51,120,43,192,97,68,128,153,56,72,7,12,133,67,73,199,197,207,36,
+103,142,35,2,3,33,80,210,113,241,115,201,25,160,146,225,160,9,34,1,124,178,
+1,139,18,19,36,229,146,8,190,36,169,27,62,18,243,35,100,135,54,92,162,2,17,
+46,72,128,89,7,200,32,33,18,225,98,236,145,188,130,64,196,75,132,188,200,
+217,32,43,39,28,128,69,19,18,228,144,42,98,79,142,179,120,248,185,228,140,
+241,201,97,129,114,229,201,37,2,68,184,200,1,147,93,159,153,213,34,235,250,
+96,48,157,32,24,94,160,1,199,4,184,235,55,143,139,158,72,207,28,226,3,81,
+46,62,46,155,167,135,147,142,47,60,129,71,197,207,36,103,142,34,92,35,104,
+194,68,1,89,58,36,8,109,109,12,133,67,73,195,18,115,36,118,182,185,168,8,
+109,109,12,133,67,73,201,18,115,36,118,182,185,168,130,27,91,75,115,149,71,
+240,196,156,201,29,173,174,129,2,27,91,75,115,149,71,242,68,156,201,29,173,
+174,129,34,12,16,28,128,62,191,42,3,71,146,68,4,16,22,188,161,240,16,40,
+104,242,103,196,16,93,158,125,96,110,115,235,64,131,16,16,58,37,192,70,32,
+194,144,114,25,67,95,40,6,18,8,32,48,156,209,2,108,124,96,224,144,6,247,62,
+16,0,143,164,143,12,248,15,18,84,145,145,34,128,11,35,160,179,140,0,44,150,
+129,18,58,0,146,116,103,32,128,105,61,104,17,36,175,1,232,217,29,5,156,179,
+224,58,26,50,95,142,43,159,64,181,130,83,226,26,50,95,142,43,159,192,7,255,
+248,41,42,72,226,1,160,18,78,97,32,26,64,114,186,60,32,4,120,6,148,13,128,
+124,3,76,12,84,46,100,140,3,78,13,18,14,130,36,67,232,23,18,14,130,39,34,
+131,30,113,15,224,3,255,253,6,48,40,194,197,204,224,142,8,240,78,25,60,231,
+192,210,197,204,224,156,50,113,238,67,103,232,62,28,138,156,104,82,170,107,
+255,32,48,191,144,1,132,112,71,128,159,168,128,161,28,17,224,156,50,112,19,
+245,144,22,39,12,156,123,144,217,240,19,245,146,3,9,205,16,39,236,62,3,161,
+163,37,248,226,251,141,1,107,4,167,196,52,100,191,28,95,113,164,13,91,132,
+5,147,130,115,30,8,147,222,64,43,1,49,31,224,64,60,72,245,128,68,249,32,13,
+34,2,34,63,204,128,89,45,2,39,209,0,89,61,104,159,213,0,153,80,50,156,80,
+211,126,16,11,155,184,183,88,145,224,129,34,122,64,17,155,184,183,8,11,39,
+22,235,18,60,16,36,79,72,1,115,119,40,247,146,60,16,36,79,72,32,140,221,
+197,184,64,89,57,71,188,145,224,129,34,122,65,1,39,20,51,244,0,52,72,242,2,
+127,18,2,165,48,70,114,229,145,51,253,141,1,4,104,229,203,34,103,251,26,64,
+132,52,75,160,201,47,105,160,26,84,12,167,31,186,8,50,0,114,58,113,163,46,
+190,120,35,11,60,4,25,68,81,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,15,210,
+62,72,91,155,0,0,0,0,0,0,2,192,240,135,88,11,237,72,5,38,210,27,50,24,145,
+129,255,255,255,255,255,254,126,134,67,172,67,118,164,2,147,105,13,153,12,
+72,192,255,255,255,255,255,255,63,195,16,240,70,68,226,27,51,199,138,120,
+35,34,112,171,112,38,121,7,16,137,112,168,106,38,77,193,1,40,151,16,217,
+144,196,142,224,144,21,18,227,65,198,238,9,67,81,46,72,5,39,16,217,144,196,
+142,224,152,228,148,227,64,0,0,0,0,0,0,0,0,131,175,223,16,194,111,8,97,119,
+224,3,205,220,42,46,65,238,200,13,155,184,75,189,205,35,102,128,47,116,64,
+92,221,199,196,130,68,144,230,239,72,65,152,12,21,224,140,137,92,128,62,
+210,98,177,252,3,107,173,88,3,146,211,141,32,0,0,0,0,0,3,225,255,19,175,
+188,0,100,221,193,130,100,228,167,20,52,215,129,3,38,238,77,12,39,37,56,
+161,166,188,10,194,94,6,18,155,184,183,8,11,39,6,9,147,146,156,80,211,94,7,
+18,155,184,183,8,11,39,38,134,19,146,156,80,211,94,8,12,53,224,130,195,222,
+8,77,133,210,24,91,224,3,152,147,228,208,194,95,0,44,196,159,11,69,175,152,
+32,35,100,33,135,24,147,237,38,34,246,139,95,48,64,70,200,68,8,49,39,198,
+57,179,61,144,138,22,98,79,180,152,153,215,54,103,178,17,129,204,73,240,96,
+153,44,132,112,163,18,125,164,196,62,130,100,178,18,1,140,73,240,96,197,
+144,146,18,98,79,180,152,135,208,98,200,74,8,49,39,195,186,145,149,144,150,
+22,98,79,180,152,143,215,82,50,178,19,2,140,73,241,136,109,38,73,89,9,161,
+166,36,251,73,137,157,67,105,50,74,200,78,10,49,39,201,16,78,104,229,100,
+39,134,152,147,237,38,41,116,130,115,71,43,33,64,60,196,159,24,133,173,18,
+32,156,209,202,200,81,18,49,39,218,76,76,234,22,180,72,130,115,71,43,33,72,
+68,196,159,38,134,19,46,105,56,226,150,68,157,160,1,228,73,242,104,97,46,
+16,31,34,79,140,66,214,137,16,78,104,229,108,169,137,72,147,237,38,38,117,
+11,90,36,65,57,163,149,178,168,21,34,79,146,32,156,209,202,218,250,161,178,
+36,251,73,138,93,32,156,209,202,218,250,193,82,36,248,196,54,147,36,173,
+191,174,27,34,79,180,152,153,212,54,147,36,173,191,176,17,34,79,135,117,35,
+43,115,236,133,200,147,237,38,35,245,212,140,173,207,180,15,34,79,131,4,
+201,108,173,133,72,147,237,38,33,244,19,37,178,184,17,34,79,140,115,102,
+123,107,238,133,200,147,237,38,38,117,205,153,237,175,188,23,34,79,133,162,
+215,204,16,17,182,254,248,116,137,62,210,98,47,104,181,243,4,4,109,191,192,
+131,152,147,230,8,8,217,12,16,60,137,62,96,128,141,178,193,160,206,1,201,
+176,113,146,0,0,0,0,0,0,0,0,49,185,252,65,137,207,227,37,215,207,227,12,86,
+127,24,152,188,254,49,88,33,46,65,120,72,4,153,37,63,33,13,127,148,4,26,0,
+57,62,6,228,163,228,74,86,215,62,55,28,110,179,226,113,70,223,62,47,24,38,
+191,30,2,125,32,40,20,87,114,41,225,42,5,240,145,139,163,145,41,68,250,128,
+80,41,174,228,85,200,129,166,39,9,24,186,57,18,148,79,172,5,2,170,238,69,
+220,137,10,72,145,162,39,9,24,186,57,18,148,79,176,5,2,186,238,69,124,150,
+27,48,95,132,140,93,28,137,74,39,218,2,129,101,119,34,158,79,15,39,9,24,
+186,57,18,148,79,184,5,2,218,238,69,29,164,80,78,198,46,142,68,165,16,64,
+28,24,61,73,25,33,205,128,0,0,0,0,1,167,166,129,108,242,151,15,39,8,34,26,
+87,97,200,3,0,167,129,32,8,194,195,16,6,84,55,10,60,3,35,69,132,30,1,140,
+130,193,143,1,196,230,60,2,158,8,131,153,64,115,42,46,191,176,8,194,246,0,
+80,5,220,193,95,6,234,5,100,225,35,23,71,35,6,228,140,93,29,180,55,108,145,
+139,163,182,112,52,107,67,76,56,3,153,132,20,28,76,156,89,26,105,158,62,0,
+0,42,193,2,201,104,17,41,34,156,204,176,160,226,100,226,200,211,76,241,240,
+0,1,86,2,131,137,147,142,41,100,73,199,192,0,5,96,6,13,10,82,70,62,0,0,42,
+130,88,115,18,124,67,103,177,69,49,129,6,36,249,68,54,123,20,82,216,65,137,
+62,33,179,209,214,162,152,208,147,18,124,162,27,61,29,106,41,112,32,196,
+159,16,217,233,233,81,76,112,73,137,62,81,13,158,158,149,20,186,20,98,79,
+133,91,129,61,61,42,41,120,40,196,159,10,183,2,122,218,148,82,248,60,137,
+62,33,179,216,166,216,192,137,18,124,162,27,61,138,109,108,34,68,159,16,
+217,232,235,83,108,104,76,137,62,81,13,158,142,181,54,184,17,34,79,136,108,
+244,244,169,182,56,38,68,159,40,134,207,79,74,155,93,10,145,39,194,173,192,
+158,158,149,54,188,21,34,79,133,91,129,61,109,74,109,125,155,51,136,71,161,
+196,201,45,167,146,59,68,89,24,70,206,0,0,0,0,0,0,7,129,249,155,51,168,71,
+161,196,201,45,167,146,59,68,89,24,70,206,0,0,0,0,0,0,7,129,249,155,51,200,
+71,161,196,201,45,167,146,59,68,89,24,70,206,0,0,0,0,0,0,7,129,249,155,51,
+232,71,161,196,201,45,167,146,59,68,89,24,70,206,0,0,0,0,0,0,0,2,1,155,52,
+8,71,161,196,201,45,167,146,59,68,89,24,70,206,0,0,0,0,0,0,0,2,1,155,52,40,
+71,161,196,201,45,167,146,59,68,89,24,70,206,0,0,0,0,0,0,0,130,1,155,52,72,
+71,161,196,201,45,167,146,59,68,89,24,70,206,0,0,0,0,0,0,0,130,1,155,52,
+104,71,161,196,201,45,167,146,59,68,89,24,70,206,0,0,0,0,0,0,0,130,1,155,
+52,136,71,161,196,201,45,167,146,59,68,89,24,70,206,0,0,0,0,0,0,1,2,1,135,
+52,166,32,76,72,1,246,136,235,103,177,69,0,136,144,3,226,27,61,138,41,44,
+50,36,0,251,68,117,179,209,214,234,201,69,16,50,36,0,251,68,117,179,209,
+214,232,73,69,34,5,196,128,31,16,217,232,235,117,100,162,147,2,226,64,15,
+136,108,244,117,186,18,81,74,129,145,32,7,218,35,173,158,158,151,86,74,40,
+161,145,32,7,218,35,173,158,158,151,66,74,41,20,46,36,0,248,134,207,79,75,
+171,37,20,154,23,18,0,124,67,103,167,165,208,146,138,85,11,137,0,62,21,110,
+4,250,178,81,70,11,137,0,62,21,110,4,250,18,81,72,193,145,32,7,193,186,129,
+89,58,178,81,71,12,137,0,62,13,212,10,201,208,146,138,71,10,137,0,62,209,
+29,108,250,178,81,104,1,81,32,7,218,35,173,159,66,74,45,32,38,36,0,248,134,
+207,171,37,22,160,19,18,0,124,67,103,208,146,139,88,10,180,81,50,118,136,
+235,103,177,77,128,155,69,19,39,16,217,236,83,105,97,182,138,38,78,209,29,
+108,244,117,186,178,83,100,13,180,81,50,118,136,235,103,163,173,208,146,
+155,68,12,180,81,50,113,13,158,142,183,86,74,109,48,50,209,68,201,196,54,
+122,58,221,9,41,181,64,219,69,19,39,104,142,182,122,122,93,89,41,178,134,
+218,40,153,59,68,117,179,211,210,232,73,77,162,134,90,40,153,56,134,207,79,
+75,171,37,54,154,25,104,162,100,226,27,61,61,46,132,148,218,168,101,162,
+137,147,133,91,129,62,172,148,217,131,45,20,76,156,42,220,9,244,36,166,209,
+131,109,20,76,156,27,168,21,147,171,37,54,112,219,69,19,39,6,234,5,100,232,
+73,77,163,133,218,40,153,59,68,117,179,234,201,78,32,5,218,40,153,59,68,
+117,179,232,73,78,36,5,90,40,153,56,134,207,171,37,56,160,21,104,162,100,
+226,27,62,132,148,226,195,95,182,97,176,218,128,8,84,45,123,38,1,137,10,1,
+114,160,64,56,156,199,130,36,160,72,8,39,63,27,24,1,100,180,8,148,146,0,45,
+162,137,147,111,2,8,4,16,7,8,96,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,254,168,48,6,90,130,1,0,39,75,80,72,8,
+9,33,186,130,80,64,76,13,212,19,2,130,96,110,150,173,0,65,6,51,212,20,128,
+65,17,11,212,19,130,137,121,211,210,209,144,6,39,75,80,80,0,201,119,234,10,
+8,41,86,231,71,80,80,129,79,135,186,122,69,224,34,25,69,233,80,3,91,141,
+168,40,96,139,113,180,181,5,36,21,110,54,142,134,160,165,1,176,23,211,47,0,
+216,134,233,215,128,111,117,181,104,128,209,3,70,230,106,64,5,139,168,209,
+234,10,32,36,144,102,234,136,3,146,27,168,40,160,146,132,103,168,40,192,
+115,3,117,5,28,22,113,163,69,168,41,103,1,66,188,17,145,52,40,4,202,113,67,
+76,130,227,68,194,13,240,108,0,0,83,96,0,2,161,0,104,146,84,97,48,0,1,78,
+192,56,169,24,145,179,192,0,5,48,8,56,16,32,128,56,18,52,125,166,86,147,
+182,140,28,50,21,13,39,31,23,60,145,158,56,140,141,47,113,6,155,186,188,24,
+49,39,199,89,188,124,92,242,70,120,224,201,33,69,15,155,163,197,68,14,49,
+39,199,197,211,116,240,242,113,197,230,18,180,253,228,3,17,46,18,243,35,
+100,128,172,156,114,70,163,146,76,34,248,146,164,108,248,75,204,141,146,28,
+217,114,137,27,78,251,241,173,234,162,160,225,1,3,34,92,170,9,105,164,32,
+225,64,131,155,1,193,133,7,19,39,22,70,154,103,143,128,0,10,176,20,28,76,
+156,113,75,34,78,62,0,0,43,0,48,104,82,146,49,240,0,1,84,11,180,192,0,5,
+114,1,18,160,65,24,131,20,145,25,172,48,132,122,28,76,146,218,121,35,180,
+69,145,132,108,224,0,0,0,0,0,0,120,31,153,172,56,132,122,28,76,146,218,121,
+35,180,69,145,132,108,224,0,0,0,0,0,0,120,31,168,160,45,110,23,30,176,33,
+184,0,0,175,32,29,235,2,27,199,23,0,0,22,4,51,88,129,8,244,56,153,37,180,
+242,71,104,139,35,8,217,192,0,0,0,0,0,0,240,63,51,88,145,8,244,56,153,37,
+180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,0,64,51,88,161,8,244,56,153,37,
+180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,0,64,51,88,177,8,244,56,153,37,
+180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,16,64,51,88,193,8,244,56,153,
+37,180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,16,64,51,88,209,8,244,56,
+153,37,180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,16,64,51,88,225,8,244,
+56,153,37,180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,32,64,32,227,194,0,
+97,57,162,4,245,232,5,34,92,35,68,225,161,166,218,16,16,137,112,52,41,73,
+29,153,1,65,196,201,197,145,166,153,245,200,3,137,204,120,34,74,8,200,58,
+112,28,211,32,130,52,78,26,26,110,248,0,0,164,4,12,70,137,195,39,252,73,
+240,117,32,57,168,97,4,104,156,52,52,221,255,160,20,160,152,23,223,250,32,
+148,25,174,137,58,23,51,191,244,84,12,50,9,195,39,240,81,238,2,3,107,173,
+214,3,192,
};
#elif defined(DUK_USE_DOUBLE_BE)
-DUK_INTERNAL const duk_uint8_t duk_builtins_data[3972] = {
-144,148,105,223,160,68,52,228,62,12,104,200,165,132,52,167,194,138,105,242,
-252,57,28,211,57,18,64,52,238,62,44,138,111,171,241,164,19,87,125,30,33,
+DUK_INTERNAL const duk_uint8_t duk_builtins_data[4116] = {
+144,148,105,224,32,68,52,228,62,12,104,200,165,132,52,167,194,138,105,243,
+124,57,28,211,57,18,64,52,238,126,44,138,111,171,241,164,19,87,129,30,33,
167,16,145,159,8,211,136,9,225,42,5,240,145,139,163,163,8,211,136,10,228,
64,211,19,132,140,93,29,56,70,156,64,119,34,66,146,36,104,137,194,70,46,
142,172,35,78,32,47,146,195,102,11,240,145,139,163,175,8,211,136,9,228,240,
242,112,145,139,163,179,8,211,136,8,237,34,130,118,49,116,118,225,26,48,0,
-1,80,29,201,158,46,183,39,135,147,132,140,93,16,132,76,66,33,8,66,16,132,
-33,8,66,34,33,154,112,0,1,73,247,35,79,91,237,198,174,192,47,31,23,95,17,
-13,51,19,35,93,68,216,209,128,0,10,192,174,79,15,32,248,8,196,24,8,107,192,
-0,5,98,118,27,94,0,0,43,19,227,94,0,0,43,20,46,215,128,0,10,197,28,198,188,
-0,0,86,41,100,53,224,0,2,177,79,85,175,0,0,21,138,154,45,120,0,0,172,85,
-217,107,192,0,5,98,182,243,86,193,106,52,127,66,249,50,94,124,35,68,225,
-146,49,13,31,170,23,201,146,243,224,200,39,12,145,136,67,134,11,49,1,255,
-224,0,0,0,0,0,3,51,1,255,192,0,0,0,0,0,3,47,18,1,172,19,120,71,10,25,196,
-136,113,162,156,136,199,42,57,204,144,115,132,240,149,2,248,72,197,209,58,
-2,185,16,52,196,225,35,23,68,233,14,228,72,82,68,141,17,56,72,197,209,58,
-130,249,44,54,96,191,9,24,186,39,88,79,39,135,147,132,140,93,19,176,35,180,
-138,9,216,197,209,59,82,79,31,40,242,1,248,58,42,96,121,14,232,94,62,46,
-190,15,38,31,145,33,86,65,76,242,150,143,69,48,242,179,79,45,56,243,51,207,
-53,64,243,116,79,57,72,243,180,207,61,80,243,245,79,65,88,244,34,249,50,94,
-124,35,68,225,146,39,163,23,201,146,243,224,200,39,12,145,61,40,183,146,37,
-116,88,6,136,158,244,241,174,230,202,80,135,130,50,39,16,217,231,208,20,
-240,70,68,225,86,224,79,60,64,84,75,141,7,27,157,32,66,37,194,161,168,153,
-51,132,9,25,4,225,147,180,138,50,196,18,25,4,225,147,180,138,5,215,49,238,
-105,27,60,185,2,72,209,56,100,237,34,140,193,4,136,209,56,100,237,34,129,
-117,204,123,154,70,207,50,64,98,72,64,121,51,68,8,163,73,33,1,228,208,16,0,
-65,112,152,56,196,159,31,23,77,211,195,201,199,23,150,73,169,234,34,24,49,
-39,199,89,188,124,92,242,70,120,224,201,33,69,15,155,163,196,64,153,137,62,
-58,205,227,226,231,146,51,199,26,6,18,92,130,64,192,148,144,102,240,23,129,
-133,18,2,100,224,160,56,100,42,26,78,62,46,121,35,60,112,216,32,50,21,13,
-39,31,23,60,145,154,9,46,18,1,36,64,47,148,64,98,196,132,201,57,68,132,95,
-18,84,141,159,9,121,145,178,67,155,46,73,2,17,46,72,128,89,7,199,32,66,37,
-194,197,217,35,120,228,131,17,46,18,243,35,100,128,172,156,98,2,40,152,151,
-32,130,166,36,248,235,55,143,139,158,72,207,28,150,24,23,46,92,130,80,72,
-151,21,0,100,213,103,229,245,8,186,190,144,24,78,136,24,94,152,3,142,9,113,
-214,111,31,23,60,145,158,57,164,13,68,184,248,186,110,158,30,78,56,188,226,
-10,62,46,121,35,60,113,18,225,27,70,18,32,10,201,208,32,134,214,208,200,84,
-52,156,49,39,50,71,107,107,152,129,13,173,161,144,168,105,57,34,78,100,142,
-214,215,49,16,134,214,210,220,229,81,252,49,39,50,71,107,107,158,65,13,173,
-165,185,202,163,249,34,78,100,142,214,215,60,146,12,16,28,128,62,175,42,6,
-143,36,136,16,64,90,242,135,192,129,67,71,147,62,65,5,215,231,214,6,215,62,
-180,8,49,1,3,162,92,4,98,12,41,14,67,40,106,229,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,192,163,11,23,51,130,56,35,
-193,56,100,243,31,6,150,46,103,4,225,147,143,114,27,63,57,241,200,169,194,
-133,42,166,175,240,6,23,240,0,97,28,17,224,39,233,32,80,142,8,240,78,25,56,
-9,250,136,22,39,12,156,123,144,217,240,19,245,18,6,19,154,32,79,214,124,14,
-134,140,151,227,139,237,52,11,88,37,62,33,163,37,248,226,251,77,32,213,184,
-64,89,56,39,49,224,137,61,196,5,96,38,35,251,200,15,18,61,96,17,62,40,6,
-145,1,17,31,228,64,89,45,2,39,205,0,178,122,209,63,162,2,101,64,202,113,67,
-77,247,64,92,221,197,186,196,143,4,9,19,208,1,25,187,139,112,128,178,113,
-110,177,35,193,2,68,244,0,46,110,229,30,242,71,130,4,137,232,4,35,55,113,
-110,16,22,78,81,239,36,120,32,72,158,128,64,147,138,25,249,0,52,72,242,2,
-127,2,5,74,96,140,229,203,34,103,250,154,4,17,163,151,44,137,159,234,105,4,
-33,162,93,6,73,123,13,1,165,64,202,113,251,33,6,64,14,71,78,20,101,213,207,
-4,194,207,2,12,162,0,158,176,23,218,168,23,66,64,127,239,255,255,255,255,
-255,255,19,214,33,187,85,2,232,72,0,0,0,0,0,0,0,0,57,136,15,255,0,0,0,0,0,
-0,4,122,247,73,19,69,73,180,134,149,13,68,241,1,255,192,0,0,0,0,0,0,143,90,
-67,2,104,169,54,144,210,161,168,158,32,127,248,0,0,0,0,0,0,14,73,78,20,0,0,
-0,0,0,0,0,0,8,58,189,233,24,77,217,24,93,240,1,230,238,21,23,32,247,68,13,
-155,184,75,189,205,35,102,128,47,114,64,185,187,143,137,4,137,33,205,222,
-17,6,96,48,87,130,50,37,114,1,246,147,21,143,224,54,186,213,128,114,90,112,
-164,63,252,0,0,0,0,0,0,98,117,119,128,25,55,112,96,153,57,41,197,13,53,224,
-65,147,119,38,134,19,146,156,80,211,94,5,194,94,6,37,55,113,110,16,22,78,
-12,19,39,37,56,161,166,188,14,74,110,226,220,32,44,156,154,24,78,74,113,67,
-77,120,32,97,175,4,28,61,224,133,172,186,70,22,248,1,204,73,242,104,97,47,
-128,44,196,159,11,69,175,152,32,35,100,33,142,49,39,218,76,69,237,22,190,
-96,128,141,144,136,32,196,159,24,230,204,246,66,40,179,18,125,164,196,206,
-185,179,61,144,140,28,196,159,6,9,146,200,71,20,98,79,180,152,135,208,76,
-150,66,64,99,18,124,24,49,100,36,137,49,39,218,76,67,232,49,100,37,8,49,39,
-195,186,145,149,144,150,44,196,159,105,49,31,174,164,101,100,38,10,49,39,
-198,33,180,153,37,100,38,141,49,39,218,76,76,234,27,73,146,86,66,112,163,
-18,124,145,4,230,142,86,66,120,211,18,125,164,197,46,144,78,104,229,100,40,
-15,49,39,198,33,107,68,136,39,52,114,178,20,73,24,147,237,38,38,117,11,90,
-36,65,57,163,149,144,164,68,196,159,38,134,19,46,105,56,226,150,68,157,160,
-3,200,147,228,208,194,92,32,124,137,62,49,11,90,36,65,57,163,149,178,166,
-74,68,159,105,49,51,168,90,209,34,9,205,28,173,149,65,82,36,249,34,9,205,
-28,173,175,170,54,68,159,105,49,75,164,19,154,57,91,95,88,84,137,62,49,13,
-164,201,43,111,235,141,145,39,218,76,76,234,27,73,146,86,223,216,17,34,79,
-135,117,35,43,115,236,139,145,39,218,76,71,235,169,25,91,159,104,60,137,62,
-12,19,37,178,182,42,68,159,105,49,15,160,153,45,149,193,18,36,248,199,54,
-103,182,190,232,185,18,125,164,196,206,185,179,61,181,247,133,200,147,225,
-104,181,243,4,4,109,191,190,58,68,159,105,49,23,180,90,249,130,2,54,223,
-224,67,152,147,230,8,8,217,12,16,121,18,124,193,1,27,101,131,131,56,7,38,
-193,198,72,0,0,0,0,0,0,0,0,198,231,240,134,39,63,136,151,95,63,136,49,89,
-252,66,98,243,248,133,96,132,185,5,224,32,36,201,41,248,200,213,249,0,131,
-64,7,39,192,218,148,124,137,74,216,231,198,227,141,182,124,78,40,217,231,
-197,227,4,213,227,192,159,72,10,5,21,218,138,120,74,129,124,36,98,232,228,
-74,81,62,160,20,10,107,181,21,114,32,105,137,194,70,46,142,68,165,19,235,1,
-64,170,187,81,119,34,66,146,36,104,137,194,70,46,142,68,165,19,236,1,64,
-174,187,81,95,37,134,204,23,225,35,23,71,34,82,137,246,128,160,89,93,168,
-167,147,195,201,194,70,46,142,68,165,19,238,1,64,182,187,81,71,105,20,19,
-177,139,163,145,41,68,16,7,6,15,82,70,72,115,96,32,105,221,32,0,0,0,0,91,
-60,149,195,200,194,8,134,149,216,114,1,128,83,192,144,8,194,195,16,12,168,
-110,20,120,12,141,22,16,120,12,100,22,12,120,28,78,99,192,41,224,136,115,
-36,14,100,197,213,245,193,48,189,112,40,2,237,96,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,
-28,1,204,178,10,14,38,78,44,141,52,207,31,0,0,21,64,129,100,180,8,148,145,
-92,203,176,160,226,100,226,200,211,76,241,240,0,1,84,2,131,137,147,142,41,
-100,73,199,192,0,5,88,6,13,10,82,70,62,0,0,42,66,88,115,18,124,67,103,177,
-69,49,130,12,73,242,136,108,246,40,165,177,6,36,248,134,207,71,90,138,99,
-68,152,147,229,16,217,232,235,81,75,130,12,73,241,13,158,158,149,20,199,9,
-49,39,202,33,179,211,210,162,151,69,24,147,225,86,224,79,79,74,138,94,20,
-98,79,133,91,129,61,109,74,41,124,60,137,62,33,179,216,166,216,193,18,36,
-249,68,54,123,20,218,216,137,18,124,67,103,163,173,77,177,162,100,73,242,
-136,108,244,117,169,181,193,18,36,248,134,207,79,74,155,99,132,200,147,229,
-16,217,233,233,83,107,162,164,73,240,171,112,39,167,165,77,175,10,145,39,
-194,173,192,158,182,165,54,191,153,51,72,71,161,196,201,45,167,146,59,68,
-89,24,70,206,1,255,128,0,0,0,0,0,1,153,51,104,71,161,196,201,45,167,146,59,
-68,89,24,70,206,1,255,128,0,0,0,0,0,1,153,51,136,71,161,196,201,45,167,146,
-59,68,89,24,70,206,1,255,128,0,0,0,0,0,1,153,51,168,71,161,196,201,45,167,
-146,59,68,89,24,70,206,2,0,0,0,0,0,0,0,1,153,51,200,71,161,196,201,45,167,
-146,59,68,89,24,70,206,2,0,0,0,0,0,0,0,1,153,51,232,71,161,196,201,45,167,
-146,59,68,89,24,70,206,2,0,128,0,0,0,0,0,1,153,52,8,71,161,196,201,45,167,
-146,59,68,89,24,70,206,2,0,128,0,0,0,0,0,1,153,52,40,71,161,196,201,45,167,
-146,59,68,89,24,70,206,2,0,128,0,0,0,0,0,1,153,52,72,71,161,196,201,45,167,
-146,59,68,89,24,70,206,2,1,0,0,0,0,0,0,1,135,52,102,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,123,
-102,53,155,80,2,21,11,94,201,128,196,133,0,185,80,32,56,156,199,130,36,160,
-72,16,78,126,54,48,5,146,208,34,82,72,1,109,20,76,155,120,28,34,1,225,32,
-32,2,223,133,69,138,43,180,132,234,219,163,161,1,0,9,174,198,238,213,84,88,
-31,86,221,40,7,252,197,200,95,223,71,61,225,122,183,27,72,144,15,253,197,
-81,217,74,224,191,131,117,110,54,142,129,32,31,237,229,189,138,147,114,135,
-2,235,209,1,0,36,135,237,81,16,180,96,63,101,8,207,71,107,74,1,255,53,4,
-243,51,249,222,104,94,202,17,158,148,3,255,106,9,230,103,243,188,210,159,
-129,228,176,192,185,127,46,155,185,41,197,13,55,38,3,127,255,20,138,160,
-192,25,106,8,8,1,58,90,130,64,128,146,27,168,37,8,9,129,186,130,96,160,152,
-27,165,171,64,32,131,25,234,10,64,65,17,11,212,19,133,18,243,167,165,163,
-32,24,157,45,65,64,6,75,191,80,80,66,149,110,116,117,5,8,41,240,247,79,72,
-188,8,134,81,122,84,1,173,198,212,20,48,139,113,180,181,5,36,42,220,109,29,
-13,65,74,6,192,95,76,188,6,196,55,78,188,6,247,91,86,136,26,32,104,220,205,
-72,1,98,234,52,122,130,136,18,72,51,117,68,3,146,27,168,40,161,37,8,207,80,
-81,129,204,13,212,20,112,179,141,26,45,65,75,112,20,43,193,25,19,66,128,
-153,78,40,105,144,92,104,152,131,124,27,253,128,0,10,116,3,68,146,163,9,
-128,0,10,102,3,138,145,137,27,60,0,0,82,129,7,2,4,16,7,2,70,143,178,203,
-164,237,35,14,25,10,134,147,143,139,158,72,207,28,54,77,47,109,13,55,113,
-120,96,196,159,29,102,241,241,115,201,25,227,131,36,133,20,62,110,143,17,
-16,113,137,62,62,46,155,167,135,147,142,47,44,151,79,221,64,98,37,194,94,
-100,108,144,21,147,140,73,168,228,19,17,124,73,82,54,124,37,230,70,201,14,
-108,185,36,155,14,243,243,83,212,69,131,132,4,12,137,114,168,37,166,145,7,
-10,4,28,200,14,12,40,56,153,56,178,52,211,60,124,0,0,85,0,160,226,100,227,
-138,89,18,113,240,0,1,86,1,131,66,148,145,143,128,0,10,144,93,134,0,0,43,
-80,17,42,4,17,136,49,73,19,49,134,16,143,67,137,146,91,79,36,118,136,178,
-48,141,156,3,255,0,0,0,0,0,0,3,49,135,16,143,67,137,146,91,79,36,118,136,
-178,48,141,156,3,255,0,0,0,0,0,0,5,20,5,173,194,227,214,4,55,0,0,21,196,7,
-122,192,134,241,197,192,0,5,121,25,140,64,132,122,28,76,146,218,121,35,180,
-69,145,132,108,224,31,248,0,0,0,0,0,0,25,140,72,132,122,28,76,146,218,121,
-35,180,69,145,132,108,224,32,0,0,0,0,0,0,0,25,140,80,132,122,28,76,146,218,
-121,35,180,69,145,132,108,224,32,0,0,0,0,0,0,0,25,140,88,132,122,28,76,146,
-218,121,35,180,69,145,132,108,224,32,8,0,0,0,0,0,0,25,140,96,132,122,28,76,
-146,218,121,35,180,69,145,132,108,224,32,8,0,0,0,0,0,0,25,140,104,132,122,
-28,76,146,218,121,35,180,69,145,132,108,224,32,8,0,0,0,0,0,0,25,140,112,
-132,122,28,76,146,218,121,35,180,69,145,132,108,224,32,16,0,0,0,0,0,0,16,
-113,225,0,48,156,209,2,122,244,5,34,92,35,68,225,161,166,218,16,33,18,224,
-104,82,146,59,50,5,7,19,39,22,70,154,103,215,32,28,78,99,193,18,80,70,131,
-165,1,205,34,8,35,68,225,161,166,239,255,4,12,70,137,195,39,248,73,7,78,3,
-154,102,16,70,137,195,67,77,223,248,1,74,9,129,125,255,130,9,65,154,232,
-147,161,115,59,255,5,64,195,32,156,50,126,197,14,2,3,107,173,213,0,
+1,82,29,201,158,46,183,39,135,147,132,140,93,16,132,76,66,33,8,66,16,132,
+33,8,66,26,179,233,97,167,60,150,34,33,154,112,0,1,75,247,35,79,95,237,198,
+174,200,47,31,23,95,17,13,51,19,35,93,68,216,209,128,0,10,208,174,79,15,32,
+248,8,196,24,8,107,192,0,5,106,118,27,94,0,0,43,83,227,94,0,0,43,84,46,215,
+128,0,10,213,28,198,188,0,0,86,169,100,53,224,0,2,181,79,85,175,0,0,21,170,
+154,45,120,0,0,173,85,217,107,192,0,5,106,182,243,86,193,106,52,127,130,
+249,50,94,124,35,68,225,146,49,13,31,186,23,201,146,243,224,200,39,12,145,
+136,67,134,19,49,1,255,224,0,0,0,0,0,3,51,1,255,192,0,0,0,0,0,3,47,18,1,
+172,19,120,71,10,25,196,136,113,162,156,136,199,42,57,204,144,115,132,240,
+149,2,248,72,197,209,58,2,185,16,52,196,225,35,23,68,233,14,228,72,82,68,
+141,17,56,72,197,209,58,130,249,44,54,96,191,9,24,186,39,88,79,39,135,147,
+132,140,93,19,176,35,180,138,9,216,197,209,59,82,79,35,40,242,65,248,58,42,
+96,121,14,232,94,62,46,190,15,42,31,145,33,86,65,76,242,214,143,73,48,242,
+243,79,49,56,243,115,207,57,64,243,180,79,61,72,243,244,207,65,80,244,53,
+79,69,88,244,98,30,8,200,156,67,102,120,241,79,4,100,78,21,110,4,207,32,47,
+147,37,231,194,52,78,25,34,122,81,124,153,47,62,12,130,112,201,19,211,139,
+121,34,87,69,128,104,137,239,83,18,238,108,165,2,162,92,104,56,220,233,1,8,
+151,10,134,162,100,206,16,18,50,9,195,39,105,20,101,136,18,25,4,225,147,
+180,138,5,215,49,238,105,27,60,185,1,36,104,156,50,118,145,70,96,129,34,52,
+78,25,59,72,160,93,115,30,230,145,179,204,144,12,73,8,15,38,104,128,138,52,
+146,16,30,77,1,0,2,11,132,193,198,36,248,248,186,110,158,30,78,56,188,194,
+70,183,170,136,48,98,79,142,179,120,248,185,228,140,241,193,146,66,138,31,
+55,71,138,128,153,137,62,58,205,227,226,231,146,51,199,26,6,18,92,146,64,
+96,74,72,51,120,43,192,97,68,128,153,56,72,7,12,133,67,73,199,197,207,36,
+103,142,35,2,3,33,80,210,113,241,115,201,25,160,146,225,160,9,34,1,124,178,
+1,139,18,19,36,229,146,8,190,36,169,27,62,18,243,35,100,135,54,92,162,2,17,
+46,72,128,89,7,200,32,33,18,225,98,236,145,188,130,64,196,75,132,188,200,
+217,32,43,39,28,128,69,19,18,228,144,42,98,79,142,179,120,248,185,228,140,
+241,201,97,129,114,229,201,37,2,68,184,200,1,147,93,159,153,213,34,235,250,
+96,48,157,32,24,94,160,1,199,4,184,235,55,143,139,158,72,207,28,226,3,81,
+46,62,46,155,167,135,147,142,47,60,129,71,197,207,36,103,142,34,92,35,104,
+194,68,1,89,58,36,8,109,109,12,133,67,73,195,18,115,36,118,182,185,168,8,
+109,109,12,133,67,73,201,18,115,36,118,182,185,168,130,27,91,75,115,149,71,
+240,196,156,201,29,173,174,129,2,27,91,75,115,149,71,242,68,156,201,29,173,
+174,129,34,12,16,28,128,62,191,42,3,71,146,68,4,16,22,188,161,240,16,40,
+104,242,103,196,16,93,158,125,96,110,115,235,64,131,16,16,58,37,192,70,32,
+194,144,114,25,67,95,40,6,18,8,32,48,156,209,2,108,124,96,224,144,6,247,62,
+16,0,143,164,143,12,248,15,18,84,145,145,34,128,11,35,160,179,140,0,44,150,
+129,18,58,0,146,116,103,32,128,105,61,104,17,36,175,1,232,217,29,5,156,179,
+224,58,26,50,95,142,43,159,64,181,130,83,226,26,50,95,142,43,159,192,7,255,
+248,41,42,72,226,1,160,18,78,97,32,26,64,114,186,60,32,4,120,6,148,13,128,
+124,3,76,12,84,46,100,140,3,78,13,18,14,130,36,67,232,23,18,14,130,39,34,
+131,30,113,15,224,3,255,253,6,48,40,194,197,204,224,142,8,240,78,25,60,231,
+192,210,197,204,224,156,50,113,238,67,103,232,62,28,138,156,104,82,170,107,
+255,32,48,191,144,1,132,112,71,128,159,168,128,161,28,17,224,156,50,112,19,
+245,144,22,39,12,156,123,144,217,240,19,245,146,3,9,205,16,39,236,62,3,161,
+163,37,248,226,251,141,1,107,4,167,196,52,100,191,28,95,113,164,13,91,132,
+5,147,130,115,30,8,147,222,64,43,1,49,31,224,64,60,72,245,128,68,249,32,13,
+34,2,34,63,204,128,89,45,2,39,209,0,89,61,104,159,213,0,153,80,50,156,80,
+211,126,16,11,155,184,183,88,145,224,129,34,122,64,17,155,184,183,8,11,39,
+22,235,18,60,16,36,79,72,1,115,119,40,247,146,60,16,36,79,72,32,140,221,
+197,184,64,89,57,71,188,145,224,129,34,122,65,1,39,20,51,244,0,52,72,242,2,
+127,18,2,165,48,70,114,229,145,51,253,141,1,4,104,229,203,34,103,251,26,64,
+132,52,75,160,201,47,105,160,26,84,12,167,31,186,8,50,0,114,58,113,163,46,
+190,120,35,11,60,4,25,68,81,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,15,210,62,
+72,91,155,0,242,192,0,0,0,0,0,0,135,88,11,237,72,5,38,210,27,50,24,145,128,
+134,127,255,255,255,255,255,254,67,172,67,118,164,2,147,105,13,153,12,72,
+192,195,63,255,255,255,255,255,255,16,240,70,68,226,27,51,199,138,120,35,
+34,112,171,112,38,121,7,16,137,112,168,106,38,77,193,1,40,151,16,217,144,
+196,142,224,144,21,18,227,65,198,238,9,67,81,46,72,5,39,16,217,144,196,142,
+224,152,228,148,227,64,0,0,0,0,0,0,0,0,131,175,223,16,194,111,8,97,119,224,
+3,205,220,42,46,65,238,200,13,155,184,75,189,205,35,102,128,47,116,64,92,
+221,199,196,130,68,144,230,239,72,65,152,12,21,224,140,137,92,128,62,210,
+98,177,252,3,107,173,88,3,146,211,141,33,255,224,0,0,0,0,0,3,19,175,188,0,
+100,221,193,130,100,228,167,20,52,215,129,3,38,238,77,12,39,37,56,161,166,
+188,10,194,94,6,18,155,184,183,8,11,39,6,9,147,146,156,80,211,94,7,18,155,
+184,183,8,11,39,38,134,19,146,156,80,211,94,8,12,53,224,130,195,222,8,77,
+133,210,24,91,224,3,152,147,228,208,194,95,0,44,196,159,11,69,175,152,32,
+35,100,33,135,24,147,237,38,34,246,139,95,48,64,70,200,68,8,49,39,198,57,
+179,61,144,138,22,98,79,180,152,153,215,54,103,178,17,129,204,73,240,96,
+153,44,132,112,163,18,125,164,196,62,130,100,178,18,1,140,73,240,96,197,
+144,146,18,98,79,180,152,135,208,98,200,74,8,49,39,195,186,145,149,144,150,
+22,98,79,180,152,143,215,82,50,178,19,2,140,73,241,136,109,38,73,89,9,161,
+166,36,251,73,137,157,67,105,50,74,200,78,10,49,39,201,16,78,104,229,100,
+39,134,152,147,237,38,41,116,130,115,71,43,33,64,60,196,159,24,133,173,18,
+32,156,209,202,200,81,18,49,39,218,76,76,234,22,180,72,130,115,71,43,33,72,
+68,196,159,38,134,19,46,105,56,226,150,68,157,160,1,228,73,242,104,97,46,
+16,31,34,79,140,66,214,137,16,78,104,229,108,169,137,72,147,237,38,38,117,
+11,90,36,65,57,163,149,178,168,21,34,79,146,32,156,209,202,218,250,161,178,
+36,251,73,138,93,32,156,209,202,218,250,193,82,36,248,196,54,147,36,173,
+191,174,27,34,79,180,152,153,212,54,147,36,173,191,176,17,34,79,135,117,35,
+43,115,236,133,200,147,237,38,35,245,212,140,173,207,180,15,34,79,131,4,
+201,108,173,133,72,147,237,38,33,244,19,37,178,184,17,34,79,140,115,102,
+123,107,238,133,200,147,237,38,38,117,205,153,237,175,188,23,34,79,133,162,
+215,204,16,17,182,254,248,116,137,62,210,98,47,104,181,243,4,4,109,191,192,
+131,152,147,230,8,8,217,12,16,60,137,62,96,128,141,178,193,160,206,1,201,
+176,113,146,0,0,0,0,0,0,0,0,49,185,252,65,137,207,227,37,215,207,227,12,86,
+127,24,152,188,254,49,88,33,46,65,120,72,4,153,37,63,33,13,127,148,4,26,0,
+57,62,6,228,163,228,74,86,215,62,55,28,110,179,226,113,70,223,62,47,24,38,
+191,30,2,125,32,40,20,87,114,41,225,42,5,240,145,139,163,145,41,68,250,128,
+80,41,174,228,85,200,129,166,39,9,24,186,57,18,148,79,172,5,2,170,238,69,
+220,137,10,72,145,162,39,9,24,186,57,18,148,79,176,5,2,186,238,69,124,150,
+27,48,95,132,140,93,28,137,74,39,218,2,129,101,119,34,158,79,15,39,9,24,
+186,57,18,148,79,184,5,2,218,238,69,29,164,80,78,198,46,142,68,165,16,64,
+28,24,61,73,25,33,205,128,129,167,166,0,0,0,0,1,108,242,151,15,39,8,34,26,
+87,97,200,3,0,167,129,32,8,194,195,16,6,84,55,10,60,3,35,69,132,30,1,140,
+130,193,143,1,196,230,60,2,158,8,131,153,64,115,42,46,191,176,8,194,246,0,
+80,5,220,193,95,6,234,5,100,225,35,23,71,35,6,228,140,93,29,180,55,108,145,
+139,163,182,112,52,107,67,76,56,3,153,132,20,28,76,156,89,26,105,158,62,0,
+0,42,193,2,201,104,17,41,34,156,204,176,160,226,100,226,200,211,76,241,240,
+0,1,86,2,131,137,147,142,41,100,73,199,192,0,5,96,6,13,10,82,70,62,0,0,42,
+130,88,115,18,124,67,103,177,69,49,129,6,36,249,68,54,123,20,82,216,65,137,
+62,33,179,209,214,162,152,208,147,18,124,162,27,61,29,106,41,112,32,196,
+159,16,217,233,233,81,76,112,73,137,62,81,13,158,158,149,20,186,20,98,79,
+133,91,129,61,61,42,41,120,40,196,159,10,183,2,122,218,148,82,248,60,137,
+62,33,179,216,166,216,192,137,18,124,162,27,61,138,109,108,34,68,159,16,
+217,232,235,83,108,104,76,137,62,81,13,158,142,181,54,184,17,34,79,136,108,
+244,244,169,182,56,38,68,159,40,134,207,79,74,155,93,10,145,39,194,173,192,
+158,158,149,54,188,21,34,79,133,91,129,61,109,74,109,125,155,51,136,71,161,
+196,201,45,167,146,59,68,89,24,70,206,1,255,128,0,0,0,0,0,1,155,51,168,71,
+161,196,201,45,167,146,59,68,89,24,70,206,1,255,128,0,0,0,0,0,1,155,51,200,
+71,161,196,201,45,167,146,59,68,89,24,70,206,1,255,128,0,0,0,0,0,1,155,51,
+232,71,161,196,201,45,167,146,59,68,89,24,70,206,2,0,0,0,0,0,0,0,1,155,52,
+8,71,161,196,201,45,167,146,59,68,89,24,70,206,2,0,0,0,0,0,0,0,1,155,52,40,
+71,161,196,201,45,167,146,59,68,89,24,70,206,2,0,128,0,0,0,0,0,1,155,52,72,
+71,161,196,201,45,167,146,59,68,89,24,70,206,2,0,128,0,0,0,0,0,1,155,52,
+104,71,161,196,201,45,167,146,59,68,89,24,70,206,2,0,128,0,0,0,0,0,1,155,
+52,136,71,161,196,201,45,167,146,59,68,89,24,70,206,2,1,0,0,0,0,0,0,1,135,
+52,166,32,76,72,1,246,136,235,103,177,69,0,136,144,3,226,27,61,138,41,44,
+50,36,0,251,68,117,179,209,214,234,201,69,16,50,36,0,251,68,117,179,209,
+214,232,73,69,34,5,196,128,31,16,217,232,235,117,100,162,147,2,226,64,15,
+136,108,244,117,186,18,81,74,129,145,32,7,218,35,173,158,158,151,86,74,40,
+161,145,32,7,218,35,173,158,158,151,66,74,41,20,46,36,0,248,134,207,79,75,
+171,37,20,154,23,18,0,124,67,103,167,165,208,146,138,85,11,137,0,62,21,110,
+4,250,178,81,70,11,137,0,62,21,110,4,250,18,81,72,193,145,32,7,193,186,129,
+89,58,178,81,71,12,137,0,62,13,212,10,201,208,146,138,71,10,137,0,62,209,
+29,108,250,178,81,104,1,81,32,7,218,35,173,159,66,74,45,32,38,36,0,248,134,
+207,171,37,22,160,19,18,0,124,67,103,208,146,139,88,10,180,81,50,118,136,
+235,103,177,77,128,155,69,19,39,16,217,236,83,105,97,182,138,38,78,209,29,
+108,244,117,186,178,83,100,13,180,81,50,118,136,235,103,163,173,208,146,
+155,68,12,180,81,50,113,13,158,142,183,86,74,109,48,50,209,68,201,196,54,
+122,58,221,9,41,181,64,219,69,19,39,104,142,182,122,122,93,89,41,178,134,
+218,40,153,59,68,117,179,211,210,232,73,77,162,134,90,40,153,56,134,207,79,
+75,171,37,54,154,25,104,162,100,226,27,61,61,46,132,148,218,168,101,162,
+137,147,133,91,129,62,172,148,217,131,45,20,76,156,42,220,9,244,36,166,209,
+131,109,20,76,156,27,168,21,147,171,37,54,112,219,69,19,39,6,234,5,100,232,
+73,77,163,133,218,40,153,59,68,117,179,234,201,78,32,5,218,40,153,59,68,
+117,179,232,73,78,36,5,90,40,153,56,134,207,171,37,56,160,21,104,162,100,
+226,27,62,132,148,226,195,95,182,97,176,218,128,8,84,45,123,38,1,137,10,1,
+114,160,64,56,156,199,130,36,160,72,8,39,63,27,24,1,100,180,8,148,146,0,45,
+162,137,147,111,2,8,4,16,7,8,96,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,54,168,48,6,90,130,1,0,39,75,80,72,8,9,
+33,186,130,80,64,76,13,212,19,2,130,96,110,150,173,0,65,6,51,212,20,128,65,
+17,11,212,19,130,137,121,211,210,209,144,6,39,75,80,80,0,201,119,234,10,8,
+41,86,231,71,80,80,129,79,135,186,122,69,224,34,25,69,233,80,3,91,141,168,
+40,96,139,113,180,181,5,36,21,110,54,142,134,160,165,1,176,23,211,47,0,216,
+134,233,215,128,111,117,181,104,128,209,3,70,230,106,64,5,139,168,209,234,
+10,32,36,144,102,234,136,3,146,27,168,40,160,146,132,103,168,40,192,115,3,
+117,5,28,22,113,163,69,168,41,103,1,66,188,17,145,52,40,4,202,113,67,76,
+130,227,68,194,13,240,108,0,0,83,96,0,2,161,0,104,146,84,97,48,0,1,78,192,
+56,169,24,145,179,192,0,5,48,8,56,16,32,128,56,18,52,125,166,86,147,182,
+140,28,50,21,13,39,31,23,60,145,158,56,140,141,47,113,6,155,186,188,24,49,
+39,199,89,188,124,92,242,70,120,224,201,33,69,15,155,163,197,68,14,49,39,
+199,197,211,116,240,242,113,197,230,18,180,253,228,3,17,46,18,243,35,100,
+128,172,156,114,70,163,146,76,34,248,146,164,108,248,75,204,141,146,28,217,
+114,137,27,78,251,241,173,234,162,160,225,1,3,34,92,170,9,105,164,32,225,
+64,131,155,1,193,133,7,19,39,22,70,154,103,143,128,0,10,176,20,28,76,156,
+113,75,34,78,62,0,0,43,0,48,104,82,146,49,240,0,1,84,11,180,192,0,5,114,1,
+18,160,65,24,131,20,145,25,172,48,132,122,28,76,146,218,121,35,180,69,145,
+132,108,224,31,248,0,0,0,0,0,0,25,172,56,132,122,28,76,146,218,121,35,180,
+69,145,132,108,224,31,248,0,0,0,0,0,0,40,160,45,110,23,30,176,33,184,0,0,
+175,32,29,235,2,27,199,23,0,0,22,4,51,88,129,8,244,56,153,37,180,242,71,
+104,139,35,8,217,192,63,240,0,0,0,0,0,0,51,88,145,8,244,56,153,37,180,242,
+71,104,139,35,8,217,192,64,0,0,0,0,0,0,0,51,88,161,8,244,56,153,37,180,242,
+71,104,139,35,8,217,192,64,0,0,0,0,0,0,0,51,88,177,8,244,56,153,37,180,242,
+71,104,139,35,8,217,192,64,16,0,0,0,0,0,0,51,88,193,8,244,56,153,37,180,
+242,71,104,139,35,8,217,192,64,16,0,0,0,0,0,0,51,88,209,8,244,56,153,37,
+180,242,71,104,139,35,8,217,192,64,16,0,0,0,0,0,0,51,88,225,8,244,56,153,
+37,180,242,71,104,139,35,8,217,192,64,32,0,0,0,0,0,0,32,227,194,0,97,57,
+162,4,245,232,5,34,92,35,68,225,161,166,218,16,16,137,112,52,41,73,29,153,
+1,65,196,201,197,145,166,153,245,200,3,137,204,120,34,74,8,200,58,112,28,
+211,32,130,52,78,26,26,110,248,0,0,164,4,12,70,137,195,39,252,73,240,117,
+32,57,168,97,4,104,156,52,52,221,255,160,20,160,152,23,223,250,32,148,25,
+174,137,58,23,51,191,244,84,12,50,9,195,39,240,81,238,2,3,107,173,214,3,
+192,
};
#elif defined(DUK_USE_DOUBLE_ME)
-DUK_INTERNAL const duk_uint8_t duk_builtins_data[3972] = {
-144,148,105,223,160,68,52,228,62,12,104,200,165,132,52,167,194,138,105,242,
-252,57,28,211,57,18,64,52,238,62,44,138,111,171,241,164,19,87,125,30,33,
+DUK_INTERNAL const duk_uint8_t duk_builtins_data[4116] = {
+144,148,105,224,32,68,52,228,62,12,104,200,165,132,52,167,194,138,105,243,
+124,57,28,211,57,18,64,52,238,126,44,138,111,171,241,164,19,87,129,30,33,
167,16,145,159,8,211,136,9,225,42,5,240,145,139,163,163,8,211,136,10,228,
64,211,19,132,140,93,29,56,70,156,64,119,34,66,146,36,104,137,194,70,46,
142,172,35,78,32,47,146,195,102,11,240,145,139,163,175,8,211,136,9,228,240,
242,112,145,139,163,179,8,211,136,8,237,34,130,118,49,116,118,225,26,48,0,
-1,80,29,201,158,46,183,39,135,147,132,140,93,16,132,76,66,33,8,66,16,132,
-33,8,66,34,33,154,112,0,1,73,247,35,79,91,237,198,174,192,47,31,23,95,17,
-13,51,19,35,93,68,216,209,128,0,10,192,174,79,15,32,248,8,196,24,8,107,192,
-0,5,98,118,27,94,0,0,43,19,227,94,0,0,43,20,46,215,128,0,10,197,28,198,188,
-0,0,86,41,100,53,224,0,2,177,79,85,175,0,0,21,138,154,45,120,0,0,172,85,
-217,107,192,0,5,98,182,243,86,193,106,52,127,66,249,50,94,124,35,68,225,
-146,49,13,31,170,23,201,146,243,224,200,39,12,145,136,67,134,11,49,0,0,3,
-225,252,0,0,0,3,51,0,0,3,193,252,0,0,0,3,47,18,1,172,19,120,71,10,25,196,
-136,113,162,156,136,199,42,57,204,144,115,132,240,149,2,248,72,197,209,58,
-2,185,16,52,196,225,35,23,68,233,14,228,72,82,68,141,17,56,72,197,209,58,
-130,249,44,54,96,191,9,24,186,39,88,79,39,135,147,132,140,93,19,176,35,180,
-138,9,216,197,209,59,82,79,31,40,242,1,248,58,42,96,121,14,232,94,62,46,
-190,15,38,31,145,33,86,65,76,242,150,143,69,48,242,179,79,45,56,243,51,207,
-53,64,243,116,79,57,72,243,180,207,61,80,243,245,79,65,88,244,34,249,50,94,
-124,35,68,225,146,39,163,23,201,146,243,224,200,39,12,145,61,40,183,146,37,
-116,88,6,136,158,244,241,174,230,202,80,135,130,50,39,16,217,231,208,20,
-240,70,68,225,86,224,79,60,64,84,75,141,7,27,157,32,66,37,194,161,168,153,
-51,132,9,25,4,225,147,180,138,50,196,18,25,4,225,147,180,138,5,215,49,238,
-105,27,60,185,2,72,209,56,100,237,34,140,193,4,136,209,56,100,237,34,129,
-117,204,123,154,70,207,50,64,98,72,64,121,51,68,8,163,73,33,1,228,208,16,0,
-65,112,152,56,196,159,31,23,77,211,195,201,199,23,150,73,169,234,34,24,49,
-39,199,89,188,124,92,242,70,120,224,201,33,69,15,155,163,196,64,153,137,62,
-58,205,227,226,231,146,51,199,26,6,18,92,130,64,192,148,144,102,240,23,129,
-133,18,2,100,224,160,56,100,42,26,78,62,46,121,35,60,112,216,32,50,21,13,
-39,31,23,60,145,154,9,46,18,1,36,64,47,148,64,98,196,132,201,57,68,132,95,
-18,84,141,159,9,121,145,178,67,155,46,73,2,17,46,72,128,89,7,199,32,66,37,
-194,197,217,35,120,228,131,17,46,18,243,35,100,128,172,156,98,2,40,152,151,
-32,130,166,36,248,235,55,143,139,158,72,207,28,150,24,23,46,92,130,80,72,
-151,21,0,100,213,103,229,245,8,186,190,144,24,78,136,24,94,152,3,142,9,113,
-214,111,31,23,60,145,158,57,164,13,68,184,248,186,110,158,30,78,56,188,226,
-10,62,46,121,35,60,113,18,225,27,70,18,32,10,201,208,32,134,214,208,200,84,
-52,156,49,39,50,71,107,107,152,129,13,173,161,144,168,105,57,34,78,100,142,
-214,215,49,16,134,214,210,220,229,81,252,49,39,50,71,107,107,158,65,13,173,
-165,185,202,163,249,34,78,100,142,214,215,60,146,12,16,28,128,62,175,42,6,
-143,36,136,16,64,90,242,135,192,129,67,71,147,62,65,5,215,231,214,6,215,62,
-180,8,49,1,3,162,92,4,98,12,41,14,67,40,106,229,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,192,163,11,23,51,130,56,35,
-193,56,100,243,31,6,150,46,103,4,225,147,143,114,27,63,57,241,200,169,194,
-133,42,166,175,240,6,23,240,0,97,28,17,224,39,233,32,80,142,8,240,78,25,56,
-9,250,136,22,39,12,156,123,144,217,240,19,245,18,6,19,154,32,79,214,124,14,
-134,140,151,227,139,237,52,11,88,37,62,33,163,37,248,226,251,77,32,213,184,
-64,89,56,39,49,224,137,61,196,5,96,38,35,251,200,15,18,61,96,17,62,40,6,
-145,1,17,31,228,64,89,45,2,39,205,0,178,122,209,63,162,2,101,64,202,113,67,
-77,247,64,92,221,197,186,196,143,4,9,19,208,1,25,187,139,112,128,178,113,
-110,177,35,193,2,68,244,0,46,110,229,30,242,71,130,4,137,232,4,35,55,113,
-110,16,22,78,81,239,36,120,32,72,158,128,64,147,138,25,249,0,52,72,242,2,
-127,2,5,74,96,140,229,203,34,103,250,154,4,17,163,151,44,137,159,234,105,4,
-33,162,93,6,73,123,13,1,165,64,202,113,251,33,6,64,14,71,78,20,101,213,207,
-4,194,207,2,12,162,0,158,176,23,218,168,23,66,64,255,255,239,127,255,255,
-255,255,19,214,33,187,85,2,232,72,0,0,0,0,0,32,0,0,25,136,0,0,31,15,224,0,
-0,0,4,122,247,73,19,69,73,180,134,149,13,68,241,0,0,3,193,252,0,0,0,0,143,
-90,67,2,104,169,54,144,210,161,168,158,32,0,0,120,127,128,0,0,0,14,73,78,
-20,0,0,0,0,0,0,0,0,8,58,189,233,24,77,217,24,93,240,1,230,238,21,23,32,247,
-68,13,155,184,75,189,205,35,102,128,47,114,64,185,187,143,137,4,137,33,205,
-222,17,6,96,48,87,130,50,37,114,1,246,147,21,143,224,54,186,213,128,114,90,
-112,164,0,0,124,63,128,0,0,0,98,117,119,128,25,55,112,96,153,57,41,197,13,
-53,224,65,147,119,38,134,19,146,156,80,211,94,5,194,94,6,37,55,113,110,16,
-22,78,12,19,39,37,56,161,166,188,14,74,110,226,220,32,44,156,154,24,78,74,
-113,67,77,120,32,97,175,4,28,61,224,133,172,186,70,22,248,1,204,73,242,104,
-97,47,128,44,196,159,11,69,175,152,32,35,100,33,142,49,39,218,76,69,237,22,
-190,96,128,141,144,136,32,196,159,24,230,204,246,66,40,179,18,125,164,196,
-206,185,179,61,144,140,28,196,159,6,9,146,200,71,20,98,79,180,152,135,208,
-76,150,66,64,99,18,124,24,49,100,36,137,49,39,218,76,67,232,49,100,37,8,49,
-39,195,186,145,149,144,150,44,196,159,105,49,31,174,164,101,100,38,10,49,
-39,198,33,180,153,37,100,38,141,49,39,218,76,76,234,27,73,146,86,66,112,
-163,18,124,145,4,230,142,86,66,120,211,18,125,164,197,46,144,78,104,229,
-100,40,15,49,39,198,33,107,68,136,39,52,114,178,20,73,24,147,237,38,38,117,
-11,90,36,65,57,163,149,144,164,68,196,159,38,134,19,46,105,56,226,150,68,
-157,160,3,200,147,228,208,194,92,32,124,137,62,49,11,90,36,65,57,163,149,
-178,166,74,68,159,105,49,51,168,90,209,34,9,205,28,173,149,65,82,36,249,34,
-9,205,28,173,175,170,54,68,159,105,49,75,164,19,154,57,91,95,88,84,137,62,
-49,13,164,201,43,111,235,141,145,39,218,76,76,234,27,73,146,86,223,216,17,
-34,79,135,117,35,43,115,236,139,145,39,218,76,71,235,169,25,91,159,104,60,
-137,62,12,19,37,178,182,42,68,159,105,49,15,160,153,45,149,193,18,36,248,
-199,54,103,182,190,232,185,18,125,164,196,206,185,179,61,181,247,133,200,
-147,225,104,181,243,4,4,109,191,190,58,68,159,105,49,23,180,90,249,130,2,
-54,223,224,67,152,147,230,8,8,217,12,16,121,18,124,193,1,27,101,131,131,56,
-7,38,193,198,72,0,0,0,0,0,0,0,0,198,231,240,134,39,63,136,151,95,63,136,49,
-89,252,66,98,243,248,133,96,132,185,5,224,32,36,201,41,248,200,213,249,0,
-131,64,7,39,192,218,148,124,137,74,216,231,198,227,141,182,124,78,40,217,
-231,197,227,4,213,227,192,159,72,10,5,21,218,138,120,74,129,124,36,98,232,
-228,74,81,62,160,20,10,107,181,21,114,32,105,137,194,70,46,142,68,165,19,
-235,1,64,170,187,81,119,34,66,146,36,104,137,194,70,46,142,68,165,19,236,1,
-64,174,187,81,95,37,134,204,23,225,35,23,71,34,82,137,246,128,160,89,93,
-168,167,147,195,201,194,70,46,142,68,165,19,238,1,64,182,187,81,71,105,20,
-19,177,139,163,145,41,68,16,7,6,15,82,70,72,115,96,32,93,105,160,0,0,0,0,
-91,60,149,195,200,194,8,134,149,216,114,1,128,83,192,144,8,194,195,16,12,
-168,110,20,120,12,141,22,16,120,12,100,22,12,120,28,78,99,192,41,224,136,
-115,36,14,100,197,213,245,193,48,189,112,40,2,237,96,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,28,1,204,178,10,14,38,78,44,141,52,207,31,0,0,21,64,129,100,180,8,148,
-145,92,203,176,160,226,100,226,200,211,76,241,240,0,1,84,2,131,137,147,142,
-41,100,73,199,192,0,5,88,6,13,10,82,70,62,0,0,42,66,88,115,18,124,67,103,
-177,69,49,130,12,73,242,136,108,246,40,165,177,6,36,248,134,207,71,90,138,
-99,68,152,147,229,16,217,232,235,81,75,130,12,73,241,13,158,158,149,20,199,
-9,49,39,202,33,179,211,210,162,151,69,24,147,225,86,224,79,79,74,138,94,20,
-98,79,133,91,129,61,109,74,41,124,60,137,62,33,179,216,166,216,193,18,36,
-249,68,54,123,20,218,216,137,18,124,67,103,163,173,77,177,162,100,73,242,
-136,108,244,117,169,181,193,18,36,248,134,207,79,74,155,99,132,200,147,229,
-16,217,233,233,83,107,162,164,73,240,171,112,39,167,165,77,175,10,145,39,
-194,173,192,158,182,165,54,191,153,51,72,71,161,196,201,45,167,146,59,68,
-89,24,70,206,0,0,7,129,248,0,0,0,1,153,51,104,71,161,196,201,45,167,146,59,
-68,89,24,70,206,0,0,7,129,248,0,0,0,1,153,51,136,71,161,196,201,45,167,146,
-59,68,89,24,70,206,0,0,7,129,248,0,0,0,1,153,51,168,71,161,196,201,45,167,
-146,59,68,89,24,70,206,0,0,0,2,0,0,0,0,1,153,51,200,71,161,196,201,45,167,
-146,59,68,89,24,70,206,0,0,0,2,0,0,0,0,1,153,51,232,71,161,196,201,45,167,
-146,59,68,89,24,70,206,0,0,0,130,0,0,0,0,1,153,52,8,71,161,196,201,45,167,
-146,59,68,89,24,70,206,0,0,0,130,0,0,0,0,1,153,52,40,71,161,196,201,45,167,
-146,59,68,89,24,70,206,0,0,0,130,0,0,0,0,1,153,52,72,71,161,196,201,45,167,
-146,59,68,89,24,70,206,0,0,1,2,0,0,0,0,1,135,52,102,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,123,
-102,53,155,80,2,21,11,94,201,128,196,133,0,185,80,32,56,156,199,130,36,160,
-72,16,78,126,54,48,5,146,208,34,82,72,1,109,20,76,155,120,28,34,1,225,32,5,
-95,130,160,52,171,138,69,132,234,219,163,161,2,197,172,9,0,89,86,214,236,
-31,86,221,40,8,69,220,199,253,231,63,95,193,122,183,27,72,144,17,197,125,
-207,255,160,138,217,67,117,110,54,142,129,32,61,229,237,159,135,114,147,10,
-130,235,209,3,236,132,37,0,96,181,17,80,63,101,8,207,71,107,74,4,245,7,49,
-254,105,219,251,48,94,202,17,158,148,9,234,15,99,252,211,183,246,98,159,
-129,228,176,192,185,127,46,155,185,41,197,13,55,38,3,127,255,20,138,160,
-192,25,106,8,8,1,58,90,130,64,128,146,27,168,37,8,9,129,186,130,96,160,152,
-27,165,171,64,32,131,25,234,10,64,65,17,11,212,19,133,18,243,167,165,163,
-32,24,157,45,65,64,6,75,191,80,80,66,149,110,116,117,5,8,41,240,247,79,72,
-188,8,134,81,122,84,1,173,198,212,20,48,139,113,180,181,5,36,42,220,109,29,
-13,65,74,6,192,95,76,188,6,196,55,78,188,6,247,91,86,136,26,32,104,220,205,
-72,1,98,234,52,122,130,136,18,72,51,117,68,3,146,27,168,40,161,37,8,207,80,
-81,129,204,13,212,20,112,179,141,26,45,65,75,112,20,43,193,25,19,66,128,
-153,78,40,105,144,92,104,152,131,124,27,253,128,0,10,116,3,68,146,163,9,
-128,0,10,102,3,138,145,137,27,60,0,0,82,129,7,2,4,16,7,2,70,143,178,203,
-164,237,35,14,25,10,134,147,143,139,158,72,207,28,54,77,47,109,13,55,113,
-120,96,196,159,29,102,241,241,115,201,25,227,131,36,133,20,62,110,143,17,
-16,113,137,62,62,46,155,167,135,147,142,47,44,151,79,221,64,98,37,194,94,
-100,108,144,21,147,140,73,168,228,19,17,124,73,82,54,124,37,230,70,201,14,
-108,185,36,155,14,243,243,83,212,69,131,132,4,12,137,114,168,37,166,145,7,
-10,4,28,200,14,12,40,56,153,56,178,52,211,60,124,0,0,85,0,160,226,100,227,
-138,89,18,113,240,0,1,86,1,131,66,148,145,143,128,0,10,144,93,134,0,0,43,
-80,17,42,4,17,136,49,73,19,49,134,16,143,67,137,146,91,79,36,118,136,178,
-48,141,156,0,0,15,3,240,0,0,0,3,49,135,16,143,67,137,146,91,79,36,118,136,
-178,48,141,156,0,0,15,3,240,0,0,0,5,20,5,173,194,227,214,4,55,0,0,21,196,7,
-122,192,134,241,197,192,0,5,121,25,140,64,132,122,28,76,146,218,121,35,180,
-69,145,132,108,224,0,0,120,31,128,0,0,0,25,140,72,132,122,28,76,146,218,
-121,35,180,69,145,132,108,224,0,0,0,32,0,0,0,0,25,140,80,132,122,28,76,146,
-218,121,35,180,69,145,132,108,224,0,0,0,32,0,0,0,0,25,140,88,132,122,28,76,
-146,218,121,35,180,69,145,132,108,224,0,0,8,32,0,0,0,0,25,140,96,132,122,
-28,76,146,218,121,35,180,69,145,132,108,224,0,0,8,32,0,0,0,0,25,140,104,
-132,122,28,76,146,218,121,35,180,69,145,132,108,224,0,0,8,32,0,0,0,0,25,
-140,112,132,122,28,76,146,218,121,35,180,69,145,132,108,224,0,0,16,32,0,0,
-0,0,16,113,225,0,48,156,209,2,122,244,5,34,92,35,68,225,161,166,218,16,33,
-18,224,104,82,146,59,50,5,7,19,39,22,70,154,103,215,32,28,78,99,193,18,80,
-70,131,165,1,205,34,8,35,68,225,161,166,239,255,4,12,70,137,195,39,248,73,
-7,78,3,154,102,16,70,137,195,67,77,223,248,1,74,9,129,125,255,130,9,65,154,
-232,147,161,115,59,255,5,64,195,32,156,50,126,197,14,2,3,107,173,213,0,
+1,82,29,201,158,46,183,39,135,147,132,140,93,16,132,76,66,33,8,66,16,132,
+33,8,66,26,179,233,97,167,60,150,34,33,154,112,0,1,75,247,35,79,95,237,198,
+174,200,47,31,23,95,17,13,51,19,35,93,68,216,209,128,0,10,208,174,79,15,32,
+248,8,196,24,8,107,192,0,5,106,118,27,94,0,0,43,83,227,94,0,0,43,84,46,215,
+128,0,10,213,28,198,188,0,0,86,169,100,53,224,0,2,181,79,85,175,0,0,21,170,
+154,45,120,0,0,173,85,217,107,192,0,5,106,182,243,86,193,106,52,127,130,
+249,50,94,124,35,68,225,146,49,13,31,186,23,201,146,243,224,200,39,12,145,
+136,67,134,19,49,0,0,3,225,252,0,0,0,3,51,0,0,3,193,252,0,0,0,3,47,18,1,
+172,19,120,71,10,25,196,136,113,162,156,136,199,42,57,204,144,115,132,240,
+149,2,248,72,197,209,58,2,185,16,52,196,225,35,23,68,233,14,228,72,82,68,
+141,17,56,72,197,209,58,130,249,44,54,96,191,9,24,186,39,88,79,39,135,147,
+132,140,93,19,176,35,180,138,9,216,197,209,59,82,79,35,40,242,65,248,58,42,
+96,121,14,232,94,62,46,190,15,42,31,145,33,86,65,76,242,214,143,73,48,242,
+243,79,49,56,243,115,207,57,64,243,180,79,61,72,243,244,207,65,80,244,53,
+79,69,88,244,98,30,8,200,156,67,102,120,241,79,4,100,78,21,110,4,207,32,47,
+147,37,231,194,52,78,25,34,122,81,124,153,47,62,12,130,112,201,19,211,139,
+121,34,87,69,128,104,137,239,83,18,238,108,165,2,162,92,104,56,220,233,1,8,
+151,10,134,162,100,206,16,18,50,9,195,39,105,20,101,136,18,25,4,225,147,
+180,138,5,215,49,238,105,27,60,185,1,36,104,156,50,118,145,70,96,129,34,52,
+78,25,59,72,160,93,115,30,230,145,179,204,144,12,73,8,15,38,104,128,138,52,
+146,16,30,77,1,0,2,11,132,193,198,36,248,248,186,110,158,30,78,56,188,194,
+70,183,170,136,48,98,79,142,179,120,248,185,228,140,241,193,146,66,138,31,
+55,71,138,128,153,137,62,58,205,227,226,231,146,51,199,26,6,18,92,146,64,
+96,74,72,51,120,43,192,97,68,128,153,56,72,7,12,133,67,73,199,197,207,36,
+103,142,35,2,3,33,80,210,113,241,115,201,25,160,146,225,160,9,34,1,124,178,
+1,139,18,19,36,229,146,8,190,36,169,27,62,18,243,35,100,135,54,92,162,2,17,
+46,72,128,89,7,200,32,33,18,225,98,236,145,188,130,64,196,75,132,188,200,
+217,32,43,39,28,128,69,19,18,228,144,42,98,79,142,179,120,248,185,228,140,
+241,201,97,129,114,229,201,37,2,68,184,200,1,147,93,159,153,213,34,235,250,
+96,48,157,32,24,94,160,1,199,4,184,235,55,143,139,158,72,207,28,226,3,81,
+46,62,46,155,167,135,147,142,47,60,129,71,197,207,36,103,142,34,92,35,104,
+194,68,1,89,58,36,8,109,109,12,133,67,73,195,18,115,36,118,182,185,168,8,
+109,109,12,133,67,73,201,18,115,36,118,182,185,168,130,27,91,75,115,149,71,
+240,196,156,201,29,173,174,129,2,27,91,75,115,149,71,242,68,156,201,29,173,
+174,129,34,12,16,28,128,62,191,42,3,71,146,68,4,16,22,188,161,240,16,40,
+104,242,103,196,16,93,158,125,96,110,115,235,64,131,16,16,58,37,192,70,32,
+194,144,114,25,67,95,40,6,18,8,32,48,156,209,2,108,124,96,224,144,6,247,62,
+16,0,143,164,143,12,248,15,18,84,145,145,34,128,11,35,160,179,140,0,44,150,
+129,18,58,0,146,116,103,32,128,105,61,104,17,36,175,1,232,217,29,5,156,179,
+224,58,26,50,95,142,43,159,64,181,130,83,226,26,50,95,142,43,159,192,7,255,
+248,41,42,72,226,1,160,18,78,97,32,26,64,114,186,60,32,4,120,6,148,13,128,
+124,3,76,12,84,46,100,140,3,78,13,18,14,130,36,67,232,23,18,14,130,39,34,
+131,30,113,15,224,3,255,253,6,48,40,194,197,204,224,142,8,240,78,25,60,231,
+192,210,197,204,224,156,50,113,238,67,103,232,62,28,138,156,104,82,170,107,
+255,32,48,191,144,1,132,112,71,128,159,168,128,161,28,17,224,156,50,112,19,
+245,144,22,39,12,156,123,144,217,240,19,245,146,3,9,205,16,39,236,62,3,161,
+163,37,248,226,251,141,1,107,4,167,196,52,100,191,28,95,113,164,13,91,132,
+5,147,130,115,30,8,147,222,64,43,1,49,31,224,64,60,72,245,128,68,249,32,13,
+34,2,34,63,204,128,89,45,2,39,209,0,89,61,104,159,213,0,153,80,50,156,80,
+211,126,16,11,155,184,183,88,145,224,129,34,122,64,17,155,184,183,8,11,39,
+22,235,18,60,16,36,79,72,1,115,119,40,247,146,60,16,36,79,72,32,140,221,
+197,184,64,89,57,71,188,145,224,129,34,122,65,1,39,20,51,244,0,52,72,242,2,
+127,18,2,165,48,70,114,229,145,51,253,141,1,4,104,229,203,34,103,251,26,64,
+132,52,75,160,201,47,105,160,26,84,12,167,31,186,8,50,0,114,58,113,163,46,
+190,120,35,11,60,4,25,68,81,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,15,210,
+62,72,91,155,0,0,2,192,240,0,0,0,0,135,88,11,237,72,5,38,210,27,50,24,145,
+129,255,254,126,135,255,255,255,254,67,172,67,118,164,2,147,105,13,153,12,
+72,192,255,255,63,195,255,255,255,255,16,240,70,68,226,27,51,199,138,120,
+35,34,112,171,112,38,121,7,16,137,112,168,106,38,77,193,1,40,151,16,217,
+144,196,142,224,144,21,18,227,65,198,238,9,67,81,46,72,5,39,16,217,144,196,
+142,224,152,228,148,227,64,0,0,0,0,0,0,0,0,131,175,223,16,194,111,8,97,119,
+224,3,205,220,42,46,65,238,200,13,155,184,75,189,205,35,102,128,47,116,64,
+92,221,199,196,130,68,144,230,239,72,65,152,12,21,224,140,137,92,128,62,
+210,98,177,252,3,107,173,88,3,146,211,141,32,0,3,225,252,0,0,0,3,19,175,
+188,0,100,221,193,130,100,228,167,20,52,215,129,3,38,238,77,12,39,37,56,
+161,166,188,10,194,94,6,18,155,184,183,8,11,39,6,9,147,146,156,80,211,94,7,
+18,155,184,183,8,11,39,38,134,19,146,156,80,211,94,8,12,53,224,130,195,222,
+8,77,133,210,24,91,224,3,152,147,228,208,194,95,0,44,196,159,11,69,175,152,
+32,35,100,33,135,24,147,237,38,34,246,139,95,48,64,70,200,68,8,49,39,198,
+57,179,61,144,138,22,98,79,180,152,153,215,54,103,178,17,129,204,73,240,96,
+153,44,132,112,163,18,125,164,196,62,130,100,178,18,1,140,73,240,96,197,
+144,146,18,98,79,180,152,135,208,98,200,74,8,49,39,195,186,145,149,144,150,
+22,98,79,180,152,143,215,82,50,178,19,2,140,73,241,136,109,38,73,89,9,161,
+166,36,251,73,137,157,67,105,50,74,200,78,10,49,39,201,16,78,104,229,100,
+39,134,152,147,237,38,41,116,130,115,71,43,33,64,60,196,159,24,133,173,18,
+32,156,209,202,200,81,18,49,39,218,76,76,234,22,180,72,130,115,71,43,33,72,
+68,196,159,38,134,19,46,105,56,226,150,68,157,160,1,228,73,242,104,97,46,
+16,31,34,79,140,66,214,137,16,78,104,229,108,169,137,72,147,237,38,38,117,
+11,90,36,65,57,163,149,178,168,21,34,79,146,32,156,209,202,218,250,161,178,
+36,251,73,138,93,32,156,209,202,218,250,193,82,36,248,196,54,147,36,173,
+191,174,27,34,79,180,152,153,212,54,147,36,173,191,176,17,34,79,135,117,35,
+43,115,236,133,200,147,237,38,35,245,212,140,173,207,180,15,34,79,131,4,
+201,108,173,133,72,147,237,38,33,244,19,37,178,184,17,34,79,140,115,102,
+123,107,238,133,200,147,237,38,38,117,205,153,237,175,188,23,34,79,133,162,
+215,204,16,17,182,254,248,116,137,62,210,98,47,104,181,243,4,4,109,191,192,
+131,152,147,230,8,8,217,12,16,60,137,62,96,128,141,178,193,160,206,1,201,
+176,113,146,0,0,0,0,0,0,0,0,49,185,252,65,137,207,227,37,215,207,227,12,86,
+127,24,152,188,254,49,88,33,46,65,120,72,4,153,37,63,33,13,127,148,4,26,0,
+57,62,6,228,163,228,74,86,215,62,55,28,110,179,226,113,70,223,62,47,24,38,
+191,30,2,125,32,40,20,87,114,41,225,42,5,240,145,139,163,145,41,68,250,128,
+80,41,174,228,85,200,129,166,39,9,24,186,57,18,148,79,172,5,2,170,238,69,
+220,137,10,72,145,162,39,9,24,186,57,18,148,79,176,5,2,186,238,69,124,150,
+27,48,95,132,140,93,28,137,74,39,218,2,129,101,119,34,158,79,15,39,9,24,
+186,57,18,148,79,184,5,2,218,238,69,29,164,80,78,198,46,142,68,165,16,64,
+28,24,61,73,25,33,205,128,1,167,166,128,0,0,0,1,108,242,151,15,39,8,34,26,
+87,97,200,3,0,167,129,32,8,194,195,16,6,84,55,10,60,3,35,69,132,30,1,140,
+130,193,143,1,196,230,60,2,158,8,131,153,64,115,42,46,191,176,8,194,246,0,
+80,5,220,193,95,6,234,5,100,225,35,23,71,35,6,228,140,93,29,180,55,108,145,
+139,163,182,112,52,107,67,76,56,3,153,132,20,28,76,156,89,26,105,158,62,0,
+0,42,193,2,201,104,17,41,34,156,204,176,160,226,100,226,200,211,76,241,240,
+0,1,86,2,131,137,147,142,41,100,73,199,192,0,5,96,6,13,10,82,70,62,0,0,42,
+130,88,115,18,124,67,103,177,69,49,129,6,36,249,68,54,123,20,82,216,65,137,
+62,33,179,209,214,162,152,208,147,18,124,162,27,61,29,106,41,112,32,196,
+159,16,217,233,233,81,76,112,73,137,62,81,13,158,158,149,20,186,20,98,79,
+133,91,129,61,61,42,41,120,40,196,159,10,183,2,122,218,148,82,248,60,137,
+62,33,179,216,166,216,192,137,18,124,162,27,61,138,109,108,34,68,159,16,
+217,232,235,83,108,104,76,137,62,81,13,158,142,181,54,184,17,34,79,136,108,
+244,244,169,182,56,38,68,159,40,134,207,79,74,155,93,10,145,39,194,173,192,
+158,158,149,54,188,21,34,79,133,91,129,61,109,74,109,125,155,51,136,71,161,
+196,201,45,167,146,59,68,89,24,70,206,0,0,7,129,248,0,0,0,1,155,51,168,71,
+161,196,201,45,167,146,59,68,89,24,70,206,0,0,7,129,248,0,0,0,1,155,51,200,
+71,161,196,201,45,167,146,59,68,89,24,70,206,0,0,7,129,248,0,0,0,1,155,51,
+232,71,161,196,201,45,167,146,59,68,89,24,70,206,0,0,0,2,0,0,0,0,1,155,52,
+8,71,161,196,201,45,167,146,59,68,89,24,70,206,0,0,0,2,0,0,0,0,1,155,52,40,
+71,161,196,201,45,167,146,59,68,89,24,70,206,0,0,0,130,0,0,0,0,1,155,52,72,
+71,161,196,201,45,167,146,59,68,89,24,70,206,0,0,0,130,0,0,0,0,1,155,52,
+104,71,161,196,201,45,167,146,59,68,89,24,70,206,0,0,0,130,0,0,0,0,1,155,
+52,136,71,161,196,201,45,167,146,59,68,89,24,70,206,0,0,1,2,0,0,0,0,1,135,
+52,166,32,76,72,1,246,136,235,103,177,69,0,136,144,3,226,27,61,138,41,44,
+50,36,0,251,68,117,179,209,214,234,201,69,16,50,36,0,251,68,117,179,209,
+214,232,73,69,34,5,196,128,31,16,217,232,235,117,100,162,147,2,226,64,15,
+136,108,244,117,186,18,81,74,129,145,32,7,218,35,173,158,158,151,86,74,40,
+161,145,32,7,218,35,173,158,158,151,66,74,41,20,46,36,0,248,134,207,79,75,
+171,37,20,154,23,18,0,124,67,103,167,165,208,146,138,85,11,137,0,62,21,110,
+4,250,178,81,70,11,137,0,62,21,110,4,250,18,81,72,193,145,32,7,193,186,129,
+89,58,178,81,71,12,137,0,62,13,212,10,201,208,146,138,71,10,137,0,62,209,
+29,108,250,178,81,104,1,81,32,7,218,35,173,159,66,74,45,32,38,36,0,248,134,
+207,171,37,22,160,19,18,0,124,67,103,208,146,139,88,10,180,81,50,118,136,
+235,103,177,77,128,155,69,19,39,16,217,236,83,105,97,182,138,38,78,209,29,
+108,244,117,186,178,83,100,13,180,81,50,118,136,235,103,163,173,208,146,
+155,68,12,180,81,50,113,13,158,142,183,86,74,109,48,50,209,68,201,196,54,
+122,58,221,9,41,181,64,219,69,19,39,104,142,182,122,122,93,89,41,178,134,
+218,40,153,59,68,117,179,211,210,232,73,77,162,134,90,40,153,56,134,207,79,
+75,171,37,54,154,25,104,162,100,226,27,61,61,46,132,148,218,168,101,162,
+137,147,133,91,129,62,172,148,217,131,45,20,76,156,42,220,9,244,36,166,209,
+131,109,20,76,156,27,168,21,147,171,37,54,112,219,69,19,39,6,234,5,100,232,
+73,77,163,133,218,40,153,59,68,117,179,234,201,78,32,5,218,40,153,59,68,
+117,179,232,73,78,36,5,90,40,153,56,134,207,171,37,56,160,21,104,162,100,
+226,27,62,132,148,226,195,95,182,97,176,218,128,8,84,45,123,38,1,137,10,1,
+114,160,64,56,156,199,130,36,160,72,8,39,63,27,24,1,100,180,8,148,146,0,45,
+162,137,147,111,2,8,4,16,7,8,96,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,154,168,48,6,90,130,1,0,39,75,80,
+72,8,9,33,186,130,80,64,76,13,212,19,2,130,96,110,150,173,0,65,6,51,212,20,
+128,65,17,11,212,19,130,137,121,211,210,209,144,6,39,75,80,80,0,201,119,
+234,10,8,41,86,231,71,80,80,129,79,135,186,122,69,224,34,25,69,233,80,3,91,
+141,168,40,96,139,113,180,181,5,36,21,110,54,142,134,160,165,1,176,23,211,
+47,0,216,134,233,215,128,111,117,181,104,128,209,3,70,230,106,64,5,139,168,
+209,234,10,32,36,144,102,234,136,3,146,27,168,40,160,146,132,103,168,40,
+192,115,3,117,5,28,22,113,163,69,168,41,103,1,66,188,17,145,52,40,4,202,
+113,67,76,130,227,68,194,13,240,108,0,0,83,96,0,2,161,0,104,146,84,97,48,0,
+1,78,192,56,169,24,145,179,192,0,5,48,8,56,16,32,128,56,18,52,125,166,86,
+147,182,140,28,50,21,13,39,31,23,60,145,158,56,140,141,47,113,6,155,186,
+188,24,49,39,199,89,188,124,92,242,70,120,224,201,33,69,15,155,163,197,68,
+14,49,39,199,197,211,116,240,242,113,197,230,18,180,253,228,3,17,46,18,243,
+35,100,128,172,156,114,70,163,146,76,34,248,146,164,108,248,75,204,141,146,
+28,217,114,137,27,78,251,241,173,234,162,160,225,1,3,34,92,170,9,105,164,
+32,225,64,131,155,1,193,133,7,19,39,22,70,154,103,143,128,0,10,176,20,28,
+76,156,113,75,34,78,62,0,0,43,0,48,104,82,146,49,240,0,1,84,11,180,192,0,5,
+114,1,18,160,65,24,131,20,145,25,172,48,132,122,28,76,146,218,121,35,180,
+69,145,132,108,224,0,0,120,31,128,0,0,0,25,172,56,132,122,28,76,146,218,
+121,35,180,69,145,132,108,224,0,0,120,31,128,0,0,0,40,160,45,110,23,30,176,
+33,184,0,0,175,32,29,235,2,27,199,23,0,0,22,4,51,88,129,8,244,56,153,37,
+180,242,71,104,139,35,8,217,192,0,0,240,63,0,0,0,0,51,88,145,8,244,56,153,
+37,180,242,71,104,139,35,8,217,192,0,0,0,64,0,0,0,0,51,88,161,8,244,56,153,
+37,180,242,71,104,139,35,8,217,192,0,0,0,64,0,0,0,0,51,88,177,8,244,56,153,
+37,180,242,71,104,139,35,8,217,192,0,0,16,64,0,0,0,0,51,88,193,8,244,56,
+153,37,180,242,71,104,139,35,8,217,192,0,0,16,64,0,0,0,0,51,88,209,8,244,
+56,153,37,180,242,71,104,139,35,8,217,192,0,0,16,64,0,0,0,0,51,88,225,8,
+244,56,153,37,180,242,71,104,139,35,8,217,192,0,0,32,64,0,0,0,0,32,227,194,
+0,97,57,162,4,245,232,5,34,92,35,68,225,161,166,218,16,16,137,112,52,41,73,
+29,153,1,65,196,201,197,145,166,153,245,200,3,137,204,120,34,74,8,200,58,
+112,28,211,32,130,52,78,26,26,110,248,0,0,164,4,12,70,137,195,39,252,73,
+240,117,32,57,168,97,4,104,156,52,52,221,255,160,20,160,152,23,223,250,32,
+148,25,174,137,58,23,51,191,244,84,12,50,9,195,39,240,81,238,2,3,107,173,
+214,3,192,
};
#else
#error invalid endianness defines
@@ -11482,10 +11715,18 @@ DUK_INTERNAL DUK_COLD void duk_default_fatal_handler(void *udata, const char *ms
DUK_UNREF(udata);
DUK_UNREF(msg);
+ msg = msg ? msg : "NULL";
+
#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_D(DUK_DPRINT("custom default fatal error handler called: %s", msg));
DUK_USE_FATAL_HANDLER(udata, msg);
+#elif defined(DUK_USE_CPP_EXCEPTIONS)
+ /* With C++ use a duk_fatal_exception which user code can catch in
+ * a natural way.
+ */
+ DUK_D(DUK_DPRINT("built-in default C++ fatal error handler called: %s", msg));
+ throw duk_fatal_exception(msg);
#else
/* Default behavior is to abort() on error. There's no printout
* which makes this awkward, so it's always recommended to use an
@@ -11502,7 +11743,7 @@ DUK_INTERNAL DUK_COLD void duk_default_fatal_handler(void *udata, const char *ms
* - http://duktape.org/api.html#taglist-protected
* ====================================================================
*/
- DUK_D(DUK_DPRINT("built-in default fatal error handler called: %s", msg ? msg : "NULL"));
+ DUK_D(DUK_DPRINT("built-in default fatal error handler called: %s", msg));
DUK_ABORT();
#endif
@@ -11657,7 +11898,7 @@ DUK_INTERNAL duk_small_int_t duk_unicode_encode_cesu8(duk_ucodepoint_t cp, duk_u
/*
* Unicode codepoints above U+FFFF are encoded as surrogate
* pairs here. This ensures that all CESU-8 codepoints are
- * 16-bit values as expected in Ecmascript. The surrogate
+ * 16-bit values as expected in ECMAScript. The surrogate
* pairs always get a 3-byte encoding (each) in CESU-8.
* See: http://en.wikipedia.org/wiki/Surrogate_pair
*
@@ -11796,8 +12037,7 @@ DUK_INTERNAL duk_ucodepoint_t duk_unicode_decode_xutf8_checked(duk_hthread *thr,
return cp;
}
DUK_ERROR_INTERNAL(thr);
- DUK_UNREACHABLE();
- return 0;
+ DUK_WO_NORETURN(return 0;);
}
/* Compute (extended) utf-8 length without codepoint encoding validation,
@@ -11946,7 +12186,7 @@ DUK_LOCAL duk_small_int_t duk__uni_range_match(const duk_uint8_t *unitab, duk_si
duk_bitdecoder_ctx bd_ctx;
duk_codepoint_t prev_re;
- DUK_MEMZERO(&bd_ctx, sizeof(bd_ctx));
+ duk_memzero(&bd_ctx, sizeof(bd_ctx));
bd_ctx.data = (const duk_uint8_t *) unitab;
bd_ctx.length = (duk_size_t) unilen;
@@ -12498,7 +12738,7 @@ duk_codepoint_t duk__case_transform_helper(duk_hthread *thr,
}
/* 1:1 or special conversions, but not locale/context specific: script generated rules */
- DUK_MEMZERO(&bd_ctx, sizeof(bd_ctx));
+ duk_memzero(&bd_ctx, sizeof(bd_ctx));
if (uppercase) {
bd_ctx.data = (const duk_uint8_t *) duk_unicode_caseconv_uc;
bd_ctx.length = (duk_size_t) sizeof(duk_unicode_caseconv_uc);
@@ -12697,7 +12937,7 @@ DUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_not_wordchar[10] = {
#endif /* DUK_USE_REGEXP_SUPPORT */
/*
- * Misc util stuff
+ * Misc util stuff.
*/
/* #include duk_internal.h -> already included */
@@ -12860,45 +13100,6 @@ DUK_INTERNAL const duk_uint16_t duk_hex_enctab[256] = {
#endif /* DUK_USE_HEX_FASTPATH */
/*
- * Table for base-64 encoding
- */
-
-#if defined(DUK_USE_BASE64_FASTPATH)
-DUK_INTERNAL const duk_uint8_t duk_base64_enctab[64] = {
- 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, /* A...P */
- 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, /* Q...f */
- 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, /* g...v */
- 0x77, 0x78, 0x79, 0x7a, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2b, 0x2f /* w.../ */
-};
-#endif /* DUK_USE_BASE64_FASTPATH */
-
-/*
- * Table for base-64 decoding
- */
-
-#if defined(DUK_USE_BASE64_FASTPATH)
-DUK_INTERNAL const duk_int8_t duk_base64_dectab[256] = {
- /* -1 = error, -2 = allowed whitespace, -3 = padding ('='), 0...63 decoded bytes */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -2, -1, -1, -2, -1, -1, /* 0x00...0x0f */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x10...0x1f */
- -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, /* 0x20...0x2f */
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -3, -1, -1, /* 0x30...0x3f */
- -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 0x40...0x4f */
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 0x50...0x5f */
- -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 0x60...0x6f */
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, /* 0x70...0x7f */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x80...0x8f */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x90...0x9f */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xa0...0xaf */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xb0...0xbf */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xc0...0xcf */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xd0...0xdf */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xe0...0xef */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 /* 0xf0...0xff */
-};
-#endif /* DUK_USE_BASE64_FASTPATH */
-
-/*
* Arbitrary byteswap for potentially unaligned values
*
* Used to byteswap pointers e.g. in debugger code.
@@ -12918,191 +13119,8 @@ DUK_INTERNAL void duk_byteswap_bytes(duk_uint8_t *p, duk_small_uint_t len) {
}
}
#endif
-
-/*
- * 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] & DUK_U64_CONSTANT(0x000000007ff00000)) == DUK_U64_CONSTANT(0x000000007ff00000);
-#else
- return (du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7ff0000000000000)) == DUK_U64_CONSTANT(0x7ff0000000000000);
-#endif
-#else
- return (du.ui[DUK_DBL_IDX_UI0] & 0x7ff00000UL) == 0x7ff00000UL;
-#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] & DUK_U64_CONSTANT(0x000000007ff00000);
- if (t == DUK_U64_CONSTANT(0x0000000000000000)) {
- t = du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x0000000080000000);
- return t == 0;
- }
- if (t == DUK_U64_CONSTANT(0x000000007ff00000)) {
- return 1;
- }
-#else
- t = du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7ff0000000000000);
- if (t == DUK_U64_CONSTANT(0x0000000000000000)) {
- t = du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x8000000000000000);
- return t == 0;
- }
- if (t == DUK_U64_CONSTANT(0x7ff0000000000000)) {
- 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_uint_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);
-}
-/*
- * Hobject Ecmascript [[Class]].
+ * Hobject ECMAScript [[Class]].
*/
/* #include duk_internal.h -> already included */
@@ -13280,9 +13298,10 @@ DUK_EXTERNAL void *duk_resize_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t
if (!(DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h))) {
DUK_ERROR_TYPE(thr, DUK_STR_WRONG_BUFFER_TYPE);
+ DUK_WO_NORETURN(return NULL;);
}
- /* maximum size check is handled by callee */
+ /* Maximum size check is handled by callee. */
duk_hbuffer_resize(thr, h, new_size);
return DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h);
@@ -13300,6 +13319,7 @@ DUK_EXTERNAL void *duk_steal_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t
if (!(DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h))) {
DUK_ERROR_TYPE(thr, DUK_STR_WRONG_BUFFER_TYPE);
+ DUK_WO_NORETURN(return NULL;);
}
/* Forget the previous allocation, setting size to 0 and alloc to
@@ -13328,6 +13348,7 @@ DUK_EXTERNAL void duk_config_buffer(duk_hthread *thr, duk_idx_t idx, void *ptr,
if (!DUK_HBUFFER_HAS_EXTERNAL(h)) {
DUK_ERROR_TYPE(thr, DUK_STR_WRONG_BUFFER_TYPE);
+ DUK_WO_NORETURN(return;);
}
DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(h));
@@ -13376,7 +13397,7 @@ DUK_LOCAL duk_uint8_t *duk__load_buffer_raw(duk_hthread *thr, duk_uint8_t *p) {
len = DUK_RAW_READ_U32_BE(p);
buf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, (duk_size_t) len);
DUK_ASSERT(buf != NULL);
- DUK_MEMCPY((void *) buf, (const void *) p, (size_t) len);
+ duk_memcpy((void *) buf, (const void *) p, (size_t) len);
p += len;
return p;
}
@@ -13391,7 +13412,7 @@ DUK_LOCAL duk_uint8_t *duk__dump_hstring_raw(duk_uint8_t *p, duk_hstring *h) {
DUK_ASSERT(len <= 0xffffffffUL); /* string limits */
tmp32 = (duk_uint32_t) len;
DUK_RAW_WRITE_U32_BE(p, tmp32);
- DUK_MEMCPY((void *) p,
+ duk_memcpy((void *) p,
(const void *) DUK_HSTRING_GET_DATA(h),
len);
p += len;
@@ -13410,9 +13431,10 @@ DUK_LOCAL duk_uint8_t *duk__dump_hbuffer_raw(duk_hthread *thr, duk_uint8_t *p, d
DUK_ASSERT(len <= 0xffffffffUL); /* buffer limits */
tmp32 = (duk_uint32_t) len;
DUK_RAW_WRITE_U32_BE(p, tmp32);
- DUK_MEMCPY((void *) p,
- (const void *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h),
- len);
+ /* When len == 0, buffer data pointer may be NULL. */
+ duk_memcpy_unsafe((void *) p,
+ (const void *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h),
+ len);
p += len;
return p;
}
@@ -13624,7 +13646,7 @@ static duk_uint8_t *duk__dump_func(duk_hthread *thr, duk_hcompfunc *func, duk_bu
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));
+ duk_memcpy_unsafe((void *) p, (const void *) ins, (size_t) (ins_end - ins));
p += (size_t) (ins_end - ins);
#else
while (ins != ins_end) {
@@ -13646,7 +13668,7 @@ static duk_uint8_t *duk__dump_func(duk_hthread *thr, duk_hcompfunc *func, duk_bu
h_str = DUK_TVAL_GET_STRING(tv);
DUK_ASSERT(h_str != NULL);
DUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= 0x7fffffffUL); /* ensures no overflow */
- p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 1U + 4U + DUK_HSTRING_GET_BYTELEN(h_str), p),
+ p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 1U + 4U + DUK_HSTRING_GET_BYTELEN(h_str), p);
*p++ = DUK__SER_STRING;
p = duk__dump_hstring_raw(p, h_str);
} else {
@@ -13810,7 +13832,7 @@ static duk_uint8_t *duk__load_func(duk_hthread *thr, duk_uint8_t *p, duk_uint8_t
DUK__ASSERT_LEFT(count_instr * sizeof(duk_instr_t));
#if defined(DUK_USE_INTEGER_BE)
q = fun_data + sizeof(duk_tval) * count_const + sizeof(duk_hobject *) * count_funcs;
- DUK_MEMCPY((void *) q,
+ duk_memcpy((void *) q,
(const void *) p,
sizeof(duk_instr_t) * count_instr);
p += sizeof(duk_instr_t) * count_instr;
@@ -13875,15 +13897,12 @@ static duk_uint8_t *duk__load_func(duk_hthread *thr, duk_uint8_t *p, duk_uint8_t
DUK_ASSERT((count_const == 0 && count_funcs == 0) || tv1 != NULL);
q = fun_data;
- if (count_const > 0) {
- /* Explicit zero size check to avoid NULL 'tv1'. */
- DUK_MEMCPY((void *) q, (const void *) tv1, sizeof(duk_tval) * count_const);
- for (n = count_const; n > 0; n--) {
- DUK_TVAL_INCREF_FAST(thr, (duk_tval *) (void *) q); /* no side effects */
- q += sizeof(duk_tval);
- }
- tv1 += count_const;
+ duk_memcpy_unsafe((void *) q, (const void *) tv1, sizeof(duk_tval) * count_const);
+ for (n = count_const; n > 0; n--) {
+ DUK_TVAL_INCREF_FAST(thr, (duk_tval *) (void *) q); /* no side effects */
+ q += sizeof(duk_tval);
}
+ tv1 += count_const;
DUK_HCOMPFUNC_SET_FUNCS(thr->heap, h_fun, (duk_hobject **) (void *) q);
for (n = count_funcs; n > 0; n--) {
@@ -14084,6 +14103,7 @@ DUK_EXTERNAL void duk_load_function(duk_hthread *thr) {
format_error:
DUK_ERROR_TYPE(thr, DUK_STR_INVALID_BYTECODE);
+ DUK_WO_NORETURN(return;);
}
#else /* DUK_USE_BYTECODE_DUMP_SUPPORT */
@@ -14091,11 +14111,13 @@ DUK_EXTERNAL void duk_load_function(duk_hthread *thr) {
DUK_EXTERNAL void duk_dump_function(duk_hthread *thr) {
DUK_ASSERT_API_ENTRY(thr);
DUK_ERROR_UNSUPPORTED(thr);
+ DUK_WO_NORETURN(return;);
}
DUK_EXTERNAL void duk_load_function(duk_hthread *thr) {
DUK_ASSERT_API_ENTRY(thr);
DUK_ERROR_UNSUPPORTED(thr);
+ DUK_WO_NORETURN(return;);
}
#endif /* DUK_USE_BYTECODE_DUMP_SUPPORT */
@@ -14162,7 +14184,7 @@ DUK_LOCAL duk_idx_t duk__call_get_idx_func(duk_hthread *thr, duk_idx_t nargs, du
idx_func = duk_get_top(thr) - nargs - other;
if (DUK_UNLIKELY((idx_func | nargs) < 0)) { /* idx_func < 0 || nargs < 0; OR sign bits */
DUK_ERROR_TYPE_INVALID_ARGS(thr);
- /* unreachable */
+ DUK_WO_NORETURN(return 0;);
}
DUK_ASSERT(duk_is_valid_index(thr, idx_func));
return idx_func;
@@ -14274,6 +14296,7 @@ DUK_EXTERNAL void duk_call_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_idx_t n
obj_idx = duk_require_normalize_index(thr, obj_idx); /* make absolute */
if (DUK_UNLIKELY(nargs < 0)) {
DUK_ERROR_TYPE_INVALID_ARGS(thr);
+ DUK_WO_NORETURN(return;);
}
duk__call_prop_prep_stack(thr, obj_idx, nargs);
@@ -14310,7 +14333,7 @@ DUK_EXTERNAL duk_int_t duk_pcall(duk_hthread *thr, duk_idx_t nargs) {
args.nargs = nargs;
if (DUK_UNLIKELY(nargs < 0)) {
DUK_ERROR_TYPE_INVALID_ARGS(thr);
- return DUK_EXEC_ERROR; /* unreachable */
+ DUK_WO_NORETURN(return DUK_EXEC_ERROR;);
}
args.call_flags = 0;
@@ -14345,7 +14368,7 @@ DUK_INTERNAL duk_int_t duk_pcall_method_flags(duk_hthread *thr, duk_idx_t nargs,
args.nargs = nargs;
if (DUK_UNLIKELY(nargs < 0)) {
DUK_ERROR_TYPE_INVALID_ARGS(thr);
- return DUK_EXEC_ERROR; /* unreachable */
+ DUK_WO_NORETURN(return DUK_EXEC_ERROR;);
}
args.call_flags = call_flags;
@@ -14386,7 +14409,7 @@ DUK_EXTERNAL duk_int_t duk_pcall_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_i
args.nargs = nargs;
if (DUK_UNLIKELY(nargs < 0)) {
DUK_ERROR_TYPE_INVALID_ARGS(thr);
- return DUK_EXEC_ERROR; /* unreachable */
+ DUK_WO_NORETURN(return DUK_EXEC_ERROR;);
}
args.call_flags = 0;
@@ -14422,7 +14445,7 @@ DUK_EXTERNAL duk_int_t duk_safe_call(duk_hthread *thr, duk_safe_call_function fu
(long) (thr->valstack_top - thr->valstack),
(long) nrets));
DUK_ERROR_TYPE_INVALID_ARGS(thr);
- return DUK_EXEC_ERROR; /* unreachable */
+ DUK_WO_NORETURN(return DUK_EXEC_ERROR;);
}
rc = duk_handle_safe_call(thr, /* thread */
@@ -14470,7 +14493,7 @@ DUK_EXTERNAL duk_int_t duk_pnew(duk_hthread *thr, duk_idx_t nargs) {
if (DUK_UNLIKELY(nargs < 0)) {
DUK_ERROR_TYPE_INVALID_ARGS(thr);
- return DUK_EXEC_ERROR; /* unreachable */
+ DUK_WO_NORETURN(return DUK_EXEC_ERROR;);
}
rc = duk_safe_call(thr, duk__pnew_helper, (void *) &nargs /*udata*/, nargs + 1 /*nargs*/, 1 /*nrets*/);
@@ -14497,6 +14520,7 @@ DUK_INTERNAL void duk_require_constructor_call(duk_hthread *thr) {
if (!duk_is_constructor_call(thr)) {
DUK_ERROR_TYPE(thr, DUK_STR_CONSTRUCT_ONLY);
+ DUK_WO_NORETURN(return;);
}
}
@@ -14507,7 +14531,7 @@ DUK_EXTERNAL duk_bool_t duk_is_strict_call(duk_hthread *thr) {
* because all Duktape/C functions are considered strict,
* and strict is also the default when nothing is running.
* However, Duktape may call this function internally when
- * the current activation is an Ecmascript function, so
+ * the current activation is an ECMAScript function, so
* this cannot be replaced by a 'return 1' without fixing
* the internal call sites.
*/
@@ -14574,7 +14598,7 @@ DUK_EXTERNAL duk_int_t duk_get_magic(duk_hthread *thr, duk_idx_t idx) {
/* fall through */
type_error:
DUK_ERROR_TYPE(thr, DUK_STR_UNEXPECTED_TYPE);
- return 0;
+ DUK_WO_NORETURN(return 0;);
}
DUK_EXTERNAL void duk_set_magic(duk_hthread *thr, duk_idx_t idx, duk_int_t magic) {
@@ -14606,7 +14630,7 @@ DUK_INTERNAL void duk_resolve_nonbound_function(duk_hthread *thr) {
h = DUK_TVAL_GET_OBJECT(tv);
DUK_ASSERT(h != NULL);
if (DUK_HOBJECT_HAS_BOUNDFUNC(h)) {
- duk_push_tval(thr, &((duk_hboundfunc *) h)->target);
+ duk_push_tval(thr, &((duk_hboundfunc *) (void *) h)->target);
duk_replace(thr, -2);
#if 0
DUK_TVAL_SET_TVAL(tv, &((duk_hboundfunc *) h)->target);
@@ -14636,6 +14660,10 @@ DUK_INTERNAL void duk_resolve_nonbound_function(duk_hthread *thr) {
/* #include duk_internal.h -> already included */
+/*
+ * Misc helpers
+ */
+
/* 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.
@@ -14657,250 +14685,425 @@ DUK_LOCAL const duk_uint8_t *duk__prep_codec_arg(duk_hthread *thr, duk_idx_t idx
return (const duk_uint8_t *) duk_to_lstring(thr, idx, out_len);
}
+/*
+ * Base64
+ */
+
+#if defined(DUK_USE_BASE64_SUPPORT)
+/* Bytes emitted for number of padding characters in range [0,4]. */
+DUK_LOCAL const duk_int8_t duk__base64_decode_nequal_step[5] = {
+ 3, /* #### -> 24 bits, emit 3 bytes */
+ 2, /* ###= -> 18 bits, emit 2 bytes */
+ 1, /* ##== -> 12 bits, emit 1 byte */
+ -1, /* #=== -> 6 bits, error */
+ 0, /* ==== -> 0 bits, emit 0 bytes */
+};
+
#if defined(DUK_USE_BASE64_FASTPATH)
-DUK_LOCAL void duk__base64_encode_helper(const duk_uint8_t *src, duk_size_t srclen, duk_uint8_t *dst) {
+DUK_LOCAL const duk_uint8_t duk__base64_enctab_fast[64] = {
+ 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, 0x48U, 0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU, 0x50U, /* A...P */
+ 0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x57U, 0x58U, 0x59U, 0x5aU, 0x61U, 0x62U, 0x63U, 0x64U, 0x65U, 0x66U, /* Q...f */
+ 0x67U, 0x68U, 0x69U, 0x6aU, 0x6bU, 0x6cU, 0x6dU, 0x6eU, 0x6fU, 0x70U, 0x71U, 0x72U, 0x73U, 0x74U, 0x75U, 0x76U, /* g...v */
+ 0x77U, 0x78U, 0x79U, 0x7aU, 0x30U, 0x31U, 0x32U, 0x33U, 0x34U, 0x35U, 0x36U, 0x37U, 0x38U, 0x39U, 0x2bU, 0x2fU /* w.../ */
+};
+#endif /* DUK_USE_BASE64_FASTPATH */
+
+#if defined(DUK_USE_BASE64_FASTPATH)
+/* Decode table for one byte of input:
+ * -1 = allowed whitespace
+ * -2 = padding
+ * -3 = error
+ * 0...63 decoded bytes
+ */
+DUK_LOCAL const duk_int8_t duk__base64_dectab_fast[256] = {
+ -3, -3, -3, -3, -3, -3, -3, -3, -3, -1, -1, -3, -3, -1, -3, -3, /* 0x00...0x0f */
+ -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, /* 0x10...0x1f */
+ -1, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, 62, -3, -3, -3, 63, /* 0x20...0x2f */
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -3, -3, -3, -2, -3, -3, /* 0x30...0x3f */
+ -3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 0x40...0x4f */
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -3, -3, -3, -3, -3, /* 0x50...0x5f */
+ -3, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 0x60...0x6f */
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -3, -3, -3, -3, -3, /* 0x70...0x7f */
+ -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, /* 0x80...0x8f */
+ -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, /* 0x90...0x9f */
+ -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, /* 0xa0...0xaf */
+ -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, /* 0xb0...0xbf */
+ -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, /* 0xc0...0xcf */
+ -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, /* 0xd0...0xdf */
+ -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, /* 0xe0...0xef */
+ -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3 /* 0xf0...0xff */
+};
+#endif /* DUK_USE_BASE64_FASTPATH */
+
+#if defined(DUK_USE_BASE64_FASTPATH)
+DUK_LOCAL DUK_ALWAYS_INLINE void duk__base64_encode_fast_3(const duk_uint8_t *src, duk_uint8_t *dst) {
duk_uint_t t;
- duk_size_t n_full, n_full3, n_final;
- const duk_uint8_t *src_end_fast;
-
- n_full = srclen / 3; /* full 3-byte -> 4-char conversions */
- n_full3 = n_full * 3;
- n_final = srclen - n_full3;
- DUK_ASSERT_DISABLE(n_final >= 0);
- DUK_ASSERT(n_final <= 2);
-
- src_end_fast = src + n_full3;
- while (DUK_UNLIKELY(src != src_end_fast)) {
- t = (duk_uint_t) (*src++);
- t = (t << 8) + (duk_uint_t) (*src++);
- t = (t << 8) + (duk_uint_t) (*src++);
-
- *dst++ = duk_base64_enctab[t >> 18];
- *dst++ = duk_base64_enctab[(t >> 12) & 0x3f];
- *dst++ = duk_base64_enctab[(t >> 6) & 0x3f];
- *dst++ = duk_base64_enctab[t & 0x3f];
-
-#if 0 /* Tested: not faster on x64 */
- /* aaaaaabb bbbbcccc ccdddddd */
- dst[0] = duk_base64_enctab[(src[0] >> 2) & 0x3f];
- dst[1] = duk_base64_enctab[((src[0] << 4) & 0x30) | ((src[1] >> 4) & 0x0f)];
- dst[2] = duk_base64_enctab[((src[1] << 2) & 0x3f) | ((src[2] >> 6) & 0x03)];
- dst[3] = duk_base64_enctab[src[2] & 0x3f];
- src += 3; dst += 4;
-#endif
- }
-
- switch (n_final) {
- /* case 0: nop */
- case 1: {
- /* XX== */
- t = (duk_uint_t) (*src++);
- *dst++ = duk_base64_enctab[t >> 2]; /* XXXXXX-- */
- *dst++ = duk_base64_enctab[(t << 4) & 0x3f]; /* ------XX */
- *dst++ = DUK_ASC_EQUALS;
- *dst++ = DUK_ASC_EQUALS;
- break;
- }
- case 2: {
- /* XXX= */
- t = (duk_uint_t) (*src++);
- t = (t << 8) + (duk_uint_t) (*src++);
- *dst++ = duk_base64_enctab[t >> 10]; /* XXXXXX-- -------- */
- *dst++ = duk_base64_enctab[(t >> 4) & 0x3f]; /* ------XX XXXX---- */
- *dst++ = duk_base64_enctab[(t << 2) & 0x3f]; /* -------- ----XXXX */
- *dst++ = DUK_ASC_EQUALS;
- break;
- }
+
+ t = (duk_uint_t) src[0];
+ t = (t << 8) + (duk_uint_t) src[1];
+ t = (t << 8) + (duk_uint_t) src[2];
+
+ dst[0] = duk__base64_enctab_fast[t >> 18];
+ dst[1] = duk__base64_enctab_fast[(t >> 12) & 0x3fU];
+ dst[2] = duk__base64_enctab_fast[(t >> 6) & 0x3fU];
+ dst[3] = duk__base64_enctab_fast[t & 0x3fU];
+
+#if 0
+ /* Tested: not faster on x64, most likely due to aliasing between
+ * output and input index computation.
+ */
+ /* aaaaaabb bbbbcccc ccdddddd */
+ dst[0] = duk__base64_enctab_fast[(src[0] >> 2) & 0x3fU];
+ dst[1] = duk__base64_enctab_fast[((src[0] << 4) & 0x30U) | ((src[1] >> 4) & 0x0fU)];
+ dst[2] = duk__base64_enctab_fast[((src[1] << 2) & 0x3fU) | ((src[2] >> 6) & 0x03U)];
+ dst[3] = duk__base64_enctab_fast[src[2] & 0x3fU];
+#endif
+}
+
+DUK_LOCAL DUK_ALWAYS_INLINE void duk__base64_encode_fast_2(const duk_uint8_t *src, duk_uint8_t *dst) {
+ duk_uint_t t;
+
+ t = (duk_uint_t) src[0];
+ t = (t << 8) + (duk_uint_t) src[1];
+ dst[0] = duk__base64_enctab_fast[t >> 10]; /* XXXXXX-- -------- */
+ dst[1] = duk__base64_enctab_fast[(t >> 4) & 0x3fU]; /* ------XX XXXX---- */
+ dst[2] = duk__base64_enctab_fast[(t << 2) & 0x3fU]; /* -------- ----XXXX */
+ dst[3] = DUK_ASC_EQUALS;
+}
+
+DUK_LOCAL DUK_ALWAYS_INLINE void duk__base64_encode_fast_1(const duk_uint8_t *src, duk_uint8_t *dst) {
+ duk_uint_t t;
+
+ t = (duk_uint_t) src[0];
+ dst[0] = duk__base64_enctab_fast[t >> 2]; /* XXXXXX-- */
+ dst[1] = duk__base64_enctab_fast[(t << 4) & 0x3fU]; /* ------XX */
+ dst[2] = DUK_ASC_EQUALS;
+ dst[3] = DUK_ASC_EQUALS;
+}
+
+DUK_LOCAL void duk__base64_encode_helper(const duk_uint8_t *src, duk_size_t srclen, duk_uint8_t *dst) {
+ duk_size_t n;
+ const duk_uint8_t *p;
+ duk_uint8_t *q;
+
+ n = srclen;
+ p = src;
+ q = dst;
+
+ if (n >= 16U) {
+ /* Fast path, unrolled by 4, allows interleaving. Process
+ * 12-byte input chunks which encode to 16-char output chunks.
+ * Only enter when at least one block is emitted (avoids div+mul
+ * for short inputs too).
+ */
+ const duk_uint8_t *p_end_fast;
+
+ p_end_fast = p + ((n / 12U) * 12U);
+ DUK_ASSERT(p_end_fast >= p + 12);
+ do {
+ duk__base64_encode_fast_3(p, q);
+ duk__base64_encode_fast_3(p + 3, q + 4);
+ duk__base64_encode_fast_3(p + 6, q + 8);
+ duk__base64_encode_fast_3(p + 9, q + 12);
+ p += 12;
+ q += 16;
+ } while (DUK_LIKELY(p != p_end_fast));
+
+ DUK_ASSERT(src + srclen >= p);
+ n = (duk_size_t) (src + srclen - p);
+ DUK_ASSERT(n < 12U);
+ }
+
+ /* Remainder. */
+ while (n >= 3U) {
+ duk__base64_encode_fast_3(p, q);
+ p += 3;
+ q += 4;
+ n -= 3U;
+ }
+ DUK_ASSERT(n == 0U || n == 1U || n == 2U);
+ if (n == 1U) {
+ duk__base64_encode_fast_1(p, q);
+#if 0 /* Unnecessary. */
+ p += 1;
+ q += 4;
+ n -= 1U;
+#endif
+ } else if (n == 2U) {
+ duk__base64_encode_fast_2(p, q);
+#if 0 /* Unnecessary. */
+ p += 2;
+ q += 4;
+ n -= 2U;
+#endif
+ } else {
+ DUK_ASSERT(n == 0U); /* nothing to do */
+ ;
}
}
#else /* DUK_USE_BASE64_FASTPATH */
DUK_LOCAL void duk__base64_encode_helper(const duk_uint8_t *src, duk_size_t srclen, duk_uint8_t *dst) {
- duk_small_uint_t i, snip;
- duk_uint_t t;
- duk_uint_fast8_t x, y;
- const duk_uint8_t *src_end;
+ duk_small_uint_t i, npad;
+ duk_uint_t t, x, y;
+ const duk_uint8_t *p;
+ const duk_uint8_t *p_end;
+ duk_uint8_t *q;
- src_end = src + srclen;
+ p = src;
+ p_end = src + srclen;
+ q = dst;
+ npad = 0U;
- while (src < src_end) {
- /* read 3 bytes into 't', padded by zero */
- snip = 4;
+ while (p < p_end) {
+ /* Read 3 bytes into 't', padded by zero. */
t = 0;
for (i = 0; i < 3; i++) {
t = t << 8;
- if (src >= src_end) {
- snip--;
+ if (p < p_end) {
+ t += (duk_uint_t) (*p++);
} else {
- t += (duk_uint_t) (*src++);
+ /* This only happens on the last loop and we're
+ * guaranteed to exit on the next loop.
+ */
+ npad++;
}
}
+ DUK_ASSERT(npad <= 2U);
- /*
- * Missing bytes snip base64 example
- * 0 4 XXXX
- * 1 3 XXX=
- * 2 2 XX==
+ /* Emit 4 encoded characters. If npad > 0, some of the
+ * chars will be incorrect (zero bits) but we fix up the
+ * padding after the loop. A straightforward 64-byte
+ * lookup would be faster and cleaner, but this is shorter.
*/
-
- DUK_ASSERT(snip >= 2 && snip <= 4);
-
for (i = 0; i < 4; i++) {
- x = (duk_uint_fast8_t) ((t >> 18) & 0x3f);
+ x = ((t >> 18) & 0x3fU);
t = t << 6;
- /* A straightforward 64-byte lookup would be faster
- * and cleaner, but this is shorter.
- */
- if (i >= snip) {
- y = '=';
- } else if (x <= 25) {
- y = x + 'A';
- } else if (x <= 51) {
- y = x - 26 + 'a';
- } else if (x <= 61) {
- y = x - 52 + '0';
- } else if (x == 62) {
- y = '+';
+ if (x <= 51U) {
+ if (x <= 25) {
+ y = x + DUK_ASC_UC_A;
+ } else {
+ y = x - 26 + DUK_ASC_LC_A;
+ }
} else {
- y = '/';
+ if (x <= 61U) {
+ y = x - 52 + DUK_ASC_0;
+ } else if (x == 62) {
+ y = DUK_ASC_PLUS;
+ } else {
+ DUK_ASSERT(x == 63);
+ y = DUK_ASC_SLASH;
+ }
}
- *dst++ = (duk_uint8_t) y;
+ *q++ = (duk_uint8_t) y;
}
}
+
+ /* Handle padding by rewriting 0-2 bogus characters at the end.
+ *
+ * Missing bytes npad base64 example
+ * 0 0 ####
+ * 1 1 ###=
+ * 2 2 ##==
+ */
+ DUK_ASSERT(npad <= 2U);
+ while (npad > 0U) {
+ *(q - npad) = DUK_ASC_EQUALS;
+ npad--;
+ }
}
#endif /* DUK_USE_BASE64_FASTPATH */
#if defined(DUK_USE_BASE64_FASTPATH)
DUK_LOCAL duk_bool_t duk__base64_decode_helper(const duk_uint8_t *src, duk_size_t srclen, duk_uint8_t *dst, duk_uint8_t **out_dst_final) {
duk_int_t x;
- duk_int_t t;
+ duk_uint_t t;
duk_small_uint_t n_equal;
- duk_small_uint_t n_chars;
- const duk_uint8_t *src_end;
- const duk_uint8_t *src_end_safe;
+ duk_int8_t step;
+ const duk_uint8_t *p;
+ const duk_uint8_t *p_end;
+ const duk_uint8_t *p_end_safe;
+ duk_uint8_t *q;
- src_end = src + srclen;
- src_end_safe = src_end - 4; /* if 'src < src_end_safe', safe to read 4 bytes */
+ p = src;
+ p_end = src + srclen;
+ p_end_safe = p_end - 8; /* If 'src <= src_end_safe', safe to read 8 bytes. */
+ q = dst;
- /* Innermost fast path processes 4 valid base-64 characters at a time
- * but bails out on whitespace, padding chars ('=') and invalid chars.
- * Once the slow path segment has been processed, we return to the
- * inner fast path again. This handles e.g. base64 with newlines
- * reasonably well because the majority of a line is in the fast path.
+ /* Alternate between a fast path which processes clean groups with no
+ * padding or whitespace, and a slow path which processes one arbitrary
+ * group and then re-enters the fast path. This handles e.g. base64
+ * with newlines reasonably well because the majority of a line is in
+ * the fast path.
*/
for (;;) {
- /* Fast path, handle units with just actual encoding characters. */
-
- while (src <= src_end_safe) {
- /* The lookup byte is intentionally sign extended to (at least)
- * 32 bits and then ORed. This ensures that is at least 1 byte
- * is negative, the highest bit of 't' will be set at the end
- * and we don't need to check every byte.
+ /* Fast path, on each loop handle two 4-char input groups.
+ * If both are clean, emit 6 bytes and continue. If first
+ * is clean, emit 3 bytes and drop out; otherwise emit
+ * nothing and drop out. This approach could be extended to
+ * more groups per loop, but for inputs with e.g. periodic
+ * newlines (which are common) it might not be an improvement.
+ */
+ while (DUK_LIKELY(p <= p_end_safe)) {
+ duk_int_t t1, t2;
+
+ /* The lookup byte is intentionally sign extended to
+ * (at least) 32 bits and then ORed. This ensures
+ * that is at least 1 byte is negative, the highest
+ * bit of the accumulator will be set at the end and
+ * we don't need to check every byte.
+ *
+ * Read all input bytes first before writing output
+ * bytes to minimize aliasing.
*/
- DUK_DDD(DUK_DDDPRINT("fast loop: src=%p, src_end_safe=%p, src_end=%p",
- (const void *) src, (const void *) src_end_safe, (const void *) src_end));
-
- t = (duk_int_t) duk_base64_dectab[*src++];
- t = (t << 6) | (duk_int_t) duk_base64_dectab[*src++];
- t = (t << 6) | (duk_int_t) duk_base64_dectab[*src++];
- t = (t << 6) | (duk_int_t) duk_base64_dectab[*src++];
-
- if (DUK_UNLIKELY(t < 0)) {
- DUK_DDD(DUK_DDDPRINT("fast loop unit was not clean, process one slow path unit"));
- src -= 4;
+ DUK_DDD(DUK_DDDPRINT("fast loop: p=%p, p_end_safe=%p, p_end=%p",
+ (const void *) p, (const void *) p_end_safe, (const void *) p_end));
+
+ t1 = (duk_int_t) duk__base64_dectab_fast[p[0]];
+ t1 = (duk_int_t) ((duk_uint_t) t1 << 6) | (duk_int_t) duk__base64_dectab_fast[p[1]];
+ t1 = (duk_int_t) ((duk_uint_t) t1 << 6) | (duk_int_t) duk__base64_dectab_fast[p[2]];
+ t1 = (duk_int_t) ((duk_uint_t) t1 << 6) | (duk_int_t) duk__base64_dectab_fast[p[3]];
+
+ t2 = (duk_int_t) duk__base64_dectab_fast[p[4]];
+ t2 = (duk_int_t) ((duk_uint_t) t2 << 6) | (duk_int_t) duk__base64_dectab_fast[p[5]];
+ t2 = (duk_int_t) ((duk_uint_t) t2 << 6) | (duk_int_t) duk__base64_dectab_fast[p[6]];
+ t2 = (duk_int_t) ((duk_uint_t) t2 << 6) | (duk_int_t) duk__base64_dectab_fast[p[7]];
+
+ q[0] = (duk_uint8_t) (((duk_uint_t) t1 >> 16) & 0xffU);
+ q[1] = (duk_uint8_t) (((duk_uint_t) t1 >> 8) & 0xffU);
+ q[2] = (duk_uint8_t) ((duk_uint_t) t1 & 0xffU);
+
+ q[3] = (duk_uint8_t) (((duk_uint_t) t2 >> 16) & 0xffU);
+ q[4] = (duk_uint8_t) (((duk_uint_t) t2 >> 8) & 0xffU);
+ q[5] = (duk_uint8_t) ((duk_uint_t) t2 & 0xffU);
+
+ /* Optimistic check using one branch. */
+ if (DUK_LIKELY((t1 | t2) >= 0)) {
+ p += 8;
+ q += 6;
+ } else if (t1 >= 0) {
+ DUK_DDD(DUK_DDDPRINT("fast loop first group was clean, second was not, process one slow path group"));
+ DUK_ASSERT(t2 < 0);
+ p += 4;
+ q += 3;
+ break;
+ } else {
+ DUK_DDD(DUK_DDDPRINT("fast loop first group was not clean, second does not matter, process one slow path group"));
+ DUK_ASSERT(t1 < 0);
break;
}
+ } /* fast path */
- DUK_ASSERT(t <= 0xffffffL);
- DUK_ASSERT((t >> 24) == 0);
- *dst++ = (duk_uint8_t) (t >> 16);
- *dst++ = (duk_uint8_t) ((t >> 8) & 0xff);
- *dst++ = (duk_uint8_t) (t & 0xff);
- }
-
- /* Handle one slow path unit (or finish if we're done). */
-
- n_equal = 0;
- n_chars = 0;
- t = 0;
+ /* Slow path step 1: try to scan a 4-character encoded group,
+ * end-of-input, or start-of-padding. We exit with:
+ * 1. n_chars == 4: full group, no padding, no end-of-input.
+ * 2. n_chars < 4: partial group (may also be 0), encountered
+ * padding or end of input.
+ *
+ * The accumulator is initialized to 1; this allows us to detect
+ * a full group by comparing >= 0x1000000 without an extra
+ * counter variable.
+ */
+ t = 1UL;
for (;;) {
- DUK_DDD(DUK_DDDPRINT("slow loop: src=%p, src_end=%p, n_chars=%ld, n_equal=%ld, t=%ld",
- (const void *) src, (const void *) src_end, (long) n_chars, (long) n_equal, (long) t));
-
- if (DUK_UNLIKELY(src >= src_end)) {
- goto done; /* two level break */
- }
-
- x = duk_base64_dectab[*src++];
- if (DUK_UNLIKELY(x < 0)) {
- if (x == -2) {
+ DUK_DDD(DUK_DDDPRINT("slow loop: p=%p, p_end=%p, t=%lu",
+ (const void *) p, (const void *) p_end, (unsigned long) t));
+
+ if (DUK_LIKELY(p < p_end)) {
+ x = duk__base64_dectab_fast[*p++];
+ if (DUK_LIKELY(x >= 0)) {
+ DUK_ASSERT(x >= 0 && x <= 63);
+ t = (t << 6) + (duk_uint_t) x;
+ if (t >= 0x1000000UL) {
+ break;
+ }
+ } else if (x == -1) {
continue; /* allowed ascii whitespace */
- } else if (x == -3) {
- n_equal++;
- t <<= 6;
+ } else if (x == -2) {
+ p--;
+ break; /* start of padding */
} else {
- DUK_ASSERT(x == -1);
+ DUK_ASSERT(x == -3);
goto decode_error;
}
} else {
- DUK_ASSERT(x >= 0 && x <= 63);
- if (n_equal > 0) {
- /* Don't allow actual chars after equal sign. */
- goto decode_error;
- }
- t = (t << 6) + x;
+ break; /* end of input */
}
+ } /* slow path step 1 */
- if (DUK_UNLIKELY(n_chars == 3)) {
- /* Emit 3 bytes and backtrack if there was padding. There's
- * always space for the whole 3 bytes so no check needed.
- */
- DUK_ASSERT(t <= 0xffffffL);
- DUK_ASSERT((t >> 24) == 0);
- *dst++ = (duk_uint8_t) (t >> 16);
- *dst++ = (duk_uint8_t) ((t >> 8) & 0xff);
- *dst++ = (duk_uint8_t) (t & 0xff);
-
- if (DUK_UNLIKELY(n_equal > 0)) {
- DUK_ASSERT(n_equal <= 4);
-
- /* There may be whitespace between the equal signs. */
- if (n_equal == 1) {
- /* XXX= */
- dst -= 1;
- } else if (n_equal == 2) {
- /* XX== */
- dst -= 2;
- } else {
- goto decode_error; /* invalid padding */
- }
+ /* Complete the padding by simulating pad characters,
+ * regardless of actual input padding chars.
+ */
+ n_equal = 0;
+ while (t < 0x1000000UL) {
+ t = (t << 6) + 0U;
+ n_equal++;
+ }
- /* Continue parsing after padding, allows concatenated,
- * padded base64.
- */
- }
- break; /* back to fast loop */
+ /* Slow path step 2: deal with full/partial group, padding,
+ * etc. Note that for num chars in [0,3] we intentionally emit
+ * 3 bytes but don't step forward that much, buffer space is
+ * guaranteed in setup.
+ *
+ * num chars:
+ * 0 #### no output (= step 0)
+ * 1 #=== reject, 6 bits of data
+ * 2 ##== 12 bits of data, output 1 byte (= step 1)
+ * 3 ###= 18 bits of data, output 2 bytes (= step 2)
+ * 4 #### 24 bits of data, output 3 bytes (= step 3)
+ */
+ q[0] = (duk_uint8_t) ((t >> 16) & 0xffU);
+ q[1] = (duk_uint8_t) ((t >> 8) & 0xffU);
+ q[2] = (duk_uint8_t) (t & 0xffU);
+
+ DUK_ASSERT(n_equal <= 4);
+ step = duk__base64_decode_nequal_step[n_equal];
+ if (DUK_UNLIKELY(step < 0)) {
+ goto decode_error;
+ }
+ q += step;
+
+ /* Slow path step 3: read and ignore padding and whitespace
+ * until (a) next non-padding and non-whitespace character
+ * after which we resume the fast path, or (b) end of input.
+ * This allows us to accept missing, partial, full, and extra
+ * padding cases uniformly. We also support concatenated
+ * base-64 documents because we resume scanning afterwards.
+ *
+ * Note that to support concatenated documents well, the '='
+ * padding found inside the input must also allow for 'extra'
+ * padding. For example, 'Zm===' decodes to 'f' and has one
+ * extra padding char. So, 'Zm===Zm' should decode 'ff', even
+ * though the standard break-up would be 'Zm==' + '=Zm' which
+ * doesn't make sense.
+ *
+ * We also accept prepended padding like '==Zm9', because it
+ * is equivalent to an empty document with extra padding ('==')
+ * followed by a valid document.
+ */
+
+ for (;;) {
+ if (DUK_UNLIKELY(p >= p_end)) {
+ goto done;
+ }
+ x = duk__base64_dectab_fast[*p++];
+ if (x == -1 || x == -2) {
+ ; /* padding or whitespace, keep eating */
} else {
- n_chars++;
+ p--;
+ break; /* backtrack and go back to fast path, even for -1 */
}
- }
- }
- done:
- DUK_DDD(DUK_DDDPRINT("done; src=%p, src_end=%p, n_chars=%ld",
- (const void *) src, (const void *) src_end, (long) n_chars));
+ } /* slow path step 3 */
+ } /* outer fast+slow path loop */
- DUK_ASSERT(src == src_end);
+ done:
+ DUK_DDD(DUK_DDDPRINT("done; p=%p, p_end=%p",
+ (const void *) p, (const void *) p_end));
- if (n_chars != 0) {
- /* Here we'd have the option of decoding unpadded base64
- * (e.g. "xxxxyy" instead of "xxxxyy==". Currently not
- * accepted.
- */
- goto decode_error;
- }
+ DUK_ASSERT(p == p_end);
- *out_dst_final = dst;
+ *out_dst_final = q;
return 1;
decode_error:
@@ -14908,94 +15111,138 @@ DUK_LOCAL duk_bool_t duk__base64_decode_helper(const duk_uint8_t *src, duk_size_
}
#else /* DUK_USE_BASE64_FASTPATH */
DUK_LOCAL duk_bool_t duk__base64_decode_helper(const duk_uint8_t *src, duk_size_t srclen, duk_uint8_t *dst, duk_uint8_t **out_dst_final) {
- duk_uint_t t;
- duk_uint_fast8_t x, y;
- duk_small_uint_t group_idx;
- duk_small_uint_t n_equal;
- const duk_uint8_t *src_end;
+ duk_uint_t t, x;
+ duk_int_t y;
+ duk_int8_t step;
+ const duk_uint8_t *p;
+ const duk_uint8_t *p_end;
+ duk_uint8_t *q;
+ /* 0x09, 0x0a, or 0x0d */
+ duk_uint32_t mask_white = (1U << 9) | (1U << 10) | (1U << 13);
- src_end = src + srclen;
- t = 0;
- group_idx = 0;
- n_equal = 0;
-
- while (src < src_end) {
- x = *src++;
-
- if (x >= 'A' && x <= 'Z') {
- y = x - 'A' + 0;
- } else if (x >= 'a' && x <= 'z') {
- y = x - 'a' + 26;
- } else if (x >= '0' && x <= '9') {
- y = x - '0' + 52;
- } else if (x == '+') {
- y = 62;
- } else if (x == '/') {
- y = 63;
- } else if (x == '=') {
- /* We don't check the zero padding bytes here right now
- * (that they're actually zero). This seems to be common
- * behavior for base-64 decoders.
+ /* 't' tracks progress of the decoded group:
+ *
+ * t == 1 no valid chars yet
+ * t >= 0x40 1x6 = 6 bits shifted in
+ * t >= 0x1000 2x6 = 12 bits shifted in
+ * t >= 0x40000 3x6 = 18 bits shifted in
+ * t >= 0x1000000 4x6 = 24 bits shifted in
+ *
+ * By initializing t=1 there's no need for a separate counter for
+ * the number of characters found so far.
+ */
+ p = src;
+ p_end = src + srclen;
+ q = dst;
+ t = 1UL;
+
+ for (;;) {
+ duk_small_uint_t n_equal;
+
+ DUK_ASSERT(t >= 1U);
+ if (p >= p_end) {
+ /* End of input: if input exists, treat like
+ * start of padding, finish the block, then
+ * re-enter here to see we're done.
*/
+ if (t == 1U) {
+ break;
+ } else {
+ goto simulate_padding;
+ }
+ }
- n_equal++;
- t <<= 6; /* shift in zeroes */
- goto skip_add;
- } else if (x == 0x09 || x == 0x0a || x == 0x0d || x == 0x20) {
- /* allow basic ASCII whitespace */
- continue;
+ x = *p++;
+
+ if (x >= 0x41U) {
+ /* Valid: a-z and A-Z. */
+ DUK_ASSERT(x >= 0x41U && x <= 0xffU);
+ if (x >= 0x61U && x <= 0x7aU) {
+ y = (duk_int_t) x - 0x61 + 26;
+ } else if (x <= 0x5aU) {
+ y = (duk_int_t) x - 0x41;
+ } else {
+ goto decode_error;
+ }
+ } else if (x >= 0x30U) {
+ /* Valid: 0-9 and =. */
+ DUK_ASSERT(x >= 0x30U && x <= 0x40U);
+ if (x <= 0x39U) {
+ y = (duk_int_t) x - 0x30 + 52;
+ } else if (x == 0x3dU) {
+ /* Skip padding and whitespace unless we're in the
+ * middle of a block. Otherwise complete group by
+ * simulating shifting in the correct padding.
+ */
+ if (t == 1U) {
+ continue;
+ }
+ goto simulate_padding;
+ } else {
+ goto decode_error;
+ }
+ } else if (x >= 0x20U) {
+ /* Valid: +, /, and 0x20 whitespace. */
+ DUK_ASSERT(x >= 0x20U && x <= 0x2fU);
+ if (x == 0x2bU) {
+ y = 62;
+ } else if (x == 0x2fU) {
+ y = 63;
+ } else if (x == 0x20U) {
+ continue;
+ } else {
+ goto decode_error;
+ }
} else {
- goto decode_error;
+ /* Valid: whitespace. */
+ duk_uint32_t m;
+ DUK_ASSERT(x < 0x20U); /* 0x00 to 0x1f */
+ m = (1U << x);
+ if (mask_white & m) {
+ /* Allow basic ASCII whitespace. */
+ continue;
+ } else {
+ goto decode_error;
+ }
}
- if (n_equal > 0) {
- /* Don't allow mixed padding and actual chars. */
- goto decode_error;
+ DUK_ASSERT(y >= 0 && y <= 63);
+ t = (t << 6) + (duk_uint_t) y;
+ if (t < 0x1000000UL) {
+ continue;
}
- t = (t << 6) + y;
- skip_add:
-
- if (group_idx == 3) {
- /* output 3 bytes from 't' */
- *dst++ = (duk_uint8_t) ((t >> 16) & 0xff);
- *dst++ = (duk_uint8_t) ((t >> 8) & 0xff);
- *dst++ = (duk_uint8_t) (t & 0xff);
-
- if (DUK_UNLIKELY(n_equal > 0)) {
- /* Backtrack. */
- DUK_ASSERT(n_equal <= 4);
- if (n_equal == 1) {
- dst -= 1;
- } else if (n_equal == 2) {
- dst -= 2;
- } else {
- goto decode_error; /* invalid padding */
- }
+ /* fall through; no padding will be added */
- /* Here we can choose either to end parsing and ignore
- * whatever follows, or to continue parsing in case
- * multiple (possibly padded) base64 strings have been
- * concatenated. Currently, keep on parsing.
- */
- n_equal = 0;
- }
+ simulate_padding:
+ n_equal = 0;
+ while (t < 0x1000000UL) {
+ t = (t << 6) + 0U;
+ n_equal++;
+ }
- t = 0;
- group_idx = 0;
- } else {
- group_idx++;
+ /* Output 3 bytes from 't' and advance as needed. */
+ q[0] = (duk_uint8_t) ((t >> 16) & 0xffU);
+ q[1] = (duk_uint8_t) ((t >> 8) & 0xffU);
+ q[2] = (duk_uint8_t) (t & 0xffU);
+
+ DUK_ASSERT(n_equal <= 4U);
+ step = duk__base64_decode_nequal_step[n_equal];
+ if (step < 0) {
+ goto decode_error;
}
- }
+ q += step;
- if (group_idx != 0) {
- /* Here we'd have the option of decoding unpadded base64
- * (e.g. "xxxxyy" instead of "xxxxyy==". Currently not
- * accepted.
+ /* Re-enter loop. The actual padding characters are skipped
+ * by the main loop. This handles cases like missing, partial,
+ * full, and extra padding, and allows parsing of concatenated
+ * documents (with extra padding) like: Zm===Zm. Also extra
+ * prepended padding is accepted: ===Zm9v.
*/
- goto decode_error;
+ t = 1U;
}
+ DUK_ASSERT(t == 1UL);
- *out_dst_final = dst;
+ *out_dst_final = q;
return 1;
decode_error:
@@ -15012,15 +15259,12 @@ DUK_EXTERNAL const char *duk_base64_encode(duk_hthread *thr, duk_idx_t idx) {
DUK_ASSERT_API_ENTRY(thr);
- /* XXX: optimize for string inputs: no need to coerce to a buffer
- * which makes a copy of the input.
- */
-
idx = duk_require_normalize_index(thr, idx);
src = duk__prep_codec_arg(thr, idx, &srclen);
/* Note: for srclen=0, src may be NULL */
- /* Computation must not wrap; this limit works for 32-bit size_t:
+ /* Compute exact output length. Computation must not wrap; this
+ * limit works for 32-bit size_t:
* >>> srclen = 3221225469
* >>> '%x' % ((srclen + 2) / 3 * 4)
* 'fffffffc'
@@ -15028,7 +15272,7 @@ DUK_EXTERNAL const char *duk_base64_encode(duk_hthread *thr, duk_idx_t idx) {
if (srclen > 3221225469UL) {
goto type_error;
}
- dstlen = (srclen + 2) / 3 * 4;
+ dstlen = (srclen + 2U) / 3U * 4U;
dst = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, dstlen);
duk__base64_encode_helper((const duk_uint8_t *) src, srclen, dst);
@@ -15039,7 +15283,7 @@ DUK_EXTERNAL const char *duk_base64_encode(duk_hthread *thr, duk_idx_t idx) {
type_error:
DUK_ERROR_TYPE(thr, DUK_STR_BASE64_ENCODE_FAILED);
- return NULL; /* never here */
+ DUK_WO_NORETURN(return NULL;);
}
DUK_EXTERNAL void duk_base64_decode(duk_hthread *thr, duk_idx_t idx) {
@@ -15048,31 +15292,24 @@ DUK_EXTERNAL void duk_base64_decode(duk_hthread *thr, duk_idx_t idx) {
duk_size_t dstlen;
duk_uint8_t *dst;
duk_uint8_t *dst_final;
- duk_bool_t retval;
DUK_ASSERT_API_ENTRY(thr);
- /* XXX: optimize for buffer inputs: no need to coerce to a string
- * which causes an unnecessary interning.
- */
-
idx = duk_require_normalize_index(thr, idx);
src = duk__prep_codec_arg(thr, idx, &srclen);
- /* Computation must not wrap, only srclen + 3 is at risk of
- * wrapping because after that the number gets smaller.
- * This limit works for 32-bit size_t:
- * 0x100000000 - 3 - 1 = 4294967292
+ /* Round up and add safety margin. Avoid addition before division to
+ * avoid possibility of wrapping. Margin includes +3 for rounding up,
+ * and +3 for one extra group: the decoder may emit and then backtrack
+ * a full group (3 bytes) from zero-sized input for technical reasons.
+ * Similarly, 'xx' may ecause 1+3 = bytes to be emitted and then
+ * backtracked.
*/
- if (srclen > 4294967292UL) {
- goto type_error;
- }
- dstlen = (srclen + 3) / 4 * 3; /* upper limit, assuming no whitespace etc */
+ dstlen = (srclen / 4) * 3 + 6; /* upper limit, assuming no whitespace etc */
dst = (duk_uint8_t *) duk_push_dynamic_buffer(thr, dstlen);
/* Note: for dstlen=0, dst may be NULL */
- retval = duk__base64_decode_helper((const duk_uint8_t *) src, srclen, dst, &dst_final);
- if (!retval) {
+ if (!duk__base64_decode_helper((const duk_uint8_t *) src, srclen, dst, &dst_final)) {
goto type_error;
}
@@ -15083,8 +15320,27 @@ DUK_EXTERNAL void duk_base64_decode(duk_hthread *thr, duk_idx_t idx) {
type_error:
DUK_ERROR_TYPE(thr, DUK_STR_BASE64_DECODE_FAILED);
+ DUK_WO_NORETURN(return;);
}
+#else /* DUK_USE_BASE64_SUPPORT */
+DUK_EXTERNAL const char *duk_base64_encode(duk_hthread *thr, duk_idx_t idx) {
+ DUK_UNREF(idx);
+ DUK_ERROR_UNSUPPORTED(thr);
+ DUK_WO_NORETURN(return;);
+}
+
+DUK_EXTERNAL void duk_base64_decode(duk_hthread *thr, duk_idx_t idx) {
+ DUK_UNREF(idx);
+ DUK_ERROR_UNSUPPORTED(thr);
+ DUK_WO_NORETURN(return;);
+}
+#endif /* DUK_USE_BASE64_SUPPORT */
+
+/*
+ * Hex
+ */
+#if defined(DUK_USE_HEX_SUPPORT)
DUK_EXTERNAL const char *duk_hex_encode(duk_hthread *thr, duk_idx_t idx) {
const duk_uint8_t *inp;
duk_size_t len;
@@ -15195,8 +15451,12 @@ DUK_EXTERNAL void duk_hex_decode(duk_hthread *thr, duk_idx_t idx) {
}
}
for (; i < len; i += 2) {
- t = (((duk_int_t) duk_hex_dectab[inp[i]]) << 4) |
- ((duk_int_t) duk_hex_dectab[inp[i + 1]]);
+ /* First cast to duk_int_t to sign extend, second cast to
+ * duk_uint_t to avoid signed left shift, and final cast to
+ * duk_int_t result type.
+ */
+ t = (duk_int_t) ((((duk_uint_t) (duk_int_t) duk_hex_dectab[inp[i]]) << 4U) |
+ ((duk_uint_t) (duk_int_t) duk_hex_dectab[inp[i + 1]]));
if (DUK_UNLIKELY(t < 0)) {
goto type_error;
}
@@ -15208,8 +15468,8 @@ DUK_EXTERNAL void duk_hex_decode(duk_hthread *thr, duk_idx_t idx) {
* at least 16 bits. If either nybble is invalid, the
* resulting 't' will be < 0.
*/
- t = (((duk_int_t) duk_hex_dectab[inp[i]]) << 4) |
- ((duk_int_t) duk_hex_dectab[inp[i + 1]]);
+ t = (duk_int_t) ((((duk_uint_t) (duk_int_t) duk_hex_dectab[inp[i]]) << 4U) |
+ ((duk_uint_t) (duk_int_t) duk_hex_dectab[inp[i + 1]]));
if (DUK_UNLIKELY(t < 0)) {
goto type_error;
}
@@ -15222,7 +15482,24 @@ DUK_EXTERNAL void duk_hex_decode(duk_hthread *thr, duk_idx_t idx) {
type_error:
DUK_ERROR_TYPE(thr, DUK_STR_HEX_DECODE_FAILED);
+ DUK_WO_NORETURN(return;);
+}
+#else /* DUK_USE_HEX_SUPPORT */
+DUK_EXTERNAL const char *duk_hex_encode(duk_hthread *thr, duk_idx_t idx) {
+ DUK_UNREF(idx);
+ DUK_ERROR_UNSUPPORTED(thr);
+ DUK_WO_NORETURN(return;);
+}
+DUK_EXTERNAL void duk_hex_decode(duk_hthread *thr, duk_idx_t idx) {
+ DUK_UNREF(idx);
+ DUK_ERROR_UNSUPPORTED(thr);
+ DUK_WO_NORETURN(return;);
}
+#endif /* DUK_USE_HEX_SUPPORT */
+
+/*
+ * JSON
+ */
#if defined(DUK_USE_JSON_SUPPORT)
DUK_EXTERNAL const char *duk_json_encode(duk_hthread *thr, duk_idx_t idx) {
@@ -15275,12 +15552,14 @@ DUK_EXTERNAL const char *duk_json_encode(duk_hthread *thr, duk_idx_t idx) {
DUK_ASSERT_API_ENTRY(thr);
DUK_UNREF(idx);
DUK_ERROR_UNSUPPORTED(thr);
+ DUK_WO_NORETURN(return NULL;);
}
DUK_EXTERNAL void duk_json_decode(duk_hthread *thr, duk_idx_t idx) {
DUK_ASSERT_API_ENTRY(thr);
DUK_UNREF(idx);
DUK_ERROR_UNSUPPORTED(thr);
+ DUK_WO_NORETURN(return;);
}
#endif /* DUK_USE_JSON_SUPPORT */
/*
@@ -15374,6 +15653,7 @@ DUK_LOCAL duk_ret_t duk__do_compile(duk_hthread *thr, void *udata) {
if ((flags & DUK_COMPILE_NOSOURCE) || /* args incorrect */
(h_sourcecode == NULL)) { /* e.g. duk_push_string_file_raw() pushed undefined */
DUK_ERROR_TYPE(thr, DUK_STR_NO_SOURCECODE);
+ DUK_WO_NORETURN(return 0;);
}
DUK_ASSERT(h_sourcecode != NULL);
comp_args->src_buffer = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_sourcecode);
@@ -15498,6 +15778,7 @@ DUK_EXTERNAL void duk_push_context_dump(duk_hthread *thr) {
DUK_EXTERNAL void duk_push_context_dump(duk_hthread *thr) {
DUK_ASSERT_API_ENTRY(thr);
DUK_ERROR_UNSUPPORTED(thr);
+ DUK_WO_NORETURN(return;);
}
#endif /* DUK_USE_JSON_SUPPORT */
@@ -15609,7 +15890,7 @@ DUK_EXTERNAL duk_bool_t duk_debugger_notify(duk_hthread *thr, duk_idx_t nvalues)
top = duk_get_top(thr);
if (top < nvalues) {
DUK_ERROR_RANGE(thr, "not enough stack values for notify");
- return ret; /* unreachable */
+ DUK_WO_NORETURN(return 0;);
}
if (duk_debug_is_attached(thr->heap)) {
duk_debug_write_notify(thr, DUK_DBG_CMD_APPNOTIFY);
@@ -15676,11 +15957,13 @@ DUK_EXTERNAL void duk_debugger_attach(duk_hthread *thr,
DUK_UNREF(detached_cb);
DUK_UNREF(udata);
DUK_ERROR_TYPE(thr, "no debugger support");
+ DUK_WO_NORETURN(return;);
}
DUK_EXTERNAL void duk_debugger_detach(duk_hthread *thr) {
DUK_ASSERT_API_ENTRY(thr);
DUK_ERROR_TYPE(thr, "no debugger support");
+ DUK_WO_NORETURN(return;);
}
DUK_EXTERNAL void duk_debugger_cooperate(duk_hthread *thr) {
@@ -15697,7 +15980,7 @@ DUK_EXTERNAL duk_bool_t duk_debugger_notify(duk_hthread *thr, duk_idx_t nvalues)
top = duk_get_top(thr);
if (top < nvalues) {
DUK_ERROR_RANGE_INVALID_COUNT(thr);
- return 0; /* unreachable */
+ DUK_WO_NORETURN(return 0;);
}
/* No debugger support, just pop values. */
@@ -15819,7 +16102,7 @@ DUK_EXTERNAL void duk_suspend(duk_hthread *thr, duk_thread_state *state) {
duk_push_tval(thr, &lj->value2);
/* XXX: creating_error == 0 is asserted above, so no need to store. */
- DUK_MEMCPY((void *) &snapshot->lj, (const void *) lj, sizeof(duk_ljstate));
+ duk_memcpy((void *) &snapshot->lj, (const void *) lj, sizeof(duk_ljstate));
snapshot->creating_error = heap->creating_error;
snapshot->curr_thread = heap->curr_thread;
snapshot->call_recursion_depth = heap->call_recursion_depth;
@@ -15849,7 +16132,7 @@ DUK_EXTERNAL void duk_resume(duk_hthread *thr, const duk_thread_state *state) {
heap = thr->heap;
- DUK_MEMCPY((void *) &heap->lj, (const void *) &snapshot->lj, sizeof(duk_ljstate));
+ duk_memcpy((void *) &heap->lj, (const void *) &snapshot->lj, sizeof(duk_ljstate));
heap->creating_error = snapshot->creating_error;
heap->curr_thread = snapshot->curr_thread;
heap->call_recursion_depth = snapshot->call_recursion_depth;
@@ -15985,7 +16268,7 @@ DUK_EXTERNAL void duk_inspect_value(duk_hthread *thr, duk_idx_t idx) {
DUK_ASSERT_API_ENTRY(thr);
/* Assume two's complement and set everything to -1. */
- DUK_MEMSET((void *) &vals, (int) 0xff, sizeof(vals));
+ duk_memset((void *) &vals, (int) 0xff, sizeof(vals));
DUK_ASSERT(vals[DUK__IDX_TYPE] == -1); /* spot check one */
tv = duk_get_tval_or_unused(thr, idx);
@@ -16001,12 +16284,12 @@ DUK_EXTERNAL void duk_inspect_value(duk_hthread *thr, duk_idx_t idx) {
goto finish;
}
duk_push_pointer(thr, (void *) h);
- duk_put_prop_string(thr, -2, "hptr");
+ duk_put_prop_literal(thr, -2, "hptr");
#if 0
/* Covers a lot of information, e.g. buffer and string variants. */
duk_push_uint(thr, (duk_uint_t) DUK_HEAPHDR_GET_FLAGS(h));
- duk_put_prop_string(thr, -2, "hflags");
+ duk_put_prop_literal(thr, -2, "hflags");
#endif
#if defined(DUK_USE_REFERENCE_COUNTING)
@@ -16051,7 +16334,7 @@ DUK_EXTERNAL void duk_inspect_value(duk_hthread *thr, duk_idx_t idx) {
}
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_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);
@@ -16252,7 +16535,7 @@ DUK_EXTERNAL void duk_gc(duk_hthread *thr, duk_uint_t flags) {
* Property handling
*
* The API exposes only the most common property handling functions.
- * The caller can invoke Ecmascript built-ins for full control (e.g.
+ * The caller can invoke ECMAScript built-ins for full control (e.g.
* defineProperty, getOwnPropertyDescriptor).
*/
@@ -16284,7 +16567,7 @@ DUK_EXTERNAL duk_bool_t duk_get_prop_string(duk_hthread *thr, duk_idx_t obj_idx,
DUK_ASSERT(key != NULL);
obj_idx = duk_require_normalize_index(thr, obj_idx);
- duk_push_string(thr, key);
+ (void) duk_push_string(thr, key);
return duk_get_prop(thr, obj_idx);
}
@@ -16293,9 +16576,21 @@ DUK_EXTERNAL duk_bool_t duk_get_prop_lstring(duk_hthread *thr, duk_idx_t obj_idx
DUK_ASSERT(key != NULL);
obj_idx = duk_require_normalize_index(thr, obj_idx);
- duk_push_lstring(thr, key, key_len);
+ (void) duk_push_lstring(thr, key, key_len);
+ return duk_get_prop(thr, obj_idx);
+}
+
+#if !defined(DUK_USE_PREFER_SIZE)
+DUK_EXTERNAL duk_bool_t duk_get_prop_literal_raw(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ASSERT(key != NULL);
+ DUK_ASSERT(key[key_len] == (char) 0);
+
+ obj_idx = duk_require_normalize_index(thr, obj_idx);
+ (void) duk_push_literal_raw(thr, key, key_len);
return duk_get_prop(thr, obj_idx);
}
+#endif
DUK_EXTERNAL duk_bool_t duk_get_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx) {
DUK_ASSERT_API_ENTRY(thr);
@@ -16309,7 +16604,7 @@ DUK_EXTERNAL duk_bool_t duk_get_prop_heapptr(duk_hthread *thr, duk_idx_t obj_idx
DUK_ASSERT_API_ENTRY(thr);
obj_idx = duk_require_normalize_index(thr, obj_idx);
- duk_push_heapptr(thr, ptr); /* NULL -> 'undefined' */
+ (void) duk_push_heapptr(thr, ptr); /* NULL -> 'undefined' */
return duk_get_prop(thr, obj_idx);
}
@@ -16318,7 +16613,7 @@ DUK_INTERNAL duk_bool_t duk_get_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx,
DUK_ASSERT_STRIDX_VALID(stridx);
obj_idx = duk_require_normalize_index(thr, obj_idx);
- duk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));
+ (void) duk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));
return duk_get_prop(thr, obj_idx);
}
@@ -16337,10 +16632,7 @@ DUK_INTERNAL duk_bool_t duk_get_prop_stridx_boolean(duk_hthread *thr, duk_idx_t
if (out_has_prop) {
*out_has_prop = rc;
}
- rc = duk_to_boolean(thr, -1);
- DUK_ASSERT(rc == 0 || rc == 1);
- duk_pop(thr);
- return rc;
+ return duk_to_boolean_top_pop(thr);
}
DUK_LOCAL duk_bool_t duk__put_prop_shared(duk_hthread *thr, duk_idx_t obj_idx, duk_idx_t idx_key) {
@@ -16400,6 +16692,18 @@ DUK_EXTERNAL duk_bool_t duk_put_prop_lstring(duk_hthread *thr, duk_idx_t obj_idx
return duk__put_prop_shared(thr, obj_idx, -1);
}
+#if !defined(DUK_USE_PREFER_SIZE)
+DUK_EXTERNAL duk_bool_t duk_put_prop_literal_raw(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ASSERT(key != NULL);
+ DUK_ASSERT(key[key_len] == (char) 0);
+
+ obj_idx = duk_normalize_index(thr, obj_idx);
+ (void) duk_push_literal_raw(thr, key, key_len);
+ return duk__put_prop_shared(thr, obj_idx, -1);
+}
+#endif
+
DUK_EXTERNAL duk_bool_t duk_put_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx) {
DUK_ASSERT_API_ENTRY(thr);
@@ -16412,7 +16716,7 @@ DUK_EXTERNAL duk_bool_t duk_put_prop_heapptr(duk_hthread *thr, duk_idx_t obj_idx
DUK_ASSERT_API_ENTRY(thr);
obj_idx = duk_require_normalize_index(thr, obj_idx);
- duk_push_heapptr(thr, ptr); /* NULL -> 'undefined' */
+ (void) duk_push_heapptr(thr, ptr); /* NULL -> 'undefined' */
return duk__put_prop_shared(thr, obj_idx, -1);
}
@@ -16459,7 +16763,7 @@ DUK_EXTERNAL duk_bool_t duk_del_prop_string(duk_hthread *thr, duk_idx_t obj_idx,
DUK_ASSERT(key != NULL);
obj_idx = duk_require_normalize_index(thr, obj_idx);
- duk_push_string(thr, key);
+ (void) duk_push_string(thr, key);
return duk_del_prop(thr, obj_idx);
}
@@ -16468,9 +16772,21 @@ DUK_EXTERNAL duk_bool_t duk_del_prop_lstring(duk_hthread *thr, duk_idx_t obj_idx
DUK_ASSERT(key != NULL);
obj_idx = duk_require_normalize_index(thr, obj_idx);
- duk_push_lstring(thr, key, key_len);
+ (void) duk_push_lstring(thr, key, key_len);
+ return duk_del_prop(thr, obj_idx);
+}
+
+#if !defined(DUK_USE_PREFER_SIZE)
+DUK_EXTERNAL duk_bool_t duk_del_prop_literal_raw(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ASSERT(key != NULL);
+ DUK_ASSERT(key[key_len] == (char) 0);
+
+ obj_idx = duk_require_normalize_index(thr, obj_idx);
+ (void) duk_push_literal_raw(thr, key, key_len);
return duk_del_prop(thr, obj_idx);
}
+#endif
DUK_EXTERNAL duk_bool_t duk_del_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx) {
DUK_ASSERT_API_ENTRY(thr);
@@ -16484,7 +16800,7 @@ DUK_EXTERNAL duk_bool_t duk_del_prop_heapptr(duk_hthread *thr, duk_idx_t obj_idx
DUK_ASSERT_API_ENTRY(thr);
obj_idx = duk_require_normalize_index(thr, obj_idx);
- duk_push_heapptr(thr, ptr); /* NULL -> 'undefined' */
+ (void) duk_push_heapptr(thr, ptr); /* NULL -> 'undefined' */
return duk_del_prop(thr, obj_idx);
}
@@ -16530,7 +16846,7 @@ DUK_EXTERNAL duk_bool_t duk_has_prop_string(duk_hthread *thr, duk_idx_t obj_idx,
DUK_ASSERT(key != NULL);
obj_idx = duk_require_normalize_index(thr, obj_idx);
- duk_push_string(thr, key);
+ (void) duk_push_string(thr, key);
return duk_has_prop(thr, obj_idx);
}
@@ -16539,9 +16855,21 @@ DUK_EXTERNAL duk_bool_t duk_has_prop_lstring(duk_hthread *thr, duk_idx_t obj_idx
DUK_ASSERT(key != NULL);
obj_idx = duk_require_normalize_index(thr, obj_idx);
- duk_push_lstring(thr, key, key_len);
+ (void) duk_push_lstring(thr, key, key_len);
+ return duk_has_prop(thr, obj_idx);
+}
+
+#if !defined(DUK_USE_PREFER_SIZE)
+DUK_EXTERNAL duk_bool_t duk_has_prop_literal_raw(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ASSERT(key != NULL);
+ DUK_ASSERT(key[key_len] == (char) 0);
+
+ obj_idx = duk_require_normalize_index(thr, obj_idx);
+ (void) duk_push_literal_raw(thr, key, key_len);
return duk_has_prop(thr, obj_idx);
}
+#endif
DUK_EXTERNAL duk_bool_t duk_has_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx) {
DUK_ASSERT_API_ENTRY(thr);
@@ -16555,7 +16883,7 @@ DUK_EXTERNAL duk_bool_t duk_has_prop_heapptr(duk_hthread *thr, duk_idx_t obj_idx
DUK_ASSERT_API_ENTRY(thr);
obj_idx = duk_require_normalize_index(thr, obj_idx);
- duk_push_heapptr(thr, ptr); /* NULL -> 'undefined' */
+ (void) duk_push_heapptr(thr, ptr); /* NULL -> 'undefined' */
return duk_has_prop(thr, obj_idx);
}
@@ -16755,17 +17083,17 @@ DUK_EXTERNAL void duk_def_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_uint_t f
fail_invalid_desc:
DUK_ERROR_TYPE(thr, DUK_STR_INVALID_DESCRIPTOR);
- return;
+ DUK_WO_NORETURN(return;);
fail_not_callable:
DUK_ERROR_TYPE(thr, DUK_STR_NOT_CALLABLE);
- return;
+ DUK_WO_NORETURN(return;);
}
/*
* Object related
*
- * Note: seal() and freeze() are accessible through Ecmascript bindings,
+ * Note: seal() and freeze() are accessible through ECMAScript bindings,
* and are not exposed through the API.
*/
@@ -16857,6 +17185,7 @@ DUK_INTERNAL void duk_seal_freeze_raw(duk_hthread *thr, duk_idx_t obj_idx, duk_b
fail_cannot_freeze:
DUK_ERROR_TYPE_INVALID_ARGS(thr); /* XXX: proper error message */
+ DUK_WO_NORETURN(return;);
}
DUK_EXTERNAL void duk_seal(duk_hthread *thr, duk_idx_t obj_idx) {
@@ -16940,6 +17269,38 @@ DUK_EXTERNAL duk_bool_t duk_get_global_lstring(duk_hthread *thr, const char *key
return ret;
}
+#if !defined(DUK_USE_PREFER_SIZE)
+DUK_EXTERNAL duk_bool_t duk_get_global_literal_raw(duk_hthread *thr, const char *key, duk_size_t key_len) {
+ duk_bool_t ret;
+
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);
+ DUK_ASSERT(key[key_len] == (char) 0);
+
+ /* XXX: direct implementation */
+
+ duk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);
+ ret = duk_get_prop_literal_raw(thr, -1, key, key_len);
+ duk_remove_m2(thr);
+ return ret;
+}
+#endif
+
+DUK_EXTERNAL duk_bool_t duk_get_global_heapptr(duk_hthread *thr, void *ptr) {
+ duk_bool_t ret;
+
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);
+
+ /* XXX: direct implementation */
+
+ duk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);
+ ret = duk_get_prop_heapptr(thr, -1, ptr);
+ duk_remove_m2(thr);
+ return ret;
+}
+
+
DUK_EXTERNAL duk_bool_t duk_put_global_string(duk_hthread *thr, const char *key) {
duk_bool_t ret;
@@ -16970,6 +17331,56 @@ DUK_EXTERNAL duk_bool_t duk_put_global_lstring(duk_hthread *thr, const char *key
return ret;
}
+#if !defined(DUK_USE_PREFER_SIZE)
+DUK_EXTERNAL duk_bool_t duk_put_global_literal_raw(duk_hthread *thr, const char *key, duk_size_t key_len) {
+ duk_bool_t ret;
+
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);
+ DUK_ASSERT(key[key_len] == (char) 0);
+
+ /* XXX: direct implementation */
+
+ duk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);
+ duk_insert(thr, -2);
+ ret = duk_put_prop_literal_raw(thr, -2, key, key_len); /* [ ... global val ] -> [ ... global ] */
+ duk_pop(thr);
+ return ret;
+}
+#endif
+
+DUK_EXTERNAL duk_bool_t duk_put_global_heapptr(duk_hthread *thr, void *ptr) {
+ duk_bool_t ret;
+
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);
+
+ /* XXX: direct implementation */
+
+ duk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);
+ duk_insert(thr, -2);
+ ret = duk_put_prop_heapptr(thr, -2, ptr); /* [ ... global val ] -> [ ... global ] */
+ duk_pop(thr);
+ return ret;
+}
+
+/*
+ * ES2015 GetMethod()
+ */
+
+DUK_INTERNAL duk_bool_t duk_get_method_stridx(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t stridx) {
+ (void) duk_get_prop_stridx(thr, idx, stridx);
+ if (duk_is_null_or_undefined(thr, -1)) {
+ duk_pop_nodecref_unsafe(thr);
+ return 0;
+ }
+ if (!duk_is_callable(thr, -1)) {
+ DUK_ERROR_TYPE(thr, DUK_STR_NOT_CALLABLE);
+ DUK_WO_NORETURN(return 0;);
+ }
+ return 1;
+}
+
/*
* Object prototype
*/
@@ -17008,7 +17419,7 @@ DUK_EXTERNAL void duk_set_prototype(duk_hthread *thr, duk_idx_t idx) {
#if defined(DUK_USE_ROM_OBJECTS)
if (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {
DUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE); /* XXX: "read only object"? */
- return;
+ DUK_WO_NORETURN(return;);
}
#endif
@@ -17065,15 +17476,26 @@ DUK_EXTERNAL void duk_get_finalizer(duk_hthread *thr, duk_idx_t idx) {
DUK_ASSERT_API_ENTRY(thr);
DUK_UNREF(idx);
DUK_ERROR_UNSUPPORTED(thr);
+ DUK_WO_NORETURN(return;);
}
DUK_EXTERNAL void duk_set_finalizer(duk_hthread *thr, duk_idx_t idx) {
DUK_ASSERT_API_ENTRY(thr);
DUK_UNREF(idx);
DUK_ERROR_UNSUPPORTED(thr);
+ DUK_WO_NORETURN(return;);
}
#endif /* DUK_USE_FINALIZER_SUPPORT */
/*
+ * Random numbers
+ */
+
+/* #include duk_internal.h -> already included */
+
+DUK_EXTERNAL duk_double_t duk_random(duk_hthread *thr) {
+ return (duk_double_t) DUK_UTIL_GET_RANDOM_DOUBLE(thr);
+}
+/*
* API calls related to general value stack manipulation: resizing the value
* stack, pushing and popping values, type checking and reading values,
* coercing values, etc.
@@ -17247,7 +17669,7 @@ DUK_LOCAL duk_int_t duk__api_coerce_d2i(duk_hthread *thr, duk_idx_t idx, duk_int
if (require) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "number", DUK_STR_NOT_NUMBER);
- /* not reachable */
+ DUK_WO_NORETURN(return 0;);
}
return def_value;
@@ -17298,7 +17720,7 @@ DUK_LOCAL duk_uint_t duk__api_coerce_d2ui(duk_hthread *thr, duk_idx_t idx, duk_u
if (require) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "number", DUK_STR_NOT_NUMBER);
- /* not reachable */
+ DUK_WO_NORETURN(return 0;);
}
return def_value;
@@ -17373,7 +17795,7 @@ DUK_EXTERNAL duk_idx_t duk_require_normalize_index(duk_hthread *thr, duk_idx_t i
return (duk_idx_t) uidx;
}
DUK_ERROR_RANGE_INDEX(thr, idx);
- return 0; /* unreachable */
+ DUK_WO_NORETURN(return 0;);
}
DUK_INTERNAL duk_tval *duk_get_tval(duk_hthread *thr, duk_idx_t idx) {
@@ -17449,7 +17871,7 @@ DUK_INTERNAL duk_tval *duk_require_tval(duk_hthread *thr, duk_idx_t idx) {
return thr->valstack_bottom + uidx;
}
DUK_ERROR_RANGE_INDEX(thr, idx);
- return NULL;
+ DUK_WO_NORETURN(return NULL;);
}
/* Non-critical. */
@@ -17467,7 +17889,7 @@ DUK_EXTERNAL void duk_require_valid_index(duk_hthread *thr, duk_idx_t idx) {
if (DUK_UNLIKELY(duk_normalize_index(thr, idx) < 0)) {
DUK_ERROR_RANGE_INDEX(thr, idx);
- return; /* unreachable */
+ DUK_WO_NORETURN(return;);
}
}
@@ -17492,6 +17914,7 @@ DUK_INTERNAL duk_idx_t duk_get_top_require_min(duk_hthread *thr, duk_idx_t min_t
ret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);
if (DUK_UNLIKELY(ret < min_top)) {
DUK_ERROR_TYPE_INVALID_ARGS(thr);
+ DUK_WO_NORETURN(return 0;);
}
return ret;
}
@@ -17536,7 +17959,7 @@ DUK_EXTERNAL void duk_set_top(duk_hthread *thr, duk_idx_t idx) {
#else
if (DUK_UNLIKELY(uidx > vs_limit)) {
DUK_ERROR_RANGE_INDEX(thr, idx);
- return; /* unreachable */
+ DUK_WO_NORETURN(return;);
}
#endif
DUK_ASSERT(uidx <= vs_limit);
@@ -17719,7 +18142,7 @@ DUK_EXTERNAL duk_idx_t duk_require_top_index(duk_hthread *thr) {
ret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom) - 1;
if (DUK_UNLIKELY(ret < 0)) {
DUK_ERROR_RANGE_INDEX(thr, -1);
- return 0; /* unreachable */
+ DUK_WO_NORETURN(return 0;);
}
return ret;
}
@@ -17920,6 +18343,7 @@ DUK_LOCAL DUK_COLD DUK_NOINLINE duk_bool_t duk__valstack_grow(duk_hthread *thr,
*/
if (throw_on_error) {
DUK_ERROR_RANGE(thr, DUK_STR_VALSTACK_LIMIT);
+ DUK_WO_NORETURN(return 0;);
}
return 0;
}
@@ -17927,6 +18351,7 @@ DUK_LOCAL DUK_COLD DUK_NOINLINE duk_bool_t duk__valstack_grow(duk_hthread *thr,
if (duk__resize_valstack(thr, new_size) == 0) {
if (throw_on_error) {
DUK_ERROR_ALLOC_FAILED(thr);
+ DUK_WO_NORETURN(return 0;);
}
return 0;
}
@@ -18187,7 +18612,7 @@ DUK_EXTERNAL void duk_dup_top(duk_hthread *thr) {
if (DUK_UNLIKELY(thr->valstack_top - thr->valstack_bottom <= 0)) {
DUK_ERROR_RANGE_INDEX(thr, -1);
- return; /* unreachable */
+ DUK_WO_NORETURN(return;);
}
tv_from = thr->valstack_top - 1;
tv_to = thr->valstack_top++;
@@ -18249,18 +18674,12 @@ DUK_EXTERNAL void duk_insert(duk_hthread *thr, duk_idx_t to_idx) {
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. */
-
- if (nbytes > 0) {
- DUK_TVAL_SET_TVAL(&tv_tmp, q);
- DUK_ASSERT(nbytes > 0);
- DUK_MEMMOVE((void *) (p + 1), (const void *) p, (size_t) nbytes);
- DUK_TVAL_SET_TVAL(p, &tv_tmp);
- } else {
- /* nop: insert top to top */
- DUK_ASSERT(nbytes == 0);
- DUK_ASSERT(p == q);
- }
+ /* No net refcount changes. No need to special case nbytes == 0
+ * (p == q).
+ */
+ DUK_TVAL_SET_TVAL(&tv_tmp, q);
+ duk_memmove((void *) (p + 1), (const void *) p, (size_t) nbytes);
+ DUK_TVAL_SET_TVAL(p, &tv_tmp);
}
DUK_INTERNAL void duk_insert_undefined(duk_hthread *thr, duk_idx_t idx) {
@@ -18352,7 +18771,7 @@ DUK_EXTERNAL void duk_remove(duk_hthread *thr, duk_idx_t idx) {
#endif
nbytes = (duk_size_t) (((duk_uint8_t *) q) - ((duk_uint8_t *) p)); /* Note: 'q' is top-1 */
- DUK_MEMMOVE((void *) p, (const void *) (p + 1), (size_t) nbytes); /* zero size not an issue: pointers are valid */
+ duk_memmove((void *) p, (const void *) (p + 1), (size_t) nbytes);
DUK_TVAL_SET_UNDEFINED(q);
thr->valstack_top--;
@@ -18405,7 +18824,7 @@ DUK_INTERNAL void duk_remove_n(duk_hthread *thr, duk_idx_t idx, duk_idx_t count)
DUK_TVAL_DECREF_NORZ(thr, tv);
}
- DUK_MEMMOVE((void *) tv_dst, (const void *) tv_src, bytes);
+ duk_memmove((void *) tv_dst, (const void *) tv_src, bytes);
tv_newtop = thr->valstack_top - count;
for (tv = tv_newtop; tv < thr->valstack_top; tv++) {
@@ -18444,14 +18863,14 @@ DUK_EXTERNAL void duk_xcopymove_raw(duk_hthread *to_thr, duk_hthread *from_thr,
if (DUK_UNLIKELY(to_thr == from_thr)) {
DUK_ERROR_TYPE(to_thr, DUK_STR_INVALID_CONTEXT);
- return;
+ DUK_WO_NORETURN(return;);
}
if (DUK_UNLIKELY((duk_uidx_t) count > (duk_uidx_t) DUK_USE_VALSTACK_LIMIT)) {
/* Maximum value check ensures 'nbytes' won't wrap below.
* Also handles negative count.
*/
DUK_ERROR_RANGE_INVALID_COUNT(to_thr);
- return;
+ DUK_WO_NORETURN(return;);
}
DUK_ASSERT(count >= 0);
@@ -18462,17 +18881,19 @@ DUK_EXTERNAL void duk_xcopymove_raw(duk_hthread *to_thr, duk_hthread *from_thr,
DUK_ASSERT(to_thr->valstack_top <= to_thr->valstack_end);
if (DUK_UNLIKELY((duk_size_t) ((duk_uint8_t *) to_thr->valstack_end - (duk_uint8_t *) to_thr->valstack_top) < nbytes)) {
DUK_ERROR_RANGE_PUSH_BEYOND(to_thr);
+ DUK_WO_NORETURN(return;);
}
src = (void *) ((duk_uint8_t *) from_thr->valstack_top - nbytes);
if (DUK_UNLIKELY(src < (void *) from_thr->valstack_bottom)) {
DUK_ERROR_RANGE_INVALID_COUNT(to_thr);
+ DUK_WO_NORETURN(return;);
}
- /* copy values (no overlap even if to_thr == from_thr; that's not
- * allowed now anyway)
+ /* Copy values (no overlap even if to_thr == from_thr; that's not
+ * allowed now anyway).
*/
DUK_ASSERT(nbytes > 0);
- DUK_MEMCPY((void *) to_thr->valstack_top, (const void *) src, (size_t) nbytes);
+ duk_memcpy((void *) to_thr->valstack_top, (const void *) src, (size_t) nbytes);
p = to_thr->valstack_top;
to_thr->valstack_top = (duk_tval *) (void *) (((duk_uint8_t *) p) + nbytes);
@@ -18521,7 +18942,7 @@ DUK_INTERNAL duk_tval *duk_reserve_gap(duk_hthread *thr, duk_idx_t idx_base, duk
tv_dst = (duk_tval *) (void *) ((duk_uint8_t *) tv_src + gap_bytes);
copy_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) tv_src);
thr->valstack_top = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_top + gap_bytes);
- DUK_MEMMOVE((void *) tv_dst, (const void *) tv_src, copy_bytes);
+ duk_memmove((void *) tv_dst, (const void *) tv_src, copy_bytes);
/* Values in the gap are left as garbage: caller must fill them in
* and INCREF them before any side effects.
@@ -18542,6 +18963,7 @@ DUK_EXTERNAL void duk_require_undefined(duk_hthread *thr, duk_idx_t idx) {
DUK_ASSERT(tv != NULL);
if (DUK_UNLIKELY(!DUK_TVAL_IS_UNDEFINED(tv))) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "undefined", DUK_STR_NOT_UNDEFINED);
+ DUK_WO_NORETURN(return;);
}
}
@@ -18554,6 +18976,7 @@ DUK_EXTERNAL void duk_require_null(duk_hthread *thr, duk_idx_t idx) {
DUK_ASSERT(tv != NULL);
if (DUK_UNLIKELY(!DUK_TVAL_IS_NULL(tv))) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "null", DUK_STR_NOT_NULL);
+ DUK_WO_NORETURN(return;);
}
}
@@ -18602,6 +19025,7 @@ DUK_EXTERNAL duk_bool_t duk_require_boolean(duk_hthread *thr, duk_idx_t idx) {
return ret;
} else {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "boolean", DUK_STR_NOT_BOOLEAN);
+ DUK_WO_NORETURN(return 0;);
}
}
@@ -18663,6 +19087,7 @@ DUK_EXTERNAL duk_double_t duk_require_number(duk_hthread *thr, duk_idx_t idx) {
DUK_ASSERT(tv != NULL);
if (DUK_UNLIKELY(!DUK_TVAL_IS_NUMBER(tv))) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "number", DUK_STR_NOT_NUMBER);
+ DUK_WO_NORETURN(return 0.0;);
}
ret.d = DUK_TVAL_GET_NUMBER(tv);
@@ -18894,6 +19319,7 @@ DUK_EXTERNAL void duk_require_object(duk_hthread *thr, duk_idx_t idx) {
DUK_ASSERT(tv != NULL);
if (DUK_UNLIKELY(!DUK_TVAL_IS_OBJECT(tv))) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "object", DUK_STR_NOT_OBJECT);
+ DUK_WO_NORETURN(return;);
}
}
@@ -18945,6 +19371,7 @@ DUK_EXTERNAL void *duk_require_pointer(duk_hthread *thr, duk_idx_t idx) {
DUK_ASSERT(tv != NULL);
if (DUK_UNLIKELY(!DUK_TVAL_IS_POINTER(tv))) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "pointer", DUK_STR_NOT_POINTER);
+ DUK_WO_NORETURN(return NULL;);
}
p = DUK_TVAL_GET_POINTER(tv); /* may be NULL */
return p;
@@ -18992,6 +19419,7 @@ DUK_LOCAL void *duk__get_buffer_helper(duk_hthread *thr, duk_idx_t idx, duk_size
} else {
if (throw_flag) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "buffer", DUK_STR_NOT_BUFFER);
+ DUK_WO_NORETURN(return NULL;);
}
len = def_size;
ret = def_ptr;
@@ -19095,6 +19523,7 @@ DUK_INTERNAL void *duk_get_buffer_data_raw(duk_hthread *thr, duk_idx_t idx, duk_
if (throw_flag) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "buffer", DUK_STR_NOT_BUFFER);
+ DUK_WO_NORETURN(return NULL;);
}
return def_ptr;
}
@@ -19174,6 +19603,7 @@ DUK_INTERNAL duk_hstring *duk_require_hstring(duk_hthread *thr, duk_idx_t idx) {
h = (duk_hstring *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_STRING);
if (DUK_UNLIKELY(h == NULL)) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "string", DUK_STR_NOT_STRING);
+ DUK_WO_NORETURN(return NULL;);
}
return h;
}
@@ -19186,6 +19616,7 @@ DUK_INTERNAL duk_hstring *duk_require_hstring_notsymbol(duk_hthread *thr, duk_id
h = (duk_hstring *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_STRING);
if (DUK_UNLIKELY(h == NULL || DUK_HSTRING_HAS_SYMBOL(h))) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "string", DUK_STR_NOT_STRING);
+ DUK_WO_NORETURN(return NULL;);
}
return h;
}
@@ -19203,6 +19634,7 @@ DUK_INTERNAL duk_hobject *duk_require_hobject(duk_hthread *thr, duk_idx_t idx) {
h = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);
if (DUK_UNLIKELY(h == NULL)) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "object", DUK_STR_NOT_OBJECT);
+ DUK_WO_NORETURN(return NULL;);
}
return h;
}
@@ -19220,6 +19652,7 @@ DUK_INTERNAL duk_hbuffer *duk_require_hbuffer(duk_hthread *thr, duk_idx_t idx) {
h = (duk_hbuffer *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_BUFFER);
if (DUK_UNLIKELY(h == NULL)) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "buffer", DUK_STR_NOT_BUFFER);
+ DUK_WO_NORETURN(return NULL;);
}
return h;
}
@@ -19244,6 +19677,7 @@ DUK_INTERNAL duk_hthread *duk_require_hthread(duk_hthread *thr, duk_idx_t idx) {
h = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);
if (DUK_UNLIKELY(!(h != NULL && DUK_HOBJECT_IS_THREAD(h)))) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "thread", DUK_STR_NOT_THREAD);
+ DUK_WO_NORETURN(return NULL;);
}
return (duk_hthread *) h;
}
@@ -19268,6 +19702,7 @@ DUK_INTERNAL duk_hcompfunc *duk_require_hcompfunc(duk_hthread *thr, duk_idx_t id
h = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);
if (DUK_UNLIKELY(!(h != NULL && DUK_HOBJECT_IS_COMPFUNC(h)))) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "compiledfunction", DUK_STR_NOT_COMPFUNC);
+ DUK_WO_NORETURN(return NULL;);
}
return (duk_hcompfunc *) h;
}
@@ -19292,6 +19727,7 @@ DUK_INTERNAL duk_hnatfunc *duk_require_hnatfunc(duk_hthread *thr, duk_idx_t idx)
h = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);
if (DUK_UNLIKELY(!(h != NULL && DUK_HOBJECT_IS_NATFUNC(h)))) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "nativefunction", DUK_STR_NOT_NATFUNC);
+ DUK_WO_NORETURN(return NULL;);
}
return (duk_hnatfunc *) h;
}
@@ -19350,6 +19786,7 @@ DUK_EXTERNAL duk_c_function duk_require_c_function(duk_hthread *thr, duk_idx_t i
ret = duk_get_c_function(thr, idx);
if (DUK_UNLIKELY(!ret)) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "nativefunction", DUK_STR_NOT_NATFUNC);
+ DUK_WO_NORETURN(return ret;);
}
return ret;
}
@@ -19358,6 +19795,7 @@ DUK_EXTERNAL void duk_require_function(duk_hthread *thr, duk_idx_t idx) {
DUK_ASSERT_API_ENTRY(thr);
if (DUK_UNLIKELY(!duk_is_function(thr, idx))) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "function", DUK_STR_NOT_FUNCTION);
+ DUK_WO_NORETURN(return;);
}
}
@@ -19369,6 +19807,7 @@ DUK_INTERNAL void duk_require_constructable(duk_hthread *thr, duk_idx_t idx) {
h = duk_require_hobject_accept_mask(thr, idx, DUK_TYPE_MASK_LIGHTFUNC);
if (DUK_UNLIKELY(h != NULL && !DUK_HOBJECT_HAS_CONSTRUCTABLE(h))) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "constructable", DUK_STR_NOT_CONSTRUCTABLE);
+ DUK_WO_NORETURN(return;);
}
/* Lightfuncs (h == NULL) are constructable. */
}
@@ -19456,6 +19895,7 @@ DUK_EXTERNAL void *duk_require_heapptr(duk_hthread *thr, duk_idx_t idx) {
DUK_ASSERT(tv != NULL);
if (DUK_UNLIKELY(!DUK_TVAL_IS_HEAP_ALLOCATED(tv))) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "heapobject", DUK_STR_UNEXPECTED_TYPE);
+ DUK_WO_NORETURN(return NULL;);
}
ret = (void *) DUK_TVAL_GET_HEAPHDR(tv);
@@ -19489,6 +19929,7 @@ DUK_LOCAL duk_hobject *duk__get_hobject_promote_mask_raw(duk_hthread *thr, duk_i
if (type_mask & DUK_TYPE_MASK_THROW) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "object", DUK_STR_NOT_OBJECT);
+ DUK_WO_NORETURN(return NULL;);
}
return NULL;
}
@@ -19549,6 +19990,7 @@ DUK_INTERNAL duk_hobject *duk_require_hobject_with_class(duk_hthread *thr, duk_i
DUK_UNREF(h_class);
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, (const char *) DUK_HSTRING_GET_DATA(h_class), DUK_STR_UNEXPECTED_TYPE);
+ DUK_WO_NORETURN(return NULL;);
}
return h;
}
@@ -19741,49 +20183,43 @@ DUK_EXTERNAL void duk_to_null(duk_hthread *thr, duk_idx_t idx) {
}
/* E5 Section 9.1 */
-DUK_EXTERNAL void duk_to_primitive(duk_hthread *thr, duk_idx_t idx, duk_int_t hint) {
- /* inline initializer for coercers[] is not allowed by old compilers like BCC */
+DUK_LOCAL const char * const duk__toprim_hint_strings[3] = {
+ "default", "string", "number"
+};
+DUK_LOCAL void duk__to_primitive_helper(duk_hthread *thr, duk_idx_t idx, duk_int_t hint, duk_bool_t check_symbol) {
+ /* Inline initializer for coercers[] is not allowed by old compilers like BCC. */
duk_small_uint_t coercers[2];
- duk_small_uint_t class_number;
DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(hint == DUK_HINT_NONE || hint == DUK_HINT_NUMBER || hint == DUK_HINT_STRING);
idx = duk_require_normalize_index(thr, idx);
+ /* If already primitive, return as is. */
if (!duk_check_type_mask(thr, idx, DUK_TYPE_MASK_OBJECT |
DUK_TYPE_MASK_LIGHTFUNC |
DUK_TYPE_MASK_BUFFER)) {
- /* Any other values stay as is. */
DUK_ASSERT(!duk_is_buffer(thr, idx)); /* duk_to_string() relies on this behavior */
return;
}
- class_number = duk_get_class_number(thr, 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.
+ /* @@toPrimitive lookup. Also do for plain buffers and lightfuncs
+ * which mimic objects.
*/
-
- 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(thr, idx);
- h_str = duk_hobject_get_internal_value_string(thr->heap, h_obj);
- if (h_str) {
- duk_push_hstring(thr, h_str);
- duk_replace(thr, idx);
- return;
+ if (check_symbol && duk_get_method_stridx(thr, idx, DUK_STRIDX_WELLKNOWN_SYMBOL_TO_PRIMITIVE)) {
+ DUK_ASSERT(hint >= 0 && (duk_size_t) hint < sizeof(duk__toprim_hint_strings) / sizeof(const char *));
+ duk_dup(thr, idx);
+ duk_push_string(thr, duk__toprim_hint_strings[hint]);
+ duk_call_method(thr, 1); /* [ ... method value hint ] -> [ ... res] */
+ if (duk_check_type_mask(thr, -1, DUK_TYPE_MASK_OBJECT |
+ DUK_TYPE_MASK_LIGHTFUNC |
+ DUK_TYPE_MASK_BUFFER)) {
+ goto fail;
}
+ duk_replace(thr, idx);
+ return;
}
-
/* Objects are coerced based on E5 specification.
* Lightfuncs are coerced because they behave like
* objects even if they're internally a primitive
@@ -19791,17 +20227,29 @@ DUK_EXTERNAL void duk_to_primitive(duk_hthread *thr, duk_idx_t idx, duk_int_t hi
* like ArrayBuffer objects since Duktape 2.x.
*/
- coercers[0] = DUK_STRIDX_VALUE_OF;
- coercers[1] = DUK_STRIDX_TO_STRING;
-
+ /* Hint magic for Date is unnecessary in ES2015 because of
+ * Date.prototype[@@toPrimitive]. However, it is needed if
+ * symbol support is not enabled.
+ */
+#if defined(DUK_USE_SYMBOL_BUILTIN)
+ if (hint == DUK_HINT_NONE) {
+ hint = DUK_HINT_NUMBER;
+ }
+#else /* DUK_USE_SYMBOL_BUILTIN */
if (hint == DUK_HINT_NONE) {
+ duk_small_uint_t class_number;
+
+ class_number = duk_get_class_number(thr, idx);
if (class_number == DUK_HOBJECT_CLASS_DATE) {
hint = DUK_HINT_STRING;
} else {
hint = DUK_HINT_NUMBER;
}
}
+#endif /* DUK_USE_SYMBOL_BUILTIN */
+ coercers[0] = DUK_STRIDX_VALUE_OF;
+ coercers[1] = DUK_STRIDX_TO_STRING;
if (hint == DUK_HINT_STRING) {
coercers[0] = DUK_STRIDX_TO_STRING;
coercers[1] = DUK_STRIDX_VALUE_OF;
@@ -19817,9 +20265,21 @@ DUK_EXTERNAL void duk_to_primitive(duk_hthread *thr, duk_idx_t idx, duk_int_t hi
return;
}
+ fail:
DUK_ERROR_TYPE(thr, DUK_STR_TOPRIMITIVE_FAILED);
+ DUK_WO_NORETURN(return;);
}
+DUK_EXTERNAL void duk_to_primitive(duk_hthread *thr, duk_idx_t idx, duk_int_t hint) {
+ duk__to_primitive_helper(thr, idx, hint, 1 /*check_symbol*/);
+}
+
+#if defined(DUK_USE_SYMBOL_BUILTIN)
+DUK_INTERNAL void duk_to_primitive_ordinary(duk_hthread *thr, duk_idx_t idx, duk_int_t hint) {
+ duk__to_primitive_helper(thr, idx, hint, 0 /*check_symbol*/);
+}
+#endif
+
/* E5 Section 9.2 */
DUK_EXTERNAL duk_bool_t duk_to_boolean(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
@@ -19840,6 +20300,22 @@ DUK_EXTERNAL duk_bool_t duk_to_boolean(duk_hthread *thr, duk_idx_t idx) {
return val;
}
+DUK_INTERNAL duk_bool_t duk_to_boolean_top_pop(duk_hthread *thr) {
+ duk_tval *tv;
+ duk_bool_t val;
+
+ DUK_ASSERT_API_ENTRY(thr);
+
+ tv = duk_require_tval(thr, -1);
+ DUK_ASSERT(tv != NULL);
+
+ val = duk_js_toboolean(tv);
+ DUK_ASSERT(val == 0 || val == 1);
+
+ duk_pop_unsafe(thr);
+ return val;
+}
+
DUK_EXTERNAL duk_double_t duk_to_number(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
duk_double_t d;
@@ -20119,68 +20595,67 @@ DUK_INTERNAL duk_hstring *duk_safe_to_hstring(duk_hthread *thr, duk_idx_t idx) {
#endif
/* Push Object.prototype.toString() output for 'tv'. */
-DUK_INTERNAL void duk_push_class_string_tval(duk_hthread *thr, duk_tval *tv) {
- duk_small_uint_t stridx;
- duk_hstring *h_strclass;
+#if 0 /* See XXX note why this variant doesn't work. */
+DUK_INTERNAL void duk_push_class_string_tval(duk_hthread *thr, duk_tval *tv, duk_bool_t avoid_side_effects) {
+ duk_uint_t stridx_bidx = 0; /* (prototype_bidx << 16) + default_tag_stridx */
DUK_ASSERT_API_ENTRY(thr);
+ /* Conceptually for any non-undefined/null value we should do a
+ * ToObject() coercion and look up @@toStringTag (from the object
+ * prototype) to see if a custom tag should be used. Avoid the
+ * actual conversion by doing a prototype lookup without the object
+ * coercion. However, see problem below.
+ */
+
+ duk_push_literal(thr, "[object "); /* -> [ ... "[object" ] */
+
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;
+ stridx_bidx = DUK_STRIDX_UC_UNDEFINED;
+ goto use_stridx;
}
case DUK_TAG_NULL: {
- stridx = DUK_STRIDX_UC_NULL;
- break;
+ stridx_bidx = DUK_STRIDX_UC_NULL;
+ goto use_stridx;
}
case DUK_TAG_BOOLEAN: {
- stridx = DUK_STRIDX_UC_BOOLEAN;
- break;
+ stridx_bidx = (DUK_BIDX_BOOLEAN_PROTOTYPE << 16) + DUK_STRIDX_UC_BOOLEAN;
+ goto use_proto_bidx;
}
case DUK_TAG_POINTER: {
- stridx = DUK_STRIDX_UC_POINTER;
- break;
+ stridx_bidx = (DUK_BIDX_POINTER_PROTOTYPE << 16) + DUK_STRIDX_UC_POINTER;
+ goto use_proto_bidx;
}
case DUK_TAG_LIGHTFUNC: {
- stridx = DUK_STRIDX_UC_FUNCTION;
- break;
+ stridx_bidx = (DUK_BIDX_FUNCTION_PROTOTYPE << 16) + DUK_STRIDX_UC_FUNCTION;
+ goto use_proto_bidx;
}
case DUK_TAG_STRING: {
duk_hstring *h;
h = DUK_TVAL_GET_STRING(tv);
DUK_ASSERT(h != NULL);
if (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {
- stridx = DUK_STRIDX_UC_SYMBOL;
+ /* Even without DUK_USE_SYMBOL_BUILTIN the Symbol
+ * prototype exists so we can lookup @@toStringTag
+ * and provide [object Symbol] for symbol values
+ * created from C code.
+ */
+ stridx_bidx = (DUK_BIDX_SYMBOL_PROTOTYPE << 16) + DUK_STRIDX_UC_SYMBOL;
} else {
- stridx = DUK_STRIDX_UC_STRING;
+ stridx_bidx = (DUK_BIDX_STRING_PROTOTYPE << 16) + DUK_STRIDX_UC_STRING;
}
- break;
+ goto use_proto_bidx;
}
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;
+ duk_push_tval(thr, tv);
+ stridx_bidx = 0xffffffffUL; /* Marker value. */
+ goto use_pushed_object;
}
case DUK_TAG_BUFFER: {
- stridx = DUK_STRIDX_UINT8_ARRAY;
- break;
+ stridx_bidx = (DUK_BIDX_UINT8ARRAY_PROTOTYPE << 16) + DUK_STRIDX_UINT8_ARRAY;
+ goto use_proto_bidx;
}
#if defined(DUK_USE_FASTINT)
case DUK_TAG_FASTINT:
@@ -20188,14 +20663,142 @@ DUK_INTERNAL void duk_push_class_string_tval(duk_hthread *thr, duk_tval *tv) {
#endif
default: {
DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv)); /* number (maybe fastint) */
- stridx = DUK_STRIDX_UC_NUMBER;
- break;
+ stridx_bidx = (DUK_BIDX_NUMBER_PROTOTYPE << 16) + DUK_STRIDX_UC_NUMBER;
+ goto use_proto_bidx;
+ }
+ }
+ DUK_ASSERT(0); /* Never here. */
+
+ use_proto_bidx:
+ DUK_ASSERT_BIDX_VALID((stridx_bidx >> 16) & 0xffffUL);
+ duk_push_hobject(thr, thr->builtins[(stridx_bidx >> 16) & 0xffffUL]);
+ /* Fall through. */
+
+ use_pushed_object:
+ /* [ ... "[object" obj ] */
+
+#if defined(DUK_USE_SYMBOL_BUILTIN)
+ /* XXX: better handling with avoid_side_effects == 1; lookup tval
+ * without Proxy or getter side effects, and use it in sanitized
+ * form if it's a string.
+ */
+ if (!avoid_side_effects) {
+ /* XXX: The problem with using the prototype object as the
+ * lookup base is that if @@toStringTag is a getter, its
+ * 'this' binding must be the ToObject() coerced input value,
+ * not the prototype object of the type.
+ */
+ (void) duk_get_prop_stridx(thr, -1, DUK_STRIDX_WELLKNOWN_SYMBOL_TO_STRING_TAG);
+ if (duk_is_string_notsymbol(thr, -1)) {
+ duk_remove_m2(thr);
+ goto finish;
+ }
+ duk_pop_unsafe(thr);
}
+#endif
+
+ if (stridx_bidx == 0xffffffffUL) {
+ duk_hobject *h_obj;
+ duk_small_uint_t classnum;
+
+ h_obj = duk_known_hobject(thr, -1);
+ DUK_ASSERT(h_obj != NULL);
+ classnum = DUK_HOBJECT_GET_CLASS_NUMBER(h_obj);
+ stridx_bidx = DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(classnum);
+ } else {
+ /* stridx_bidx already has the desired fallback stridx. */
+ ;
}
- h_strclass = DUK_HTHREAD_GET_STRING(thr, stridx);
- DUK_ASSERT(h_strclass != NULL);
+ duk_pop_unsafe(thr);
+ /* Fall through. */
+
+ use_stridx:
+ /* [ ... "[object" ] */
+ duk_push_hstring_stridx(thr, stridx_bidx & 0xffffUL);
- duk_push_sprintf(thr, "[object %s]", (const char *) DUK_HSTRING_GET_DATA(h_strclass));
+ finish:
+ /* [ ... "[object" tag ] */
+ duk_push_literal(thr, "]");
+ duk_concat(thr, 3); /* [ ... "[object" tag "]" ] -> [ ... res ] */
+}
+#endif /* 0 */
+
+DUK_INTERNAL void duk_push_class_string_tval(duk_hthread *thr, duk_tval *tv, duk_bool_t avoid_side_effects) {
+ duk_hobject *h_obj;
+ duk_small_uint_t classnum;
+ duk_small_uint_t stridx;
+ duk_tval tv_tmp;
+
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ASSERT(tv != NULL);
+
+ /* Stabilize 'tv', duk_push_literal() may trigger side effects. */
+ DUK_TVAL_SET_TVAL(&tv_tmp, tv);
+ tv = &tv_tmp;
+
+ /* Conceptually for any non-undefined/null value we should do a
+ * ToObject() coercion and look up @@toStringTag (from the object
+ * prototype) to see if a custom result should be used. We'd like to
+ * avoid the actual conversion, but even for primitive types the
+ * prototype may have @@toStringTag. What's worse, the @@toStringTag
+ * property may be a getter that must get the object coerced value
+ * (not the prototype) as its 'this' binding.
+ *
+ * For now, do an actual object coercion. This could be avoided by
+ * doing a side effect free lookup to see if a getter would be invoked.
+ * If not, the value can be read directly and the object coercion could
+ * be avoided. This may not be worth it in practice, because
+ * Object.prototype.toString() is usually not performance critical.
+ */
+
+ duk_push_literal(thr, "[object "); /* -> [ ... "[object" ] */
+
+ switch (DUK_TVAL_GET_TAG(tv)) {
+ case DUK_TAG_UNUSED: /* Treat like 'undefined', shouldn't happen. */
+ case DUK_TAG_UNDEFINED: {
+ duk_push_hstring_stridx(thr, DUK_STRIDX_UC_UNDEFINED);
+ goto finish;
+ }
+ case DUK_TAG_NULL: {
+ duk_push_hstring_stridx(thr, DUK_STRIDX_UC_NULL);
+ goto finish;
+ }
+ }
+
+ duk_push_tval(thr, tv);
+ tv = NULL; /* Invalidated by ToObject(). */
+ duk_to_object(thr, -1);
+
+ /* [ ... "[object" obj ] */
+
+#if defined(DUK_USE_SYMBOL_BUILTIN)
+ /* XXX: better handling with avoid_side_effects == 1; lookup tval
+ * without Proxy or getter side effects, and use it in sanitized
+ * form if it's a string.
+ */
+ if (!avoid_side_effects) {
+ (void) duk_get_prop_stridx(thr, -1, DUK_STRIDX_WELLKNOWN_SYMBOL_TO_STRING_TAG);
+ if (duk_is_string_notsymbol(thr, -1)) {
+ duk_remove_m2(thr);
+ goto finish;
+ }
+ duk_pop_unsafe(thr);
+ }
+#else
+ DUK_UNREF(avoid_side_effects);
+#endif
+
+ h_obj = duk_known_hobject(thr, -1);
+ DUK_ASSERT(h_obj != NULL);
+ classnum = DUK_HOBJECT_GET_CLASS_NUMBER(h_obj);
+ stridx = DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(classnum);
+ duk_pop_unsafe(thr);
+ duk_push_hstring_stridx(thr, stridx);
+
+ finish:
+ /* [ ... "[object" tag ] */
+ duk_push_literal(thr, "]");
+ duk_concat(thr, 3); /* [ ... "[object" tag "]" ] -> [ ... res ] */
}
/* XXX: other variants like uint, u32 etc */
@@ -20255,6 +20858,7 @@ DUK_INTERNAL duk_int_t duk_to_int_clamped_raw(duk_hthread *thr, duk_idx_t idx, d
/* coerced value is updated to value stack even when RangeError thrown */
if (clamped) {
DUK_ERROR_RANGE(thr, DUK_STR_NUMBER_OUTSIDE_RANGE);
+ DUK_WO_NORETURN(return 0;);
}
}
@@ -20312,12 +20916,14 @@ DUK_EXTERNAL const char *duk_to_string(duk_hthread *thr, duk_idx_t idx) {
DUK_ASSERT(h != NULL);
if (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {
DUK_ERROR_TYPE(thr, DUK_STR_CANNOT_STRING_COERCE_SYMBOL);
+ DUK_WO_NORETURN(goto skip_replace;);
} else {
goto skip_replace;
}
#else
goto skip_replace;
#endif
+ break;
}
case DUK_TAG_BUFFER: /* Go through Uint8Array.prototype.toString() for coercion. */
case DUK_TAG_OBJECT: {
@@ -20468,14 +21074,9 @@ DUK_EXTERNAL void *duk_to_buffer_raw(duk_hthread *thr, duk_idx_t idx, duk_size_t
}
dst_data = (duk_uint8_t *) duk_push_buffer(thr, src_size, (mode == DUK_BUF_MODE_DYNAMIC) /*dynamic*/);
- if (DUK_LIKELY(src_size > 0)) {
- /* When src_size == 0, src_data may be NULL (if source
- * buffer is dynamic), and dst_data may be NULL (if
- * target buffer is dynamic). Avoid zero-size memcpy()
- * with an invalid pointer.
- */
- DUK_MEMCPY((void *) dst_data, (const void *) src_data, (size_t) src_size);
- }
+ /* dst_data may be NULL if size is zero. */
+ duk_memcpy_unsafe((void *) dst_data, (const void *) src_data, (size_t) src_size);
+
duk_replace(thr, idx);
skip_copy:
@@ -20591,6 +21192,7 @@ DUK_EXTERNAL void duk_to_object(duk_hthread *thr, duk_idx_t idx) {
case DUK_TAG_UNDEFINED:
case DUK_TAG_NULL: {
DUK_ERROR_TYPE(thr, DUK_STR_NOT_OBJECT_COERCIBLE);
+ DUK_WO_NORETURN(return;);
break;
}
case DUK_TAG_BOOLEAN: {
@@ -20898,7 +21500,7 @@ DUK_EXTERNAL duk_bool_t duk_check_type_mask(duk_hthread *thr, duk_idx_t idx, duk
}
if (mask & DUK_TYPE_MASK_THROW) {
DUK_ERROR_TYPE(thr, DUK_STR_UNEXPECTED_TYPE);
- DUK_UNREACHABLE();
+ DUK_WO_NORETURN(return 0;);
}
return 0;
}
@@ -21371,21 +21973,22 @@ DUK_EXTERNAL const char *duk_push_lstring(duk_hthread *thr, const char *str, duk
DUK_ASSERT_API_ENTRY(thr);
- /* check stack before interning (avoid hanging temp) */
+ /* Check stack before interning (avoid hanging temp). */
DUK__CHECK_SPACE();
/* NULL with zero length represents an empty string; NULL with higher
- * length is also now trated like an empty string although it is
+ * length is also now treated like an empty string although it is
* a bit dubious. This is unlike duk_push_string() which pushes a
* 'null' if the input string is a NULL.
*/
- if (!str) {
- len = 0;
+ if (DUK_UNLIKELY(str == NULL)) {
+ len = 0U;
}
- /* Check for maximum string length */
+ /* Check for maximum string length. */
if (DUK_UNLIKELY(len > DUK_HSTRING_MAX_BYTELEN)) {
DUK_ERROR_RANGE(thr, DUK_STR_STRING_TOO_LONG);
+ DUK_WO_NORETURN(return NULL;);
}
h = duk_heap_strtable_intern_checked(thr, (const duk_uint8_t *) str, (duk_uint32_t) len);
@@ -21409,6 +22012,42 @@ DUK_EXTERNAL const char *duk_push_string(duk_hthread *thr, const char *str) {
}
}
+#if !defined(DUK_USE_PREFER_SIZE)
+#if defined(DUK_USE_LITCACHE_SIZE)
+DUK_EXTERNAL const char *duk_push_literal_raw(duk_hthread *thr, const char *str, duk_size_t len) {
+ duk_hstring *h;
+ duk_tval *tv_slot;
+
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ASSERT(str != NULL);
+ DUK_ASSERT(str[len] == (char) 0);
+
+ /* Check for maximum string length. */
+ if (DUK_UNLIKELY(len > DUK_HSTRING_MAX_BYTELEN)) {
+ DUK_ERROR_RANGE(thr, DUK_STR_STRING_TOO_LONG);
+ DUK_WO_NORETURN(return NULL;);
+ }
+
+ h = duk_heap_strtable_intern_literal_checked(thr, (const duk_uint8_t *) str, (duk_uint32_t) len);
+ DUK_ASSERT(h != NULL);
+
+ tv_slot = thr->valstack_top++;
+ DUK_TVAL_SET_STRING(tv_slot, h);
+ DUK_HSTRING_INCREF(thr, h); /* no side effects */
+
+ return (const char *) DUK_HSTRING_GET_DATA(h);
+}
+#else /* DUK_USE_LITCACHE_SIZE */
+DUK_EXTERNAL const char *duk_push_literal_raw(duk_hthread *thr, const char *str, duk_size_t len) {
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ASSERT(str != NULL);
+ DUK_ASSERT(str[len] == (char) 0);
+
+ return duk_push_lstring(thr, str, len);
+}
+#endif /* DUK_USE_LITCACHE_SIZE */
+#endif /* !DUK_USE_PREFER_SIZE */
+
DUK_EXTERNAL void duk_push_pointer(duk_hthread *thr, void *val) {
duk_tval *tv_slot;
@@ -21462,6 +22101,7 @@ DUK_LOCAL void duk__push_this_helper(duk_hthread *thr, duk_small_uint_t check_ob
type_error:
DUK_ERROR_TYPE(thr, DUK_STR_NOT_OBJECT_COERCIBLE);
+ DUK_WO_NORETURN(return;);
}
DUK_EXTERNAL void duk_push_this(duk_hthread *thr) {
@@ -21505,6 +22145,46 @@ DUK_INTERNAL duk_tval *duk_get_borrowed_this_tval(duk_hthread *thr) {
return thr->valstack_bottom - 1;
}
+DUK_EXTERNAL void duk_push_new_target(duk_hthread *thr) {
+ duk_activation *act;
+
+ DUK_ASSERT_API_ENTRY(thr);
+
+ /* https://www.ecma-international.org/ecma-262/6.0/#sec-meta-properties-runtime-semantics-evaluation
+ * https://www.ecma-international.org/ecma-262/6.0/#sec-getnewtarget
+ *
+ * No newTarget support now, so as a first approximation
+ * use the resolved (non-bound) target function.
+ *
+ * Check CONSTRUCT flag from current function, or if running
+ * direct eval, from a non-direct-eval parent (with possibly
+ * more than one nested direct eval). An alternative to this
+ * would be to store [[NewTarget]] as a hidden symbol of the
+ * lexical scope, and then just look up that variable.
+ *
+ * Calls from the application will either be for an empty
+ * call stack, or a Duktape/C function as the top activation.
+ */
+
+ act = thr->callstack_curr;
+ for (;;) {
+ if (act == NULL) {
+ break;
+ }
+
+ if (act->flags & DUK_ACT_FLAG_CONSTRUCT) {
+ duk_push_tval(thr, &act->tv_func);
+ return;
+ } else if (act->flags & DUK_ACT_FLAG_DIRECT_EVAL) {
+ act = act->parent;
+ } else {
+ break;
+ }
+ }
+
+ duk_push_undefined(thr);
+}
+
DUK_EXTERNAL void duk_push_current_function(duk_hthread *thr) {
duk_activation *act;
@@ -21565,7 +22245,7 @@ DUK_EXTERNAL void duk_push_thread_stash(duk_hthread *thr, duk_hthread *target_th
DUK_ASSERT_API_ENTRY(thr);
if (DUK_UNLIKELY(target_thr == NULL)) {
DUK_ERROR_TYPE_INVALID_ARGS(thr);
- return; /* not reached */
+ DUK_WO_NORETURN(return;);
}
duk_push_hobject(thr, (duk_hobject *) target_thr);
duk__push_stash(thr);
@@ -21641,6 +22321,7 @@ DUK_EXTERNAL const char *duk_push_vsprintf(duk_hthread *thr, const char *fmt, va
sz = sz * 2;
if (DUK_UNLIKELY(sz >= DUK_PUSH_SPRINTF_SANITY_LIMIT)) {
DUK_ERROR_RANGE(thr, DUK_STR_RESULT_TOO_LONG);
+ DUK_WO_NORETURN(return NULL;);
}
}
@@ -21829,6 +22510,7 @@ DUK_EXTERNAL duk_idx_t duk_push_thread_raw(duk_hthread *thr, duk_uint_t flags) {
/* important to do this *after* pushing, to make the thread reachable for gc */
if (DUK_UNLIKELY(!duk_hthread_init_stacks(thr->heap, obj))) {
DUK_ERROR_ALLOC_FAILED(thr);
+ DUK_WO_NORETURN(return 0;);
}
/* initialize built-ins - either by copying or creating new ones */
@@ -21870,6 +22552,7 @@ DUK_INTERNAL duk_hcompfunc *duk_push_hcompfunc(duk_hthread *thr) {
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION));
if (DUK_UNLIKELY(obj == NULL)) {
DUK_ERROR_ALLOC_FAILED(thr);
+ DUK_WO_NORETURN(return NULL;);
}
DUK_DDD(DUK_DDDPRINT("created compiled function object with flags: 0x%08lx", (unsigned long) obj->obj.hdr.h_flags));
@@ -21901,6 +22584,7 @@ DUK_INTERNAL duk_hboundfunc *duk_push_hboundfunc(duk_hthread *thr) {
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION));
if (!obj) {
DUK_ERROR_ALLOC_FAILED(thr);
+ DUK_WO_NORETURN(return NULL;);
}
tv_slot = thr->valstack_top++;
@@ -21957,7 +22641,7 @@ DUK_LOCAL duk_idx_t duk__push_c_function_raw(duk_hthread *thr, duk_c_function fu
api_error:
DUK_ERROR_TYPE_INVALID_ARGS(thr);
- return 0; /* not reached */
+ DUK_WO_NORETURN(return 0;);
}
DUK_EXTERNAL duk_idx_t duk_push_c_function(duk_hthread *thr, duk_c_function func, duk_int_t nargs) {
@@ -22049,7 +22733,7 @@ DUK_EXTERNAL duk_idx_t duk_push_c_lightfunc(duk_hthread *thr, duk_c_function fun
api_error:
DUK_ERROR_TYPE_INVALID_ARGS(thr);
- return 0; /* not reached */
+ DUK_WO_NORETURN(return 0;);
}
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
@@ -22201,11 +22885,11 @@ DUK_EXTERNAL void duk_push_buffer_object(duk_hthread *thr, duk_idx_t idx_buffer,
range_error:
DUK_ERROR_RANGE(thr, DUK_STR_INVALID_ARGS);
- return; /* not reached */
+ DUK_WO_NORETURN(return;);
arg_error:
DUK_ERROR_TYPE(thr, DUK_STR_INVALID_ARGS);
- return; /* not reached */
+ DUK_WO_NORETURN(return;);
}
#else /* DUK_USE_BUFFEROBJECT_SUPPORT */
DUK_EXTERNAL void duk_push_buffer_object(duk_hthread *thr, duk_idx_t idx_buffer, duk_size_t byte_offset, duk_size_t byte_length, duk_uint_t flags) {
@@ -22215,6 +22899,7 @@ DUK_EXTERNAL void duk_push_buffer_object(duk_hthread *thr, duk_idx_t idx_buffer,
DUK_UNREF(byte_length);
DUK_UNREF(flags);
DUK_ERROR_UNSUPPORTED(thr);
+ DUK_WO_NORETURN(return;);
}
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
@@ -22252,7 +22937,7 @@ DUK_EXTERNAL duk_idx_t duk_push_error_object_va_raw(duk_hthread *thr, duk_errcod
duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE, DUK_PROPDESC_FLAGS_WC);
} else {
/* If no explicit message given, put error code into message field
- * (as a number). This is not fully in keeping with the Ecmascript
+ * (as a number). This is not fully in keeping with the ECMAScript
* error model because messages are supposed to be strings (Error
* constructors use ToString() on their argument). However, it's
* probably more useful than having a separate 'code' property.
@@ -22314,11 +22999,13 @@ DUK_EXTERNAL void *duk_push_buffer_raw(duk_hthread *thr, duk_size_t size, duk_sm
/* Check for maximum buffer length. */
if (DUK_UNLIKELY(size > DUK_HBUFFER_MAX_BYTELEN)) {
DUK_ERROR_RANGE(thr, DUK_STR_BUFFER_TOO_LONG);
+ DUK_WO_NORETURN(return NULL;);
}
h = duk_hbuffer_alloc(thr->heap, size, flags, &buf_data);
if (DUK_UNLIKELY(h == NULL)) {
DUK_ERROR_ALLOC_FAILED(thr);
+ DUK_WO_NORETURN(return NULL;);
}
tv_slot = thr->valstack_top;
@@ -22340,11 +23027,12 @@ DUK_INTERNAL void *duk_push_fixed_buffer_zero(duk_hthread *thr, duk_size_t len)
DUK_ASSERT_API_ENTRY(thr);
ptr = duk_push_buffer_raw(thr, len, 0);
+ DUK_ASSERT(ptr != NULL);
#if !defined(DUK_USE_ZERO_BUFFER_DATA)
/* ES2015 requires zeroing even when DUK_USE_ZERO_BUFFER_DATA
* is not set.
*/
- DUK_MEMZERO((void *) ptr, (size_t) len);
+ duk_memzero((void *) ptr, (size_t) len);
#endif
return ptr;
}
@@ -22441,12 +23129,14 @@ DUK_EXTERNAL duk_idx_t duk_push_proxy(duk_hthread *thr, duk_uint_t proxy_flags)
fail_args:
DUK_ERROR_TYPE_INVALID_ARGS(thr);
+ DUK_WO_NORETURN(return 0;);
}
#else /* DUK_USE_ES6_PROXY */
DUK_EXTERNAL duk_idx_t duk_push_proxy(duk_hthread *thr, duk_uint_t proxy_flags) {
DUK_ASSERT_API_ENTRY(thr);
DUK_UNREF(proxy_flags);
DUK_ERROR_UNSUPPORTED(thr);
+ DUK_WO_NORETURN(return 0;);
}
#endif /* DUK_USE_ES6_PROXY */
@@ -22744,7 +23434,7 @@ DUK_EXTERNAL void duk_pop_n(duk_hthread *thr, duk_idx_t count) {
if (DUK_UNLIKELY((duk_uidx_t) (thr->valstack_top - thr->valstack_bottom) < (duk_uidx_t) count)) {
DUK_ERROR_RANGE_INVALID_COUNT(thr);
- return;
+ DUK_WO_NORETURN(return;);
}
DUK_ASSERT(count >= 0);
@@ -22832,6 +23522,7 @@ DUK_EXTERNAL void duk_pop(duk_hthread *thr) {
DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
if (DUK_UNLIKELY(thr->valstack_top == thr->valstack_bottom)) {
DUK_ERROR_RANGE_INVALID_COUNT(thr);
+ DUK_WO_NORETURN(return;);
}
duk__pop_unsafe_raw(thr);
@@ -22920,6 +23611,7 @@ DUK_EXTERNAL void duk_pop_2(duk_hthread *thr) {
DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
if (DUK_UNLIKELY(thr->valstack_top - 2 < thr->valstack_bottom)) {
DUK_ERROR_RANGE_INVALID_COUNT(thr);
+ DUK_WO_NORETURN(return;);
}
duk__pop_2_unsafe_raw(thr);
@@ -22977,7 +23669,7 @@ DUK_INTERNAL void duk_pack(duk_hthread *thr, duk_idx_t count) {
if (DUK_UNLIKELY((duk_uidx_t) count > (duk_uidx_t) top)) {
/* Also handles negative count. */
DUK_ERROR_RANGE_INVALID_COUNT(thr);
- return;
+ DUK_WO_NORETURN(return;);
}
DUK_ASSERT(count >= 0);
@@ -22994,9 +23686,8 @@ DUK_INTERNAL void duk_pack(duk_hthread *thr, duk_idx_t count) {
/* Copy value stack values directly to the array part without
* any refcount updates: net refcount changes are zero.
*/
-
tv_src = thr->valstack_top - count - 1;
- DUK_MEMCPY((void *) tv_dst, (const void *) tv_src, (size_t) count * sizeof(duk_tval));
+ duk_memcpy_unsafe((void *) tv_dst, (const void *) tv_src, (size_t) count * sizeof(duk_tval));
/* Overwrite result array to final value stack location and wipe
* the rest; no refcount operations needed.
@@ -23114,11 +23805,11 @@ DUK_INTERNAL duk_idx_t duk_unpack_array_like(duk_hthread *thr, duk_idx_t idx) {
}
DUK_ERROR_TYPE_INVALID_ARGS(thr);
- return 0;
+ DUK_WO_NORETURN(return 0;);
fail_over_2g:
DUK_ERROR_RANGE_INVALID_LENGTH(thr);
- return 0;
+ DUK_WO_NORETURN(return 0;);
}
/*
@@ -23135,6 +23826,7 @@ DUK_EXTERNAL void duk_throw_raw(duk_hthread *thr) {
if (DUK_UNLIKELY(thr->valstack_top == thr->valstack_bottom)) {
DUK_ERROR_TYPE_INVALID_ARGS(thr);
+ DUK_WO_NORETURN(return;);
}
/* Errors are augmented when they are created, not when they are
@@ -23198,6 +23890,7 @@ DUK_EXTERNAL void duk_error_va_raw(duk_hthread *thr, duk_errcode_t err_code, con
duk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap);
(void) duk_throw(thr);
+ DUK_WO_NORETURN(return;);
}
DUK_EXTERNAL void duk_error_raw(duk_hthread *thr, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, ...) {
@@ -23209,6 +23902,7 @@ DUK_EXTERNAL void duk_error_raw(duk_hthread *thr, duk_errcode_t err_code, const
duk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap);
va_end(ap);
(void) duk_throw(thr);
+ DUK_WO_NORETURN(return;);
}
#if !defined(DUK_USE_VARIADIC_MACROS)
@@ -23227,6 +23921,7 @@ DUK_LOCAL void duk__throw_error_from_stash(duk_hthread *thr, duk_errcode_t err_c
duk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap);
(void) duk_throw(thr);
+ DUK_WO_NORETURN(return;);
}
#define DUK__ERROR_STASH_SHARED(code) do { \
@@ -23234,7 +23929,7 @@ DUK_LOCAL void duk__throw_error_from_stash(duk_hthread *thr, duk_errcode_t err_c
va_start(ap, fmt); \
duk__throw_error_from_stash(thr, (code), fmt, ap); \
va_end(ap); \
- /* Never reached; if return 0 here, gcc/clang will complain. */ \
+ DUK_WO_NORETURN(return 0;); \
} while (0)
DUK_EXTERNAL duk_ret_t duk_error_stash(duk_hthread *thr, duk_errcode_t err_code, const char *fmt, ...) {
@@ -23364,7 +24059,7 @@ DUK_INTERNAL void duk_push_lightfunc_name_raw(duk_hthread *thr, duk_c_function f
DUK_ASSERT_API_ENTRY(thr);
- duk_push_sprintf(thr, "light_");
+ duk_push_literal(thr, "light_");
duk_push_string_funcptr(thr, (duk_uint8_t *) &func, sizeof(func));
duk_push_sprintf(thr, "_%04x", (unsigned int) lf_flags);
duk_concat(thr, 3);
@@ -23389,9 +24084,9 @@ DUK_INTERNAL void duk_push_lightfunc_tostring(duk_hthread *thr, duk_tval *tv) {
DUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv));
DUK_TVAL_GET_LIGHTFUNC(tv, func, lf_flags); /* read before 'tv' potentially invalidated */
- duk_push_string(thr, "function ");
+ duk_push_literal(thr, "function ");
duk_push_lightfunc_name_raw(thr, func, lf_flags);
- duk_push_string(thr, "() { [lightfunc code] }");
+ duk_push_literal(thr, "() { [lightfunc code] }");
duk_concat(thr, 3);
}
@@ -23503,7 +24198,7 @@ DUK_LOCAL const char *duk__push_string_tval_readable(duk_hthread *thr, duk_tval
/* 'tv' may be NULL */
if (tv == NULL) {
- duk_push_string(thr, "none");
+ duk_push_literal(thr, "none");
} else {
switch (DUK_TVAL_GET_TAG(tv)) {
case DUK_TAG_STRING: {
@@ -23512,11 +24207,11 @@ DUK_LOCAL const char *duk__push_string_tval_readable(duk_hthread *thr, duk_tval
/* XXX: string summary produces question marks
* so this is not very ideal.
*/
- duk_push_string(thr, "[Symbol ");
+ duk_push_literal(thr, "[Symbol ");
duk_push_string(thr, duk__get_symbol_type_string(h));
- duk_push_string(thr, " ");
+ duk_push_literal(thr, " ");
duk__push_hstring_readable_unicode(thr, h, DUK__READABLE_STRING_MAXCHARS);
- duk_push_string(thr, "]");
+ duk_push_literal(thr, "]");
duk_concat(thr, 5);
break;
}
@@ -23546,7 +24241,7 @@ DUK_LOCAL const char *duk__push_string_tval_readable(duk_hthread *thr, duk_tval
break;
}
}
- duk_push_class_string_tval(thr, tv);
+ duk_push_class_string_tval(thr, tv, 1 /*avoid_side_effects*/);
break;
}
case DUK_TAG_BUFFER: {
@@ -23601,7 +24296,7 @@ DUK_INTERNAL void duk_push_symbol_descriptive_string(duk_hthread *thr, duk_hstri
DUK_ASSERT_API_ENTRY(thr);
/* .toString() */
- duk_push_string(thr, "Symbol(");
+ duk_push_literal(thr, "Symbol(");
p = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);
p_end = p + DUK_HSTRING_GET_BYTELEN(h);
DUK_ASSERT(p[0] == 0xff || (p[0] & 0xc0) == 0x80);
@@ -23617,7 +24312,7 @@ DUK_INTERNAL void duk_push_symbol_descriptive_string(duk_hthread *thr, duk_hstri
}
}
duk_push_lstring(thr, (const char *) p, (duk_size_t) (q - p));
- duk_push_string(thr, ")");
+ duk_push_literal(thr, ")");
duk_concat(thr, 3);
}
@@ -23653,7 +24348,8 @@ DUK_INTERNAL void duk_copy_tvals_incref(duk_hthread *thr, duk_tval *tv_dst, duk_
DUK_ASSERT_API_ENTRY(thr);
DUK_UNREF(thr);
DUK_ASSERT(count * sizeof(duk_tval) >= count); /* no wrap */
- DUK_MEMCPY((void *) tv_dst, (const void *) tv_src, count * sizeof(duk_tval));
+
+ duk_memcpy_unsafe((void *) tv_dst, (const void *) tv_src, count * sizeof(duk_tval));
tv = tv_dst;
while (count-- > 0) {
@@ -23689,7 +24385,7 @@ DUK_LOCAL void duk__concat_and_join_helper(duk_hthread *thr, duk_idx_t count_in,
if (DUK_UNLIKELY(count_in <= 0)) {
if (count_in < 0) {
DUK_ERROR_RANGE_INVALID_COUNT(thr);
- return;
+ DUK_WO_NORETURN(return;);
}
DUK_ASSERT(count_in == 0);
duk_push_hstring_empty(thr);
@@ -23745,11 +24441,11 @@ DUK_LOCAL void duk__concat_and_join_helper(duk_hthread *thr, duk_idx_t count_in,
for (i = count; i >= 1; i--) {
if (is_join && i != count) {
h = duk_require_hstring(thr, -((duk_idx_t) count) - 2); /* extra -1 for buffer */
- DUK_MEMCPY(buf + idx, DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));
+ duk_memcpy(buf + idx, DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));
idx += DUK_HSTRING_GET_BYTELEN(h);
}
h = duk_require_hstring(thr, -((duk_idx_t) i) - 1); /* extra -1 for buffer */
- DUK_MEMCPY(buf + idx, DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));
+ duk_memcpy(buf + idx, DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));
idx += DUK_HSTRING_GET_BYTELEN(h);
}
@@ -23776,6 +24472,7 @@ DUK_LOCAL void duk__concat_and_join_helper(duk_hthread *thr, duk_idx_t count_in,
error_overflow:
DUK_ERROR_RANGE(thr, DUK_STR_RESULT_TOO_LONG);
+ DUK_WO_NORETURN(return;);
}
DUK_EXTERNAL void duk_concat(duk_hthread *thr, duk_idx_t count) {
@@ -23813,8 +24510,8 @@ DUK_INTERNAL void duk_concat_2(duk_hthread *thr) {
buf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, len);
DUK_ASSERT(buf != NULL);
- DUK_MEMCPY((void *) buf, (const void *) DUK_HSTRING_GET_DATA(h1), (size_t) len1);
- DUK_MEMCPY((void *) (buf + len1), (const void *) DUK_HSTRING_GET_DATA(h2), (size_t) len2);
+ duk_memcpy((void *) buf, (const void *) DUK_HSTRING_GET_DATA(h1), (size_t) len1);
+ duk_memcpy((void *) (buf + len1), (const void *) DUK_HSTRING_GET_DATA(h2), (size_t) len2);
(void) duk_buffer_to_string(thr, -1); /* Safe if inputs are safe. */
/* [ ... str1 str2 buf ] */
@@ -23825,6 +24522,7 @@ DUK_INTERNAL void duk_concat_2(duk_hthread *thr) {
error_overflow:
DUK_ERROR_RANGE(thr, DUK_STR_RESULT_TOO_LONG);
+ DUK_WO_NORETURN(return;);
}
#endif /* DUK_USE_PREFER_SIZE */
@@ -24053,7 +24751,7 @@ DUK_EXTERNAL duk_codepoint_t duk_char_code_at(duk_hthread *thr, duk_idx_t idx, d
/* #include duk_internal.h -> already included */
DUK_INTERNAL duk_double_t duk_time_get_ecmascript_time(duk_hthread *thr) {
- /* Ecmascript time, with millisecond fractions. Exposed via
+ /* ECMAScript time, with millisecond fractions. Exposed via
* duk_get_now() for example.
*/
DUK_UNREF(thr);
@@ -24061,7 +24759,7 @@ DUK_INTERNAL duk_double_t duk_time_get_ecmascript_time(duk_hthread *thr) {
}
DUK_INTERNAL duk_double_t duk_time_get_ecmascript_time_nofrac(duk_hthread *thr) {
- /* Ecmascript time without millisecond fractions. Exposed via
+ /* ECMAScript time without millisecond fractions. Exposed via
* the Date built-in which doesn't allow fractions.
*/
DUK_UNREF(thr);
@@ -24104,7 +24802,7 @@ DUK_EXTERNAL void duk_time_to_components(duk_hthread *thr, duk_double_t timeval,
DUK_UNREF(thr);
/* Convert as one-based, but change month to zero-based to match the
- * Ecmascript Date built-in behavior 1:1.
+ * ECMAScript Date built-in behavior 1:1.
*/
flags = DUK_DATE_FLAG_ONEBASED | DUK_DATE_FLAG_NAN_TO_ZERO;
@@ -24159,9 +24857,9 @@ DUK_EXTERNAL duk_double_t duk_components_to_time(duk_hthread *thr, duk_time_comp
/*
* Array built-ins
*
- * Most Array built-ins are intentionally generic in Ecmascript, and are
+ * Most Array built-ins are intentionally generic in ECMAScript, and are
* intended to work even when the 'this' binding is not an Array instance.
- * This Ecmascript feature is also used by much real world code. For this
+ * This ECMAScript feature is also used by much real world code. For this
* reason the implementations here don't assume exotic Array behavior or
* e.g. presence of a .length property. However, some algorithms have a
* fast path for duk_harray backed actual Array instances, enabled when
@@ -24235,6 +24933,7 @@ DUK_LOCAL duk_uint32_t duk__push_this_obj_len_u32_limited(duk_hthread *thr) {
duk_uint32_t ret = duk__push_this_obj_len_u32(thr);
if (DUK_UNLIKELY(ret >= 0x80000000UL)) {
DUK_ERROR_RANGE_INVALID_LENGTH(thr);
+ DUK_WO_NORETURN(return 0U;);
}
return ret;
}
@@ -24387,11 +25086,17 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_to_string(duk_hthread *thr) {
DUK_INTERNAL duk_ret_t duk_bi_array_prototype_concat(duk_hthread *thr) {
duk_idx_t i, n;
- duk_uarridx_t idx, idx_last;
- duk_uarridx_t j, len;
+ duk_uint32_t j, idx, len;
duk_hobject *h;
+ duk_size_t tmp_len;
- /* XXX: the insert here is a bit expensive if there are a lot of items.
+ /* XXX: In ES2015 Array .length can be up to 2^53-1. The current
+ * implementation is limited to 2^32-1.
+ */
+
+ /* XXX: Fast path for array 'this' and array element. */
+
+ /* XXX: The insert here is a bit expensive if there are a lot of items.
* It could also be special cased in the outermost for loop quite easily
* (as the element is dup()'d anyway).
*/
@@ -24409,59 +25114,97 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_concat(duk_hthread *thr) {
*/
idx = 0;
- idx_last = 0;
for (i = 0; i < n; i++) {
+ duk_bool_t spreadable;
+ duk_bool_t need_has_check;
+
DUK_ASSERT_TOP(thr, n + 1);
/* [ ToObject(this) item1 ... itemN arr ] */
- duk_dup(thr, i);
- h = duk_get_hobject_with_class(thr, -1, DUK_HOBJECT_CLASS_ARRAY);
- if (!h) {
- duk_xdef_prop_index_wec(thr, -2, idx++);
- idx_last = idx;
+ h = duk_get_hobject(thr, i);
+
+ if (h == NULL) {
+ spreadable = 0;
+ } else {
+#if defined(DUK_USE_SYMBOL_BUILTIN)
+ duk_get_prop_stridx(thr, i, DUK_STRIDX_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE);
+ if (duk_is_undefined(thr, -1)) {
+ spreadable = (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY);
+ } else {
+ spreadable = duk_to_boolean(thr, -1);
+ }
+ duk_pop_nodecref_unsafe(thr);
+#else
+ spreadable = (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY);
+#endif
+ }
+
+ if (!spreadable) {
+ duk_dup(thr, i);
+ duk_xdef_prop_index_wec(thr, -2, idx);
+ idx++;
+ if (DUK_UNLIKELY(idx == 0U)) {
+ /* Index after update is 0, and index written
+ * was 0xffffffffUL which is no longer a valid
+ * array index.
+ */
+ goto fail_wrap;
+ }
continue;
}
- /* [ ToObject(this) item1 ... itemN arr item(i) ] */
+ DUK_ASSERT(duk_is_object(thr, i));
+ need_has_check = (DUK_HOBJECT_IS_PROXY(h) != 0); /* Always 0 w/o Proxy support. */
- /* XXX: an array can have length higher than 32 bits; this is not handled
- * correctly now.
- */
- len = (duk_uarridx_t) duk_get_length(thr, -1);
+ /* [ ToObject(this) item1 ... itemN arr ] */
+
+ tmp_len = duk_get_length(thr, i);
+ len = (duk_uint32_t) tmp_len;
+ if (DUK_UNLIKELY(tmp_len != (duk_size_t) len)) {
+ goto fail_wrap;
+ }
+ if (DUK_UNLIKELY(idx + len < idx)) {
+ /* Result length must be at most 0xffffffffUL to be
+ * a valid 32-bit array index.
+ */
+ goto fail_wrap;
+ }
for (j = 0; j < len; j++) {
- if (duk_get_prop_index(thr, -1, j)) {
- /* [ ToObject(this) item1 ... itemN arr item(i) item(i)[j] ] */
- duk_xdef_prop_index_wec(thr, -3, idx++);
- idx_last = idx;
+ /* For a Proxy element, an explicit 'has' check is
+ * needed to allow the Proxy to present gaps.
+ */
+ if (need_has_check) {
+ if (duk_has_prop_index(thr, i, j)) {
+ duk_get_prop_index(thr, i, j);
+ duk_xdef_prop_index_wec(thr, -2, idx);
+ }
} else {
- idx++;
- duk_pop_undefined(thr);
-#if defined(DUK_USE_NONSTD_ARRAY_CONCAT_TRAILER)
- /* According to E5.1 Section 15.4.4.4 nonexistent trailing
- * elements do not affect 'length' of the result. Test262
- * and other engines disagree, so update idx_last here too.
- */
- idx_last = idx;
-#else
- /* Strict standard behavior, ignore trailing elements for
- * result 'length'.
- */
-#endif
+ if (duk_get_prop_index(thr, i, j)) {
+ duk_xdef_prop_index_wec(thr, -2, idx);
+ } else {
+ duk_pop_undefined(thr);
+ }
}
+ idx++;
+ DUK_ASSERT(idx != 0U); /* Wrap check above. */
}
- duk_pop_unsafe(thr);
}
- /* The E5.1 Section 15.4.4.4 algorithm doesn't set the length explicitly
- * in the end, but because we're operating with an internal value which
- * is known to be an array, this should be equivalent.
+ /* ES5.1 has a specification "bug" in that nonexistent trailing
+ * elements don't affect the result .length. Test262 and other
+ * engines disagree, and the specification bug was fixed in ES2015
+ * (see NOTE 1 in https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.concat).
*/
- duk_push_uarridx(thr, idx_last);
+ duk_push_uarridx(thr, idx);
duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W);
DUK_ASSERT_TOP(thr, n + 1);
return 1;
+
+ fail_wrap:
+ DUK_ERROR_RANGE_INVALID_LENGTH(thr);
+ DUK_WO_NORETURN(return 0;);
}
/*
@@ -25583,20 +26326,12 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_iter_shared(duk_hthread *thr) {
DUK_ASSERT_TOP(thr, 5);
if (!duk_get_prop_index(thr, 2, (duk_uarridx_t) i)) {
-#if defined(DUK_USE_NONSTD_ARRAY_MAP_TRAILER)
- /* Real world behavior for map(): trailing non-existent
- * elements don't invoke the user callback, but are still
- * counted towards result 'length'.
+ /* For 'map' trailing missing elements don't invoke the
+ * callback but count towards the result length.
*/
if (iter_type == DUK__ITER_MAP) {
res_length = i + 1;
}
-#else
- /* Standard behavior for map(): trailing non-existent
- * elements don't invoke the user callback and are not
- * counted towards result 'length'.
- */
-#endif
duk_pop_undefined(thr);
continue;
}
@@ -26021,6 +26756,7 @@ DUK_LOCAL duk_heaphdr *duk__getrequire_bufobj_this(duk_hthread *thr, duk_small_u
if (flags & DUK__BUFOBJ_FLAG_THROW) {
DUK_ERROR_TYPE(thr, DUK_STR_NOT_BUFFER);
+ DUK_WO_NORETURN(return NULL;);
}
return NULL;
}
@@ -26062,7 +26798,7 @@ DUK_LOCAL duk_hbufobj *duk__require_bufobj_value(duk_hthread *thr, duk_idx_t idx
}
DUK_ERROR_TYPE(thr, DUK_STR_NOT_BUFFER);
- return NULL; /* not reachable */
+ DUK_WO_NORETURN(return NULL;);
}
DUK_LOCAL void duk__set_bufobj_buffer(duk_hthread *thr, duk_hbufobj *h_bufobj, duk_hbuffer *h_val) {
@@ -26137,6 +26873,7 @@ DUK_LOCAL void duk__resolve_offset_opt_length(duk_hthread *thr,
fail_range:
DUK_ERROR_RANGE(thr, DUK_STR_INVALID_ARGS);
+ DUK_WO_NORETURN(return;);
}
/* Shared lenient buffer length clamping helper. No negative indices, no
@@ -26287,7 +27024,8 @@ DUK_INTERNAL void duk_hbufobj_push_uint8array_from_plain(duk_hthread *thr, duk_h
DUK_INTERNAL void duk_hbufobj_push_validated_read(duk_hthread *thr, duk_hbufobj *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size) {
duk_double_union du;
- DUK_MEMCPY((void *) du.uc, (const void *) p, (size_t) elem_size);
+ DUK_ASSERT(elem_size > 0);
+ duk_memcpy((void *) du.uc, (const void *) p, (size_t) elem_size);
switch (h_bufobj->elem_type) {
case DUK_HBUFOBJ_ELEM_UINT8:
@@ -26355,7 +27093,11 @@ DUK_INTERNAL void duk_hbufobj_validated_write(duk_hthread *thr, duk_hbufobj *h_b
du.ui[0] = (duk_uint32_t) duk_to_int32(thr, -1);
break;
case DUK_HBUFOBJ_ELEM_FLOAT32:
- du.f[0] = (duk_float_t) duk_to_number_m1(thr);
+ /* A double-to-float cast is undefined behavior in C99 if
+ * the cast is out-of-range, so use a helper. Example:
+ * runtime error: value -1e+100 is outside the range of representable values of type 'float'
+ */
+ du.f[0] = duk_double_to_float_t(duk_to_number_m1(thr));
break;
case DUK_HBUFOBJ_ELEM_FLOAT64:
du.d = (duk_double_t) duk_to_number_m1(thr);
@@ -26364,7 +27106,8 @@ DUK_INTERNAL void duk_hbufobj_validated_write(duk_hthread *thr, duk_hbufobj *h_b
DUK_UNREACHABLE();
}
- DUK_MEMCPY((void *) p, (const void *) du.uc, (size_t) elem_size);
+ DUK_ASSERT(elem_size > 0);
+ duk_memcpy((void *) p, (const void *) du.uc, (size_t) elem_size);
}
/* Helper to create a fixed buffer from argument value at index 0.
@@ -26400,12 +27143,14 @@ DUK_LOCAL duk_hbuffer *duk__hbufobj_fixed_from_argvalue(duk_hthread *thr) {
h_bufobj = (duk_hbufobj *) h;
if (DUK_UNLIKELY(h_bufobj->buf == NULL)) {
DUK_ERROR_TYPE_INVALID_ARGS(thr);
+ DUK_WO_NORETURN(return NULL;);
}
if (DUK_UNLIKELY(h_bufobj->offset != 0 || h_bufobj->length != DUK_HBUFFER_GET_SIZE(h_bufobj->buf))) {
/* No support for ArrayBuffers with slice
* offset/length.
*/
DUK_ERROR_TYPE_INVALID_ARGS(thr);
+ DUK_WO_NORETURN(return NULL;);
}
duk_push_hbuffer(thr, h_bufobj->buf);
return h_bufobj->buf;
@@ -26421,6 +27166,7 @@ DUK_LOCAL duk_hbuffer *duk__hbufobj_fixed_from_argvalue(duk_hthread *thr) {
}
default:
DUK_ERROR_TYPE_INVALID_ARGS(thr);
+ DUK_WO_NORETURN(return NULL;);
}
done:
@@ -26462,7 +27208,7 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_constructor(duk_hthread *thr) {
duk_push_buffer_object(thr,
-1,
0,
- DUK_HBUFFER_FIXED_GET_SIZE((duk_hbuffer_fixed *) h_buf),
+ DUK_HBUFFER_FIXED_GET_SIZE((duk_hbuffer_fixed *) (void *) h_buf),
DUK_BUFOBJ_UINT8ARRAY);
duk_push_hobject_bidx(thr, DUK_BIDX_NODEJS_BUFFER_PROTOTYPE);
duk_set_prototype(thr, -2);
@@ -26790,7 +27536,7 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_hthread *thr) {
DUK_DDD(DUK_DDDPRINT("using memcpy: p_src=%p, p_dst=%p, byte_length=%ld",
(void *) p_src, (void *) p_dst, (long) byte_length));
- DUK_MEMCPY((void *) p_dst, (const void *) p_src, (size_t) byte_length);
+ duk_memcpy_unsafe((void *) p_dst, (const void *) p_src, (size_t) byte_length);
break;
}
case 1: {
@@ -27026,7 +27772,7 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_tostring(duk_hthread *thr) {
h_this = duk__get_bufobj_this(thr);
if (h_this == NULL) {
/* XXX: happens e.g. when evaluating: String(Buffer.prototype). */
- duk_push_string(thr, "[object Object]");
+ duk_push_literal(thr, "[object Object]");
return 1;
}
DUK_ASSERT_HBUFOBJ_VALID(h_this);
@@ -27057,9 +27803,9 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_tostring(duk_hthread *thr) {
*/
DUK_ASSERT(DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_this, (duk_size_t) start_offset + slice_length));
- DUK_MEMCPY((void *) buf_slice,
- (const void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + start_offset),
- (size_t) slice_length);
+ duk_memcpy_unsafe((void *) buf_slice,
+ (const void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + start_offset),
+ (size_t) slice_length);
/* Use the equivalent of: new TextEncoder().encode(this) to convert the
* string. Result will be valid UTF-8; non-CESU-8 inputs are currently
@@ -27221,7 +27967,7 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_fill(duk_hthread *thr) {
/* Handle single character fills as memset() even when
* the fill data comes from a one-char argument.
*/
- DUK_MEMSET((void *) p, (int) fill_str_ptr[0], (size_t) fill_length);
+ duk_memset_unsafe((void *) p, (int) fill_str_ptr[0], (size_t) fill_length);
} else if (fill_str_len > 1) {
duk_size_t i, n, t;
@@ -27272,9 +28018,9 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_write(duk_hthread *thr) {
if (DUK_HBUFOBJ_VALID_SLICE(h_this)) {
/* Cannot overlap. */
- DUK_MEMCPY((void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + offset),
- (const void *) str_data,
- (size_t) length);
+ duk_memcpy_unsafe((void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + offset),
+ (const void *) str_data,
+ (size_t) length);
} else {
DUK_DDD(DUK_DDDPRINT("write() target buffer is not covered, silent ignore"));
}
@@ -27370,9 +28116,9 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_copy(duk_hthread *thr) {
/* Must use memmove() because copy area may overlap (source and target
* buffer may be the same, or from different slices.
*/
- DUK_MEMMOVE((void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufarg) + target_ustart),
- (const void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + source_ustart),
- (size_t) copy_size);
+ duk_memmove_unsafe((void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufarg) + target_ustart),
+ (const void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + source_ustart),
+ (size_t) copy_size);
} else {
DUK_DDD(DUK_DDDPRINT("buffer copy not covered by underlying buffer(s), ignoring"));
}
@@ -27558,7 +28304,7 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_set(duk_hthread *thr) {
DUK_ASSERT(src_length == dst_length);
DUK_DDD(DUK_DDDPRINT("fast path: able to use memmove() because views are compatible"));
- DUK_MEMMOVE((void *) p_dst_base, (const void *) p_src_base, (size_t) dst_length);
+ duk_memmove_unsafe((void *) p_dst_base, (const void *) p_src_base, (size_t) dst_length);
return 0;
}
DUK_DDD(DUK_DDDPRINT("fast path: views are not compatible with a byte copy, copy by item"));
@@ -27601,7 +28347,7 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_set(duk_hthread *thr) {
DUK_DDD(DUK_DDDPRINT("there is overlap, make a copy of the source"));
p_src_copy = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, src_length);
DUK_ASSERT(p_src_copy != NULL);
- DUK_MEMCPY((void *) p_src_copy, (const void *) p_src_base, (size_t) src_length);
+ duk_memcpy_unsafe((void *) p_src_copy, (const void *) p_src_base, (size_t) src_length);
p_src_base = p_src_copy; /* use p_src_base from now on */
}
@@ -27728,9 +28474,9 @@ DUK_LOCAL void duk__arraybuffer_plain_slice(duk_hthread *thr, duk_hbuffer *h_val
DUK_ASSERT(p_copy != NULL);
copy_length = slice_length;
- DUK_MEMCPY((void *) p_copy,
- (const void *) ((duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_val) + start_offset),
- copy_length);
+ duk_memcpy_unsafe((void *) p_copy,
+ (const void *) ((duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_val) + start_offset),
+ copy_length);
}
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
@@ -27852,9 +28598,9 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_slice_shared(duk_hthread *thr) {
* is left as zero.
*/
copy_length = DUK_HBUFOBJ_CLAMP_BYTELENGTH(h_this, slice_length);
- DUK_MEMCPY((void *) p_copy,
- (const void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + start_offset),
- copy_length);
+ duk_memcpy_unsafe((void *) p_copy,
+ (const void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + start_offset),
+ copy_length);
h_val = duk_known_hbuffer(thr, -1);
@@ -28046,9 +28792,9 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_concat(duk_hthread *thr) {
if (h_bufobj->buf != NULL &&
DUK_HBUFOBJ_VALID_SLICE(h_bufobj)) {
- DUK_MEMCPY((void *) p,
- (const void *) DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufobj),
- copy_size);
+ duk_memcpy_unsafe((void *) p,
+ (const void *) DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufobj),
+ copy_size);
} else {
/* Just skip, leaving zeroes in the result. */
;
@@ -28198,7 +28944,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_readfield(duk_hthread *thr) {
if (offset + 2U > check_length) {
goto fail_bounds;
}
- DUK_MEMCPY((void *) du.uc, (const void *) (buf + offset), 2);
+ duk_memcpy((void *) du.uc, (const void *) (buf + offset), 2);
tmp = du.us[0];
if (endswap) {
tmp = DUK_BSWAP16(tmp);
@@ -28215,7 +28961,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_readfield(duk_hthread *thr) {
if (offset + 4U > check_length) {
goto fail_bounds;
}
- DUK_MEMCPY((void *) du.uc, (const void *) (buf + offset), 4);
+ duk_memcpy((void *) du.uc, (const void *) (buf + offset), 4);
tmp = du.ui[0];
if (endswap) {
tmp = DUK_BSWAP32(tmp);
@@ -28232,7 +28978,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_readfield(duk_hthread *thr) {
if (offset + 4U > check_length) {
goto fail_bounds;
}
- DUK_MEMCPY((void *) du.uc, (const void *) (buf + offset), 4);
+ duk_memcpy((void *) du.uc, (const void *) (buf + offset), 4);
if (endswap) {
tmp = du.ui[0];
tmp = DUK_BSWAP32(tmp);
@@ -28245,7 +28991,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_readfield(duk_hthread *thr) {
if (offset + 8U > check_length) {
goto fail_bounds;
}
- DUK_MEMCPY((void *) du.uc, (const void *) (buf + offset), 8);
+ duk_memcpy((void *) du.uc, (const void *) (buf + offset), 8);
if (endswap) {
DUK_DBLUNION_BSWAP64(&du);
}
@@ -28302,9 +29048,12 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_readfield(duk_hthread *thr) {
} while (i != i_end);
if (magic_signed) {
- /* Shift to sign extend. */
+ /* Shift to sign extend. Left shift must be unsigned
+ * to avoid undefined behavior; right shift must be
+ * signed to sign extend properly.
+ */
shift_tmp = (duk_small_uint_t) (64U - (duk_small_uint_t) field_bytelen * 8U);
- tmp = (tmp << shift_tmp) >> shift_tmp;
+ tmp = (duk_int64_t) ((duk_uint64_t) tmp << shift_tmp) >> shift_tmp;
}
duk_push_i64(thr, tmp);
@@ -28480,7 +29229,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_hthread *thr) {
}
du.us[0] = tmp;
/* sign doesn't matter when writing */
- DUK_MEMCPY((void *) (buf + offset), (const void *) du.uc, 2);
+ duk_memcpy((void *) (buf + offset), (const void *) du.uc, 2);
break;
}
case DUK__FLD_32BIT: {
@@ -28494,7 +29243,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_hthread *thr) {
}
du.ui[0] = tmp;
/* sign doesn't matter when writing */
- DUK_MEMCPY((void *) (buf + offset), (const void *) du.uc, 4);
+ duk_memcpy((void *) (buf + offset), (const void *) du.uc, 4);
break;
}
case DUK__FLD_FLOAT: {
@@ -28509,7 +29258,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_hthread *thr) {
du.ui[0] = tmp;
}
/* sign doesn't matter when writing */
- DUK_MEMCPY((void *) (buf + offset), (const void *) du.uc, 4);
+ duk_memcpy((void *) (buf + offset), (const void *) du.uc, 4);
break;
}
case DUK__FLD_DOUBLE: {
@@ -28521,7 +29270,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_hthread *thr) {
DUK_DBLUNION_BSWAP64(&du);
}
/* sign doesn't matter when writing */
- DUK_MEMCPY((void *) (buf + offset), (const void *) du.uc, 8);
+ duk_memcpy((void *) (buf + offset), (const void *) du.uc, 8);
break;
}
case DUK__FLD_VARINT: {
@@ -28967,7 +29716,7 @@ DUK_LOCAL duk_bool_t duk__parse_string_iso8601_subset(duk_hthread *thr, const ch
duk_small_uint_t i;
/* During parsing, month and day are one-based; set defaults here. */
- DUK_MEMZERO(parts, sizeof(parts));
+ duk_memzero(parts, sizeof(parts));
DUK_ASSERT(parts[DUK_DATE_IDX_YEAR] == 0); /* don't care value, year is mandatory */
parts[DUK_DATE_IDX_MONTH] = 1;
parts[DUK_DATE_IDX_DAY] = 1;
@@ -29194,13 +29943,13 @@ DUK_LOCAL duk_uint8_t duk__days_in_month[12] = {
};
/* Maximum iteration count for computing UTC-to-local time offset when
- * creating an Ecmascript time value from local parts.
+ * creating an ECMAScript time value from local parts.
*/
#define DUK__LOCAL_TZOFFSET_MAXITER 4
/* Because 'day since epoch' can be negative and is used to compute weekday
* using a modulo operation, add this multiple of 7 to avoid negative values
- * when year is below 1970 epoch. Ecmascript time values are restricted to
+ * when year is below 1970 epoch. ECMAScript time values are restricted to
* +/- 100 million days from epoch, so this adder fits nicely into 32 bits.
* Round to a multiple of 7 (= floor(100000000 / 7) * 7) and add margin.
*/
@@ -29391,10 +30140,10 @@ DUK_INTERNAL void duk_bi_date_timeval_to_parts(duk_double_t d, duk_int_t *parts,
d = DUK_FLOOR(d); /* remove fractions if present */
DUK_ASSERT(DUK_FLOOR(d) == d);
- /* The timevalue must be in valid Ecmascript range, but since a local
+ /* The timevalue must be in valid ECMAScript range, but since a local
* time offset can be applied, we need to allow a +/- 24h leeway to
* the value. In other words, although the UTC time is within the
- * Ecmascript range, the local part values can be just outside of it.
+ * ECMAScript range, the local part values can be just outside of it.
*/
DUK_UNREF(duk_bi_date_timeval_in_leeway_range);
DUK_ASSERT(duk_bi_date_timeval_in_leeway_range(d));
@@ -29437,7 +30186,7 @@ DUK_INTERNAL void duk_bi_date_timeval_to_parts(duk_double_t d, duk_int_t *parts,
(long) parts[DUK_DATE_IDX_MILLISECOND]));
/* This assert depends on the input parts representing time inside
- * the Ecmascript range.
+ * the ECMAScript range.
*/
DUK_ASSERT(t2 + DUK__WEEKDAY_MOD_ADDER >= 0);
parts[DUK_DATE_IDX_WEEKDAY] = (t2 + 4 + DUK__WEEKDAY_MOD_ADDER) % 7; /* E5.1 Section 15.9.1.6 */
@@ -29557,7 +30306,7 @@ DUK_INTERNAL duk_double_t duk_bi_date_get_timeval_from_dparts(duk_double_t *dpar
* computation happens with intermediate results coerced to
* double values (instead of using something more accurate).
* E.g. E5.1 Section 15.9.1.11 requires use of IEEE 754
- * rules (= Ecmascript '+' and '*' operators).
+ * rules (= ECMAScript '+' and '*' operators).
*
* Without 'volatile' even this approach fails on some platform
* and compiler combinations. For instance, gcc 4.8.1 on Ubuntu
@@ -29664,6 +30413,7 @@ DUK_LOCAL duk_double_t duk__push_this_get_timeval_tzoffset(duk_hthread *thr, duk
h = duk_get_hobject(thr, -1); /* XXX: getter with class check, useful in built-ins */
if (h == NULL || DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_DATE) {
DUK_ERROR_TYPE(thr, "expected Date");
+ DUK_WO_NORETURN(return 0.0;);
}
duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);
@@ -29676,6 +30426,7 @@ DUK_LOCAL duk_double_t duk__push_this_get_timeval_tzoffset(duk_hthread *thr, duk
}
if (flags & DUK_DATE_FLAG_NAN_TO_RANGE_ERROR) {
DUK_ERROR_RANGE(thr, "Invalid Date");
+ DUK_WO_NORETURN(return 0.0;);
}
}
/* if no NaN handling flag, may still be NaN here, but not Inf */
@@ -30292,7 +31043,7 @@ DUK_INTERNAL duk_ret_t duk_bi_date_constructor_now(duk_hthread *thr) {
* Notes:
*
* - Date.prototype.toGMTString() and Date.prototype.toUTCString() are
- * required to be the same Ecmascript function object (!), so it is
+ * required to be the same ECMAScript function object (!), so it is
* omitted from here.
*
* - Date.prototype.toUTCString(): E5.1 specification does not require a
@@ -30488,6 +31239,41 @@ DUK_INTERNAL duk_ret_t duk_bi_date_prototype_set_time(duk_hthread *thr) {
return 1;
}
+/*
+ * Misc.
+ */
+
+#if defined(DUK_USE_SYMBOL_BUILTIN)
+DUK_INTERNAL duk_ret_t duk_bi_date_prototype_toprimitive(duk_hthread *thr) {
+ duk_size_t hintlen;
+ const char *hintstr;
+ duk_int_t hint;
+
+ /* Invokes OrdinaryToPrimitive() with suitable hint. Note that the
+ * method is generic, and works on non-Date arguments too.
+ *
+ * https://www.ecma-international.org/ecma-262/6.0/#sec-date.prototype-@@toprimitive
+ */
+
+ duk_push_this(thr);
+ duk_require_object(thr, -1);
+ DUK_ASSERT_TOP(thr, 2);
+
+ hintstr = duk_require_lstring(thr, 0, &hintlen);
+ if ((hintlen == 6 && DUK_STRCMP(hintstr, "string") == 0) ||
+ (hintlen == 7 && DUK_STRCMP(hintstr, "default") == 0)) {
+ hint = DUK_HINT_STRING;
+ } else if (hintlen == 6 && DUK_STRCMP(hintstr, "number") == 0) {
+ hint = DUK_HINT_NUMBER;
+ } else {
+ DUK_DCERROR_TYPE_INVALID_ARGS(thr);
+ }
+
+ duk_to_primitive_ordinary(thr, -1, hint);
+ return 1;
+}
+#endif /* DUK_USE_SYMBOL_BUILTIN */
+
#endif /* DUK_USE_DATE_BUILTIN */
/* automatic undefs */
@@ -30555,7 +31341,7 @@ DUK_INTERNAL duk_ret_t duk_bi_date_prototype_set_time(duk_hthread *thr) {
#define DUK__STRFTIME_BUF_SIZE 64
#if defined(DUK_USE_DATE_NOW_GETTIMEOFDAY)
-/* Get current Ecmascript time (= UNIX/Posix time, but in milliseconds). */
+/* Get current ECMAScript time (= UNIX/Posix time, but in milliseconds). */
DUK_INTERNAL duk_double_t duk_bi_date_get_now_gettimeofday(void) {
struct timeval tv;
duk_double_t d;
@@ -30603,7 +31389,7 @@ DUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_gmtime(duk_double_t d) {
return 0;
}
- /* If not within Ecmascript range, some integer time calculations
+ /* If not within ECMAScript range, some integer time calculations
* won't work correctly (and some asserts will fail), so bail out
* if so. This fixes test-bug-date-insane-setyear.js. There is
* a +/- 24h leeway in this range check to avoid a test262 corner
@@ -30654,10 +31440,10 @@ DUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_gmtime(duk_double_t d) {
* Since we rely on the platform APIs for conversions between local
* time and UTC, we can't guarantee the above. Rather, if the platform
* has historical DST rules they will be applied. This seems to be the
- * general preferred direction in Ecmascript standardization (or at least
+ * general preferred direction in ECMAScript standardization (or at least
* implementations) anyway, and even the equivalent year mapping should
* be disabled if the platform is known to handle DST properly for the
- * full Ecmascript range.
+ * full ECMAScript range.
*
* The following has useful discussion and links:
*
@@ -30672,7 +31458,7 @@ DUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_gmtime(duk_double_t d) {
t = (time_t) (d / 1000.0);
DUK_DDD(DUK_DDDPRINT("timeval: %lf -> time_t %ld", (double) d, (long) t));
- DUK_MEMZERO((void *) tms, sizeof(struct tm) * 2);
+ duk_memzero((void *) tms, sizeof(struct tm) * 2);
#if defined(DUK_USE_DATE_TZO_GMTIME_R)
(void) gmtime_r(&t, &tms[0]);
@@ -30682,9 +31468,9 @@ DUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_gmtime(duk_double_t d) {
(void) localtime_s(&t, &tms[1]);
#elif defined(DUK_USE_DATE_TZO_GMTIME)
tm_ptr = gmtime(&t);
- DUK_MEMCPY((void *) &tms[0], tm_ptr, sizeof(struct tm));
+ duk_memcpy((void *) &tms[0], tm_ptr, sizeof(struct tm));
tm_ptr = localtime(&t);
- DUK_MEMCPY((void *) &tms[1], tm_ptr, sizeof(struct tm));
+ duk_memcpy((void *) &tms[1], tm_ptr, sizeof(struct tm));
#else
#error internal error
#endif
@@ -30745,13 +31531,13 @@ DUK_INTERNAL duk_bool_t duk_bi_date_parse_string_strptime(duk_hthread *thr, cons
/* Copy to buffer with slack to avoid Valgrind gripes from strptime. */
DUK_ASSERT(str != NULL);
- DUK_MEMZERO(buf, sizeof(buf)); /* valgrind whine without this */
+ duk_memzero(buf, sizeof(buf)); /* valgrind whine without this */
DUK_SNPRINTF(buf, sizeof(buf), "%s", (const char *) str);
buf[sizeof(buf) - 1] = (char) 0;
DUK_DDD(DUK_DDDPRINT("parsing: '%s'", (const char *) buf));
- DUK_MEMZERO(&tm, sizeof(tm));
+ duk_memzero(&tm, sizeof(tm));
if (strptime((const char *) buf, "%c", &tm) != NULL) {
DUK_DDD(DUK_DDDPRINT("before mktime: tm={sec:%ld,min:%ld,hour:%ld,mday:%ld,mon:%ld,year:%ld,"
"wday:%ld,yday:%ld,isdst:%ld}",
@@ -30782,7 +31568,7 @@ DUK_INTERNAL duk_bool_t duk_bi_date_parse_string_getdate(duk_hthread *thr, const
* convenient for an embeddable interpreter.
*/
- DUK_MEMZERO(&tm, sizeof(struct tm));
+ duk_memzero(&tm, sizeof(struct tm));
rc = (duk_small_int_t) getdate_r(str, &tm);
DUK_DDD(DUK_DDDPRINT("getdate_r() -> %ld", (long) rc));
@@ -30807,16 +31593,16 @@ DUK_INTERNAL duk_bool_t duk_bi_date_format_parts_strftime(duk_hthread *thr, duk_
DUK_UNREF(tzoffset);
- /* If the platform doesn't support the entire Ecmascript range, we need
+ /* If the platform doesn't support the entire ECMAScript range, we need
* to return 0 so that the caller can fall back to the default formatter.
*
- * For now, assume that if time_t is 8 bytes or more, the whole Ecmascript
+ * For now, assume that if time_t is 8 bytes or more, the whole ECMAScript
* range is supported. For smaller time_t values (4 bytes in practice),
* assumes that the signed 32-bit range is supported.
*
* XXX: detect this more correctly per platform. The size of time_t is
* probably not an accurate guarantee of strftime() supporting or not
- * supporting a large time range (the full Ecmascript range).
+ * supporting a large time range (the full ECMAScript range).
*/
if (sizeof(time_t) < 8 &&
(parts[DUK_DATE_IDX_YEAR] < 1970 || parts[DUK_DATE_IDX_YEAR] > 2037)) {
@@ -30824,7 +31610,7 @@ DUK_INTERNAL duk_bool_t duk_bi_date_format_parts_strftime(duk_hthread *thr, duk_
return 0;
}
- DUK_MEMZERO(&tm, sizeof(tm));
+ duk_memzero(&tm, sizeof(tm));
tm.tm_sec = parts[DUK_DATE_IDX_SECOND];
tm.tm_min = parts[DUK_DATE_IDX_MINUTE];
tm.tm_hour = parts[DUK_DATE_IDX_HOUR];
@@ -30834,7 +31620,7 @@ DUK_INTERNAL duk_bool_t duk_bi_date_format_parts_strftime(duk_hthread *thr, duk_
tm.tm_wday = parts[DUK_DATE_IDX_WEEKDAY];
tm.tm_isdst = 0;
- DUK_MEMZERO(buf, sizeof(buf));
+ duk_memzero(buf, sizeof(buf));
if ((flags & DUK_DATE_FLAG_TOSTRING_DATE) && (flags & DUK_DATE_FLAG_TOSTRING_TIME)) {
fmt = "%c";
} else if (flags & DUK_DATE_FLAG_TOSTRING_DATE) {
@@ -30892,13 +31678,15 @@ DUK_LOCAL void duk__convert_systime_to_ularge(const SYSTEMTIME *st, ULARGE_INTEG
}
}
+#if defined(DUK_USE_DATE_NOW_WINDOWS_SUBMS)
DUK_LOCAL void duk__convert_filetime_to_ularge(const FILETIME *ft, ULARGE_INTEGER *res) {
res->LowPart = ft->dwLowDateTime;
res->HighPart = ft->dwHighDateTime;
}
+#endif /* DUK_USE_DATE_NOW_WINDOWS_SUBMS */
DUK_LOCAL void duk__set_systime_jan1970(SYSTEMTIME *st) {
- DUK_MEMZERO((void *) st, sizeof(*st));
+ duk_memzero((void *) st, sizeof(*st));
st->wYear = 1970;
st->wMonth = 1;
st->wDayOfWeek = 4; /* not sure whether or not needed; Thursday */
@@ -30963,10 +31751,11 @@ DUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_windows(duk_double_t d) {
ULARGE_INTEGER tmp2;
ULARGE_INTEGER tmp3;
FILETIME ft1;
+ BOOL ret;
/* XXX: handling of timestamps outside Windows supported range.
* How does Windows deal with dates before 1600? Does windows
- * support all Ecmascript years (like -200000 and +200000)?
+ * support all ECMAScript years (like -200000 and +200000)?
* Should equivalent year mapping be used here too? If so, use
* a shared helper (currently integrated into timeval-to-parts).
*/
@@ -30982,7 +31771,11 @@ DUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_windows(duk_double_t d) {
ft1.dwLowDateTime = tmp2.LowPart;
ft1.dwHighDateTime = tmp2.HighPart;
- FileTimeToSystemTime((const FILETIME *) &ft1, &st2);
+ ret = FileTimeToSystemTime((const FILETIME *) &ft1, &st2);
+ if (!ret) {
+ DUK_D(DUK_DPRINT("FileTimeToSystemTime() failed, return tzoffset 0"));
+ return 0;
+ }
if (SystemTimeToTzSpecificLocalTime((LPTIME_ZONE_INFORMATION) NULL, &st2, &st3) == 0) {
DUK_D(DUK_DPRINT("SystemTimeToTzSpecificLocalTime() failed, return tzoffset 0"));
return 0;
@@ -31002,6 +31795,7 @@ DUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_windows_no_dst(duk_double_
FILETIME ft2;
ULARGE_INTEGER tmp1;
ULARGE_INTEGER tmp2;
+ BOOL ret;
/* Do a similar computation to duk_bi_date_get_local_tzoffset_windows
* but without accounting for daylight savings time. Use this on
@@ -31017,9 +31811,17 @@ DUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_windows_no_dst(duk_double_
ft1.dwLowDateTime = tmp1.LowPart;
ft1.dwHighDateTime = tmp1.HighPart;
- FileTimeToLocalFileTime((const FILETIME *) &ft1, &ft2);
+ ret = FileTimeToLocalFileTime((const FILETIME *) &ft1, &ft2);
+ if (!ret) {
+ DUK_D(DUK_DPRINT("FileTimeToLocalFileTime() failed, return tzoffset 0"));
+ return 0;
+ }
- FileTimeToSystemTime((const FILETIME *) &ft2, &st2);
+ ret = FileTimeToSystemTime((const FILETIME *) &ft2, &st2);
+ if (!ret) {
+ DUK_D(DUK_DPRINT("FileTimeToSystemTime() failed, return tzoffset 0"));
+ return 0;
+ }
duk__convert_systime_to_ularge((const SYSTEMTIME *) &st2, &tmp2);
return (duk_int_t) (((LONGLONG) tmp2.QuadPart - (LONGLONG) tmp1.QuadPart) / DUK_I64_CONSTANT(10000000)); /* seconds */
@@ -31055,7 +31857,7 @@ DUK_INTERNAL duk_double_t duk_bi_date_get_monotonic_time_windows_qpc(void) {
*
* Size optimization note: it might seem that vararg multipurpose functions
* like fin(), enc(), and dec() are not very size optimal, but using a single
- * user-visible Ecmascript function saves a lot of run-time footprint; each
+ * user-visible ECMAScript function saves a lot of run-time footprint; each
* Function instance takes >100 bytes. Using a shared native helper and a
* 'magic' value won't save much if there are multiple Function instances
* anyway.
@@ -31449,7 +32251,7 @@ DUK_LOCAL duk_ret_t duk__decode_helper(duk_hthread *thr, duk__decode_context *de
DUK_TYPE_MASK_LIGHTFUNC |
DUK_TYPE_MASK_BUFFER |
DUK_TYPE_MASK_OBJECT);
- if (duk_get_prop_string(thr, 1, "stream")) {
+ if (duk_get_prop_literal(thr, 1, "stream")) {
stream = duk_to_boolean(thr, -1);
}
}
@@ -31464,6 +32266,7 @@ DUK_LOCAL duk_ret_t duk__decode_helper(duk_hthread *thr, duk__decode_context *de
*/
if (len >= (DUK_HBUFFER_MAX_BYTELEN / 3) - 3) {
DUK_ERROR_TYPE(thr, DUK_STR_RESULT_TOO_LONG);
+ DUK_WO_NORETURN(return 0;);
}
output = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, 3 + (3 * len)); /* used parts will be always manually written over */
@@ -31541,7 +32344,7 @@ DUK_LOCAL duk_ret_t duk__decode_helper(duk_hthread *thr, duk__decode_context *de
fail_type:
DUK_ERROR_TYPE(thr, DUK_STR_UTF8_DECODE_FAILED);
- DUK_UNREACHABLE();
+ DUK_WO_NORETURN(return 0;);
}
/*
@@ -31559,7 +32362,7 @@ DUK_INTERNAL duk_ret_t duk_bi_textencoder_constructor(duk_hthread *thr) {
}
DUK_INTERNAL duk_ret_t duk_bi_textencoder_prototype_encoding_getter(duk_hthread *thr) {
- duk_push_string(thr, "utf-8");
+ duk_push_literal(thr, "utf-8");
return 1;
}
@@ -31581,6 +32384,7 @@ DUK_INTERNAL duk_ret_t duk_bi_textencoder_prototype_encode(duk_hthread *thr) {
len = (duk_size_t) DUK_HSTRING_GET_CHARLEN(h_input);
if (len >= DUK_HBUFFER_MAX_BYTELEN / 3) {
DUK_ERROR_TYPE(thr, DUK_STR_RESULT_TOO_LONG);
+ DUK_WO_NORETURN(return 0;);
}
}
@@ -31600,14 +32404,14 @@ DUK_INTERNAL duk_ret_t duk_bi_textencoder_prototype_encode(duk_hthread *thr) {
DUK_ASSERT(duk_is_string(thr, 0)); /* True if len > 0. */
/* XXX: duk_decode_string() is used to process the input
- * string. For standard Ecmascript strings, represented
+ * string. For standard ECMAScript strings, represented
* internally as CESU-8, this is fine. However, behavior
* beyond CESU-8 is not very strict: codepoints using an
* extended form of UTF-8 are also accepted, and invalid
* codepoint sequences (which are allowed in Duktape strings)
* are not handled as well as they could (e.g. invalid
* continuation bytes may mask following codepoints).
- * This is how Ecmascript code would also see such strings.
+ * This is how ECMAScript code would also see such strings.
* Maybe replace duk_decode_string() with an explicit strict
* CESU-8 decoder here?
*/
@@ -31635,7 +32439,7 @@ DUK_INTERNAL duk_ret_t duk_bi_textencoder_prototype_encode(duk_hthread *thr) {
/* Standard WHATWG output is a Uint8Array. Here the Uint8Array will
* be backed by a dynamic buffer which differs from e.g. Uint8Arrays
- * created as 'new Uint8Array(N)'. Ecmascript code won't see the
+ * created as 'new Uint8Array(N)'. ECMAScript code won't see the
* difference but C code will. When bufferobjects are not supported,
* returns a plain dynamic buffer.
*/
@@ -31657,10 +32461,10 @@ DUK_INTERNAL duk_ret_t duk_bi_textdecoder_constructor(duk_hthread *thr) {
duk_to_string(thr, 0);
}
if (!duk_is_null_or_undefined(thr, 1)) {
- if (duk_get_prop_string(thr, 1, "fatal")) {
+ if (duk_get_prop_literal(thr, 1, "fatal")) {
fatal = duk_to_boolean(thr, -1);
}
- if (duk_get_prop_string(thr, 1, "ignoreBOM")) {
+ if (duk_get_prop_literal(thr, 1, "ignoreBOM")) {
ignore_bom = duk_to_boolean(thr, -1);
}
}
@@ -31675,7 +32479,7 @@ DUK_INTERNAL duk_ret_t duk_bi_textdecoder_constructor(duk_hthread *thr) {
dec_ctx->ignore_bom = (duk_uint8_t) ignore_bom;
duk__utf8_decode_init(dec_ctx); /* Initializes remaining fields. */
- duk_put_prop_string(thr, -2, DUK_INTERNAL_SYMBOL("Context"));
+ duk_put_prop_literal(thr, -2, DUK_INTERNAL_SYMBOL("Context"));
return 0;
}
@@ -31683,7 +32487,7 @@ DUK_INTERNAL duk_ret_t duk_bi_textdecoder_constructor(duk_hthread *thr) {
DUK_LOCAL duk__decode_context *duk__get_textdecoder_context(duk_hthread *thr) {
duk__decode_context *dec_ctx;
duk_push_this(thr);
- duk_get_prop_string(thr, -1, DUK_INTERNAL_SYMBOL("Context"));
+ duk_get_prop_literal(thr, -1, DUK_INTERNAL_SYMBOL("Context"));
dec_ctx = (duk__decode_context *) duk_require_buffer(thr, -1, NULL);
DUK_ASSERT(dec_ctx != NULL);
return dec_ctx;
@@ -31700,7 +32504,7 @@ DUK_INTERNAL duk_ret_t duk_bi_textdecoder_prototype_shared_getter(duk_hthread *t
/* Encoding is now fixed, so _Context lookup is only needed to
* validate the 'this' binding (TypeError if not TextDecoder-like).
*/
- duk_push_string(thr, "utf-8");
+ duk_push_literal(thr, "utf-8");
break;
case 1:
duk_push_boolean(thr, dec_ctx->fatal);
@@ -31800,7 +32604,7 @@ DUK_INTERNAL duk_ret_t duk_bi_error_prototype_to_string(duk_hthread *thr) {
duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_NAME);
if (duk_is_undefined(thr, -1)) {
duk_pop(thr);
- duk_push_string(thr, "Error");
+ duk_push_literal(thr, "Error");
} else {
duk_to_string(thr, -1);
}
@@ -31830,7 +32634,7 @@ DUK_INTERNAL duk_ret_t duk_bi_error_prototype_to_string(duk_hthread *thr) {
duk_pop(thr);
return 1;
}
- duk_push_string(thr, ": ");
+ duk_push_literal(thr, ": ");
duk_insert(thr, -2); /* ... name ': ' message */
duk_concat(thr, 3);
@@ -31899,13 +32703,13 @@ DUK_LOCAL duk_ret_t duk__error_getter_helper(duk_hthread *thr, duk_small_int_t o
duk_get_prop_index(thr, idx_td, (duk_uarridx_t) i);
duk_get_prop_index(thr, idx_td, (duk_uarridx_t) (i + 1));
d = duk_to_number_m1(thr);
- pc = (duk_int_t) DUK_FMOD(d, DUK_DOUBLE_2TO32);
- flags = (duk_uint_t) DUK_FLOOR(d / DUK_DOUBLE_2TO32);
+ pc = duk_double_to_int_t(DUK_FMOD(d, DUK_DOUBLE_2TO32));
+ flags = duk_double_to_uint_t(DUK_FLOOR(d / DUK_DOUBLE_2TO32));
t = (duk_small_int_t) duk_get_type(thr, -2);
if (t == DUK_TYPE_OBJECT || t == DUK_TYPE_LIGHTFUNC) {
/*
- * Ecmascript/native function call or lightfunc call
+ * ECMAScript/native function call or lightfunc call
*/
count_func++;
@@ -32174,7 +32978,7 @@ DUK_INTERNAL duk_ret_t duk_bi_function_constructor(duk_hthread *thr) {
duk_push_hstring_empty(thr);
} else {
duk_insert(thr, 0); /* [ arg1 ... argN-1 body] -> [body arg1 ... argN-1] */
- duk_push_string(thr, ",");
+ duk_push_literal(thr, ",");
duk_insert(thr, 1);
duk_join(thr, nargs - 1);
}
@@ -32186,11 +32990,11 @@ DUK_INTERNAL duk_ret_t duk_bi_function_constructor(duk_hthread *thr) {
/* XXX: this placeholder is not always correct, but use for now.
* It will fail in corner cases; see test-dev-func-cons-args.js.
*/
- duk_push_string(thr, "function(");
+ duk_push_literal(thr, "function(");
duk_dup_1(thr);
- duk_push_string(thr, "){");
+ duk_push_literal(thr, "){");
duk_dup_0(thr);
- duk_push_string(thr, "\n}"); /* Newline is important to handle trailing // comment. */
+ duk_push_literal(thr, "\n}"); /* Newline is important to handle trailing // comment. */
duk_concat(thr, 5);
/* [ body formals source ] */
@@ -32208,7 +33012,7 @@ DUK_INTERNAL duk_ret_t duk_bi_function_constructor(duk_hthread *thr) {
comp_flags);
/* Force .name to 'anonymous' (ES2015). */
- duk_push_string(thr, "anonymous");
+ duk_push_literal(thr, "anonymous");
duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);
func = (duk_hcompfunc *) duk_known_hobject(thr, -1);
@@ -32420,7 +33224,7 @@ DUK_INTERNAL duk_ret_t duk_bi_function_prototype_bind(duk_hthread *thr) {
if (DUK_HOBJECT_HAS_BOUNDFUNC(h_target)) {
duk_hboundfunc *h_boundtarget;
- h_boundtarget = (duk_hboundfunc *) h_target;
+ h_boundtarget = (duk_hboundfunc *) (void *) h_target;
/* The final function should always be non-bound, unless
* there's a bug in the internals. Assert for it.
@@ -32454,7 +33258,7 @@ DUK_INTERNAL duk_ret_t duk_bi_function_prototype_bind(duk_hthread *thr) {
DUK_DCERROR_RANGE_INVALID_COUNT(thr);
}
tv_res = (duk_tval *) DUK_ALLOC_CHECKED(thr, ((duk_size_t) bound_nargs) * sizeof(duk_tval));
- DUK_ASSERT(tv_res != NULL);
+ DUK_ASSERT(tv_res != NULL || bound_nargs == 0);
DUK_ASSERT(h_bound->args == NULL);
DUK_ASSERT(h_bound->nargs == 0);
h_bound->args = tv_res;
@@ -32494,7 +33298,7 @@ DUK_INTERNAL duk_ret_t duk_bi_function_prototype_bind(duk_hthread *thr) {
duk_xdef_prop_stridx_thrower(thr, -1, DUK_STRIDX_LC_ARGUMENTS);
/* Function name and fileName (non-standard). */
- duk_push_string(thr, "bound "); /* ES2015 19.2.3.2. */
+ duk_push_literal(thr, "bound "); /* ES2015 19.2.3.2. */
duk_get_prop_stridx(thr, -3, DUK_STRIDX_NAME);
if (!duk_is_string_notsymbol(thr, -1)) {
/* ES2015 has requirement to check that .name of target is a string
@@ -32578,6 +33382,17 @@ DUK_INTERNAL duk_ret_t duk_bi_native_function_name(duk_hthread *thr) {
fail_type:
DUK_DCERROR_TYPE_INVALID_ARGS(thr);
}
+
+#if defined(DUK_USE_SYMBOL_BUILTIN)
+DUK_INTERNAL duk_ret_t duk_bi_function_prototype_hasinstance(duk_hthread *thr) {
+ /* This binding: RHS, stack index 0: LHS. */
+ duk_bool_t ret;
+
+ ret = duk_js_instanceof_ordinary(thr, DUK_GET_TVAL_POSIDX(thr, 0), DUK_GET_THIS_TVAL_PTR(thr));
+ duk_push_boolean(thr, ret);
+ return 1;
+}
+#endif /* DUK_USE_SYMBOL_BUILTIN */
/*
* Global object built-ins
*/
@@ -32780,6 +33595,7 @@ DUK_LOCAL void duk__transform_callback_encode_uri(duk__transform_context *tfm_ct
uri_error:
DUK_ERROR_URI(tfm_ctx->thr, DUK_STR_INVALID_INPUT);
+ DUK_WO_NORETURN(return;);
}
DUK_LOCAL void duk__transform_callback_decode_uri(duk__transform_context *tfm_ctx, const void *udata, duk_codepoint_t cp) {
@@ -32918,6 +33734,7 @@ DUK_LOCAL void duk__transform_callback_decode_uri(duk__transform_context *tfm_ct
uri_error:
DUK_ERROR_URI(tfm_ctx->thr, DUK_STR_INVALID_INPUT);
+ DUK_WO_NORETURN(return;);
}
#if defined(DUK_USE_SECTION_B)
@@ -32958,6 +33775,7 @@ DUK_LOCAL void duk__transform_callback_escape(duk__transform_context *tfm_ctx, c
esc_error:
DUK_ERROR_TYPE(tfm_ctx->thr, DUK_STR_INVALID_INPUT);
+ DUK_WO_NORETURN(return;);
}
DUK_LOCAL void duk__transform_callback_unescape(duk__transform_context *tfm_ctx, const void *udata, duk_codepoint_t cp) {
@@ -32990,7 +33808,7 @@ DUK_LOCAL void duk__transform_callback_unescape(duk__transform_context *tfm_ctx,
* Eval needs to handle both a "direct eval" and an "indirect eval".
* Direct eval handling needs access to the caller's activation so that its
* lexical environment can be accessed. A direct eval is only possible from
- * Ecmascript code; an indirect eval call is possible also from C code.
+ * ECMAScript code; an indirect eval call is possible also from C code.
* When an indirect eval call is made from C code, there may not be a
* calling activation at all which needs careful handling.
*/
@@ -33029,7 +33847,7 @@ DUK_INTERNAL duk_ret_t duk_bi_global_object_eval(duk_hthread *thr) {
#if defined(DUK_USE_DEBUGGER_SUPPORT)
/* NOTE: level is used only by the debugger and should never be present
- * for an Ecmascript eval().
+ * for an ECMAScript eval().
*/
DUK_ASSERT(level == -2); /* by default, use caller's environment */
if (duk_get_top(thr) >= 2 && duk_is_number(thr, 1)) {
@@ -33522,6 +34340,7 @@ DUK_LOCAL void duk__dec_syntax_error(duk_json_dec_ctx *js_ctx) {
*/
DUK_ERROR_FMT1(js_ctx->thr, DUK_ERR_SYNTAX_ERROR, DUK_STR_FMT_INVALID_JSON,
(long) (js_ctx->p - js_ctx->p_start));
+ DUK_WO_NORETURN(return;);
}
DUK_LOCAL void duk__dec_eat_white(duk_json_dec_ctx *js_ctx) {
@@ -33937,7 +34756,7 @@ DUK_LOCAL void duk__dec_buffer(duk_json_dec_ctx *js_ctx) {
src_len = (duk_size_t) (p - js_ctx->p);
buf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, src_len);
DUK_ASSERT(buf != NULL);
- DUK_MEMCPY((void *) buf, (const void *) js_ctx->p, src_len);
+ duk_memcpy((void *) buf, (const void *) js_ctx->p, src_len);
duk_hex_decode(thr, -1);
js_ctx->p = p + 1; /* skip '|' */
@@ -34028,6 +34847,7 @@ DUK_LOCAL void duk__dec_objarr_entry(duk_json_dec_ctx *js_ctx) {
DUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);
if (js_ctx->recursion_depth >= js_ctx->recursion_limit) {
DUK_ERROR_RANGE(thr, DUK_STR_JSONDEC_RECLIMIT);
+ DUK_WO_NORETURN(return;);
}
js_ctx->recursion_depth++;
}
@@ -34604,9 +35424,9 @@ DUK_LOCAL void duk__enc_quote_string(duk_json_enc_ctx *js_ctx, duk_hstring *h_st
/* If XUTF-8 decoding fails, treat the offending byte as a codepoint directly
* and go forward one byte. This is of course very lossy, but allows some kind
* of output to be produced even for internal strings which don't conform to
- * XUTF-8. All standard Ecmascript strings are always CESU-8, so this behavior
- * does not violate the Ecmascript specification. The behavior is applied to
- * all modes, including Ecmascript standard JSON. Because the current XUTF-8
+ * XUTF-8. All standard ECMAScript strings are always CESU-8, so this behavior
+ * does not violate the ECMAScript specification. The behavior is applied to
+ * all modes, including ECMAScript standard JSON. Because the current XUTF-8
* decoding is not very strict, this behavior only really affects initial bytes
* and truncated codepoints.
*
@@ -34743,7 +35563,7 @@ DUK_LOCAL duk_uint8_t *duk__enc_buffer_data_hex(const duk_uint8_t *src, duk_size
/* Unlike in duk_hex_encode() 'dst' is not necessarily aligned by 2.
* For platforms where unaligned accesses are not allowed, shift 'dst'
- * ahead by 1 byte to get alignment and then DUK_MEMMOVE() the result
+ * ahead by 1 byte to get alignment and then duk_memmove() the result
* in place. The faster encoding loop makes up the difference.
* There's always space for one extra byte because a terminator always
* follows the hex data and that's been accounted for by the caller.
@@ -34776,7 +35596,7 @@ DUK_LOCAL duk_uint8_t *duk__enc_buffer_data_hex(const duk_uint8_t *src, duk_size
#if !defined(DUK_USE_UNALIGNED_ACCESSES_POSSIBLE)
if (shift_dst) {
q--;
- DUK_MEMMOVE((void *) dst, (const void *) (dst + 1), 2 * len_safe);
+ duk_memmove((void *) dst, (const void *) (dst + 1), 2 * len_safe);
DUK_ASSERT(dst + 2 * len_safe == q);
}
#endif
@@ -34852,7 +35672,7 @@ DUK_LOCAL void duk__enc_buffer_data(duk_json_enc_ctx *js_ctx, duk_uint8_t *buf_d
#if defined(DUK_USE_JC)
{
DUK_ASSERT(js_ctx->flag_ext_compatible);
- DUK_MEMCPY((void *) q, (const void *) "{\"_buf\":\"", 9); /* len: 9 */
+ duk_memcpy((void *) q, (const void *) "{\"_buf\":\"", 9); /* len: 9 */
q += 9;
q = duk__enc_buffer_data_hex(buf_data, buf_len, q);
*q++ = DUK_ASC_DOUBLEQUOTE;
@@ -34925,7 +35745,7 @@ DUK_LOCAL void duk__enc_pointer(duk_json_enc_ctx *js_ctx, void *ptr) {
DUK_ASSERT(js_ctx->flag_ext_custom || js_ctx->flag_ext_compatible); /* caller checks */
DUK_ASSERT(js_ctx->flag_ext_custom_or_compatible);
- DUK_MEMZERO(buf, sizeof(buf));
+ duk_memzero(buf, sizeof(buf));
/* The #if defined() clutter here needs to handle the three
* cases: (1) JX+JC, (2) JX only, (3) JC only.
@@ -35015,21 +35835,21 @@ DUK_LOCAL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t dept
p = DUK_BW_ENSURE_GETPTR(js_ctx->thr, &js_ctx->bw, need_bytes);
p_start = p;
- DUK_MEMCPY((void *) p, (const void *) gap_data, (size_t) gap_len);
+ duk_memcpy((void *) p, (const void *) gap_data, (size_t) gap_len);
p += gap_len;
avail_bytes = gap_len;
DUK_ASSERT(need_bytes >= gap_len);
need_bytes -= gap_len;
while (need_bytes >= avail_bytes) {
- DUK_MEMCPY((void *) p, (const void *) p_start, (size_t) avail_bytes);
+ duk_memcpy((void *) p, (const void *) p_start, (size_t) avail_bytes);
p += avail_bytes;
need_bytes -= avail_bytes;
avail_bytes <<= 1;
}
DUK_ASSERT(need_bytes < avail_bytes); /* need_bytes may be zero */
- DUK_MEMCPY((void *) p, (const void *) p_start, (size_t) need_bytes);
+ duk_memcpy((void *) p, (const void *) p_start, (size_t) need_bytes);
p += need_bytes;
/*avail_bytes += need_bytes*/
@@ -35061,6 +35881,7 @@ DUK_LOCAL void duk__enc_objarr_entry(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_
if (DUK_UNLIKELY(js_ctx->visiting[i] == h_target)) {
DUK_DD(DUK_DDPRINT("slow path loop detect"));
DUK_ERROR_TYPE(thr, DUK_STR_CYCLIC_INPUT);
+ DUK_WO_NORETURN(return;);
}
}
if (js_ctx->recursion_depth < DUK_JSON_ENC_LOOPARRAY) {
@@ -35070,6 +35891,7 @@ DUK_LOCAL void duk__enc_objarr_entry(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_
duk_dup_top(thr); /* -> [ ... voidp voidp ] */
if (duk_has_prop(thr, js_ctx->idx_loop)) {
DUK_ERROR_TYPE(thr, DUK_STR_CYCLIC_INPUT);
+ DUK_WO_NORETURN(return;);
}
duk_push_true(thr); /* -> [ ... voidp true ] */
duk_put_prop(thr, js_ctx->idx_loop); /* -> [ ... ] */
@@ -35081,6 +35903,7 @@ DUK_LOCAL void duk__enc_objarr_entry(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_
DUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);
if (js_ctx->recursion_depth >= js_ctx->recursion_limit) {
DUK_ERROR_RANGE(thr, DUK_STR_JSONENC_RECLIMIT);
+ DUK_WO_NORETURN(return;);
}
js_ctx->recursion_depth++;
@@ -35678,12 +36501,14 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du
if (js_ctx->recursion_depth >= js_ctx->recursion_limit) {
DUK_DD(DUK_DDPRINT("fast path recursion limit"));
DUK_ERROR_RANGE(js_ctx->thr, DUK_STR_JSONDEC_RECLIMIT);
+ DUK_WO_NORETURN(return 0;);
}
for (i = 0, n = (duk_uint_fast32_t) js_ctx->recursion_depth; i < n; i++) {
if (DUK_UNLIKELY(js_ctx->visiting[i] == obj)) {
DUK_DD(DUK_DDPRINT("fast path loop detect"));
DUK_ERROR_TYPE(js_ctx->thr, DUK_STR_CYCLIC_INPUT);
+ DUK_WO_NORETURN(return 0;);
}
}
@@ -36064,7 +36889,7 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du
/* Error message doesn't matter: the error is ignored anyway. */
DUK_DD(DUK_DDPRINT("aborting fast path"));
DUK_ERROR_INTERNAL(js_ctx->thr);
- return 0; /* unreachable */
+ DUK_WO_NORETURN(return 0;);
}
DUK_LOCAL duk_ret_t duk__json_stringify_fast(duk_hthread *thr, void *udata) {
@@ -36113,7 +36938,7 @@ void duk_bi_json_parse_helper(duk_hthread *thr,
(unsigned long) flags,
(long) duk_get_top(thr)));
- DUK_MEMZERO(&js_ctx_alloc, sizeof(js_ctx_alloc));
+ duk_memzero(&js_ctx_alloc, sizeof(js_ctx_alloc));
js_ctx->thr = thr;
#if defined(DUK_USE_EXPLICIT_NULL_INIT)
/* nothing now */
@@ -36223,7 +37048,7 @@ void duk_bi_json_stringify_helper(duk_hthread *thr,
* Context init
*/
- DUK_MEMZERO(&js_ctx_alloc, sizeof(js_ctx_alloc));
+ duk_memzero(&js_ctx_alloc, sizeof(js_ctx_alloc));
js_ctx->thr = thr;
#if defined(DUK_USE_EXPLICIT_NULL_INIT)
js_ctx->h_replacer = NULL;
@@ -36621,7 +37446,7 @@ DUK_LOCAL duk_ret_t duk__math_minmax(duk_hthread *thr, duk_double_t initial, duk
DUK_LOCAL double duk__fmin_fixed(double x, double y) {
/* fmin() with args -0 and +0 is not guaranteed to return
- * -0 as Ecmascript requires.
+ * -0 as ECMAScript requires.
*/
if (x == 0 && y == 0) {
duk_double_union du1, du2;
@@ -36648,7 +37473,7 @@ DUK_LOCAL double duk__fmin_fixed(double x, double y) {
DUK_LOCAL double duk__fmax_fixed(double x, double y) {
/* fmax() with args -0 and +0 is not guaranteed to return
- * +0 as Ecmascript requires.
+ * +0 as ECMAScript requires.
*/
if (x == 0 && y == 0) {
if (DUK_SIGNBIT(x) == 0 || DUK_SIGNBIT(y) == 0) {
@@ -37111,6 +37936,7 @@ DUK_LOCAL duk_double_t duk__push_this_number_plain(duk_hthread *thr) {
(DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_NUMBER)) {
DUK_DDD(DUK_DDDPRINT("unacceptable this value: %!T", (duk_tval *) duk_get_tval(thr, -1)));
DUK_ERROR_TYPE(thr, "number expected");
+ DUK_WO_NORETURN(return 0.0;);
}
duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);
DUK_ASSERT(duk_is_number(thr, -1));
@@ -37217,8 +38043,11 @@ DUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_fixed(duk_hthread *thr) {
duk_small_int_t c;
duk_small_uint_t n2s_flags;
- frac_digits = (duk_small_int_t) duk_to_int_check_range(thr, 0, 0, 20);
+ /* In ES5.1 frac_digits is coerced first; in ES2015 the 'this number
+ * value' check is done first.
+ */
d = duk__push_this_number_plain(thr);
+ frac_digits = (duk_small_int_t) duk_to_int_check_range(thr, 0, 0, 20);
c = (duk_small_int_t) DUK_FPCLASSIFY(d);
if (c == DUK_FP_NAN || c == DUK_FP_INFINITE) {
@@ -37325,6 +38154,42 @@ DUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_precision(duk_hthread *thr) {
return 1;
}
+/*
+ * ES2015 isFinite() etc
+ */
+
+#if defined(DUK_USE_ES6)
+DUK_INTERNAL duk_ret_t duk_bi_number_check_shared(duk_hthread *thr) {
+ duk_int_t magic;
+ duk_bool_t ret = 0;
+
+ if (duk_is_number(thr, 0)) {
+ duk_double_t d;
+
+ magic = duk_get_current_magic(thr);
+ d = duk_get_number(thr, 0);
+
+ switch (magic) {
+ case 0: /* isFinite() */
+ ret = duk_double_is_finite(d);
+ break;
+ case 1: /* isInteger() */
+ ret = duk_double_is_integer(d);
+ break;
+ case 2: /* isNaN() */
+ ret = duk_double_is_nan(d);
+ break;
+ default: /* isSafeInteger() */
+ DUK_ASSERT(magic == 3);
+ ret = duk_double_is_safe_integer(d);
+ }
+ }
+
+ duk_push_boolean(thr, ret);
+ return 1;
+}
+#endif /* DUK_USE_ES6 */
+
#endif /* DUK_USE_NUMBER_BUILTIN */
/*
* Object built-ins
@@ -37335,12 +38200,9 @@ DUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_precision(duk_hthread *thr) {
/* Needed even when Object built-in disabled. */
DUK_INTERNAL duk_ret_t duk_bi_object_prototype_to_string(duk_hthread *thr) {
duk_tval *tv;
+
tv = DUK_HTHREAD_THIS_PTR(thr);
- /* XXX: This is not entirely correct anymore; in ES2015 the
- * default lookup should use @@toStringTag to come up with
- * e.g. [object Symbol].
- */
- duk_push_class_string_tval(thr, tv);
+ duk_push_class_string_tval(thr, tv, 0 /*avoid_side_effects*/);
return 1;
}
@@ -37845,7 +38707,7 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_property(duk_hthread *th
DUK_ASSERT(duk_get_hobject(thr, 2) != NULL);
/*
- * Validate and convert argument property descriptor (an Ecmascript
+ * Validate and convert argument property descriptor (an ECMAScript
* object) into a set of defprop_flags and possibly property value,
* getter, and/or setter values on the value stack.
*
@@ -38123,6 +38985,7 @@ DUK_INTERNAL duk_ret_t duk_bi_object_prototype_lookupaccessor(duk_hthread *thr)
if (DUK_UNLIKELY(sanity-- == 0)) {
DUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);
+ DUK_WO_NORETURN(return 0;);
}
duk_get_prototype(thr, -1);
@@ -38247,37 +39110,37 @@ DUK_INTERNAL duk_ret_t duk_bi_pointer_prototype_tostring_shared(duk_hthread *thr
DUK_INTERNAL duk_ret_t duk_bi_promise_constructor(duk_hthread *thr) {
DUK_ERROR_TYPE(thr, "unimplemented");
- return 0;
+ DUK_WO_NORETURN(return 0;);
}
DUK_INTERNAL duk_ret_t duk_bi_promise_all(duk_hthread *thr) {
DUK_ERROR_TYPE(thr, "unimplemented");
- return 0;
+ DUK_WO_NORETURN(return 0;);
}
DUK_INTERNAL duk_ret_t duk_bi_promise_race(duk_hthread *thr) {
DUK_ERROR_TYPE(thr, "unimplemented");
- return 0;
+ DUK_WO_NORETURN(return 0;);
}
DUK_INTERNAL duk_ret_t duk_bi_promise_reject(duk_hthread *thr) {
DUK_ERROR_TYPE(thr, "unimplemented");
- return 0;
+ DUK_WO_NORETURN(return 0;);
}
DUK_INTERNAL duk_ret_t duk_bi_promise_resolve(duk_hthread *thr) {
DUK_ERROR_TYPE(thr, "unimplemented");
- return 0;
+ DUK_WO_NORETURN(return 0;);
}
DUK_INTERNAL duk_ret_t duk_bi_promise_catch(duk_hthread *thr) {
DUK_ERROR_TYPE(thr, "unimplemented");
- return 0;
+ DUK_WO_NORETURN(return 0;);
}
DUK_INTERNAL duk_ret_t duk_bi_promise_then(duk_hthread *thr) {
DUK_ERROR_TYPE(thr, "unimplemented");
- return 0;
+ DUK_WO_NORETURN(return 0;);
}
#endif /* DUK_USE_PROMISE_BUILTIN */
@@ -38311,6 +39174,7 @@ DUK_INTERNAL void duk_proxy_ownkeys_postprocess(duk_hthread *thr, duk_hobject *h
h = duk_get_hstring(thr, -1);
if (h == NULL) {
DUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr);
+ DUK_WO_NORETURN(return;);
}
if (!(flags & DUK_ENUM_INCLUDE_NONENUMERABLE)) {
@@ -38418,6 +39282,7 @@ DUK_INTERNAL duk_ret_t duk_bi_reflect_object_get(duk_hthread *thr) {
if (nargs >= 3 && !duk_strict_equals(thr, 0, 2)) {
/* XXX: [[Get]] receiver currently unsupported */
DUK_ERROR_UNSUPPORTED(thr);
+ DUK_WO_NORETURN(return 0;);
}
/* [ target key receiver? ...? ] */
@@ -38461,6 +39326,7 @@ DUK_INTERNAL duk_ret_t duk_bi_reflect_object_set(duk_hthread *thr) {
if (nargs >= 4 && !duk_strict_equals(thr, 0, 3)) {
/* XXX: [[Set]] receiver currently unsupported */
DUK_ERROR_UNSUPPORTED(thr);
+ DUK_WO_NORETURN(return 0;);
}
/* [ target key value receiver? ...? ] */
@@ -38594,7 +39460,7 @@ DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_tostring(duk_hthread *thr) {
/* This must be generic in ES2015 and later. */
DUK_ASSERT_TOP(thr, 0);
duk_push_this(thr);
- duk_push_string(thr, "/");
+ duk_push_literal(thr, "/");
duk_get_prop_stridx(thr, 0, DUK_STRIDX_SOURCE);
duk_dup_m2(thr); /* another "/" */
duk_get_prop_stridx(thr, 0, DUK_STRIDX_FLAGS);
@@ -38658,7 +39524,7 @@ DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_shared_getter(duk_hthread *thr) {
if (magic != 16 /* .source */) {
return 0;
}
- duk_push_string(thr, "(?:)"); /* .source handled by switch-case */
+ duk_push_literal(thr, "(?:)"); /* .source handled by switch-case */
re_flags = 0;
} else {
DUK_DCERROR_TYPE_INVALID_ARGS(thr);
@@ -38729,6 +39595,7 @@ DUK_LOCAL duk_hstring *duk__str_tostring_notregexp(duk_hthread *thr, duk_idx_t i
if (duk_get_class_number(thr, idx) == DUK_HOBJECT_CLASS_REGEXP) {
DUK_ERROR_TYPE_INVALID_ARGS(thr);
+ DUK_WO_NORETURN(return NULL;);
}
h = duk_to_hstring(thr, idx);
DUK_ASSERT(h != NULL);
@@ -38775,14 +39642,14 @@ DUK_LOCAL duk_int_t duk__str_search_shared(duk_hthread *thr, duk_hstring *h_this
while (p <= p_end && p >= p_start) {
t = *p;
- /* For Ecmascript strings, this check can only match for
+ /* For ECMAScript strings, this check can only match for
* initial UTF-8 bytes (not continuation bytes). For other
* strings all bets are off.
*/
if ((t == firstbyte) && ((duk_size_t) (p_end - p) >= (duk_size_t) q_blen)) {
- DUK_ASSERT(q_blen > 0); /* no issues with memcmp() zero size, even if broken */
- if (DUK_MEMCMP((const void *) p, (const void *) q_start, (size_t) q_blen) == 0) {
+ DUK_ASSERT(q_blen > 0);
+ if (duk_memcmp((const void *) p, (const void *) q_start, (size_t) q_blen) == 0) {
return cpos;
}
}
@@ -38964,13 +39831,37 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_to_string(duk_hthread *thr) {
*/
DUK_INTERNAL duk_ret_t duk_bi_string_prototype_char_at(duk_hthread *thr) {
+ duk_hstring *h;
duk_int_t pos;
/* XXX: faster implementation */
- (void) duk_push_this_coercible_to_string(thr);
+ h = duk_push_this_coercible_to_string(thr);
+ DUK_ASSERT(h != NULL);
+
pos = duk_to_int(thr, 0);
- duk_substring(thr, -1, (duk_size_t) pos, (duk_size_t) (pos + 1));
+
+ if (sizeof(duk_size_t) >= sizeof(duk_uint_t)) {
+ /* Cast to duk_size_t works in this case:
+ * - If pos < 0, (duk_size_t) pos will always be
+ * >= max_charlen, and result will be the empty string
+ * (see duk_substring()).
+ * - If pos >= 0, pos + 1 cannot wrap.
+ */
+ DUK_ASSERT((duk_size_t) DUK_INT_MIN >= DUK_HSTRING_MAX_BYTELEN);
+ DUK_ASSERT((duk_size_t) DUK_INT_MAX + 1U > (duk_size_t) DUK_INT_MAX);
+ duk_substring(thr, -1, (duk_size_t) pos, (duk_size_t) pos + 1U);
+ } else {
+ /* If size_t is smaller than int, explicit bounds checks
+ * are needed because an int may wrap multiple times.
+ */
+ if (DUK_UNLIKELY(pos < 0 || (duk_uint_t) pos >= (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h))) {
+ duk_push_hstring_empty(thr);
+ } else {
+ duk_substring(thr, -1, (duk_size_t) pos, (duk_size_t) pos + 1U);
+ }
+ }
+
return 1;
}
@@ -39360,7 +40251,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_hthread *thr) {
while (p <= p_end) {
DUK_ASSERT(p + q_blen <= DUK_HSTRING_GET_DATA(h_input) + DUK_HSTRING_GET_BYTELEN(h_input));
- if (DUK_MEMCMP((const void *) p, (const void *) q_start, (size_t) q_blen) == 0) {
+ if (duk_memcmp((const void *) p, (const void *) q_start, (size_t) q_blen) == 0) {
duk_dup_0(thr);
h_match = duk_known_hstring(thr, -1);
#if defined(DUK_USE_REGEXP_SUPPORT)
@@ -39741,7 +40632,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_split(duk_hthread *thr) {
while (p <= p_end) {
DUK_ASSERT(p + q_blen <= DUK_HSTRING_GET_DATA(h_input) + DUK_HSTRING_GET_BYTELEN(h_input));
DUK_ASSERT(q_blen > 0); /* no issues with empty memcmp() */
- if (DUK_MEMCMP((const void *) p, (const void *) q_start, (size_t) q_blen) == 0) {
+ if (duk_memcmp((const void *) p, (const void *) q_start, (size_t) q_blen) == 0) {
/* never an empty match, so step 13.c.iii can't be triggered */
goto found;
}
@@ -40054,12 +40945,14 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_repeat(duk_hthread *thr) {
/* Temporary fixed buffer, later converted to string. */
buf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, result_len);
+ DUK_ASSERT(buf != NULL);
src = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input);
+ DUK_ASSERT(src != NULL);
#if defined(DUK_USE_PREFER_SIZE)
p = buf;
while (count-- > 0) {
- DUK_MEMCPY((void *) p, (const void *) src, input_blen); /* copy size may be zero */
+ duk_memcpy((void *) p, (const void *) src, input_blen); /* copy size may be zero, but pointers are valid */
p += input_blen;
}
#else /* DUK_USE_PREFER_SIZE */
@@ -40076,12 +40969,12 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_repeat(duk_hthread *thr) {
(long) result_len));
if (remain <= copy_size) {
/* If result_len is zero, this case is taken and does
- * a zero size copy.
+ * a zero size copy (with valid pointers).
*/
- DUK_MEMCPY((void *) p, (const void *) src, remain);
+ duk_memcpy((void *) p, (const void *) src, remain);
break;
} else {
- DUK_MEMCPY((void *) p, (const void *) src, copy_size);
+ duk_memcpy((void *) p, (const void *) src, copy_size);
p += copy_size;
}
@@ -40136,8 +41029,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_locale_compare(duk_hthread *thr)
h2_len = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h2);
prefix_len = (h1_len <= h2_len ? h1_len : h2_len);
- /* Zero size compare not an issue with DUK_MEMCMP. */
- rc = (duk_small_int_t) DUK_MEMCMP((const void *) DUK_HSTRING_GET_DATA(h1),
+ rc = (duk_small_int_t) duk_memcmp((const void *) DUK_HSTRING_GET_DATA(h1),
(const void *) DUK_HSTRING_GET_DATA(h2),
(size_t) prefix_len);
@@ -40187,7 +41079,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_startswith_endswith(duk_hthread *
if (duk_is_undefined(thr, 1)) {
if (magic) {
- p_cmp_start += DUK_HSTRING_GET_BYTELEN(h) - blen_search;
+ p_cmp_start = p_cmp_start + DUK_HSTRING_GET_BYTELEN(h) - blen_search;
} else {
/* p_cmp_start already OK */
}
@@ -40218,7 +41110,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_startswith_endswith(duk_hthread *
result = 0;
if (p_cmp_start >= DUK_HSTRING_GET_DATA(h) &&
(duk_size_t) (p_cmp_start - (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h)) + blen_search <= DUK_HSTRING_GET_BYTELEN(h)) {
- if (DUK_MEMCMP((const void *) p_cmp_start,
+ if (duk_memcmp((const void *) p_cmp_start,
(const void *) DUK_HSTRING_GET_DATA(h_search),
(size_t) blen_search) == 0) {
result = 1;
@@ -40292,9 +41184,10 @@ DUK_INTERNAL duk_ret_t duk_bi_symbol_constructor_shared(duk_hthread *thr) {
* +1 0xff after unique suffix for symbols with undefined description
*/
buf = (duk_uint8_t *) duk_push_fixed_buffer(thr, 1 + len + 1 + 17 + 1);
+ DUK_ASSERT(buf != NULL);
p = buf + 1;
DUK_ASSERT(desc != NULL || len == 0); /* may be NULL if len is 0 */
- DUK_MEMCPY((void *) p, (const void *) desc, len);
+ duk_memcpy_unsafe((void *) p, (const void *) desc, len);
p += len;
if (magic == 0) {
/* Symbol(): create unique symbol. Use two 32-bit values
@@ -40465,7 +41358,7 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_constructor(duk_hthread *thr) {
*
* The thread must be in resumable state, either (a) new thread which hasn't
* yet started, or (b) a thread which has previously yielded. This method
- * must be called from an Ecmascript function.
+ * must be called from an ECMAScript function.
*
* Args:
* - thread
@@ -40491,8 +41384,9 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_resume(duk_hthread *ctx) {
DUK_ASSERT(thr->heap->curr_thread == thr);
thr_resume = duk_require_hthread(thr, 0);
- is_error = (duk_small_uint_t) duk_to_boolean(thr, 2);
- duk_set_top(thr, 2);
+ DUK_ASSERT(duk_get_top(thr) == 3);
+ is_error = (duk_small_uint_t) duk_to_boolean_top_pop(thr);
+ DUK_ASSERT(duk_get_top(thr) == 2);
/* [ thread value ] */
@@ -40512,7 +41406,7 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_resume(duk_hthread *ctx) {
caller_func = DUK_ACT_GET_FUNC(thr->callstack_curr->parent);
if (!DUK_HOBJECT_IS_COMPFUNC(caller_func)) {
- DUK_DD(DUK_DDPRINT("resume state invalid: caller must be Ecmascript code"));
+ DUK_DD(DUK_DDPRINT("resume state invalid: caller must be ECMAScript code"));
goto state_error;
}
@@ -40540,7 +41434,7 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_resume(duk_hthread *ctx) {
DUK_ASSERT(thr_resume->state == DUK_HTHREAD_STATE_INACTIVE);
- /* The initial function must be an Ecmascript function (but
+ /* The initial function must be an ECMAScript function (but
* can be bound). We must make sure of that before we longjmp
* because an error in the RESUME handler call processing will
* not be handled very cleanly.
@@ -40619,7 +41513,7 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_resume(duk_hthread *ctx) {
* The thread must be in yieldable state: it must have a resumer, and there
* must not be any yield-preventing calls (native calls and constructor calls,
* currently) in the thread's call stack (otherwise a resume would not be
- * possible later). This method must be called from an Ecmascript function.
+ * possible later). This method must be called from an ECMAScript function.
*
* Args:
* - value
@@ -40640,8 +41534,9 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_yield(duk_hthread *thr) {
DUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);
DUK_ASSERT(thr->heap->curr_thread == thr);
- is_error = (duk_small_uint_t) duk_to_boolean(thr, 1);
- duk_set_top(thr, 1);
+ DUK_ASSERT(duk_get_top(thr) == 2);
+ is_error = (duk_small_uint_t) duk_to_boolean_top_pop(thr);
+ DUK_ASSERT(duk_get_top(thr) == 1);
/* [ value ] */
@@ -40667,7 +41562,7 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_yield(duk_hthread *thr) {
caller_func = DUK_ACT_GET_FUNC(thr->callstack_curr->parent);
if (!DUK_HOBJECT_IS_COMPFUNC(caller_func)) {
- DUK_DD(DUK_DDPRINT("yield state invalid: caller must be Ecmascript code"));
+ DUK_DD(DUK_DDPRINT("yield state invalid: caller must be ECMAScript code"));
goto state_error;
}
@@ -40764,7 +41659,7 @@ DUK_INTERNAL void duk_fb_put_bytes(duk_fixedbuffer *fb, const duk_uint8_t *buffe
} else {
copylen = length;
}
- DUK_MEMCPY(fb->buffer + fb->offset, buffer, copylen);
+ duk_memcpy_unsafe(fb->buffer + fb->offset, buffer, copylen);
fb->offset += copylen;
}
@@ -40850,7 +41745,7 @@ DUK_INTERNAL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb) {
* (excluding the null terminator). If retval == buffer size,
* output was truncated (except for corner cases).
*
- * * Output format is intentionally different from Ecmascript
+ * * Output format is intentionally different from ECMAScript
* formatting requirements, as formatting here serves debugging
* of internals.
*
@@ -41636,7 +42531,7 @@ DUK_INTERNAL duk_int_t duk_debug_vsnprintf(char *str, duk_size_t size, const cha
const char *p_end = p + DUK_STRLEN(format);
duk_int_t retval;
- DUK_MEMZERO(&fb, sizeof(fb));
+ duk_memzero(&fb, sizeof(fb));
fb.buffer = (duk_uint8_t *) str;
fb.length = size;
fb.offset = 0;
@@ -41661,7 +42556,7 @@ DUK_INTERNAL duk_int_t duk_debug_vsnprintf(char *str, duk_size_t size, const cha
* understand. See man 3 printf.
*/
- DUK_MEMZERO(&st, sizeof(st));
+ duk_memzero(&st, sizeof(st));
st.fb = &fb;
st.depth = 0;
st.depth_limit = 1;
@@ -41728,8 +42623,8 @@ DUK_INTERNAL duk_int_t duk_debug_vsnprintf(char *str, duk_size_t size, const cha
/* format is too large, abort */
goto format_error;
}
- DUK_MEMZERO(fmtbuf, sizeof(fmtbuf));
- DUK_MEMCPY(fmtbuf, p_begfmt, fmtlen);
+ duk_memzero(fmtbuf, sizeof(fmtbuf));
+ duk_memcpy(fmtbuf, p_begfmt, fmtlen);
/* assume exactly 1 arg, which is why '*' is forbidden; arg size still
* depends on type though.
@@ -41834,7 +42729,8 @@ DUK_INTERNAL void duk_debug_format_funcptr(char *buf, duk_size_t buf_size, duk_u
duk_uint8_t *p = (duk_uint8_t *) buf;
duk_uint8_t *p_end = (duk_uint8_t *) (buf + buf_size - 1);
- DUK_MEMZERO(buf, buf_size);
+ DUK_ASSERT(buf != NULL);
+ duk_memzero(buf, buf_size);
for (i = 0; i < fptr_size; i++) {
duk_int_t left = (duk_int_t) (p_end - p);
@@ -42172,6 +43068,7 @@ DUK_INTERNAL void duk_debug_read_bytes(duk_hthread *thr, duk_uint8_t *data, duk_
DUK_ASSERT(thr != NULL);
heap = thr->heap;
DUK_ASSERT(heap != NULL);
+ DUK_ASSERT(data != NULL);
if (heap->dbg_read_cb == NULL) {
DUK_D(DUK_DPRINT("attempt to read %ld bytes in detached state, return zero data", (long) length));
@@ -42209,7 +43106,7 @@ DUK_INTERNAL void duk_debug_read_bytes(duk_hthread *thr, duk_uint8_t *data, duk_
return;
fail:
- DUK_MEMZERO((void *) data, (size_t) length);
+ duk_memzero((void *) data, (size_t) length);
}
DUK_INTERNAL duk_uint8_t duk_debug_read_byte(duk_hthread *thr) {
@@ -42822,7 +43719,7 @@ DUK_INTERNAL void duk_debug_write_tval(duk_hthread *thr, duk_tval *tv) {
(unsigned int) du2.uc[4], (unsigned int) du2.uc[5],
(unsigned int) du2.uc[6], (unsigned int) du2.uc[7]));
- if (DUK_MEMCMP((const void *) du1.uc, (const void *) du2.uc, sizeof(du1.uc)) == 0) {
+ if (duk_memcmp((const void *) du1.uc, (const void *) du2.uc, sizeof(du1.uc)) == 0) {
duk_debug_write_int(thr, i32);
} else {
DUK_DBLUNION_DOUBLE_HTON(&du1);
@@ -42931,9 +43828,9 @@ DUK_INTERNAL void duk_debug_send_status(duk_hthread *thr) {
duk_debug_write_int(thr, 0);
} else {
duk_push_tval(thr, &act->tv_func);
- duk_get_prop_string(thr, -1, "fileName");
+ duk_get_prop_literal(thr, -1, "fileName");
duk__debug_write_hstring_safe_top(thr);
- duk_get_prop_string(thr, -2, "name");
+ duk_get_prop_literal(thr, -2, "name");
duk__debug_write_hstring_safe_top(thr);
duk_pop_3(thr);
/* Report next pc/line to be executed. */
@@ -42978,7 +43875,7 @@ DUK_INTERNAL void duk_debug_send_throw(duk_hthread *thr, duk_bool_t fatal) {
act = thr->callstack_curr;
if (act != NULL) {
duk_push_tval(thr, &act->tv_func);
- duk_get_prop_string(thr, -1, "fileName");
+ duk_get_prop_literal(thr, -1, "fileName");
duk__debug_write_hstring_safe_top(thr);
pc = (duk_uint32_t) duk_hthread_get_act_prev_pc(thr, act);
duk_debug_write_uint(thr, (duk_uint32_t) duk_hobject_pc2line_query(thr, -2, pc));
@@ -43455,7 +44352,7 @@ DUK_LOCAL void duk__debug_handle_eval(duk_hthread *thr, duk_heap *heap) {
fun = DUK_ACT_GET_FUNC(act);
if (fun != NULL && DUK_HOBJECT_IS_COMPFUNC(fun)) {
/* Direct eval requires that there's a current
- * activation and it is an Ecmascript function.
+ * activation and it is an ECMAScript function.
* When Eval is executed from e.g. cooperate API
* call we'll need to do an indirect eval instead.
*/
@@ -44121,7 +45018,7 @@ DUK_LOCAL void duk__debug_handle_get_heap_obj_info(duk_hthread *thr, duk_heap *h
if (DUK_HOBJECT_IS_BOUNDFUNC(h_obj)) {
duk_hboundfunc *h_bfun;
- h_bfun = (duk_hboundfunc *) h_obj;
+ h_bfun = (duk_hboundfunc *) (void *) h_obj;
duk__debug_getinfo_flags_key(thr, "target");
duk_debug_write_tval(thr, &h_bfun->target);
@@ -44598,7 +45495,7 @@ DUK_INTERNAL void duk_debug_halt_execution(duk_hthread *thr, duk_bool_t use_prev
fun = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);
/* Short circuit if is safe: if act->curr_pc != NULL, 'fun' is
- * guaranteed to be a non-NULL Ecmascript function.
+ * guaranteed to be a non-NULL ECMAScript function.
*/
DUK_ASSERT(act->curr_pc == NULL ||
(fun != NULL && DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) fun)));
@@ -44694,11 +45591,10 @@ DUK_INTERNAL duk_bool_t duk_debug_remove_breakpoint(duk_hthread *thr, duk_small_
DUK_ASSERT(h != NULL);
move_size = sizeof(duk_breakpoint) * (heap->dbg_breakpoint_count - breakpoint_index - 1);
- if (move_size > 0) {
- DUK_MEMMOVE((void *) b,
- (const void *) (b + 1),
- (size_t) move_size);
- }
+ duk_memmove((void *) b,
+ (const void *) (b + 1),
+ (size_t) move_size);
+
heap->dbg_breakpoint_count--;
heap->dbg_breakpoints_active[0] = (duk_breakpoint *) NULL;
@@ -44784,7 +45680,7 @@ DUK_INTERNAL void duk_debug_clear_pause_state(duk_heap *heap) {
*
* Error augmentation may throw an internal error (e.g. alloc error).
*
- * Ecmascript allows throwing any values, so all values cannot be
+ * ECMAScript allows throwing any values, so all values cannot be
* augmented. Currently, the built-in augmentation at error creation
* only augments error values which are Error instances (= have the
* built-in Error.prototype in their prototype chain) and are also
@@ -45124,7 +46020,6 @@ DUK_LOCAL void duk__add_fileline(duk_hthread *thr, duk_hthread *thr_callstack, c
DUK_UNREF(pc);
DUK_ASSERT_DISABLE(pc >= 0); /* unsigned */
DUK_ASSERT((duk_double_t) pc < DUK_DOUBLE_2TO32); /* assume PC is at most 32 bits and non-negative */
- act = NULL; /* invalidated by pushes, so get out of the way */
duk_push_hobject(thr, func);
@@ -45339,12 +46234,15 @@ DUK_INTERNAL void duk_err_augment_error_throw(duk_hthread *thr) {
/* #include duk_internal.h -> already included */
#if defined(DUK_USE_PREFER_SIZE)
+DUK_NORETURN(DUK_LOCAL_DECL void duk__uncaught_minimal(duk_hthread *thr));
DUK_LOCAL void duk__uncaught_minimal(duk_hthread *thr) {
(void) duk_fatal(thr, "uncaught error");
+ DUK_WO_NORETURN(return;);
}
#endif
#if 0
+DUK_NORETURN(DUK_LOCAL_DECL void duk__uncaught_readable(duk_hthread *thr));
DUK_LOCAL void duk__uncaught_readable(duk_hthread *thr) {
const char *summary;
char buf[DUK_USE_FATAL_MAXLEN];
@@ -45353,10 +46251,12 @@ DUK_LOCAL void duk__uncaught_readable(duk_hthread *thr) {
DUK_SNPRINTF(buf, sizeof(buf), "uncaught: %s", summary);
buf[sizeof(buf) - 1] = (char) 0;
(void) duk_fatal(thr, (const char *) buf);
+ DUK_WO_NORETURN(return;);
}
#endif
#if !defined(DUK_USE_PREFER_SIZE)
+DUK_NORETURN(DUK_LOCAL_DECL void duk__uncaught_error_aware(duk_hthread *thr));
DUK_LOCAL void duk__uncaught_error_aware(duk_hthread *thr) {
const char *summary;
char buf[DUK_USE_FATAL_MAXLEN];
@@ -45366,6 +46266,7 @@ DUK_LOCAL void duk__uncaught_error_aware(duk_hthread *thr) {
DUK_SNPRINTF(buf, sizeof(buf), "uncaught: %s", summary);
buf[sizeof(buf) - 1] = (char) 0;
(void) duk_fatal(thr, (const char *) buf);
+ DUK_WO_NORETURN(return;);
}
#endif
@@ -45403,14 +46304,9 @@ DUK_INTERNAL void duk_err_longjmp(duk_hthread *thr) {
DUK_DD(DUK_DDPRINT("about to longjmp, pf_prevent_count=%ld", (long) thr->heap->pf_prevent_count));
-#if !defined(DUK_USE_CPP_EXCEPTIONS)
/* If we don't have a jmpbuf_ptr, there is little we can do except
* cause a fatal error. The caller's expectation is that we never
* return.
- *
- * With C++ exceptions we now just propagate an uncaught error
- * instead of invoking the fatal error handler. Because there's
- * a dummy jmpbuf for C++ exceptions now, this could be changed.
*/
if (!thr->heap->lj.jmpbuf_ptr) {
DUK_D(DUK_DPRINT("uncaught error: type=%d iserror=%d value1=%!T value2=%!T",
@@ -45424,16 +46320,12 @@ DUK_INTERNAL void duk_err_longjmp(duk_hthread *thr) {
#endif
DUK_UNREACHABLE();
}
-#endif /* DUK_USE_CPP_EXCEPTIONS */
#if defined(DUK_USE_CPP_EXCEPTIONS)
- {
- duk_internal_exception exc; /* dummy */
- throw exc;
- }
-#else /* DUK_USE_CPP_EXCEPTIONS */
+ throw duk_internal_exception(); /* dummy */
+#else
DUK_LONGJMP(thr->heap->lj.jmpbuf_ptr->jb);
-#endif /* DUK_USE_CPP_EXCEPTIONS */
+#endif
DUK_UNREACHABLE();
}
@@ -45612,10 +46504,10 @@ DUK_INTERNAL void duk_err_setup_ljstate1(duk_hthread *thr, duk_small_uint_t lj_t
DUK_ASSERT_LJSTATE_SET(heap);
}
/*
- * Create and throw an Ecmascript error object based on a code and a message.
+ * Create and throw an ECMAScript error object based on a code and a message.
*
- * Used when we throw errors internally. Ecmascript generated error objects
- * are created by Ecmascript code, and the throwing is handled by the bytecode
+ * Used when we throw errors internally. ECMAScript generated error objects
+ * are created by ECMAScript code, and the throwing is handled by the bytecode
* executor.
*/
@@ -45771,7 +46663,7 @@ DUK_INTERNAL void duk_error_throw_from_negative_rc(duk_hthread *thr, duk_ret_t r
*/
duk_error_raw(thr, -rc, NULL, 0, "error (rc %ld)", (long) rc);
- DUK_UNREACHABLE();
+ DUK_WO_NORETURN(return;);
}
/*
* duk_hbuffer allocation and freeing.
@@ -45822,10 +46714,10 @@ DUK_INTERNAL duk_hbuffer *duk_hbuffer_alloc(duk_heap *heap, duk_size_t size, duk
/* zero everything unless requested not to do so */
#if defined(DUK_USE_ZERO_BUFFER_DATA)
- DUK_MEMZERO((void *) res,
+ duk_memzero((void *) res,
(flags & DUK_BUF_FLAG_NOZERO) ? header_size : alloc_size);
#else
- DUK_MEMZERO((void *) res, header_size);
+ duk_memzero((void *) res, header_size);
#endif
if (flags & DUK_BUF_FLAG_EXTERNAL) {
@@ -45872,7 +46764,7 @@ DUK_INTERNAL duk_hbuffer *duk_hbuffer_alloc(duk_heap *heap, duk_size_t size, duk
DUK_ASSERT(DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, h) == NULL);
}
} else {
- *out_bufdata = (void *) ((duk_hbuffer_fixed *) res + 1);
+ *out_bufdata = (void *) ((duk_hbuffer_fixed *) (void *) res + 1);
}
DUK_HBUFFER_SET_SIZE(res, size);
@@ -45931,6 +46823,7 @@ DUK_INTERNAL void duk_hbuffer_resize(duk_hthread *thr, duk_hbuffer_dynamic *buf,
if (new_size > DUK_HBUFFER_MAX_BYTELEN) {
DUK_ERROR_RANGE(thr, "buffer too long");
+ DUK_WO_NORETURN(return;);
}
/*
@@ -45959,7 +46852,7 @@ DUK_INTERNAL void duk_hbuffer_resize(duk_hthread *thr, duk_hbuffer_dynamic *buf,
if (new_size > prev_size) {
DUK_ASSERT(new_size - prev_size > 0);
#if defined(DUK_USE_ZERO_BUFFER_DATA)
- DUK_MEMZERO((void *) ((char *) res + prev_size),
+ duk_memzero((void *) ((char *) res + prev_size),
(duk_size_t) (new_size - prev_size));
#endif
}
@@ -45968,6 +46861,7 @@ DUK_INTERNAL void duk_hbuffer_resize(duk_hthread *thr, duk_hbuffer_dynamic *buf,
DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(thr->heap, buf, res);
} else {
DUK_ERROR_ALLOC_FAILED(thr);
+ DUK_WO_NORETURN(return;);
}
DUK_ASSERT(res != NULL || new_size == 0);
@@ -46069,7 +46963,7 @@ DUK_INTERNAL void duk_free_hobject(duk_heap *heap, duk_hobject *h) {
* functions in the callstack.
*/
} else if (DUK_HOBJECT_IS_BOUNDFUNC(h)) {
- duk_hboundfunc *f = (duk_hboundfunc *) h;
+ duk_hboundfunc *f = (duk_hboundfunc *) (void *) h;
DUK_FREE(heap, f->args);
}
@@ -46467,7 +47361,7 @@ DUK_LOCAL duk_bool_t duk__init_heap_strings(duk_heap *heap) {
duk_bitdecoder_ctx *bd = &bd_ctx; /* convenience */
duk_small_uint_t i;
- DUK_MEMZERO(&bd_ctx, sizeof(bd_ctx));
+ duk_memzero(&bd_ctx, sizeof(bd_ctx));
bd->data = (const duk_uint8_t *) duk_strings_data;
bd->length = (duk_size_t) DUK_STRDATA_DATA_LENGTH;
@@ -46688,7 +47582,8 @@ DUK_LOCAL void duk__dump_type_sizes(void) {
DUK__DUMPSZ(duk_heap);
DUK__DUMPSZ(duk_activation);
DUK__DUMPSZ(duk_catcher);
- DUK__DUMPSZ(duk_strcache);
+ DUK__DUMPSZ(duk_strcache_entry);
+ DUK__DUMPSZ(duk_litcache_entry);
DUK__DUMPSZ(duk_ljstate);
DUK__DUMPSZ(duk_fixedbuffer);
DUK__DUMPSZ(duk_bitdecoder_ctx);
@@ -46897,7 +47792,7 @@ duk_heap *duk_heap_alloc(duk_alloc_function alloc_func,
* Zero the struct, and start initializing roughly in order
*/
- DUK_MEMZERO(res, sizeof(*res));
+ duk_memzero(res, sizeof(*res));
#if defined(DUK_USE_ASSERTIONS)
res->heap_initializing = 1;
#endif
@@ -46982,7 +47877,7 @@ duk_heap *duk_heap_alloc(duk_alloc_function alloc_func,
/* XXX: use the pointer as a seed for now: mix in time at least */
- /* The casts through duk_intptr_t is to avoid the following GCC warning:
+ /* The casts through duk_uintptr_t is to avoid the following GCC warning:
*
* warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
*
@@ -46993,7 +47888,7 @@ duk_heap *duk_heap_alloc(duk_alloc_function alloc_func,
DUK_D(DUK_DPRINT("using rom strings, force heap hash_seed to fixed value 0x%08lx", (long) DUK__FIXED_HASH_SEED));
res->hash_seed = (duk_uint32_t) DUK__FIXED_HASH_SEED;
#else /* DUK_USE_ROM_STRINGS */
- res->hash_seed = (duk_uint32_t) (duk_intptr_t) res;
+ res->hash_seed = (duk_uint32_t) (duk_uintptr_t) res;
#if !defined(DUK_USE_STRHASH_DENSE)
res->hash_seed ^= 5381; /* Bernstein hash init value is normally 5381; XOR it in in case pointer low bits are 0 */
#endif
@@ -47033,17 +47928,17 @@ duk_heap *duk_heap_alloc(duk_alloc_function alloc_func,
#if defined(DUK_USE_STRTAB_PTRCOMP)
/* zero assumption */
- DUK_MEMZERO(res->strtable16, sizeof(duk_uint16_t) * st_initsize);
+ duk_memzero(res->strtable16, sizeof(duk_uint16_t) * st_initsize);
#else
#if defined(DUK_USE_EXPLICIT_NULL_INIT)
{
- duk_small_uint_t i;
+ duk_uint32_t i;
for (i = 0; i < st_initsize; i++) {
res->strtable[i] = NULL;
}
}
#else
- DUK_MEMZERO(res->strtable, sizeof(duk_hstring *) * st_initsize);
+ duk_memzero(res->strtable, sizeof(duk_hstring *) * st_initsize);
#endif /* DUK_USE_EXPLICIT_NULL_INIT */
#endif /* DUK_USE_STRTAB_PTRCOMP */
@@ -47053,13 +47948,30 @@ duk_heap *duk_heap_alloc(duk_alloc_function alloc_func,
#if defined(DUK_USE_EXPLICIT_NULL_INIT)
{
- duk_small_uint_t i;
+ duk_uint_t i;
for (i = 0; i < DUK_HEAP_STRCACHE_SIZE; i++) {
res->strcache[i].h = NULL;
}
}
#endif
+ /*
+ * Init litcache
+ */
+#if defined(DUK_USE_LITCACHE_SIZE)
+ DUK_ASSERT(DUK_USE_LITCACHE_SIZE > 0);
+ DUK_ASSERT(DUK_IS_POWER_OF_TWO((duk_uint_t) DUK_USE_LITCACHE_SIZE));
+#if defined(DUK_USE_EXPLICIT_NULL_INIT)
+ {
+ duk_uint_t i;
+ for (i = 0; i < DUK_USE_LITCACHE_SIZE; i++) {
+ res->litcache[i].addr = NULL;
+ res->litcache[i].h = NULL;
+ }
+ }
+#endif
+#endif /* DUK_USE_LITCACHE_SIZE */
+
/* XXX: error handling is incomplete. It would be cleanest if
* there was a setjmp catchpoint, so that all init code could
* freely throw errors. If that were the case, the return code
@@ -47131,7 +48043,7 @@ duk_heap *duk_heap_alloc(duk_alloc_function alloc_func,
{
duk_uint64_t tmp_u64;
tmp_u64 = 0;
- DUK_MEMCPY((void *) &tmp_u64,
+ duk_memcpy((void *) &tmp_u64,
(const void *) &res,
(size_t) (sizeof(void *) >= sizeof(duk_uint64_t) ? sizeof(duk_uint64_t) : sizeof(void *)));
res->rnd_state[1] ^= tmp_u64;
@@ -47886,7 +48798,7 @@ DUK_LOCAL void duk__mark_hobject(duk_heap *heap, duk_hobject *h) {
duk__mark_heaphdr(heap, (duk_heaphdr *) b->buf_prop);
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
} else if (DUK_HOBJECT_IS_BOUNDFUNC(h)) {
- duk_hboundfunc *f = (duk_hboundfunc *) h;
+ duk_hboundfunc *f = (duk_hboundfunc *) (void *) h;
DUK_ASSERT_HBOUNDFUNC_VALID(f);
duk__mark_tval(heap, &f->target);
duk__mark_tval(heap, &f->this_binding);
@@ -48360,7 +49272,8 @@ DUK_LOCAL void duk__sweep_stringtable(duk_heap *heap, duk_size_t *out_count_keep
duk_hstring *next;
next = h->hdr.h_next;
- if (DUK_HEAPHDR_HAS_REACHABLE((duk_heaphdr *) h)) {
+ if (DUK_HEAPHDR_HAS_REACHABLE((duk_heaphdr *) h))
+ {
DUK_HEAPHDR_CLEAR_REACHABLE((duk_heaphdr *) h);
count_keep++;
prev = h;
@@ -48369,13 +49282,26 @@ DUK_LOCAL void duk__sweep_stringtable(duk_heap *heap, duk_size_t *out_count_keep
count_free++;
#endif
+ /* For pinned strings the refcount has been
+ * bumped. We could unbump it here before
+ * freeing, but that's actually not necessary
+ * except for assertions.
+ */
+#if 0
+ if (DUK_HSTRING_HAS_PINNED_LITERAL(h)) {
+ DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h) > 0U);
+ DUK_HSTRING_DECREF_NORZ(heap->heap_thread, h);
+ DUK_HSTRING_CLEAR_PINNED_LITERAL(h);
+ }
+#endif
#if defined(DUK_USE_REFERENCE_COUNTING)
/* Non-zero refcounts should not happen for unreachable strings,
* because we refcount finalize all unreachable objects which
* should have decreased unreachable string refcounts to zero
- * (even for cycles).
+ * (even for cycles). However, pinned strings have a +1 bump.
*/
- DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h) == 0);
+ DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h) ==
+ DUK_HSTRING_HAS_PINNED_LITERAL(h) ? 1U : 0U);
#endif
/* Deal with weak references first. */
@@ -48579,6 +49505,26 @@ DUK_LOCAL void duk__sweep_heap(duk_heap *heap, duk_small_uint_t flags, duk_size_
}
/*
+ * Litcache helpers.
+ */
+
+#if defined(DUK_USE_LITCACHE_SIZE)
+DUK_LOCAL void duk__wipe_litcache(duk_heap *heap) {
+ duk_uint_t i;
+ duk_litcache_entry *e;
+
+ e = heap->litcache;
+ for (i = 0; i < DUK_USE_LITCACHE_SIZE; i++) {
+ e->addr = NULL;
+ /* e->h does not need to be invalidated: when e->addr is
+ * NULL, e->h is considered garbage.
+ */
+ e++;
+ }
+}
+#endif /* DUK_USE_LITCACHE_SIZE */
+
+/*
* Object compaction.
*
* Compaction is assumed to never throw an error.
@@ -48762,6 +49708,7 @@ DUK_LOCAL void duk__clear_assert_refcounts(duk_heap *heap) {
DUK_LOCAL void duk__check_refcount_heaphdr(duk_heaphdr *hdr) {
duk_bool_t count_ok;
+ duk_size_t expect_refc;
/* The refcount check only makes sense for reachable objects on
* heap_allocated or string table, after the sweep phase. Prior to
@@ -48778,7 +49725,11 @@ DUK_LOCAL void duk__check_refcount_heaphdr(duk_heaphdr *hdr) {
*/
DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(hdr));
- count_ok = ((duk_size_t) DUK_HEAPHDR_GET_REFCOUNT(hdr) == hdr->h_assert_refcount);
+ expect_refc = hdr->h_assert_refcount;
+ if (DUK_HEAPHDR_IS_STRING(hdr) && DUK_HSTRING_HAS_PINNED_LITERAL((duk_hstring *) hdr)) {
+ expect_refc++;
+ }
+ count_ok = ((duk_size_t) DUK_HEAPHDR_GET_REFCOUNT(hdr) == expect_refc);
if (!count_ok) {
DUK_D(DUK_DPRINT("refcount mismatch for: %p: header=%ld counted=%ld --> %!iO",
(void *) hdr, (long) DUK_HEAPHDR_GET_REFCOUNT(hdr),
@@ -48815,6 +49766,22 @@ DUK_LOCAL void duk__check_assert_refcounts(duk_heap *heap) {
}
}
#endif /* DUK_USE_REFERENCE_COUNTING */
+
+#if defined(DUK_USE_LITCACHE_SIZE)
+DUK_LOCAL void duk__assert_litcache_nulls(duk_heap *heap) {
+ duk_uint_t i;
+ duk_litcache_entry *e;
+
+ e = heap->litcache;
+ for (i = 0; i < DUK_USE_LITCACHE_SIZE; i++) {
+ /* Entry addresses were NULLed before mark-and-sweep, check
+ * that they're still NULL afterwards to ensure no pointers
+ * were recorded through any side effects.
+ */
+ DUK_ASSERT(e->addr == NULL);
+ }
+}
+#endif /* DUK_USE_LITCACHE_SIZE */
#endif /* DUK_USE_ASSERTIONS */
/*
@@ -48835,10 +49802,13 @@ DUK_LOCAL void duk__dump_stats(duk_heap *heap) {
DUK_D(DUK_DPRINT("stats mark-and-sweep: try_count=%ld, skip_count=%ld, emergency_count=%ld",
(long) heap->stats_ms_try_count, (long) heap->stats_ms_skip_count,
(long) heap->stats_ms_emergency_count));
- DUK_D(DUK_DPRINT("stats stringtable: intern_hit=%ld, intern_miss=%ld, resize_check=%ld, resize_grow=%ld, resize_shrink=%ld",
+ DUK_D(DUK_DPRINT("stats stringtable: intern_hit=%ld, intern_miss=%ld, "
+ "resize_check=%ld, resize_grow=%ld, resize_shrink=%ld, "
+ "litcache_hit=%ld, litcache_miss=%ld, litcache_pin=%ld",
(long) heap->stats_strtab_intern_hit, (long) heap->stats_strtab_intern_miss,
(long) heap->stats_strtab_resize_check, (long) heap->stats_strtab_resize_grow,
- (long) heap->stats_strtab_resize_shrink));
+ (long) heap->stats_strtab_resize_shrink, (long) heap->stats_strtab_litcache_hit,
+ (long) heap->stats_strtab_litcache_miss, (long) heap->stats_strtab_litcache_pin));
DUK_D(DUK_DPRINT("stats object: realloc_props=%ld, abandon_array=%ld",
(long) heap->stats_object_realloc_props, (long) heap->stats_object_abandon_array));
DUK_D(DUK_DPRINT("stats getownpropdesc: count=%ld, hit=%ld, miss=%ld",
@@ -48979,6 +49949,9 @@ DUK_INTERNAL void duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags
#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING)
duk__clear_assert_refcounts(heap);
#endif
+#if defined(DUK_USE_LITCACHE_SIZE)
+ duk__wipe_litcache(heap);
+#endif
duk__mark_roots_heap(heap); /* Mark main reachability roots. */
#if defined(DUK_USE_REFERENCE_COUNTING)
DUK_ASSERT(heap->refzero_list == NULL); /* Always handled to completion inline in DECREF. */
@@ -49084,6 +50057,9 @@ DUK_INTERNAL void duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags
*/
duk__assert_valid_refcounts(heap);
#endif /* DUK_USE_REFERENCE_COUNTING */
+#if defined(DUK_USE_LITCACHE_SIZE)
+ duk__assert_litcache_nulls(heap);
+#endif /* DUK_USE_LITCACHE_SIZE */
#endif /* DUK_USE_ASSERTIONS */
/*
@@ -49273,8 +50249,7 @@ DUK_INTERNAL void *duk_heap_mem_alloc_zeroed(duk_heap *heap, duk_size_t size) {
res = DUK_ALLOC(heap, size);
if (DUK_LIKELY(res != NULL)) {
- /* assume memset with zero size is OK */
- DUK_MEMZERO(res, size);
+ duk_memzero(res, size);
}
return res;
}
@@ -49288,7 +50263,7 @@ DUK_INTERNAL void *duk_heap_mem_alloc_checked(duk_hthread *thr, duk_size_t size)
return res;
}
DUK_ERROR_ALLOC_FAILED(thr);
- return NULL;
+ DUK_WO_NORETURN(return NULL;);
}
DUK_INTERNAL void *duk_heap_mem_alloc_checked_zeroed(duk_hthread *thr, duk_size_t size) {
@@ -49300,7 +50275,7 @@ DUK_INTERNAL void *duk_heap_mem_alloc_checked_zeroed(duk_hthread *thr, duk_size_
return res;
}
DUK_ERROR_ALLOC_FAILED(thr);
- return NULL;
+ DUK_WO_NORETURN(return NULL;);
}
/*
@@ -49863,7 +50838,7 @@ DUK_INTERNAL void duk_hobject_refcount_finalize_norz(duk_heap *heap, duk_hobject
DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) b->buf_prop);
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
} else if (DUK_HOBJECT_IS_BOUNDFUNC(h)) {
- duk_hboundfunc *f = (duk_hboundfunc *) h;
+ duk_hboundfunc *f = (duk_hboundfunc *) (void *) h;
DUK_ASSERT_HBOUNDFUNC_VALID(f);
DUK_TVAL_DECREF_NORZ(thr, &f->target);
DUK_TVAL_DECREF_NORZ(thr, &f->this_binding);
@@ -50553,9 +51528,9 @@ DUK_INTERNAL void duk_hobject_decref_norz(duk_hthread *thr, duk_hobject *h) {
*/
DUK_INTERNAL void duk_heap_strcache_string_remove(duk_heap *heap, duk_hstring *h) {
- duk_small_int_t i;
+ duk_uint_t i;
for (i = 0; i < DUK_HEAP_STRCACHE_SIZE; i++) {
- duk_strcache *c = heap->strcache + i;
+ duk_strcache_entry *c = heap->strcache + i;
if (c->h == h) {
DUK_DD(DUK_DDPRINT("deleting weak strcache reference to hstring %p from heap %p",
(void *) h, (void *) heap));
@@ -50627,9 +51602,9 @@ DUK_LOCAL const duk_uint8_t *duk__scan_backwards(const duk_uint8_t *p, const duk
DUK_INTERNAL duk_uint_fast32_t duk_heap_strcache_offset_char2byte(duk_hthread *thr, duk_hstring *h, duk_uint_fast32_t char_offset) {
duk_heap *heap;
- duk_strcache *sce;
+ duk_strcache_entry *sce;
duk_uint_fast32_t byte_offset;
- duk_small_int_t i;
+ duk_uint_t i;
duk_bool_t use_cache;
duk_uint_fast32_t dist_start, dist_end, dist_sce;
duk_uint_fast32_t char_length;
@@ -50680,14 +51655,14 @@ DUK_INTERNAL duk_uint_fast32_t duk_heap_strcache_offset_char2byte(duk_hthread *t
#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)
DUK_DDD(DUK_DDDPRINT("stringcache before char2byte (using cache):"));
for (i = 0; i < DUK_HEAP_STRCACHE_SIZE; i++) {
- duk_strcache *c = heap->strcache + i;
+ duk_strcache_entry *c = heap->strcache + i;
DUK_DDD(DUK_DDDPRINT(" [%ld] -> h=%p, cidx=%ld, bidx=%ld",
(long) i, (void *) c->h, (long) c->cidx, (long) c->bidx));
}
#endif
for (i = 0; i < DUK_HEAP_STRCACHE_SIZE; i++) {
- duk_strcache *c = heap->strcache + i;
+ duk_strcache_entry *c = heap->strcache + i;
if (c->h == h) {
sce = c;
@@ -50816,10 +51791,10 @@ DUK_INTERNAL duk_uint_fast32_t duk_heap_strcache_offset_char2byte(duk_hthread *t
* C <- sce ==> B
* D D
*/
- duk_strcache tmp;
+ duk_strcache_entry tmp;
tmp = *sce;
- DUK_MEMMOVE((void *) (&heap->strcache[1]),
+ duk_memmove((void *) (&heap->strcache[1]),
(const void *) (&heap->strcache[0]),
(size_t) (((char *) sce) - ((char *) &heap->strcache[0])));
heap->strcache[0] = tmp;
@@ -50829,7 +51804,7 @@ DUK_INTERNAL duk_uint_fast32_t duk_heap_strcache_offset_char2byte(duk_hthread *t
#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)
DUK_DDD(DUK_DDDPRINT("stringcache after char2byte (using cache):"));
for (i = 0; i < DUK_HEAP_STRCACHE_SIZE; i++) {
- duk_strcache *c = heap->strcache + i;
+ duk_strcache_entry *c = heap->strcache + i;
DUK_DDD(DUK_DDDPRINT(" [%ld] -> h=%p, cidx=%ld, bidx=%ld",
(long) i, (void *) c->h, (long) c->cidx, (long) c->bidx));
}
@@ -50840,7 +51815,7 @@ DUK_INTERNAL duk_uint_fast32_t duk_heap_strcache_offset_char2byte(duk_hthread *t
scan_error:
DUK_ERROR_INTERNAL(thr);
- return 0;
+ DUK_WO_NORETURN(return 0;);
}
/*
* Heap string table handling, string interning.
@@ -50898,7 +51873,7 @@ DUK_INTERNAL void duk_heap_strtable_dump(duk_heap *heap) {
return;
}
- DUK_MEMZERO((void *) count_len, sizeof(count_len));
+ duk_memzero((void *) count_len, sizeof(count_len));
for (i = 0; i < heap->st_size; i++) {
h = DUK__HEAPPTR_DEC16(heap, strtable[i]);
count_chain = 0;
@@ -51010,7 +51985,7 @@ DUK_LOCAL duk_hstring *duk__strtable_alloc_hstring(duk_heap *heap,
if (DUK_UNLIKELY(res == NULL)) {
goto alloc_error;
}
- DUK_MEMZERO(res, sizeof(duk_hstring_external));
+ duk_memzero(res, sizeof(duk_hstring_external));
#if defined(DUK_USE_EXPLICIT_NULL_INIT)
DUK_HEAPHDR_STRING_INIT_NULLS(&res->hdr);
#endif
@@ -51030,14 +52005,14 @@ DUK_LOCAL duk_hstring *duk__strtable_alloc_hstring(duk_heap *heap,
if (DUK_UNLIKELY(res == NULL)) {
goto alloc_error;
}
- DUK_MEMZERO(res, sizeof(duk_hstring));
+ duk_memzero(res, sizeof(duk_hstring));
#if defined(DUK_USE_EXPLICIT_NULL_INIT)
DUK_HEAPHDR_STRING_INIT_NULLS(&res->hdr);
#endif
DUK_HEAPHDR_SET_TYPE_AND_FLAGS(&res->hdr, DUK_HTYPE_STRING, 0);
data_tmp = (duk_uint8_t *) (res + 1);
- DUK_MEMCPY(data_tmp, str, blen);
+ duk_memcpy(data_tmp, str, blen);
data_tmp[blen] = (duk_uint8_t) 0;
data = (const duk_uint8_t *) data_tmp;
}
@@ -51530,11 +52505,12 @@ DUK_LOCAL duk_hstring *duk__strtab_romstring_lookup(duk_heap *heap, const duk_ui
}
lookup_hash &= 0xff;
- curr = DUK_LOSE_CONST(duk_rom_strings_lookup[lookup_hash]);
+ curr = (duk_hstring *) DUK_LOSE_CONST(duk_rom_strings_lookup[lookup_hash]);
while (curr != NULL) {
+ /* Unsafe memcmp() because for zero blen, str may be NULL. */
if (strhash == DUK_HSTRING_GET_HASH(curr) &&
blen == DUK_HSTRING_GET_BYTELEN(curr) &&
- DUK_MEMCMP((const void *) str, (const void *) DUK_HSTRING_GET_DATA(curr), blen) == 0) {
+ duk_memcmp_unsafe((const void *) str, (const void *) DUK_HSTRING_GET_DATA(curr), blen) == 0) {
DUK_DDD(DUK_DDDPRINT("intern check: rom string: %!O, computed hash 0x%08lx, rom hash 0x%08lx",
curr, (unsigned long) strhash, (unsigned long) DUK_HSTRING_GET_HASH(curr)));
return curr;
@@ -51554,6 +52530,7 @@ DUK_INTERNAL duk_hstring *duk_heap_strtable_intern(duk_heap *heap, const duk_uin
/* Preliminaries. */
+ /* XXX: maybe just require 'str != NULL' even for zero size? */
DUK_ASSERT(heap != NULL);
DUK_ASSERT(blen == 0 || str != NULL);
DUK_ASSERT(blen <= DUK_HSTRING_MAX_BYTELEN); /* Caller is responsible for ensuring this. */
@@ -51572,7 +52549,7 @@ DUK_INTERNAL duk_hstring *duk_heap_strtable_intern(duk_heap *heap, const duk_uin
while (h != NULL) {
if (DUK_HSTRING_GET_HASH(h) == strhash &&
DUK_HSTRING_GET_BYTELEN(h) == blen &&
- DUK_MEMCMP((const void *) str, (const void *) DUK_HSTRING_GET_DATA(h), (size_t) blen) == 0) {
+ duk_memcmp_unsafe((const void *) str, (const void *) DUK_HSTRING_GET_DATA(h), (size_t) blen) == 0) {
/* Found existing entry. */
DUK_STATS_INC(heap, stats_strtab_intern_hit);
return h;
@@ -51645,10 +52622,67 @@ DUK_INTERNAL duk_hstring *duk_heap_strtable_intern_checked(duk_hthread *thr, con
res = duk_heap_strtable_intern(thr->heap, str, blen);
if (DUK_UNLIKELY(res == NULL)) {
DUK_ERROR_ALLOC_FAILED(thr);
+ DUK_WO_NORETURN(return NULL;);
}
return res;
}
+#if defined(DUK_USE_LITCACHE_SIZE)
+DUK_LOCAL duk_uint_t duk__strtable_litcache_key(const duk_uint8_t *str, duk_uint32_t blen) {
+ duk_uintptr_t key;
+
+ DUK_ASSERT(DUK_USE_LITCACHE_SIZE > 0);
+ DUK_ASSERT(DUK_IS_POWER_OF_TWO((duk_uint_t) DUK_USE_LITCACHE_SIZE));
+
+ key = (duk_uintptr_t) blen ^ (duk_uintptr_t) str;
+ key &= (duk_uintptr_t) (DUK_USE_LITCACHE_SIZE - 1); /* Assumes size is power of 2. */
+ /* Due to masking, cast is in 32-bit range. */
+ DUK_ASSERT(key <= DUK_UINT_MAX);
+ return (duk_uint_t) key;
+}
+
+DUK_INTERNAL duk_hstring *duk_heap_strtable_intern_literal_checked(duk_hthread *thr, const duk_uint8_t *str, duk_uint32_t blen) {
+ duk_uint_t key;
+ duk_litcache_entry *ent;
+ duk_hstring *h;
+
+ /* Fast path check: literal exists in literal cache. */
+ key = duk__strtable_litcache_key(str, blen);
+ ent = thr->heap->litcache + key;
+ if (ent->addr == str) {
+ DUK_DD(DUK_DDPRINT("intern check for cached, pinned literal: str=%p, blen=%ld -> duk_hstring %!O",
+ (const void *) str, (long) blen, (duk_heaphdr *) ent->h));
+ DUK_ASSERT(ent->h != NULL);
+ DUK_ASSERT(DUK_HSTRING_HAS_PINNED_LITERAL(ent->h));
+ DUK_STATS_INC(thr->heap, stats_strtab_litcache_hit);
+ return ent->h;
+ }
+
+ /* Intern and update (overwrite) cache entry. */
+ h = duk_heap_strtable_intern_checked(thr, str, blen);
+ ent->addr = str;
+ ent->h = h;
+ DUK_STATS_INC(thr->heap, stats_strtab_litcache_miss);
+
+ /* Pin the duk_hstring until the next mark-and-sweep. This means
+ * litcache entries don't need to be invalidated until the next
+ * mark-and-sweep as their target duk_hstring is not freed before
+ * the mark-and-sweep happens. The pin remains even if the literal
+ * cache entry is overwritten, and is still useful to avoid string
+ * table traffic.
+ */
+ if (!DUK_HSTRING_HAS_PINNED_LITERAL(h)) {
+ DUK_DD(DUK_DDPRINT("pin duk_hstring because it is a literal: %!O", (duk_heaphdr *) h));
+ DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h));
+ DUK_HSTRING_INCREF(thr, h);
+ DUK_HSTRING_SET_PINNED_LITERAL(h);
+ DUK_STATS_INC(thr->heap, stats_strtab_litcache_pin);
+ }
+
+ return h;
+}
+#endif /* DUK_USE_LITCACHE_SIZE */
+
DUK_INTERNAL duk_hstring *duk_heap_strtable_intern_u32_checked(duk_hthread *thr, duk_uint32_t val) {
duk_hstring *res;
@@ -51658,6 +52692,7 @@ DUK_INTERNAL duk_hstring *duk_heap_strtable_intern_u32_checked(duk_hthread *thr,
res = duk_heap_strtable_intern_u32(thr->heap, val);
if (DUK_UNLIKELY(res == NULL)) {
DUK_ERROR_ALLOC_FAILED(thr);
+ DUK_WO_NORETURN(return NULL;);
}
return res;
}
@@ -51963,7 +52998,7 @@ DUK_INTERNAL duk_hboundfunc *duk_hboundfunc_alloc(duk_heap *heap, duk_uint_t hob
if (!res) {
return NULL;
}
- DUK_MEMZERO(res, sizeof(duk_hboundfunc));
+ duk_memzero(res, sizeof(duk_hboundfunc));
duk__init_object_parts(heap, hobject_flags, &res->obj);
@@ -52005,7 +53040,7 @@ DUK_INTERNAL duk_hthread *duk_hthread_alloc_unchecked(duk_heap *heap, duk_uint_t
if (DUK_UNLIKELY(res == NULL)) {
return NULL;
}
- DUK_MEMZERO(res, sizeof(duk_hthread));
+ duk_memzero(res, sizeof(duk_hthread));
duk__init_object_parts(heap, hobject_flags, &res->obj);
@@ -52047,6 +53082,7 @@ DUK_INTERNAL duk_hthread *duk_hthread_alloc(duk_hthread *thr, duk_uint_t hobject
res = duk_hthread_alloc_unchecked(thr->heap, hobject_flags);
if (res == NULL) {
DUK_ERROR_ALLOC_FAILED(thr);
+ DUK_WO_NORETURN(return NULL;);
}
return res;
}
@@ -52262,7 +53298,7 @@ DUK_LOCAL void duk__sort_enum_keys_es6(duk_hthread *thr, duk_hobject *h_obj, duk
* are very often in order already.
*/
if (idx != idx_insert) {
- DUK_MEMMOVE((void *) (keys + idx_insert + 1),
+ duk_memmove((void *) (keys + idx_insert + 1),
(const void *) (keys + idx_insert),
((size_t) (idx - idx_insert) * sizeof(duk_hstring *)));
keys[idx_insert] = h_curr;
@@ -52746,7 +53782,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_enumerator_next(duk_hthread *thr, duk_bool_t
}
/*
- * Get enumerated keys in an Ecmascript array. Matches Object.keys() behavior
+ * Get enumerated keys in an ECMAScript array. Matches Object.keys() behavior
* described in E5 Section 15.2.3.14.
*/
@@ -52832,6 +53868,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_prototype_chain_contains(duk_hthread *thr, d
break;
} else {
DUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);
+ DUK_WO_NORETURN(return 0;);
}
}
h = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h);
@@ -52915,7 +53952,7 @@ DUK_INTERNAL void duk_hobject_pc2line_pack(duk_hthread *thr, duk_compiler_instr
(long) hdr[hdr_index + 1]));
#endif
- DUK_MEMZERO(be_ctx, sizeof(*be_ctx));
+ duk_memzero(be_ctx, sizeof(*be_ctx));
be_ctx->data = ((duk_uint8_t *) hdr) + curr_offset;
be_ctx->length = (duk_size_t) DUK_PC2LINE_MAX_DIFF_LENGTH;
@@ -53026,7 +54063,7 @@ DUK_LOCAL duk_uint_fast32_t duk__hobject_pc2line_query_raw(duk_hthread *thr, duk
* Iterate the bitstream (line diffs) until PC is reached
*/
- DUK_MEMZERO(bd_ctx, sizeof(*bd_ctx));
+ duk_memzero(bd_ctx, sizeof(*bd_ctx));
bd_ctx->data = ((duk_uint8_t *) hdr) + start_offset;
bd_ctx->length = (duk_size_t) (DUK_HBUFFER_FIXED_GET_SIZE(buf) - start_offset);
@@ -53086,7 +54123,7 @@ DUK_INTERNAL duk_uint_fast32_t duk_hobject_pc2line_query(duk_hthread *thr, duk_i
*/
duk_get_prop_stridx(thr, idx_func, DUK_STRIDX_INT_PC2LINE);
- pc2line = (duk_hbuffer_fixed *) duk_get_hbuffer(thr, -1);
+ pc2line = (duk_hbuffer_fixed *) (void *) duk_get_hbuffer(thr, -1);
if (pc2line != NULL) {
DUK_ASSERT(!DUK_HBUFFER_HAS_DYNAMIC((duk_hbuffer *) pc2line) && !DUK_HBUFFER_HAS_EXTERNAL((duk_hbuffer *) pc2line));
line = duk__hobject_pc2line_query_raw(thr, pc2line, (duk_uint_fast32_t) pc);
@@ -53154,7 +54191,7 @@ DUK_INTERNAL duk_uint_fast32_t duk_hobject_pc2line_query(duk_hthread *thr, duk_i
#define DUK__HASH_DELETED DUK_HOBJECT_HASHIDX_DELETED
/* Valstack space that suffices for all local calls, excluding any recursion
- * into Ecmascript or Duktape/C calls (Proxy, getters, etc).
+ * into ECMAScript or Duktape/C calls (Proxy, getters, etc).
*/
#define DUK__VALSTACK_SPACE 10
@@ -53704,6 +54741,7 @@ DUK_INTERNAL void duk_hobject_realloc_props(duk_hthread *thr,
if (new_e_size_adjusted + new_a_size > DUK_HOBJECT_MAX_PROPERTIES) {
DUK_ERROR_ALLOC_FAILED(thr);
+ DUK_WO_NORETURN(return;);
}
/*
@@ -53907,18 +54945,14 @@ DUK_INTERNAL void duk_hobject_realloc_props(duk_hthread *thr,
} else {
array_copy_size = sizeof(duk_tval) * new_a_size;
}
- if (array_copy_size > 0) {
- /* Avoid zero copy with an invalid pointer. If obj->p is NULL,
- * the 'new_a' pointer will be invalid which is not allowed even
- * when copy size is zero.
- */
- DUK_ASSERT(new_a != NULL);
- DUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL);
- DUK_ASSERT(DUK_HOBJECT_GET_ASIZE(obj) > 0);
- DUK_MEMCPY((void *) new_a,
- (const void *) DUK_HOBJECT_A_GET_BASE(thr->heap, obj),
- array_copy_size);
- }
+
+ DUK_ASSERT(new_a != NULL || array_copy_size == 0U);
+ DUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL || array_copy_size == 0U);
+ DUK_ASSERT(DUK_HOBJECT_GET_ASIZE(obj) > 0 || array_copy_size == 0U);
+ duk_memcpy_unsafe((void *) new_a,
+ (const void *) DUK_HOBJECT_A_GET_BASE(thr->heap, obj),
+ array_copy_size);
+
for (i = DUK_HOBJECT_GET_ASIZE(obj); i < new_a_size; i++) {
duk_tval *tv = &new_a[i];
DUK_TVAL_SET_UNUSED(tv);
@@ -53943,7 +54977,7 @@ DUK_INTERNAL void duk_hobject_realloc_props(duk_hthread *thr,
/* fill new_h with u32 0xff = UNUSED */
DUK_ASSERT(new_h_size > 0);
- DUK_MEMSET(new_h, 0xff, sizeof(duk_uint32_t) * new_h_size);
+ duk_memset(new_h, 0xff, sizeof(duk_uint32_t) * new_h_size);
DUK_ASSERT(new_e_next <= new_h_size); /* equality not actually possible */
@@ -54053,6 +55087,7 @@ DUK_INTERNAL void duk_hobject_realloc_props(duk_hthread *thr,
#endif
DUK_ERROR_ALLOC_FAILED(thr);
+ DUK_WO_NORETURN(return;);
}
/*
@@ -54530,7 +55565,7 @@ DUK_INTERNAL duk_hstring *duk_hobject_get_internal_value_string(duk_heap *heap,
/* This is not strictly necessary, but avoids compiler warnings; e.g.
* gcc won't reliably detect that no uninitialized data is read below.
*/
- DUK_MEMZERO((void *) &tv, sizeof(duk_tval));
+ duk_memzero((void *) &tv, sizeof(duk_tval));
if (duk_hobject_get_internal_value(heap, obj, &tv)) {
duk_hstring *h;
@@ -54718,7 +55753,7 @@ DUK_LOCAL void duk__check_arguments_map_for_delete(duk_hthread *thr, duk_hobject
}
/*
- * Ecmascript compliant [[GetOwnProperty]](P), for internal use only.
+ * ECMAScript compliant [[GetOwnProperty]](P), for internal use only.
*
* If property is found:
* - Fills descriptor fields to 'out_desc'
@@ -55093,7 +56128,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_get_own_propdesc(duk_hthread *thr, duk_hobje
}
/*
- * Ecmascript compliant [[GetProperty]](P), for internal use only.
+ * ECMAScript compliant [[GetProperty]](P), for internal use only.
*
* If property is found:
* - Fills descriptor fields to 'out_desc'
@@ -55150,6 +56185,7 @@ DUK_LOCAL duk_bool_t duk__get_propdesc(duk_hthread *thr, duk_hobject *obj, duk_h
break;
} else {
DUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);
+ DUK_WO_NORETURN(return 0;);
}
}
curr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);
@@ -55431,7 +56467,7 @@ DUK_LOCAL duk_bool_t duk__putprop_fastpath_bufobj_tval(duk_hthread *thr, duk_hob
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
/*
- * GETPROP: Ecmascript property read.
+ * GETPROP: ECMAScript property read.
*/
DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key) {
@@ -55485,7 +56521,8 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
DUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, "cannot read property %s of %s",
duk_push_string_tval_readable(thr, tv_key), duk_push_string_tval_readable(thr, tv_obj));
#endif
- return 0;
+ DUK_WO_NORETURN(return 0;);
+ break;
}
case DUK_TAG_BOOLEAN: {
@@ -55641,6 +56678,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
!DUK_TVAL_IS_UNDEFINED(tv_hook);
if (datadesc_reject || accdesc_reject) {
DUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);
+ DUK_WO_NORETURN(return 0;);
}
duk_pop_2_unsafe(thr);
@@ -55832,6 +56870,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
*/
if (DUK_UNLIKELY(sanity-- == 0)) {
DUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);
+ DUK_WO_NORETURN(return 0;);
}
curr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);
} while (curr != NULL);
@@ -55902,6 +56941,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
DUK_HOBJECT_HAS_STRICT(h)) {
/* XXX: sufficient to check 'strict', assert for 'is function' */
DUK_ERROR_TYPE(thr, DUK_STR_STRICT_CALLER_READ);
+ DUK_WO_NORETURN(return 0;);
}
}
}
@@ -55914,7 +56954,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
}
/*
- * HASPROP: Ecmascript property existence check ("in" operator).
+ * HASPROP: ECMAScript property existence check ("in" operator).
*
* Interestingly, the 'in' operator does not do any coercion of
* the target object.
@@ -55980,6 +57020,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_hasprop(duk_hthread *thr, duk_tval *tv_obj,
/* Note: unconditional throw */
DUK_DDD(DUK_DDDPRINT("base object is not an object -> reject"));
DUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE);
+ DUK_WO_NORETURN(return 0;);
}
/* XXX: fast path for arrays? */
@@ -56004,7 +57045,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_hasprop(duk_hthread *thr, duk_tval *tv_obj,
duk_push_hobject(thr, h_target); /* target */
duk_push_tval(thr, tv_key); /* P */
duk_call_method(thr, 2 /*nargs*/);
- tmp_bool = duk_to_boolean(thr, -1);
+ tmp_bool = duk_to_boolean_top_pop(thr);
if (!tmp_bool) {
/* Target object must be checked for a conflicting
* non-configurable property.
@@ -56023,11 +57064,12 @@ DUK_INTERNAL duk_bool_t duk_hobject_hasprop(duk_hthread *thr, duk_tval *tv_obj,
if (!((desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && /* property is configurable and */
DUK_HOBJECT_HAS_EXTENSIBLE(h_target))) { /* ... target is extensible */
DUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);
+ DUK_WO_NORETURN(return 0;);
}
}
}
- duk_pop_2_unsafe(thr); /* [ key trap_result ] -> [] */
+ duk_pop_unsafe(thr); /* [ key ] -> [] */
return tmp_bool;
}
@@ -56119,7 +57161,7 @@ DUK_LOCAL duk_uint32_t duk__to_new_array_length_checked(duk_hthread *thr, duk_tv
/* Refuse to update an Array's 'length' to a value outside the
* 32-bit range. Negative zero is accepted as zero.
*/
- res = (duk_uint32_t) d;
+ res = duk_double_to_uint32_t(d);
if ((duk_double_t) res != d) {
goto fail_range;
}
@@ -56128,7 +57170,7 @@ DUK_LOCAL duk_uint32_t duk__to_new_array_length_checked(duk_hthread *thr, duk_tv
fail_range:
DUK_ERROR_RANGE(thr, DUK_STR_INVALID_ARRAY_LENGTH);
- return 0; /* unreachable */
+ DUK_WO_NORETURN(return 0;);
}
/* Delete elements required by a smaller length, taking into account
@@ -56397,9 +57439,9 @@ DUK_LOCAL duk_bool_t duk__handle_put_array_length(duk_hthread *thr, duk_hobject
}
/*
- * PUTPROP: Ecmascript property write.
+ * PUTPROP: ECMAScript property write.
*
- * Unlike Ecmascript primitive which returns nothing, returns 1 to indicate
+ * Unlike ECMAScript primitive which returns nothing, returns 1 to indicate
* success and 0 to indicate failure (assuming throw is not set).
*
* This is an extremely tricky function. Some examples:
@@ -56486,7 +57528,8 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
DUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, "cannot write property %s of %s",
duk_push_string_tval_readable(thr, tv_key), duk_push_string_tval_readable(thr, tv_obj));
#endif
- return 0;
+ DUK_WO_NORETURN(return 0;);
+ break;
}
case DUK_TAG_BOOLEAN: {
@@ -56590,8 +57633,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
duk_push_tval(thr, tv_val); /* V */
duk_push_tval(thr, tv_obj); /* Receiver: Proxy object */
duk_call_method(thr, 4 /*nargs*/);
- tmp_bool = duk_to_boolean(thr, -1);
- duk_pop_nodecref_unsafe(thr);
+ tmp_bool = duk_to_boolean_top_pop(thr);
if (!tmp_bool) {
goto fail_proxy_rejected;
}
@@ -56623,6 +57665,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
(desc.set == NULL);
if (datadesc_reject || accdesc_reject) {
DUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);
+ DUK_WO_NORETURN(return 0;);
}
duk_pop_2_unsafe(thr);
@@ -56922,6 +57965,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
*/
if (DUK_UNLIKELY(sanity-- == 0)) {
DUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);
+ DUK_WO_NORETURN(return 0;);
}
curr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);
} while (curr != NULL);
@@ -57271,6 +58315,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
DUK_DDD(DUK_DDDPRINT("result: error, proxy rejects"));
if (throw_flag) {
DUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);
+ DUK_WO_NORETURN(return 0;);
}
/* Note: no key on stack */
return 0;
@@ -57285,6 +58330,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
DUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, "cannot write property %s of %s",
duk_push_string_tval_readable(thr, tv_key), duk_push_string_tval_readable(thr, tv_obj));
#endif
+ DUK_WO_NORETURN(return 0;);
}
duk_pop_unsafe(thr); /* remove key */
return 0;
@@ -57293,6 +58339,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
DUK_DDD(DUK_DDDPRINT("result: error, not extensible"));
if (throw_flag) {
DUK_ERROR_TYPE(thr, DUK_STR_NOT_EXTENSIBLE);
+ DUK_WO_NORETURN(return 0;);
}
duk_pop_unsafe(thr); /* remove key */
return 0;
@@ -57301,6 +58348,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
DUK_DDD(DUK_DDDPRINT("result: error, not writable"));
if (throw_flag) {
DUK_ERROR_TYPE(thr, DUK_STR_NOT_WRITABLE);
+ DUK_WO_NORETURN(return 0;);
}
duk_pop_unsafe(thr); /* remove key */
return 0;
@@ -57310,6 +58358,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
DUK_DDD(DUK_DDDPRINT("result: error, not writable"));
if (throw_flag) {
DUK_ERROR_TYPE(thr, DUK_STR_NOT_WRITABLE);
+ DUK_WO_NORETURN(return 0;);
}
return 0;
#endif
@@ -57318,6 +58367,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
DUK_DD(DUK_DDPRINT("result: error, array length write only partially successful"));
if (throw_flag) {
DUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);
+ DUK_WO_NORETURN(return 0;);
}
duk_pop_unsafe(thr); /* remove key */
return 0;
@@ -57326,6 +58376,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
DUK_DDD(DUK_DDDPRINT("result: error, accessor property without setter"));
if (throw_flag) {
DUK_ERROR_TYPE(thr, DUK_STR_SETTER_UNDEFINED);
+ DUK_WO_NORETURN(return 0;);
}
duk_pop_unsafe(thr); /* remove key */
return 0;
@@ -57334,13 +58385,14 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
DUK_DDD(DUK_DDDPRINT("result: error, internal"));
if (throw_flag) {
DUK_ERROR_INTERNAL(thr);
+ DUK_WO_NORETURN(return 0;);
}
duk_pop_unsafe(thr); /* remove key */
return 0;
}
/*
- * Ecmascript compliant [[Delete]](P, Throw).
+ * ECMAScript compliant [[Delete]](P, Throw).
*/
DUK_INTERNAL duk_bool_t duk_hobject_delprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags) {
@@ -57494,12 +58546,13 @@ DUK_INTERNAL duk_bool_t duk_hobject_delprop_raw(duk_hthread *thr, duk_hobject *o
if (throw_flag) {
DUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);
+ DUK_WO_NORETURN(return 0;);
}
return 0;
}
/*
- * DELPROP: Ecmascript property deletion.
+ * DELPROP: ECMAScript property deletion.
*/
DUK_INTERNAL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key, duk_bool_t throw_flag) {
@@ -57554,8 +58607,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj,
duk_push_hobject(thr, h_target); /* target */
duk_dup_m4(thr); /* P */
duk_call_method(thr, 2 /*nargs*/);
- tmp_bool = duk_to_boolean(thr, -1);
- duk_pop_nodecref_unsafe(thr);
+ tmp_bool = duk_to_boolean_top_pop(thr);
if (!tmp_bool) {
goto fail_proxy_rejected; /* retval indicates delete failed */
}
@@ -57580,6 +58632,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj,
if (desc_reject) {
/* unconditional */
DUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);
+ DUK_WO_NORETURN(return 0;);
}
}
rc = 1; /* success */
@@ -57663,12 +58716,13 @@ DUK_INTERNAL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj,
DUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, "cannot delete property %s of %s",
duk_push_string_tval_readable(thr, tv_key), duk_push_string_tval_readable(thr, tv_obj));
#endif
- return 0;
+ DUK_WO_NORETURN(return 0;);
#if defined(DUK_USE_ES6_PROXY)
fail_proxy_rejected:
if (throw_flag) {
DUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);
+ DUK_WO_NORETURN(return 0;);
}
duk_set_top_unsafe(thr, entry_top);
return 0;
@@ -57677,6 +58731,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj,
fail_not_configurable:
if (throw_flag) {
DUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);
+ DUK_WO_NORETURN(return 0;);
}
duk_set_top_unsafe(thr, entry_top);
return 0;
@@ -57816,7 +58871,7 @@ DUK_INTERNAL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hob
error_virtual: /* share error message */
error_internal:
DUK_ERROR_INTERNAL(thr);
- return;
+ DUK_WO_NORETURN(return;);
}
/*
@@ -57896,7 +58951,7 @@ DUK_INTERNAL duk_size_t duk_hobject_get_length(duk_hthread *thr, duk_hobject *ob
val = duk_to_number_m1(thr);
duk_pop_3_unsafe(thr);
- /* This isn't part of Ecmascript semantics; return a value within
+ /* This isn't part of ECMAScript semantics; return a value within
* duk_size_t range, or 0 otherwise.
*/
if (val >= 0.0 && val <= (duk_double_t) DUK_SIZE_MAX) {
@@ -58007,7 +59062,7 @@ DUK_INTERNAL void duk_hobject_object_get_own_property_descriptor(duk_hthread *th
* NormalizePropertyDescriptor() related helper.
*
* Internal helper which validates and normalizes a property descriptor
- * represented as an Ecmascript object (e.g. argument to defineProperty()).
+ * represented as an ECMAScript object (e.g. argument to defineProperty()).
* The output of this conversion is a set of defprop_flags and possibly
* some values pushed on the value stack to (1) ensure borrowed pointers
* remain valid, and (2) avoid unnecessary pops for footprint reasons.
@@ -58057,7 +59112,7 @@ void duk_hobject_prepare_property_descriptor(duk_hthread *thr,
if (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_WRITABLE)) {
is_data_desc = 1;
- if (duk_to_boolean(thr, -1)) {
+ if (duk_to_boolean_top_pop(thr)) {
defprop_flags |= DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_WRITABLE;
} else {
defprop_flags |= DUK_DEFPROP_HAVE_WRITABLE;
@@ -58109,7 +59164,7 @@ void duk_hobject_prepare_property_descriptor(duk_hthread *thr,
}
if (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_ENUMERABLE)) {
- if (duk_to_boolean(thr, -1)) {
+ if (duk_to_boolean_top_pop(thr)) {
defprop_flags |= DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE;
} else {
defprop_flags |= DUK_DEFPROP_HAVE_ENUMERABLE;
@@ -58117,7 +59172,7 @@ void duk_hobject_prepare_property_descriptor(duk_hthread *thr,
}
if (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_CONFIGURABLE)) {
- if (duk_to_boolean(thr, -1)) {
+ if (duk_to_boolean_top_pop(thr)) {
defprop_flags |= DUK_DEFPROP_HAVE_CONFIGURABLE | DUK_DEFPROP_CONFIGURABLE;
} else {
defprop_flags |= DUK_DEFPROP_HAVE_CONFIGURABLE;
@@ -58138,6 +59193,7 @@ void duk_hobject_prepare_property_descriptor(duk_hthread *thr,
type_error:
DUK_ERROR_TYPE(thr, DUK_STR_INVALID_DESCRIPTOR);
+ DUK_WO_NORETURN(return;);
}
/*
@@ -58146,7 +59202,7 @@ void duk_hobject_prepare_property_descriptor(duk_hthread *thr,
*
* Inlines all [[DefineOwnProperty]] exotic behaviors.
*
- * Note: Ecmascript compliant [[DefineOwnProperty]](P, Desc, Throw) is not
+ * Note: ECMAScript compliant [[DefineOwnProperty]](P, Desc, Throw) is not
* implemented directly, but Object.defineProperty() serves its purpose.
* We don't need the [[DefineOwnProperty]] internally and we don't have a
* property descriptor with 'missing values' so it's easier to avoid it
@@ -59019,6 +60075,7 @@ duk_bool_t duk_hobject_define_property_helper(duk_hthread *thr,
fail_not_extensible:
if (throw_flag) {
DUK_ERROR_TYPE(thr, DUK_STR_NOT_EXTENSIBLE);
+ DUK_WO_NORETURN(return 0;);
}
return 0;
@@ -59026,6 +60083,7 @@ duk_bool_t duk_hobject_define_property_helper(duk_hthread *thr,
fail_not_configurable:
if (throw_flag) {
DUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);
+ DUK_WO_NORETURN(return 0;);
}
return 0;
}
@@ -59081,6 +60139,7 @@ DUK_INTERNAL void duk_hobject_object_seal_freeze_helper(duk_hthread *thr, duk_ho
if (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {
DUK_DD(DUK_DDPRINT("attempt to seal/freeze a readonly object, reject"));
DUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);
+ DUK_WO_NORETURN(return;);
}
#endif
@@ -59228,7 +60287,7 @@ DUK_INTERNAL duk_ucodepoint_t duk_hstring_char_code_at_raw(duk_hthread *thr, duk
(const void *) p_start, (const void *) p_end,
(const void *) p));
- /* For invalid UTF-8 (never happens for standard Ecmascript strings)
+ /* For invalid UTF-8 (never happens for standard ECMAScript strings)
* return U+FFFD replacement character.
*/
if (duk_unicode_decode_xutf8(thr, &p, p_start, p_end, &cp1)) {
@@ -59384,7 +60443,7 @@ DUK_INTERNAL duk_bool_t duk_hstring_equals_ascii_cstring(duk_hstring *h, const c
if (len != DUK_HSTRING_GET_BYTELEN(h)) {
return 0;
}
- if (DUK_MEMCMP((const void *) cstr, (const void *) DUK_HSTRING_GET_DATA(h), len) == 0) {
+ if (duk_memcmp((const void *) cstr, (const void *) DUK_HSTRING_GET_DATA(h), len) == 0) {
return 1;
}
return 0;
@@ -59421,7 +60480,7 @@ DUK_INTERNAL duk_bool_t duk_hthread_init_stacks(duk_heap *heap, duk_hthread *thr
if (!thr->valstack) {
goto fail;
}
- DUK_MEMZERO(thr->valstack, alloc_size);
+ duk_memzero(thr->valstack, alloc_size);
thr->valstack_end = thr->valstack + DUK_VALSTACK_API_ENTRY_MINIMUM;
thr->valstack_alloc_end = thr->valstack + DUK_VALSTACK_INITIAL_SIZE;
thr->valstack_bottom = thr->valstack;
@@ -59525,7 +60584,7 @@ DUK_LOCAL void duk__duplicate_ram_global_object(duk_hthread *thr) {
props = DUK_ALLOC_CHECKED(thr, alloc_size);
DUK_ASSERT(props != NULL);
DUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, h_oldglobal) != NULL);
- DUK_MEMCPY((void *) props, (const void *) DUK_HOBJECT_GET_PROPS(thr->heap, h_oldglobal), alloc_size);
+ duk_memcpy((void *) props, (const void *) DUK_HOBJECT_GET_PROPS(thr->heap, h_oldglobal), alloc_size);
/* XXX: keep property attributes or tweak them here?
* Properties will now be non-configurable even when they're
@@ -59652,7 +60711,7 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
DUK_D(DUK_DPRINT("INITBUILTINS BEGIN: DUK_NUM_BUILTINS=%d, DUK_NUM_BUILTINS_ALL=%d", (int) DUK_NUM_BUILTINS, (int) DUK_NUM_ALL_BUILTINS));
- DUK_MEMZERO(&bd_ctx, sizeof(bd_ctx));
+ duk_memzero(&bd_ctx, sizeof(bd_ctx));
bd->data = (const duk_uint8_t *) duk_builtins_data;
bd->length = (duk_size_t) DUK_BUILTINS_DATA_LENGTH;
@@ -59894,11 +60953,9 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
* signaled using a single flag bit in the bitstream.
*/
- if (duk_bd_decode_flag(bd)) {
- defprop_flags = (duk_small_uint_t) duk_bd_decode(bd, DUK__PROP_FLAGS_BITS);
- } else {
- defprop_flags = DUK_PROPDESC_FLAGS_WC;
- }
+ defprop_flags = (duk_small_uint_t) duk_bd_decode_flagged(bd,
+ DUK__PROP_FLAGS_BITS,
+ (duk_uint32_t) DUK_PROPDESC_FLAGS_WC);
defprop_flags |= DUK_DEFPROP_FORCE |
DUK_DEFPROP_HAVE_VALUE |
DUK_DEFPROP_HAVE_WRITABLE |
@@ -60003,6 +61060,7 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
#if defined(DUK_USE_LIGHTFUNC_BUILTINS)
duk_small_int_t lightfunc_eligible;
#endif
+ duk_small_uint_t defprop_flags;
duk__push_stridx_or_string(thr, bd);
h_key = duk_known_hstring(thr, -1);
@@ -60122,10 +61180,19 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
lightfunc_skip:
#endif
- /* XXX: So far all ES builtins are 'wc' but e.g.
- * performance.now() should be 'wec'.
- */
- duk_xdef_prop(thr, (duk_idx_t) i, DUK_PROPDESC_FLAGS_WC);
+ defprop_flags = (duk_small_uint_t) duk_bd_decode_flagged(bd,
+ DUK__PROP_FLAGS_BITS,
+ (duk_uint32_t) DUK_PROPDESC_FLAGS_WC);
+ defprop_flags |= DUK_DEFPROP_FORCE |
+ DUK_DEFPROP_HAVE_VALUE |
+ DUK_DEFPROP_HAVE_WRITABLE |
+ DUK_DEFPROP_HAVE_ENUMERABLE |
+ DUK_DEFPROP_HAVE_CONFIGURABLE;
+ DUK_ASSERT(DUK_PROPDESC_FLAG_WRITABLE == DUK_DEFPROP_WRITABLE);
+ DUK_ASSERT(DUK_PROPDESC_FLAG_ENUMERABLE == DUK_DEFPROP_ENUMERABLE);
+ DUK_ASSERT(DUK_PROPDESC_FLAG_CONFIGURABLE == DUK_DEFPROP_CONFIGURABLE);
+
+ duk_def_prop(thr, (duk_idx_t) i, defprop_flags);
/* [ (builtin objects) ] */
}
@@ -60198,7 +61265,7 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
"f"
#endif
" "
- /* Low memory options */
+ /* Low memory/performance options */
#if defined(DUK_USE_STRTAB_PTRCOMP)
"s"
#endif
@@ -60239,6 +61306,9 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
*/
"Z"
#endif
+#if defined(DUK_USE_LITCACHE_SIZE)
+ "l"
+#endif
" "
/* Object property allocation layout */
#if defined(DUK_USE_HOBJECT_LAYOUT_1)
@@ -60813,8 +61883,8 @@ DUK_INTERNAL void duk_hthread_valstack_torture_realloc(duk_hthread *thr) {
/* Use DUK_ALLOC_RAW() to avoid side effects. */
new_ptr = (duk_tval *) DUK_ALLOC_RAW(thr->heap, alloc_size);
if (new_ptr != NULL) {
- DUK_MEMCPY((void *) new_ptr, (const void *) thr->valstack, alloc_size);
- DUK_MEMSET((void *) thr->valstack, 0x55, alloc_size);
+ duk_memcpy((void *) new_ptr, (const void *) thr->valstack, alloc_size);
+ duk_memset((void *) thr->valstack, 0x55, alloc_size);
DUK_FREE_CHECKED(thr, (void *) thr->valstack);
thr->valstack = new_ptr;
thr->valstack_alloc_end = (duk_tval *) ((duk_uint8_t *) new_ptr + alloc_end_off);
@@ -60832,7 +61902,7 @@ DUK_INTERNAL void duk_hthread_valstack_torture_realloc(duk_hthread *thr) {
/* #include duk_internal.h -> already included */
-/* Ecmascript modulus ('%') does not match IEEE 754 "remainder" operation
+/* ECMAScript modulus ('%') does not match IEEE 754 "remainder" operation
* (implemented by remainder() in C99) but does seem to match ANSI C fmod().
* Compare E5 Section 11.5.3 and "man fmod".
*/
@@ -60886,9 +61956,9 @@ DUK_INTERNAL double duk_js_arith_mod(double d1, double d2) {
/* Shared helper for Math.pow() and exponentiation operator. */
DUK_INTERNAL double duk_js_arith_pow(double x, double y) {
- /* The ANSI C pow() semantics differ from Ecmascript.
+ /* The ANSI C pow() semantics differ from ECMAScript.
*
- * E.g. when x==1 and y is +/- infinite, the Ecmascript required
+ * E.g. when x==1 and y is +/- infinite, the ECMAScript required
* result is NaN, while at least Linux pow() returns 1.
*/
@@ -60968,7 +62038,7 @@ DUK_INTERNAL double duk_js_arith_pow(double x, double y) {
*
* duk_handle_call_unprotected():
*
- * - Unprotected call to Ecmascript or Duktape/C function, from native
+ * - Unprotected call to ECMAScript or Duktape/C function, from native
* code or bytecode executor.
*
* - Also handles Ecma-to-Ecma calls which reuses a currently running
@@ -61022,6 +62092,7 @@ DUK_LOCAL DUK_NOINLINE void duk__call_c_recursion_limit_check_slowpath(duk_hthre
DUK_D(DUK_DPRINT("call prevented because C recursion limit reached"));
DUK_ERROR_RANGE(thr, DUK_STR_C_CALLSTACK_LIMIT);
+ DUK_WO_NORETURN(return;);
}
DUK_LOCAL DUK_ALWAYS_INLINE void duk__call_c_recursion_limit_check(duk_hthread *thr) {
@@ -61057,6 +62128,7 @@ DUK_LOCAL DUK_NOINLINE void duk__call_callstack_limit_check_slowpath(duk_hthread
*/
DUK_D(DUK_DPRINT("call prevented because call stack limit reached"));
DUK_ERROR_RANGE(thr, DUK_STR_CALLSTACK_LIMIT);
+ DUK_WO_NORETURN(return;);
}
DUK_LOCAL DUK_ALWAYS_INLINE void duk__call_callstack_limit_check(duk_hthread *thr) {
@@ -61470,6 +62542,7 @@ DUK_INTERNAL void duk_call_construct_postprocess(duk_hthread *thr, duk_small_uin
if (DUK_UNLIKELY(proxy_invariant != 0U)) {
/* Proxy 'construct' return value invariant violated. */
DUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr);
+ DUK_WO_NORETURN(return;);
}
/* XXX: direct value stack access */
duk_pop(thr);
@@ -61530,7 +62603,7 @@ DUK_LOCAL void duk__handle_bound_chain_for_call(duk_hthread *thr,
duk_tval *tv_args;
duk_tval *tv_gap;
- h_bound = (duk_hboundfunc *) func;
+ h_bound = (duk_hboundfunc *) (void *) func;
tv_args = h_bound->args;
len = h_bound->nargs;
DUK_ASSERT(len == 0 || tv_args != NULL);
@@ -61570,6 +62643,7 @@ DUK_LOCAL void duk__handle_bound_chain_for_call(duk_hthread *thr,
} else {
/* Shouldn't happen, so ugly error is enough. */
DUK_ERROR_INTERNAL(thr);
+ DUK_WO_NORETURN(return;);
}
DUK_ASSERT(duk_get_top(thr) >= idx_func + 2);
@@ -61745,11 +62819,13 @@ DUK_LOCAL duk_bool_t duk__handle_specialfuncs_for_call(duk_hthread *thr, duk_idx
if (top < idx_func + 3) {
/* argArray is a mandatory argument for Reflect.construct(). */
DUK_ERROR_TYPE_INVALID_ARGS(thr);
+ DUK_WO_NORETURN(return 0;);
}
if (top > idx_func + 3) {
if (!duk_strict_equals(thr, idx_func, idx_func + 3)) {
/* XXX: [[Construct]] newTarget currently unsupported */
DUK_ERROR_UNSUPPORTED(thr);
+ DUK_WO_NORETURN(return 0;);
}
duk_set_top_unsafe(thr, idx_func + 3); /* remove any args beyond argArray */
}
@@ -62286,6 +63362,7 @@ DUK_LOCAL duk_hobject *duk__resolve_target_func_and_this_binding(duk_hthread *th
if (duk_hobject_find_existing_entry_tval_ptr(thr->heap, DUK_TVAL_GET_OBJECT(tv_func), DUK_HTHREAD_STRING_INT_TARGET(thr)) != NULL) {
duk_push_tval(thr, tv_func);
(void) duk_throw(thr);
+ DUK_WO_NORETURN(return NULL;);
}
}
#endif
@@ -62299,8 +63376,7 @@ DUK_LOCAL duk_hobject *duk__resolve_target_func_and_this_binding(duk_hthread *th
#else
DUK_ERROR_TYPE(thr, DUK_STR_NOT_CALLABLE);
#endif
- DUK_UNREACHABLE();
- return NULL; /* never executed */
+ DUK_WO_NORETURN(return NULL;);
not_constructable:
/* For now GETPROPC delayed error not needed for constructor calls. */
@@ -62313,8 +63389,7 @@ DUK_LOCAL duk_hobject *duk__resolve_target_func_and_this_binding(duk_hthread *th
#else
DUK_ERROR_TYPE(thr, DUK_STR_NOT_CONSTRUCTABLE);
#endif
- DUK_UNREACHABLE();
- return NULL; /* never executed */
+ DUK_WO_NORETURN(return NULL;);
}
/*
@@ -62338,6 +63413,7 @@ DUK_LOCAL void duk__safe_call_adjust_valstack(duk_hthread *thr, duk_idx_t idx_re
idx_rcbase = duk_get_top(thr) - num_actual_rets; /* base of known return values */
if (DUK_UNLIKELY(idx_rcbase < 0)) {
DUK_ERROR_TYPE(thr, DUK_STR_INVALID_CFUNC_RC);
+ DUK_WO_NORETURN(return;);
}
DUK_DDD(DUK_DDDPRINT("adjust valstack after func call: "
@@ -62641,10 +63717,10 @@ DUK_LOCAL void duk__call_setup_act_not_tailcall(duk_hthread *thr,
* Update return value stack index of current activation (if any).
*
* Although it might seem this is not necessary (bytecode executor
- * does this for Ecmascript-to-Ecmascript calls; other calls are
+ * does this for ECMAScript-to-ECMAScript calls; other calls are
* handled here), this turns out to be necessary for handling yield
- * and resume. For them, an Ecmascript-to-native call happens, and
- * the Ecmascript call's retval_byteoff must be set for things to work.
+ * and resume. For them, an ECMAScript-to-native call happens, and
+ * the ECMAScript call's retval_byteoff must be set for things to work.
*/
act->retval_byteoff = entry_valstack_bottom_byteoff + (duk_size_t) idx_func * sizeof(duk_tval);
@@ -62851,16 +63927,16 @@ DUK_LOCAL void duk__call_thread_state_update(duk_hthread *thr) {
thread_state_error:
DUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, "invalid thread state (%ld)", (long) thr->state);
- DUK_UNREACHABLE();
+ DUK_WO_NORETURN(return;);
}
/*
* Main unprotected call handler, handles:
*
- * - All combinations of native/Ecmascript caller and native/Ecmascript
+ * - All combinations of native/ECMAScript caller and native/ECMAScript
* target.
*
- * - Optimized Ecmascript-to-Ecmascript call where call handling only
+ * - Optimized ECMAScript-to-ECMAScript call where call handling only
* sets up a new duk_activation but reuses an existing bytecode executor
* (the caller) without native recursion.
*
@@ -62909,7 +63985,7 @@ DUK_LOCAL duk_int_t duk__handle_call_raw(duk_hthread *thr,
DUK_STATS_INC(thr->heap, stats_call_all);
/* If a tail call:
- * - an Ecmascript activation must be on top of the callstack
+ * - an ECMAScript activation must be on top of the callstack
* - there cannot be any catch stack entries that would catch
* a return
*/
@@ -63014,6 +64090,12 @@ DUK_LOCAL duk_int_t duk__handle_call_raw(duk_hthread *thr,
* Because 'act' is not zeroed, all fields must be filled in.
*/
+ /* Should not be necessary, but initialize to silence warnings. */
+ act = NULL;
+ nargs = 0;
+ nregs = 0;
+ vs_min_bytes = 0;
+
#if defined(DUK_USE_TAILCALL)
use_tailcall = (call_flags & DUK_CALL_FLAG_TAILCALL);
if (use_tailcall) {
@@ -63061,7 +64143,7 @@ DUK_LOCAL duk_int_t duk__handle_call_raw(duk_hthread *thr,
* compiler; the compiled function's parent env will contain
* the (immutable) binding already.
*
- * This handling is now identical for C and Ecmascript functions.
+ * This handling is now identical for C and ECMAScript functions.
* C functions always have the 'NEWENV' flag set, so their
* environment record initialization is delayed (which is good).
*
@@ -63108,7 +64190,7 @@ DUK_LOCAL duk_int_t duk__handle_call_raw(duk_hthread *thr,
if (func != NULL && DUK_HOBJECT_IS_COMPFUNC(func)) {
/*
- * Ecmascript call.
+ * ECMAScript call.
*/
DUK_ASSERT(func != NULL);
@@ -63202,9 +64284,10 @@ DUK_LOCAL duk_int_t duk__handle_call_raw(duk_hthread *thr,
;
} else if (rc < 0) {
duk_error_throw_from_negative_rc(thr, rc);
- DUK_UNREACHABLE();
+ DUK_WO_NORETURN(return 0;);
} else {
DUK_ERROR_TYPE(thr, DUK_STR_INVALID_CFUNC_RC);
+ DUK_WO_NORETURN(return 0;);
}
}
DUK_ASSERT(thr->ptr_curr_pc == NULL);
@@ -63292,7 +64375,7 @@ DUK_LOCAL duk_int_t duk__handle_call_raw(duk_hthread *thr,
* calls caused by side effects (e.g. when doing a DUK_OP_GETPROP), see
* GH-303. Only needed for success path, error path always causes a
* breakpoint recheck in the executor. It would be enough to set this
- * only when returning to an Ecmascript activation, but setting the flag
+ * only when returning to an ECMAScript activation, but setting the flag
* on every return should have no ill effect.
*/
#if defined(DUK_USE_DEBUGGER_SUPPORT)
@@ -63404,6 +64487,7 @@ DUK_LOCAL void duk__handle_safe_call_inner(duk_hthread *thr,
if (DUK_UNLIKELY(rc < 0)) {
duk_error_throw_from_negative_rc(thr, rc);
+ DUK_WO_NORETURN(return;);
}
DUK_ASSERT(rc >= 0);
@@ -63681,7 +64765,10 @@ DUK_INTERNAL duk_int_t duk_handle_safe_call(duk_hthread *thr,
retval = DUK_EXEC_ERROR;
}
#if defined(DUK_USE_CPP_EXCEPTIONS)
- catch (std::exception &exc) {
+ catch (duk_fatal_exception &exc) {
+ DUK_D(DUK_DPRINT("rethrow duk_fatal_exception"));
+ throw;
+ } catch (std::exception &exc) {
const char *what = exc.what();
DUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);
DUK_STATS_INC(thr->heap, stats_safecall_throw);
@@ -63691,6 +64778,7 @@ DUK_INTERNAL duk_int_t duk_handle_safe_call(duk_hthread *thr,
DUK_D(DUK_DPRINT("unexpected c++ std::exception (perhaps thrown by user code)"));
try {
DUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, "caught invalid c++ std::exception '%s' (perhaps thrown by user code)", what);
+ DUK_WO_NORETURN(return 0;);
} catch (duk_internal_exception exc) {
DUK_D(DUK_DPRINT("caught api error thrown from unexpected c++ std::exception"));
DUK_UNREF(exc);
@@ -63713,6 +64801,7 @@ DUK_INTERNAL duk_int_t duk_handle_safe_call(duk_hthread *thr,
DUK_STATS_INC(thr->heap, stats_safecall_throw);
try {
DUK_ERROR_TYPE(thr, "caught invalid c++ exception (perhaps thrown by user code)");
+ DUK_WO_NORETURN(return 0;);
} catch (duk_internal_exception exc) {
DUK_D(DUK_DPRINT("caught api error thrown from unexpected c++ exception"));
DUK_UNREF(exc);
@@ -63772,7 +64861,7 @@ DUK_INTERNAL duk_int_t duk_handle_safe_call(duk_hthread *thr,
/*
* Property-based call (foo.noSuch()) error setup: replace target function
* on stack top with a specially tagged (hidden Symbol) error which gets
- * thrown in call handling at the proper spot to follow Ecmascript semantics.
+ * thrown in call handling at the proper spot to follow ECMAScript semantics.
*/
#if defined(DUK_USE_VERBOSE_ERRORS)
@@ -63830,7 +64919,7 @@ DUK_INTERNAL DUK_NOINLINE DUK_COLD void duk_call_setup_propcall_error(duk_hthrea
/* automatic undefs */
#undef DUK__AUGMENT_CALL_RELAX_COUNT
/*
- * Ecmascript compiler.
+ * ECMAScript compiler.
*
* Parses an input string and generates a function template result.
* Compilation may happen in multiple contexts (global code, eval
@@ -64066,9 +65155,9 @@ DUK_LOCAL_DECL void duk__parse_try_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *
DUK_LOCAL_DECL void duk__parse_with_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res);
DUK_LOCAL_DECL void duk__parse_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_bool_t allow_source_elem);
DUK_LOCAL_DECL duk_int_t duk__stmt_label_site(duk_compiler_ctx *comp_ctx, duk_int_t label_id);
-DUK_LOCAL_DECL void duk__parse_stmts(duk_compiler_ctx *comp_ctx, duk_bool_t allow_source_elem, duk_bool_t expect_eof);
+DUK_LOCAL_DECL void duk__parse_stmts(duk_compiler_ctx *comp_ctx, duk_bool_t allow_source_elem, duk_bool_t expect_eof, duk_bool_t regexp_after);
-DUK_LOCAL_DECL void duk__parse_func_body(duk_compiler_ctx *comp_ctx, duk_bool_t expect_eof, duk_bool_t implicit_return_value, duk_small_int_t expect_token);
+DUK_LOCAL_DECL void duk__parse_func_body(duk_compiler_ctx *comp_ctx, duk_bool_t expect_eof, duk_bool_t implicit_return_value, duk_bool_t regexp_after, duk_small_int_t expect_token);
DUK_LOCAL_DECL void duk__parse_func_formals(duk_compiler_ctx *comp_ctx);
DUK_LOCAL_DECL void duk__parse_func_like_raw(duk_compiler_ctx *comp_ctx, duk_small_uint_t flags);
DUK_LOCAL_DECL duk_int_t duk__parse_func_like_fnum(duk_compiler_ctx *comp_ctx, duk_small_uint_t flags);
@@ -64240,6 +65329,7 @@ DUK_LOCAL void duk__comp_recursion_increase(duk_compiler_ctx *comp_ctx) {
DUK_ASSERT(comp_ctx->recursion_depth >= 0);
if (comp_ctx->recursion_depth >= comp_ctx->recursion_limit) {
DUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_COMPILER_RECURSION_LIMIT);
+ DUK_WO_NORETURN(return;);
}
comp_ctx->recursion_depth++;
}
@@ -64294,15 +65384,20 @@ DUK_LOCAL void duk__advance_helper(duk_compiler_ctx *comp_ctx, duk_small_int_t e
comp_ctx->curr_func.reject_regexp_in_adv = 0;
regexp = 0;
}
+ if (comp_ctx->curr_func.allow_regexp_in_adv) {
+ comp_ctx->curr_func.allow_regexp_in_adv = 0;
+ regexp = 1;
+ }
if (expect >= 0 && comp_ctx->curr_token.t != (duk_small_uint_t) expect) {
DUK_D(DUK_DPRINT("parse error: expect=%ld, got=%ld",
(long) expect, (long) comp_ctx->curr_token.t));
DUK_ERROR_SYNTAX(thr, DUK_STR_PARSE_ERROR);
+ DUK_WO_NORETURN(return;);
}
/* make current token the previous; need to fiddle with valstack "backing store" */
- DUK_MEMCPY(&comp_ctx->prev_token, &comp_ctx->curr_token, sizeof(duk_token));
+ duk_memcpy(&comp_ctx->prev_token, &comp_ctx->curr_token, sizeof(duk_token));
duk_copy(thr, comp_ctx->tok11_idx, comp_ctx->tok21_idx);
duk_copy(thr, comp_ctx->tok12_idx, comp_ctx->tok22_idx);
@@ -64350,7 +65445,7 @@ DUK_LOCAL void duk__init_func_valstack_slots(duk_compiler_ctx *comp_ctx) {
entry_top = duk_get_top(thr);
- DUK_MEMZERO(func, sizeof(*func)); /* intentional overlap with earlier memzero */
+ duk_memzero(func, sizeof(*func)); /* intentional overlap with earlier memzero */
#if defined(DUK_USE_EXPLICIT_NULL_INIT)
func->h_name = NULL;
func->h_consts = NULL;
@@ -64597,7 +65692,7 @@ DUK_LOCAL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx) {
(long) code_size, (long) data_size));
duk_push_fixed_buffer_nozero(thr, data_size);
- h_data = (duk_hbuffer_fixed *) duk_known_hbuffer(thr, -1);
+ h_data = (duk_hbuffer_fixed *) (void *) duk_known_hbuffer(thr, -1);
DUK_HCOMPFUNC_SET_DATA(thr->heap, h_res, (duk_hbuffer *) h_data);
DUK_HEAPHDR_INCREF(thr, h_data);
@@ -64802,7 +65897,7 @@ DUK_LOCAL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx) {
*/
#if 0
- duk_push_string(thr, "XXX");
+ duk_push_literal(thr, "XXX");
duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_SOURCE, DUK_PROPDESC_FLAGS_NONE);
#endif
}
@@ -65001,6 +66096,7 @@ DUK_LOCAL void duk__emit(duk_compiler_ctx *comp_ctx, duk_instr_t ins) {
fail_bc_limit:
DUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_BYTECODE_LIMIT);
+ DUK_WO_NORETURN(return;);
}
/* Update function min/max line from current token. Needed to improve
@@ -65285,6 +66381,7 @@ DUK_LOCAL void duk__emit_a_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_f
error_outofregs:
DUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_REG_LIMIT);
+ DUK_WO_NORETURN(return;);
}
/* For many of the helpers below it'd be technically correct to add
@@ -65383,6 +66480,7 @@ DUK_LOCAL void duk__emit_a_bc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_fl
error_outofregs:
DUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_REG_LIMIT);
+ DUK_WO_NORETURN(return;);
}
DUK_LOCAL void duk__emit_bc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op, duk_regconst_t bc) {
@@ -65417,6 +66515,7 @@ DUK_LOCAL void duk__emit_abc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op, du
error_outofregs:
DUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_REG_LIMIT);
+ DUK_WO_NORETURN(return;);
}
DUK_LOCAL void duk__emit_load_int32_raw(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val, duk_small_uint_t op_flags) {
@@ -65514,6 +66613,7 @@ DUK_LOCAL void duk__insert_jump_entry(duk_compiler_ctx *comp_ctx, duk_int_t jump
fail_bc_limit:
DUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_BYTECODE_LIMIT);
+ DUK_WO_NORETURN(return;);
}
/* Does not assume that jump_pc contains a DUK_OP_JUMP previously; this is intentional
@@ -65569,6 +66669,7 @@ DUK_LOCAL void duk__patch_trycatch(duk_compiler_ctx *comp_ctx, duk_int_t ldconst
DUK_D(DUK_DPRINT("failed to patch trycatch: flags=%ld, reg_catch=%ld, const_varname=%ld (0x%08lx)",
(long) flags, (long) reg_catch, (long) const_varname, (long) const_varname));
DUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_REG_LIMIT);
+ DUK_WO_NORETURN(return;);
}
instr->ins |= DUK_ENC_OP_A_BC(0, 0, const_varname);
} else {
@@ -65760,6 +66861,7 @@ DUK_LOCAL duk_regconst_t duk__alloctemps(duk_compiler_ctx *comp_ctx, duk_small_i
if (comp_ctx->curr_func.temp_next > DUK__MAX_TEMPS) { /* == DUK__MAX_TEMPS is OK */
DUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_TEMP_LIMIT);
+ DUK_WO_NORETURN(return 0;);
}
/* maintain highest 'used' temporary, needed to figure out nregs of function */
@@ -65819,6 +66921,7 @@ DUK_LOCAL duk_regconst_t duk__getconst(duk_compiler_ctx *comp_ctx) {
if (n > DUK__MAX_CONSTS) {
DUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_CONST_LIMIT);
+ DUK_WO_NORETURN(return 0;);
}
DUK_DDD(DUK_DDDPRINT("allocating new constant for %!T -> const index %ld",
@@ -65992,6 +67095,7 @@ duk_regconst_t duk__ispec_toregconst_raw(duk_compiler_ctx *comp_ctx,
}
}
} /* end switch */
+ goto fail_internal; /* never here */
}
case DUK_ISPEC_REGCONST: {
if (forced_reg >= 0) {
@@ -66024,12 +67128,13 @@ duk_regconst_t duk__ispec_toregconst_raw(duk_compiler_ctx *comp_ctx,
return x->regconst;
}
default: {
- break;
+ break; /* never here */
}
}
+ fail_internal:
DUK_ERROR_INTERNAL(thr);
- return 0;
+ DUK_WO_NORETURN(return 0;);
}
DUK_LOCAL void duk__ispec_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ispec *x, duk_regconst_t forced_reg) {
@@ -66102,7 +67207,10 @@ DUK_LOCAL void duk__ivalue_toplain_raw(duk_compiler_ctx *comp_ctx, duk_ivalue *x
break;
}
case DUK_OP_DIV: {
- d3 = d1 / d2;
+ /* Division-by-zero is undefined
+ * behavior, so rely on a helper.
+ */
+ d3 = duk_double_div(d1, d2);
break;
}
case DUK_OP_EXP: {
@@ -66129,7 +67237,7 @@ DUK_LOCAL void duk__ivalue_toplain_raw(duk_compiler_ctx *comp_ctx, duk_ivalue *x
}
} else if (x->op == DUK_OP_ADD && DUK_TVAL_IS_STRING(tv1) && DUK_TVAL_IS_STRING(tv2)) {
/* Inline string concatenation. No need to check for
- * symbols, as all inputs are valid Ecmascript strings.
+ * symbols, as all inputs are valid ECMAScript strings.
*/
duk_dup(thr, x->x1.valstack_idx);
duk_dup(thr, x->x2.valstack_idx);
@@ -66227,7 +67335,7 @@ DUK_LOCAL void duk__ivalue_toplain_raw(duk_compiler_ctx *comp_ctx, duk_ivalue *x
}
DUK_ERROR_INTERNAL(thr);
- return;
+ DUK_WO_NORETURN(return;);
}
/* evaluate to plain value, no forced register (temp/bound reg both ok) */
@@ -66459,6 +67567,7 @@ DUK_LOCAL void duk__add_label(duk_compiler_ctx *comp_ctx, duk_hstring *h_label,
if (li->h_label == h_label && h_label != DUK_HTHREAD_STRING_EMPTY_STRING(thr)) {
DUK_ERROR_SYNTAX(thr, DUK_STR_DUPLICATE_LABEL);
+ DUK_WO_NORETURN(return;);
}
}
@@ -66588,6 +67697,7 @@ DUK_LOCAL void duk__lookup_active_label(duk_compiler_ctx *comp_ctx, duk_hstring
*/
if (h_label != DUK_HTHREAD_STRING_EMPTY_STRING(thr)) {
DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_LABEL);
+ DUK_WO_NORETURN(return;);
} else {
DUK_DDD(DUK_DDDPRINT("continue matched an empty label which does not "
"allow a continue -> continue lookup deeper in label stack"));
@@ -66597,6 +67707,7 @@ DUK_LOCAL void duk__lookup_active_label(duk_compiler_ctx *comp_ctx, duk_hstring
/* XXX: match flag is awkward, rework */
if (!match) {
DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_LABEL);
+ DUK_WO_NORETURN(return;);
}
DUK_DDD(DUK_DDDPRINT("label match: %!O -> label_id %ld, catch_depth=%ld, pc_label=%ld",
@@ -66786,6 +67897,7 @@ DUK_LOCAL void duk__nud_array_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *re
syntax_error:
DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_ARRAY_LITERAL);
+ DUK_WO_NORETURN(return;);
}
typedef struct {
@@ -67062,13 +68174,14 @@ DUK_LOCAL void duk__nud_object_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *r
#endif
DUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_RCURLY);
- duk__advance(comp_ctx);
+ duk__advance(comp_ctx); /* No RegExp after object literal. */
duk__ivalue_regconst(res, st.reg_obj);
return;
syntax_error:
DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_OBJECT_LITERAL);
+ DUK_WO_NORETURN(return;);
}
/* Parse argument list. Arguments are written to temps starting from
@@ -67112,7 +68225,7 @@ DUK_LOCAL duk_int_t duk__parse_arguments(duk_compiler_ctx *comp_ctx, duk_ivalue
}
/* eat the right paren */
- duk__advance_expect(comp_ctx, DUK_TOK_RPAREN);
+ duk__advance_expect(comp_ctx, DUK_TOK_RPAREN); /* RegExp mode does not matter. */
DUK_DDD(DUK_DDDPRINT("end parsing arguments"));
@@ -67245,7 +68358,7 @@ DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
duk__expr(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/); /* Expression, terminates at a ')' */
- duk__advance_expect(comp_ctx, DUK_TOK_RPAREN);
+ duk__advance_expect(comp_ctx, DUK_TOK_RPAREN); /* No RegExp after parenthesized expression. */
comp_ctx->curr_func.allow_in = prev_allow_in;
comp_ctx->curr_func.paren_level--;
return;
@@ -67380,6 +68493,7 @@ DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
if (comp_ctx->curr_func.is_strict) {
DUK_ERROR_SYNTAX(thr, DUK_STR_CANNOT_DELETE_IDENTIFIER);
+ DUK_WO_NORETURN(return;);
}
DUK__SETTEMP(comp_ctx, temp_at_entry);
@@ -67544,7 +68658,7 @@ DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
} /* end switch */
DUK_ERROR_SYNTAX(thr, DUK_STR_PARSE_ERROR);
- return;
+ DUK_WO_NORETURN(return;);
unary:
{
@@ -67648,10 +68762,12 @@ DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
#if defined(DUK_USE_ES6)
syntax_error_newtarget:
DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_NEWTARGET);
+ DUK_WO_NORETURN(return;);
#endif
syntax_error:
DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_EXPRESSION);
+ DUK_WO_NORETURN(return;);
}
/* XXX: add flag to indicate whether caller cares about return value; this
@@ -67706,6 +68822,7 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
/* NB: must accept reserved words as property name */
if (comp_ctx->curr_token.t_nores != DUK_TOK_IDENTIFIER) {
DUK_ERROR_SYNTAX(thr, DUK_STR_EXPECTED_IDENTIFIER);
+ DUK_WO_NORETURN(return;);
}
res->t = DUK_IVAL_PROP;
@@ -68135,7 +69252,7 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
DUK_D(DUK_DPRINT("parse error: unexpected token: %ld", (long) tok));
DUK_ERROR_SYNTAX(thr, DUK_STR_PARSE_ERROR);
- return;
+ DUK_WO_NORETURN(return;);
#if 0
/* XXX: shared handling for 'duk__expr_lhs'? */
@@ -68365,7 +69482,7 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
* one instruction, so use explicit PC computation.
*/
DUK_DD(DUK_DDPRINT("rhs is side effect free, rewind and avoid unnecessary temp for reg-based <op>="));
- DUK_BW_ADD_PTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code, (duk_size_t) (pc_temp_load - pc_before_rhs) * sizeof(duk_compiler_instr));
+ DUK_BW_ADD_PTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code, (pc_temp_load - pc_before_rhs) * (duk_int_t) sizeof(duk_compiler_instr));
reg_src = reg_varbind;
} else {
DUK_DD(DUK_DDPRINT("rhs evaluation emitted code, not sure if rhs is side effect free; use temp reg for LHS"));
@@ -68625,11 +69742,11 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
syntax_error:
DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_EXPRESSION);
- return;
+ DUK_WO_NORETURN(return;);
syntax_error_lvalue:
DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_LVALUE);
- return;
+ DUK_WO_NORETURN(return;);
}
DUK_LOCAL duk_small_uint_t duk__expr_lbp(duk_compiler_ctx *comp_ctx) {
@@ -68694,7 +69811,7 @@ DUK_LOCAL void duk__expr(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_
(long) rbp_flags, (long) rbp, (long) comp_ctx->curr_func.allow_in,
(long) comp_ctx->curr_func.paren_level));
- DUK_MEMZERO(&tmp_alloc, sizeof(tmp_alloc));
+ duk_memzero(&tmp_alloc, sizeof(tmp_alloc));
tmp->x1.valstack_idx = duk_get_top(thr);
tmp->x2.valstack_idx = tmp->x1.valstack_idx + 1;
duk_push_undefined(thr);
@@ -68714,6 +69831,7 @@ DUK_LOCAL void duk__expr(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_
DUK_DDD(DUK_DDDPRINT("empty expression"));
if (!(rbp_flags & DUK__EXPR_FLAG_ALLOW_EMPTY)) {
DUK_ERROR_SYNTAX(thr, DUK_STR_EMPTY_EXPR_NOT_ALLOWED);
+ DUK_WO_NORETURN(return;);
}
duk_push_undefined(thr);
duk__ivalue_plain_fromstack(comp_ctx, res);
@@ -68752,6 +69870,7 @@ DUK_LOCAL void duk__exprtop(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_sma
if (!(rbp_flags & DUK__EXPR_FLAG_ALLOW_EMPTY) && duk__expr_is_empty(comp_ctx)) {
DUK_ERROR_SYNTAX(thr, DUK_STR_EMPTY_EXPR_NOT_ALLOWED);
+ DUK_WO_NORETURN(return;);
}
}
@@ -68944,6 +70063,7 @@ DUK_LOCAL void duk__parse_var_decl(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
syntax_error:
DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_VAR_DECLARATION);
+ DUK_WO_NORETURN(return;);
}
DUK_LOCAL void duk__parse_var_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t expr_flags) {
@@ -69175,7 +70295,8 @@ DUK_LOCAL void duk__parse_for_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
}
DUK__SETTEMP(comp_ctx, temp_reset);
- duk__advance_expect(comp_ctx, DUK_TOK_RPAREN);
+ comp_ctx->curr_func.allow_regexp_in_adv = 1;
+ duk__advance_expect(comp_ctx, DUK_TOK_RPAREN); /* Allow RegExp as part of next stmt. */
pc_l3 = duk__get_current_pc(comp_ctx);
duk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);
@@ -69266,7 +70387,8 @@ DUK_LOCAL void duk__parse_for_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
pc_jumpto_l4 = duk__emit_jump_empty(comp_ctx);
DUK__SETTEMP(comp_ctx, temp_reset);
- duk__advance_expect(comp_ctx, DUK_TOK_RPAREN);
+ comp_ctx->curr_func.allow_regexp_in_adv = 1;
+ duk__advance_expect(comp_ctx, DUK_TOK_RPAREN); /* Allow RegExp as part of next stmt. */
pc_l3 = duk__get_current_pc(comp_ctx);
duk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);
@@ -69315,6 +70437,7 @@ DUK_LOCAL void duk__parse_for_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
syntax_error:
DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_FOR);
+ DUK_WO_NORETURN(return;);
}
DUK_LOCAL void duk__parse_switch_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site) {
@@ -69356,7 +70479,7 @@ DUK_LOCAL void duk__parse_switch_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *re
duk__advance(comp_ctx);
duk__advance_expect(comp_ctx, DUK_TOK_LPAREN);
rc_switch = duk__exprtop_toregconst(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);
- duk__advance_expect(comp_ctx, DUK_TOK_RPAREN);
+ duk__advance_expect(comp_ctx, DUK_TOK_RPAREN); /* RegExp mode does not matter. */
duk__advance_expect(comp_ctx, DUK_TOK_LCURLY);
DUK_DDD(DUK_DDDPRINT("switch value in register %ld", (long) rc_switch));
@@ -69481,7 +70604,8 @@ DUK_LOCAL void duk__parse_switch_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *re
}
DUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_RCURLY);
- duk__advance(comp_ctx);
+ comp_ctx->curr_func.allow_regexp_in_adv = 1;
+ duk__advance(comp_ctx); /* Allow RegExp as part of next stmt. */
/* default case control flow patchup; note that if pc_prevcase < 0
* (i.e. no case clauses), control enters default case automatically.
@@ -69514,6 +70638,7 @@ DUK_LOCAL void duk__parse_switch_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *re
syntax_error:
DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_SWITCH);
+ DUK_WO_NORETURN(return;);
}
DUK_LOCAL void duk__parse_if_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
@@ -69533,7 +70658,8 @@ DUK_LOCAL void duk__parse_if_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
pc_jump_false = duk__emit_jump_empty(comp_ctx); /* jump to end or else part */
DUK__SETTEMP(comp_ctx, temp_reset);
- duk__advance_expect(comp_ctx, DUK_TOK_RPAREN);
+ comp_ctx->curr_func.allow_regexp_in_adv = 1;
+ duk__advance_expect(comp_ctx, DUK_TOK_RPAREN); /* Allow RegExp as part of next stmt. */
duk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);
@@ -69569,7 +70695,7 @@ DUK_LOCAL void duk__parse_do_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, d
DUK_DDD(DUK_DDDPRINT("begin parsing do statement"));
- duk__advance(comp_ctx); /* eat 'do' */
+ duk__advance(comp_ctx); /* Eat 'do'; allow RegExp as part of next stmt. */
pc_start = duk__get_current_pc(comp_ctx);
duk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);
@@ -69583,6 +70709,7 @@ DUK_LOCAL void duk__parse_do_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, d
duk__emit_jump(comp_ctx, pc_start);
/* no need to reset temps, as we're finished emitting code */
+ comp_ctx->curr_func.allow_regexp_in_adv = 1; /* Allow RegExp as part of next stmt. */
duk__advance_expect(comp_ctx, DUK_TOK_RPAREN);
duk__patch_jump_here(comp_ctx, pc_label_site + 1); /* break jump */
@@ -69612,7 +70739,8 @@ DUK_LOCAL void duk__parse_while_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res
pc_jump_false = duk__emit_jump_empty(comp_ctx);
DUK__SETTEMP(comp_ctx, temp_reset);
- duk__advance_expect(comp_ctx, DUK_TOK_RPAREN);
+ comp_ctx->curr_func.allow_regexp_in_adv = 1;
+ duk__advance_expect(comp_ctx, DUK_TOK_RPAREN); /* Allow RegExp as part of next stmt. */
duk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);
duk__emit_jump(comp_ctx, pc_start);
@@ -69648,6 +70776,7 @@ DUK_LOCAL void duk__parse_break_or_continue_stmt(duk_compiler_ctx *comp_ctx, duk
duk__advance(comp_ctx);
} else {
DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_BREAK_CONT_LABEL);
+ DUK_WO_NORETURN(return;);
}
/* Use a fast break/continue when possible. A fast break/continue is
@@ -69689,6 +70818,7 @@ DUK_LOCAL void duk__parse_return_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *re
*/
if (!comp_ctx->curr_func.is_function) {
DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_RETURN);
+ DUK_WO_NORETURN(return;);
}
if (comp_ctx->curr_token.t == DUK_TOK_SEMICOLON || /* explicit semi follows */
@@ -69790,6 +70920,7 @@ DUK_LOCAL void duk__parse_throw_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res
if (comp_ctx->curr_token.lineterm) {
DUK_ERROR_SYNTAX(comp_ctx->thr, DUK_STR_INVALID_THROW);
+ DUK_WO_NORETURN(return;);
}
reg_val = duk__exprtop_toreg(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);
@@ -69846,10 +70977,9 @@ DUK_LOCAL void duk__parse_try_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res)
/* try part */
duk__advance_expect(comp_ctx, DUK_TOK_LCURLY);
- duk__parse_stmts(comp_ctx, 0 /*allow_source_elem*/, 0 /*expect_eof*/);
+ duk__parse_stmts(comp_ctx, 0 /*allow_source_elem*/, 0 /*expect_eof*/, 1 /*regexp_after*/);
/* the DUK_TOK_RCURLY is eaten by duk__parse_stmts() */
- duk__emit_op_only(comp_ctx,
- DUK_OP_ENDTRY);
+ duk__emit_op_only(comp_ctx, DUK_OP_ENDTRY);
if (comp_ctx->curr_token.t == DUK_TOK_CATCH) {
/*
@@ -69945,7 +71075,7 @@ DUK_LOCAL void duk__parse_try_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res)
DUK_DDD(DUK_DDDPRINT("varmap before parsing catch clause: %!iT",
(duk_tval *) duk_get_tval(thr, comp_ctx->curr_func.varmap_idx)));
- duk__parse_stmts(comp_ctx, 0 /*allow_source_elem*/, 0 /*expect_eof*/);
+ duk__parse_stmts(comp_ctx, 0 /*allow_source_elem*/, 0 /*expect_eof*/, 1 /*regexp_after*/);
/* the DUK_TOK_RCURLY is eaten by duk__parse_stmts() */
if (varmap_value == -2) {
@@ -69987,7 +71117,7 @@ DUK_LOCAL void duk__parse_try_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res)
duk__advance(comp_ctx);
duk__advance_expect(comp_ctx, DUK_TOK_LCURLY);
- duk__parse_stmts(comp_ctx, 0 /*allow_source_elem*/, 0 /*expect_eof*/);
+ duk__parse_stmts(comp_ctx, 0 /*allow_source_elem*/, 0 /*expect_eof*/, 1 /*regexp_after*/);
/* the DUK_TOK_RCURLY is eaten by duk__parse_stmts() */
duk__emit_abc(comp_ctx,
DUK_OP_ENDFIN,
@@ -70030,6 +71160,7 @@ DUK_LOCAL void duk__parse_try_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res)
syntax_error:
DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_TRY);
+ DUK_WO_NORETURN(return;);
}
DUK_LOCAL void duk__parse_with_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
@@ -70040,6 +71171,7 @@ DUK_LOCAL void duk__parse_with_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res)
if (comp_ctx->curr_func.is_strict) {
DUK_ERROR_SYNTAX(comp_ctx->thr, DUK_STR_WITH_IN_STRICT_MODE);
+ DUK_WO_NORETURN(return;);
}
comp_ctx->curr_func.catch_depth++;
@@ -70050,7 +71182,8 @@ DUK_LOCAL void duk__parse_with_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res)
duk__advance_expect(comp_ctx, DUK_TOK_LPAREN);
duk__exprtop_toforcedreg(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/, reg_catch);
- duk__advance_expect(comp_ctx, DUK_TOK_RPAREN);
+ comp_ctx->curr_func.allow_regexp_in_adv = 1;
+ duk__advance_expect(comp_ctx, DUK_TOK_RPAREN); /* Allow RegExp as part of next stmt. */
pc_trycatch = duk__get_current_pc(comp_ctx);
trycatch_flags = DUK_BC_TRYCATCH_FLAG_WITH_BINDING;
@@ -70062,8 +71195,7 @@ DUK_LOCAL void duk__parse_with_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res)
duk__emit_invalid(comp_ctx); /* finished jump */
duk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);
- duk__emit_op_only(comp_ctx,
- DUK_OP_ENDTRY);
+ duk__emit_op_only(comp_ctx, DUK_OP_ENDTRY);
pc_finished = duk__get_current_pc(comp_ctx);
@@ -70230,13 +71362,14 @@ DUK_LOCAL void duk__parse_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_
break;
} else {
DUK_ERROR_SYNTAX(thr, DUK_STR_FUNC_STMT_NOT_ALLOWED);
+ DUK_WO_NORETURN(return;);
}
break;
}
case DUK_TOK_LCURLY: {
DUK_DDD(DUK_DDDPRINT("block statement"));
duk__advance(comp_ctx);
- duk__parse_stmts(comp_ctx, 0 /*allow_source_elem*/, 0 /*expect_eof*/);
+ duk__parse_stmts(comp_ctx, 0 /*allow_source_elem*/, 0 /*expect_eof*/, 1 /*regexp_after*/);
/* the DUK_TOK_RCURLY is eaten by duk__parse_stmts() */
if (label_id >= 0) {
duk__patch_jump_here(comp_ctx, pc_at_entry + 1); /* break jump */
@@ -70490,7 +71623,7 @@ DUK_LOCAL void duk__parse_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_
*/
if (DUK_HSTRING_GET_BYTELEN(h_dir) == 10 &&
- DUK_STRNCMP((const char *) DUK_HSTRING_GET_DATA(h_dir), "use strict", 10) == 0) {
+ DUK_STRCMP((const char *) DUK_HSTRING_GET_DATA(h_dir), "use strict") == 0) {
#if defined(DUK_USE_STRICT_DECL)
DUK_DDD(DUK_DDDPRINT("use strict directive detected: strict flag %ld -> %ld",
(long) comp_ctx->curr_func.is_strict, (long) 1));
@@ -70499,7 +71632,7 @@ DUK_LOCAL void duk__parse_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_
DUK_DDD(DUK_DDDPRINT("use strict detected but strict declarations disabled, ignoring"));
#endif
} else if (DUK_HSTRING_GET_BYTELEN(h_dir) == 14 &&
- DUK_STRNCMP((const char *) DUK_HSTRING_GET_DATA(h_dir), "use duk notail", 14) == 0) {
+ DUK_STRCMP((const char *) DUK_HSTRING_GET_DATA(h_dir), "use duk notail") == 0) {
DUK_DDD(DUK_DDDPRINT("use duk notail directive detected: notail flag %ld -> %ld",
(long) comp_ctx->curr_func.is_notail, (long) 1));
comp_ctx->curr_func.is_notail = 1;
@@ -70567,6 +71700,7 @@ DUK_LOCAL void duk__parse_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_
"even though no lineterm present before next token)"));
} else {
DUK_ERROR_SYNTAX(thr, DUK_STR_UNTERMINATED_STMT);
+ DUK_WO_NORETURN(return;);
}
}
} else {
@@ -70615,7 +71749,7 @@ DUK_LOCAL void duk__parse_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_
* (EOF or closing brace).
*/
-DUK_LOCAL void duk__parse_stmts(duk_compiler_ctx *comp_ctx, duk_bool_t allow_source_elem, duk_bool_t expect_eof) {
+DUK_LOCAL void duk__parse_stmts(duk_compiler_ctx *comp_ctx, duk_bool_t allow_source_elem, duk_bool_t expect_eof, duk_bool_t regexp_after) {
duk_hthread *thr = comp_ctx->thr;
duk_ivalue res_alloc;
duk_ivalue *res = &res_alloc;
@@ -70629,7 +71763,7 @@ DUK_LOCAL void duk__parse_stmts(duk_compiler_ctx *comp_ctx, duk_bool_t allow_sou
* for nested functions (which may occur inside expressions).
*/
- DUK_MEMZERO(&res_alloc, sizeof(res_alloc));
+ duk_memzero(&res_alloc, sizeof(res_alloc));
res->t = DUK_IVAL_PLAIN;
res->x1.t = DUK_ISPEC_VALUE;
res->x1.valstack_idx = duk_get_top(thr);
@@ -70663,6 +71797,15 @@ DUK_LOCAL void duk__parse_stmts(duk_compiler_ctx *comp_ctx, duk_bool_t allow_sou
duk__parse_stmt(comp_ctx, res, allow_source_elem);
}
+ /* RegExp is allowed / not allowed depending on context. For function
+ * declarations RegExp is allowed because it follows a function
+ * declaration statement and may appear as part of the next statement.
+ * For function expressions RegExp is not allowed, and it's possible
+ * to do something like '(function () {} / 123)'.
+ */
+ if (regexp_after) {
+ comp_ctx->curr_func.allow_regexp_in_adv = 1;
+ }
duk__advance(comp_ctx);
/* Tear down state. */
@@ -70986,13 +72129,11 @@ DUK_LOCAL void duk__init_varmap_and_prologue_for_pass2(duk_compiler_ctx *comp_ct
error_outofregs:
DUK_ERROR_RANGE(thr, DUK_STR_REG_LIMIT);
- DUK_UNREACHABLE();
- return;
+ DUK_WO_NORETURN(return;);
error_argname:
DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_ARG_NAME);
- DUK_UNREACHABLE();
- return;
+ DUK_WO_NORETURN(return;);
}
/*
@@ -71029,7 +72170,7 @@ DUK_LOCAL void duk__init_varmap_and_prologue_for_pass2(duk_compiler_ctx *comp_ct
* token (EOF or closing brace).
*/
-DUK_LOCAL void duk__parse_func_body(duk_compiler_ctx *comp_ctx, duk_bool_t expect_eof, duk_bool_t implicit_return_value, duk_small_int_t expect_token) {
+DUK_LOCAL void duk__parse_func_body(duk_compiler_ctx *comp_ctx, duk_bool_t expect_eof, duk_bool_t implicit_return_value, duk_bool_t regexp_after, duk_small_int_t expect_token) {
duk_compiler_func *func;
duk_hthread *thr;
duk_regconst_t reg_stmt_value = -1;
@@ -71101,7 +72242,9 @@ DUK_LOCAL void duk__parse_func_body(duk_compiler_ctx *comp_ctx, duk_bool_t expec
func->max_line = 0;
#endif
- /* duk__parse_stmts() expects curr_tok to be set; parse in "allow regexp literal" mode with current strictness */
+ /* duk__parse_stmts() expects curr_tok to be set; parse in "allow
+ * regexp literal" mode with current strictness.
+ */
if (expect_token >= 0) {
/* Eating a left curly; regexp mode is allowed by left curly
* based on duk__token_lbp[] automatically.
@@ -71120,7 +72263,8 @@ DUK_LOCAL void duk__parse_func_body(duk_compiler_ctx *comp_ctx, duk_bool_t expec
DUK_DDD(DUK_DDDPRINT("begin 1st pass"));
duk__parse_stmts(comp_ctx,
1, /* allow source elements */
- expect_eof); /* expect EOF instead of } */
+ expect_eof, /* expect EOF instead of } */
+ regexp_after); /* regexp after */
DUK_DDD(DUK_DDDPRINT("end 1st pass"));
/*
@@ -71227,7 +72371,8 @@ DUK_LOCAL void duk__parse_func_body(duk_compiler_ctx *comp_ctx, duk_bool_t expec
DUK_DDD(DUK_DDDPRINT("begin 2nd pass"));
duk__parse_stmts(comp_ctx,
1, /* allow source elements */
- expect_eof); /* expect EOF instead of } */
+ expect_eof, /* expect EOF instead of } */
+ regexp_after); /* regexp after */
DUK_DDD(DUK_DDDPRINT("end 2nd pass"));
duk__update_lineinfo_currtoken(comp_ctx);
@@ -71240,6 +72385,7 @@ DUK_LOCAL void duk__parse_func_body(duk_compiler_ctx *comp_ctx, duk_bool_t expec
/* Should never happen but avoid infinite loop just in case. */
DUK_D(DUK_DPRINT("more than 3 compile passes needed, should never happen"));
DUK_ERROR_INTERNAL(thr);
+ DUK_WO_NORETURN(return;);
}
DUK_D(DUK_DPRINT("need additional round to compile function, round now %d", (int) compile_round));
}
@@ -71283,6 +72429,7 @@ DUK_LOCAL void duk__parse_func_body(duk_compiler_ctx *comp_ctx, duk_bool_t expec
error_funcname:
DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_FUNC_NAME);
+ DUK_WO_NORETURN(return;);
}
/*
@@ -71331,6 +72478,7 @@ DUK_LOCAL void duk__parse_func_formals(duk_compiler_ctx *comp_ctx) {
if (comp_ctx->curr_token.t != DUK_TOK_IDENTIFIER) {
DUK_ERROR_SYNTAX(thr, DUK_STR_EXPECTED_IDENTIFIER);
+ DUK_WO_NORETURN(return;);
}
DUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_IDENTIFIER);
DUK_ASSERT(comp_ctx->curr_token.str1 != NULL);
@@ -71396,6 +72544,7 @@ DUK_LOCAL void duk__parse_func_like_raw(duk_compiler_ctx *comp_ctx, duk_small_ui
duk_to_string(thr, -1);
} else {
DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_GETSET_NAME);
+ DUK_WO_NORETURN(return;);
}
comp_ctx->curr_func.h_name = duk_known_hstring(thr, -1); /* borrowed reference */
} else {
@@ -71413,6 +72562,7 @@ DUK_LOCAL void duk__parse_func_like_raw(duk_compiler_ctx *comp_ctx, duk_small_ui
no_advance = 1;
if (flags & DUK__FUNC_FLAG_DECL) {
DUK_ERROR_SYNTAX(thr, DUK_STR_FUNC_NAME_REQUIRED);
+ DUK_WO_NORETURN(return;);
}
}
}
@@ -71446,6 +72596,7 @@ DUK_LOCAL void duk__parse_func_like_raw(duk_compiler_ctx *comp_ctx, duk_small_ui
duk__parse_func_body(comp_ctx,
0, /* expect_eof */
0, /* implicit_return_value */
+ flags & DUK__FUNC_FLAG_DECL, /* regexp_after */
DUK_TOK_LCURLY); /* expect_token */
/*
@@ -71498,6 +72649,14 @@ DUK_LOCAL duk_int_t duk__parse_func_like_fnum(duk_compiler_ctx *comp_ctx, duk_sm
comp_ctx->curr_token.t = 0; /* this is needed for regexp mode */
comp_ctx->curr_token.start_line = 0; /* needed for line number tracking (becomes prev_token.start_line) */
duk__advance(comp_ctx);
+
+ /* RegExp is not allowed after a function expression, e.g. in
+ * (function () {} / 123). A RegExp *is* allowed after a
+ * function declaration!
+ */
+ if (flags & DUK__FUNC_FLAG_DECL) {
+ comp_ctx->curr_func.allow_regexp_in_adv = 1;
+ }
duk__advance_expect(comp_ctx, DUK_TOK_RCURLY);
return fnum;
@@ -71512,9 +72671,9 @@ DUK_LOCAL duk_int_t duk__parse_func_like_fnum(duk_compiler_ctx *comp_ctx, duk_sm
DUK_DDD(DUK_DDDPRINT("before func: entry_top=%ld, curr_tok.start_offset=%ld",
(long) entry_top, (long) comp_ctx->curr_token.start_offset));
- DUK_MEMCPY(&old_func, &comp_ctx->curr_func, sizeof(duk_compiler_func));
+ duk_memcpy(&old_func, &comp_ctx->curr_func, sizeof(duk_compiler_func));
- DUK_MEMZERO(&comp_ctx->curr_func, sizeof(duk_compiler_func));
+ duk_memzero(&comp_ctx->curr_func, sizeof(duk_compiler_func));
duk__init_func_valstack_slots(comp_ctx);
DUK_ASSERT(comp_ctx->curr_func.num_formals == 0);
@@ -71556,6 +72715,7 @@ DUK_LOCAL duk_int_t duk__parse_func_like_fnum(duk_compiler_ctx *comp_ctx, duk_sm
if (fnum > DUK__MAX_FUNCS) {
DUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_FUNC_LIMIT);
+ DUK_WO_NORETURN(return 0;);
}
/* array writes autoincrement length */
@@ -71580,7 +72740,7 @@ DUK_LOCAL duk_int_t duk__parse_func_like_fnum(duk_compiler_ctx *comp_ctx, duk_sm
} else {
duk_set_top(thr, entry_top);
}
- DUK_MEMCPY((void *) &comp_ctx->curr_func, (void *) &old_func, sizeof(duk_compiler_func));
+ duk_memcpy((void *) &comp_ctx->curr_func, (void *) &old_func, sizeof(duk_compiler_func));
return fnum;
}
@@ -71589,7 +72749,7 @@ DUK_LOCAL duk_int_t duk__parse_func_like_fnum(duk_compiler_ctx *comp_ctx, duk_sm
* Compile input string into an executable function template without
* arguments.
*
- * The string is parsed as the "Program" production of Ecmascript E5.
+ * The string is parsed as the "Program" production of ECMAScript E5.
* Compilation context can be either global code or eval code (see E5
* Sections 14 and 15.1.2.1).
*
@@ -71730,6 +72890,7 @@ DUK_LOCAL duk_ret_t duk__js_compile_raw(duk_hthread *thr, void *udata) {
duk__parse_func_body(comp_ctx,
1, /* expect_eof */
1, /* implicit_return_value */
+ 1, /* regexp_after (does not matter) */
-1); /* expect_token */
}
@@ -71757,7 +72918,7 @@ DUK_INTERNAL void duk_js_compile(duk_hthread *thr, const duk_uint8_t *src_buffer
DUK_ASSERT(src_buffer != NULL);
/* preinitialize lexer state partially */
- DUK_MEMZERO(&comp_stk, sizeof(comp_stk));
+ duk_memzero(&comp_stk, sizeof(comp_stk));
comp_stk.flags = flags;
DUK_LEXER_INITCTX(&comp_stk.comp_ctx_alloc.lex);
comp_stk.comp_ctx_alloc.lex.input = src_buffer;
@@ -71774,6 +72935,7 @@ DUK_INTERNAL void duk_js_compile(duk_hthread *thr, const duk_uint8_t *src_buffer
if (safe_rc != DUK_EXEC_SUCCESS) {
DUK_D(DUK_DPRINT("compilation failed: %!T", duk_get_tval(thr, -1)));
(void) duk_throw(thr);
+ DUK_WO_NORETURN(return;);
}
/* [ ... template ] */
@@ -71864,7 +73026,7 @@ DUK_INTERNAL void duk_js_compile(duk_hthread *thr, const duk_uint8_t *src_buffer
#undef DUK__TOKEN_LBP_FLAG_UNUSED
#undef DUK__TOKEN_LBP_GET_BP
/*
- * Ecmascript bytecode executor.
+ * ECMAScript bytecode executor.
*/
/* #include duk_internal.h -> already included */
@@ -71915,7 +73077,7 @@ DUK_LOCAL void duk__push_tvals_incref_only(duk_hthread *thr, duk_tval *tv_src, d
tv_dst = thr->valstack_top;
copy_size = sizeof(duk_tval) * count;
- DUK_MEMCPY((void *) tv_dst, (const void *) tv_src, copy_size);
+ duk_memcpy((void *) tv_dst, (const void *) tv_src, copy_size);
for (i = 0; i < count; i++) {
DUK_TVAL_INCREF(thr, tv_dst);
tv_dst++;
@@ -72179,7 +73341,10 @@ DUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_binary_op(duk_hthread *thr, duk_tv
break;
}
case DUK_OP_DIV >> 2: {
- du.d = d1 / d2;
+ /* Division-by-zero is undefined behavior, so
+ * rely on a helper.
+ */
+ du.d = duk_double_div(d1, d2);
break;
}
case DUK_OP_MOD >> 2: {
@@ -72636,7 +73801,7 @@ DUK_LOCAL DUK__INLINE_PERF void duk__prepost_incdec_var_helper(duk_hthread *thr,
* top are combined into one pass.
*/
-/* Reconfigure value stack for return to an Ecmascript function at
+/* Reconfigure value stack for return to an ECMAScript function at
* callstack top (caller unwinds).
*/
DUK_LOCAL void duk__reconfig_valstack_ecma_return(duk_hthread *thr) {
@@ -72652,7 +73817,7 @@ DUK_LOCAL void duk__reconfig_valstack_ecma_return(duk_hthread *thr) {
/* Clamp so that values at 'clamp_top' and above are wiped and won't
* retain reachable garbage. Then extend to 'nregs' because we're
- * returning to an Ecmascript function.
+ * returning to an ECMAScript function.
*/
h_func = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);
@@ -72668,7 +73833,7 @@ DUK_LOCAL void duk__reconfig_valstack_ecma_return(duk_hthread *thr) {
/* XXX: a best effort shrink check would be OK here */
}
-/* Reconfigure value stack for an Ecmascript catcher. Use topmost catcher
+/* Reconfigure value stack for an ECMAScript catcher. Use topmost catcher
* in 'act'.
*/
DUK_LOCAL void duk__reconfig_valstack_ecma_catcher(duk_hthread *thr, duk_activation *act) {
@@ -72904,7 +74069,7 @@ DUK_LOCAL void duk__handle_yield(duk_hthread *thr, duk_hthread *resumer, duk_tva
act_resumer = resumer->callstack_curr;
DUK_ASSERT(act_resumer != NULL);
DUK_ASSERT(DUK_ACT_GET_FUNC(act_resumer) != NULL);
- DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(act_resumer))); /* resume caller must be an ecmascript func */
+ DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(act_resumer))); /* resume caller must be an ECMAScript func */
tv1 = (duk_tval *) (void *) ((duk_uint8_t *) resumer->valstack + act_resumer->retval_byteoff); /* return value from Duktape.Thread.resume() */
DUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv_val_unstable); /* side effects */ /* XXX: avoid side effects */
@@ -72960,7 +74125,7 @@ DUK_LOCAL duk_small_uint_t duk__handle_longjmp(duk_hthread *thr, duk_activation
/* duk_bi_duk_object_yield() and duk_bi_duk_object_resume() ensure all of these are met */
DUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING); /* unchanged by Duktape.Thread.resume() */
- DUK_ASSERT(thr->callstack_top >= 2); /* Ecmascript activation + Duktape.Thread.resume() activation */
+ DUK_ASSERT(thr->callstack_top >= 2); /* ECMAScript activation + Duktape.Thread.resume() activation */
DUK_ASSERT(thr->callstack_curr != NULL);
DUK_ASSERT(thr->callstack_curr->parent != NULL);
DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL &&
@@ -72978,7 +74143,7 @@ DUK_LOCAL duk_small_uint_t duk__handle_longjmp(duk_hthread *thr, duk_activation
DUK_ASSERT(resumee->state == DUK_HTHREAD_STATE_INACTIVE ||
resumee->state == DUK_HTHREAD_STATE_YIELDED); /* checked by Duktape.Thread.resume() */
DUK_ASSERT(resumee->state != DUK_HTHREAD_STATE_YIELDED ||
- resumee->callstack_top >= 2); /* YIELDED: Ecmascript activation + Duktape.Thread.yield() activation */
+ resumee->callstack_top >= 2); /* YIELDED: ECMAScript activation + Duktape.Thread.yield() activation */
DUK_ASSERT(resumee->state != DUK_HTHREAD_STATE_YIELDED ||
(DUK_ACT_GET_FUNC(resumee->callstack_curr) != NULL &&
DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(resumee->callstack_curr)) &&
@@ -73016,8 +74181,8 @@ DUK_LOCAL duk_small_uint_t duk__handle_longjmp(duk_hthread *thr, duk_activation
goto check_longjmp;
} else if (resumee->state == DUK_HTHREAD_STATE_YIELDED) {
/* Unwind previous Duktape.Thread.yield() call. The
- * activation remaining must always be an Ecmascript
- * call now (yield() accepts calls from Ecmascript
+ * activation remaining must always be an ECMAScript
+ * call now (yield() accepts calls from ECMAScript
* only).
*/
duk_activation *act_resumee;
@@ -73025,7 +74190,7 @@ DUK_LOCAL duk_small_uint_t duk__handle_longjmp(duk_hthread *thr, duk_activation
DUK_ASSERT(resumee->callstack_top >= 2);
act_resumee = resumee->callstack_curr; /* Duktape.Thread.yield() */
DUK_ASSERT(act_resumee != NULL);
- act_resumee = act_resumee->parent; /* Ecmascript call site for yield() */
+ act_resumee = act_resumee->parent; /* ECMAScript call site for yield() */
DUK_ASSERT(act_resumee != NULL);
tv = (duk_tval *) (void *) ((duk_uint8_t *) resumee->valstack + act_resumee->retval_byteoff); /* return value from Duktape.Thread.yield() */
@@ -73073,6 +74238,7 @@ DUK_LOCAL duk_small_uint_t duk__handle_longjmp(duk_hthread *thr, duk_activation
* executor which can be quite misleading.
*/
DUK_ERROR_INTERNAL(thr);
+ DUK_WO_NORETURN(return 0;);
}
DUK_ASSERT(resumee->resumer == NULL);
@@ -73095,7 +74261,7 @@ DUK_LOCAL duk_small_uint_t duk__handle_longjmp(duk_hthread *thr, duk_activation
case DUK_LJ_TYPE_YIELD: {
/*
* Currently only allowed only if yielding thread has only
- * Ecmascript activations (except for the Duktape.Thread.yield()
+ * ECMAScript activations (except for the Duktape.Thread.yield()
* call at the callstack top) and none of them constructor
* calls.
*
@@ -73111,27 +74277,27 @@ DUK_LOCAL duk_small_uint_t duk__handle_longjmp(duk_hthread *thr, duk_activation
DUK_ASSERT(thr != entry_thread); /* Duktape.Thread.yield() should prevent */
#endif
DUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING); /* unchanged from Duktape.Thread.yield() */
- DUK_ASSERT(thr->callstack_top >= 2); /* Ecmascript activation + Duktape.Thread.yield() activation */
+ DUK_ASSERT(thr->callstack_top >= 2); /* ECMAScript activation + Duktape.Thread.yield() activation */
DUK_ASSERT(thr->callstack_curr != NULL);
DUK_ASSERT(thr->callstack_curr->parent != NULL);
DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL &&
DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)) &&
((duk_hnatfunc *) DUK_ACT_GET_FUNC(thr->callstack_curr))->func == duk_bi_thread_yield);
DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr->parent) != NULL &&
- DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr->parent))); /* an Ecmascript function */
+ DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr->parent))); /* an ECMAScript function */
resumer = thr->resumer;
DUK_ASSERT(resumer != NULL);
DUK_ASSERT(resumer->state == DUK_HTHREAD_STATE_RESUMED); /* written by a previous RESUME handling */
- DUK_ASSERT(resumer->callstack_top >= 2); /* Ecmascript activation + Duktape.Thread.resume() activation */
+ DUK_ASSERT(resumer->callstack_top >= 2); /* ECMAScript activation + Duktape.Thread.resume() activation */
DUK_ASSERT(resumer->callstack_curr != NULL);
DUK_ASSERT(resumer->callstack_curr->parent != NULL);
DUK_ASSERT(DUK_ACT_GET_FUNC(resumer->callstack_curr) != NULL &&
DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(resumer->callstack_curr)) &&
((duk_hnatfunc *) DUK_ACT_GET_FUNC(resumer->callstack_curr))->func == duk_bi_thread_resume);
DUK_ASSERT(DUK_ACT_GET_FUNC(resumer->callstack_curr->parent) != NULL &&
- DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(resumer->callstack_curr->parent))); /* an Ecmascript function */
+ DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(resumer->callstack_curr->parent))); /* an ECMAScript function */
if (thr->heap->lj.iserror) {
thr->state = DUK_HTHREAD_STATE_YIELDED;
@@ -73185,7 +74351,7 @@ DUK_LOCAL duk_small_uint_t duk__handle_longjmp(duk_hthread *thr, duk_activation
* resumer in this case.)
*
* Note: until we hit the entry level, there can only be
- * Ecmascript activations.
+ * ECMAScript activations.
*/
duk_activation *act;
@@ -73252,11 +74418,11 @@ DUK_LOCAL duk_small_uint_t duk__handle_longjmp(duk_hthread *thr, duk_activation
*/
DUK_ASSERT(thr->resumer != NULL);
- DUK_ASSERT(thr->resumer->callstack_top >= 2); /* Ecmascript activation + Duktape.Thread.resume() activation */
+ DUK_ASSERT(thr->resumer->callstack_top >= 2); /* ECMAScript activation + Duktape.Thread.resume() activation */
DUK_ASSERT(thr->resumer->callstack_curr != NULL);
DUK_ASSERT(thr->resumer->callstack_curr->parent != NULL);
DUK_ASSERT(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr->parent) != NULL &&
- DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr->parent))); /* an Ecmascript function */
+ DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr->parent))); /* an ECMAScript function */
resumer = thr->resumer;
@@ -73309,8 +74475,7 @@ DUK_LOCAL duk_small_uint_t duk__handle_longjmp(duk_hthread *thr, duk_activation
* infinite loop in this catchpoint.
*/
DUK_ERROR_INTERNAL(thr);
- DUK_UNREACHABLE();
- return retval;
+ DUK_WO_NORETURN(return 0;);
}
/* Handle a BREAK/CONTINUE opcode. Avoid using longjmp() for BREAK/CONTINUE
@@ -73374,7 +74539,7 @@ DUK_LOCAL DUK__NOINLINE_PERF void duk__handle_break_or_continue(duk_hthread *thr
/* Should never happen, but be robust. */
DUK_D(DUK_DPRINT("-> break/continue not caught by anything in the current function (should never happen), throw internal error"));
DUK_ERROR_INTERNAL(thr);
- return;
+ DUK_WO_NORETURN(return;);
}
/* Handle a RETURN opcode. Avoid using longjmp() for return handling because
@@ -73409,7 +74574,7 @@ DUK_LOCAL duk_small_uint_t duk__handle_return(duk_hthread *thr, duk_activation *
* 2. The return happens at the entry level of the bytecode
* executor, so return from the executor (in C stack).
*
- * 3. There is a calling (Ecmascript) activation in the call
+ * 3. There is a calling (ECMAScript) activation in the call
* stack => return to it, in the same executor instance.
*
* 4. There is no calling activation, and the thread is
@@ -73454,16 +74619,16 @@ DUK_LOCAL duk_small_uint_t duk__handle_return(duk_hthread *thr, duk_activation *
}
if (thr->callstack_top >= 2) {
- /* There is a caller; it MUST be an Ecmascript caller (otherwise it would
+ /* There is a caller; it MUST be an ECMAScript caller (otherwise it would
* match entry_act check).
*/
- DUK_DDD(DUK_DDDPRINT("return to Ecmascript caller, retval_byteoff=%ld, lj_value1=%!T",
+ DUK_DDD(DUK_DDDPRINT("return to ECMAScript caller, retval_byteoff=%ld, lj_value1=%!T",
(long) (thr->callstack_curr->parent->retval_byteoff),
(duk_tval *) &thr->heap->lj.value1));
DUK_ASSERT(thr->callstack_curr != NULL);
DUK_ASSERT(thr->callstack_curr->parent != NULL);
- DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr->parent))); /* must be ecmascript */
+ DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr->parent))); /* must be ECMAScript */
#if defined(DUK_USE_ES6_PROXY)
if (thr->callstack_curr->flags & (DUK_ACT_FLAG_CONSTRUCT | DUK_ACT_FLAG_CONSTRUCT_PROXY)) {
@@ -73493,14 +74658,14 @@ DUK_LOCAL duk_small_uint_t duk__handle_return(duk_hthread *thr, duk_activation *
DUK_DD(DUK_DDPRINT("no calling activation, thread finishes (similar to yield)"));
DUK_ASSERT(thr->resumer != NULL);
- DUK_ASSERT(thr->resumer->callstack_top >= 2); /* Ecmascript activation + Duktape.Thread.resume() activation */
+ DUK_ASSERT(thr->resumer->callstack_top >= 2); /* ECMAScript activation + Duktape.Thread.resume() activation */
DUK_ASSERT(thr->resumer->callstack_curr != NULL);
DUK_ASSERT(thr->resumer->callstack_curr->parent != NULL);
DUK_ASSERT(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr) != NULL &&
DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr)) &&
((duk_hnatfunc *) DUK_ACT_GET_FUNC(thr->resumer->callstack_curr))->func == duk_bi_thread_resume); /* Duktape.Thread.resume() */
DUK_ASSERT(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr->parent) != NULL &&
- DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr->parent))); /* an Ecmascript function */
+ DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr->parent))); /* an ECMAScript function */
DUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);
DUK_ASSERT(thr->resumer->state == DUK_HTHREAD_STATE_RESUMED);
@@ -73547,7 +74712,7 @@ DUK_LOCAL duk_small_uint_t duk__handle_return(duk_hthread *thr, duk_activation *
#else
/* Without coroutine support this case should never happen. */
DUK_ERROR_INTERNAL(thr);
- return DUK__RETHAND_FINISHED; /* not executed */
+ DUK_WO_NORETURN(return 0;);
#endif
}
@@ -73697,7 +74862,7 @@ DUK_LOCAL void duk__interrupt_handle_debugger(duk_hthread *thr, duk_bool_t *out_
if (diff_last < 0.0 || diff_last >= (duk_double_t) DUK_HEAP_DBG_RATELIMIT_MILLISECS) {
/* Monotonic time should not experience time jumps,
* but the provider may be missing and we're actually
- * using Ecmascript time. So, tolerate negative values
+ * using ECMAScript time. So, tolerate negative values
* so that a time jump works reasonably.
*
* Same interval is now used for status sending and
@@ -73846,6 +75011,7 @@ DUK_LOCAL DUK__NOINLINE_PERF DUK_COLD duk_small_uint_t duk__executor_interrupt(d
thr->interrupt_counter = 0;
DUK_HEAP_CLEAR_INTERRUPT_RUNNING(thr->heap);
DUK_ERROR_RANGE(thr, "execution timeout");
+ DUK_WO_NORETURN(return 0;);
}
#endif /* DUK_USE_EXEC_TIMEOUT_CHECK */
@@ -74531,7 +75697,7 @@ DUK_LOCAL duk_bool_t duk__executor_handle_call(duk_hthread *thr, duk_idx_t idx,
}
/*
- * Ecmascript bytecode executor.
+ * ECMAScript bytecode executor.
*
* Resume execution for the current thread from its current activation.
* Returns when execution would return from the entry level activation,
@@ -74540,7 +75706,7 @@ DUK_LOCAL duk_bool_t duk__executor_handle_call(duk_hthread *thr, duk_idx_t idx,
* a longjmp() with type DUK_LJ_TYPE_THROW is called on the entry level
* setjmp() jmpbuf.
*
- * Ecmascript function calls and coroutine resumptions are handled
+ * ECMAScript function calls and coroutine resumptions are handled
* internally (by the outer executor function) without recursive C calls.
* Other function calls are handled using duk_handle_call(), increasing
* C recursion depth.
@@ -74633,6 +75799,7 @@ DUK_LOCAL duk_bool_t duk__executor_handle_call(duk_hthread *thr, duk_idx_t idx,
#if defined(DUK_USE_VERBOSE_EXECUTOR_ERRORS)
#define DUK__INTERNAL_ERROR(msg) do { \
DUK_ERROR_ERROR(thr, (msg)); \
+ DUK_WO_NORETURN(return;); \
} while (0)
#else
#define DUK__INTERNAL_ERROR(msg) do { \
@@ -74797,7 +75964,10 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) {
entry_jmpbuf_ptr);
}
#if defined(DUK_USE_CPP_EXCEPTIONS)
- catch (std::exception &exc) {
+ catch (duk_fatal_exception &exc) {
+ DUK_D(DUK_DPRINT("rethrow duk_fatal_exception"));
+ throw;
+ } catch (std::exception &exc) {
const char *what = exc.what();
if (!what) {
what = "unknown";
@@ -74807,6 +75977,7 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) {
try {
DUK_ASSERT(heap->curr_thread != NULL);
DUK_ERROR_FMT1(heap->curr_thread, DUK_ERR_TYPE_ERROR, "caught invalid c++ std::exception '%s' (perhaps thrown by user code)", what);
+ DUK_WO_NORETURN(return;);
} catch (duk_internal_exception exc) {
DUK_D(DUK_DPRINT("caught api error thrown from unexpected c++ std::exception"));
DUK_UNREF(exc);
@@ -74821,6 +75992,7 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) {
try {
DUK_ASSERT(heap->curr_thread != NULL);
DUK_ERROR_TYPE(heap->curr_thread, "caught invalid c++ exception (perhaps thrown by user code)");
+ DUK_WO_NORETURN(return;);
} catch (duk_internal_exception exc) {
DUK_D(DUK_DPRINT("caught api error thrown from unexpected c++ exception"));
DUK_UNREF(exc);
@@ -74833,7 +76005,7 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) {
#endif
}
- DUK_UNREACHABLE();
+ DUK_WO_NORETURN(return;);
}
/* Inner executor, performance critical. */
@@ -75202,7 +76374,7 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
/* XXX: fast double-to-int conversion, we know number is integer in [-0x80000000,0xffffffff]. */
val = (duk_int32_t) DUK_TVAL_GET_NUMBER(tv1);
#endif
- val = (val << DUK_BC_LDINTX_SHIFT) + (duk_int32_t) DUK_DEC_BC(ins); /* no bias */
+ val = (duk_int32_t) ((duk_uint32_t) val << DUK_BC_LDINTX_SHIFT) + (duk_int32_t) DUK_DEC_BC(ins); /* no bias */
DUK_TVAL_SET_I32_UPDREF(thr, tv1, val); /* side effects */
break;
}
@@ -76857,7 +78029,7 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
case DUK_OP_INVLHS: {
DUK_ERROR_REFERENCE(thr, DUK_STR_INVALID_LVALUE);
- DUK_UNREACHABLE();
+ DUK_WO_NORETURN(return;);
break;
}
@@ -76892,45 +78064,13 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
case DUK_OP_INVALID: {
DUK_ERROR_FMT1(thr, DUK_ERR_ERROR, "INVALID opcode (%ld)", (long) DUK_DEC_ABC(ins));
+ DUK_WO_NORETURN(return;);
break;
}
#if defined(DUK_USE_ES6)
case DUK_OP_NEWTARGET: {
- /* https://www.ecma-international.org/ecma-262/6.0/#sec-meta-properties-runtime-semantics-evaluation
- * https://www.ecma-international.org/ecma-262/6.0/#sec-getnewtarget
- *
- * No newTarget support now, so as a first approximation
- * use the resolved (non-bound) target function.
- */
- /* XXX: C API: push_new_target()? */
- duk_activation *act;
-
- act = thr->callstack_curr;
- DUK_ASSERT(act != NULL);
-
- /* Check CONSTRUCT flag from current function, or if running
- * direct eval, from a non-direct-eval parent (with possibly
- * more than one nested direct eval). An alternative to this
- * would be to store [[NewTarget]] as a hidden symbol of the
- * lexical scope, and then just look up that variable.
- */
- for (;;) {
- if (act == NULL) {
- duk_push_undefined(thr);
- break;
- }
- if (act->flags & DUK_ACT_FLAG_CONSTRUCT) {
- duk_push_tval(thr, &act->tv_func);
- break;
- } else if (act->flags & DUK_ACT_FLAG_DIRECT_EVAL) {
- act = act->parent;
- } else {
- duk_push_undefined(thr);
- break;
- }
- }
-
+ duk_push_new_target(thr);
DUK__REPLACE_TOP_BC_BREAK();
}
#endif /* DUK_USE_ES6 */
@@ -77032,11 +78172,12 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
continue;
#endif
}
- DUK_UNREACHABLE();
+ DUK_WO_NORETURN(return;);
#if !defined(DUK_USE_VERBOSE_EXECUTOR_ERRORS)
internal_error:
DUK_ERROR_INTERNAL(thr);
+ DUK_WO_NORETURN(return;);
#endif
}
@@ -77105,9 +78246,9 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
#undef DUK__SYNC_CURR_PC
#undef DUK__TVAL_SHIFT
/*
- * Ecmascript specification algorithm and conversion helpers.
+ * ECMAScript specification algorithm and conversion helpers.
*
- * These helpers encapsulate the primitive Ecmascript operation semantics,
+ * These helpers encapsulate the primitive ECMAScript operation semantics,
* and are used by the bytecode executor and the API (among other places).
* Some primitives are only implemented as part of the API and have no
* "internal" helper. This is the case when an internal helper would not
@@ -77323,6 +78464,7 @@ DUK_INTERNAL duk_double_t duk_js_tonumber(duk_hthread *thr, duk_tval *tv) {
duk_hstring *h = DUK_TVAL_GET_STRING(tv);
if (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {
DUK_ERROR_TYPE(thr, DUK_STR_CANNOT_NUMBER_COERCE_SYMBOL);
+ DUK_WO_NORETURN(return 0.0;);
}
duk_push_hstring(thr, h);
return duk__tonumber_string_raw(thr);
@@ -77538,7 +78680,7 @@ DUK_LOCAL duk_bool_t duk__js_equals_number(duk_double_t x, duk_double_t y) {
return 0;
#else /* DUK_USE_PARANOID_MATH */
/* Better equivalent algorithm. If the compiler is compliant, C and
- * Ecmascript semantics are identical for this particular comparison.
+ * ECMAScript semantics are identical for this particular comparison.
* In particular, NaNs must never compare equal and zeroes must compare
* equal regardless of sign. Could also use a macro, but this inlines
* already nicely (no difference on gcc, for instance).
@@ -77831,12 +78973,12 @@ DUK_INTERNAL duk_small_int_t duk_js_data_compare(const duk_uint8_t *buf1, const
prefix_len = (len1 <= len2 ? len1 : len2);
- /* DUK_MEMCMP() is guaranteed to return zero (equal) for zero length
- * inputs so no zero length check is needed.
+ /* duk_memcmp() is guaranteed to return zero (equal) for zero length
+ * inputs.
*/
- rc = DUK_MEMCMP((const void *) buf1,
- (const void *) buf2,
- (size_t) prefix_len);
+ rc = duk_memcmp_unsafe((const void *) buf1,
+ (const void *) buf2,
+ (size_t) prefix_len);
if (rc < 0) {
return -1;
@@ -78103,22 +79245,19 @@ DUK_INTERNAL duk_bool_t duk_js_compare_helper(duk_hthread *thr, duk_tval *tv_x,
*/
/*
- * E5 Section 11.8.6 describes the main algorithm, which uses
- * [[HasInstance]]. [[HasInstance]] is defined for only
- * function objects:
- *
- * - Normal functions:
- * E5 Section 15.3.5.3
- * - Functions established with Function.prototype.bind():
- * E5 Section 15.3.4.5.3
+ * ES2015 Section 7.3.19 describes the OrdinaryHasInstance() algorithm
+ * which covers both bound and non-bound functions; in effect the algorithm
+ * includes E5 Sections 11.8.6, 15.3.5.3, and 15.3.4.5.3.
*
- * For other objects, a TypeError is thrown.
+ * ES2015 Section 12.9.4 describes the instanceof operator which first
+ * checks @@hasInstance well-known symbol and falls back to
+ * OrdinaryHasInstance().
*
* Limited Proxy support: don't support 'getPrototypeOf' trap but
* continue lookup in Proxy target if the value is a Proxy.
*/
-DUK_INTERNAL duk_bool_t duk_js_instanceof(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y) {
+DUK_LOCAL duk_bool_t duk__js_instanceof_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_bool_t skip_sym_check) {
duk_hobject *func;
duk_hobject *val;
duk_hobject *proto;
@@ -78141,6 +79280,23 @@ DUK_INTERNAL duk_bool_t duk_js_instanceof(duk_hthread *thr, duk_tval *tv_x, duk_
func = duk_require_hobject(thr, -1);
DUK_ASSERT(func != NULL);
+#if defined(DUK_USE_SYMBOL_BUILTIN)
+ /*
+ * @@hasInstance check, ES2015 Section 12.9.4, Steps 2-4.
+ */
+ if (!skip_sym_check) {
+ if (duk_get_method_stridx(thr, -1, DUK_STRIDX_WELLKNOWN_SYMBOL_HAS_INSTANCE)) {
+ /* [ ... lhs rhs func ] */
+ duk_insert(thr, -3); /* -> [ ... func lhs rhs ] */
+ duk_swap_top(thr, -2); /* -> [ ... func rhs(this) lhs ] */
+ duk_call_method(thr, 1);
+ return duk_to_boolean_top_pop(thr);
+ }
+ }
+#else
+ DUK_UNREF(skip_sym_check);
+#endif
+
/*
* For bound objects, [[HasInstance]] just calls the target function
* [[HasInstance]]. If that is again a bound object, repeat until
@@ -78152,7 +79308,7 @@ DUK_INTERNAL duk_bool_t duk_js_instanceof(duk_hthread *thr, duk_tval *tv_x, duk_
if (!DUK_HOBJECT_IS_CALLABLE(func)) {
/*
- * Note: of native Ecmascript objects, only Function instances
+ * Note: of native ECMAScript objects, only Function instances
* have a [[HasInstance]] internal property. Custom objects might
* also have it, but not in current implementation.
*
@@ -78162,7 +79318,7 @@ DUK_INTERNAL duk_bool_t duk_js_instanceof(duk_hthread *thr, duk_tval *tv_x, duk_
}
if (DUK_HOBJECT_HAS_BOUNDFUNC(func)) {
- duk_push_tval(thr, &((duk_hboundfunc *) func)->target);
+ duk_push_tval(thr, &((duk_hboundfunc *) (void *) func)->target);
duk_replace(thr, -2);
func = duk_require_hobject(thr, -1); /* lightfunc throws */
@@ -78267,6 +79423,7 @@ DUK_INTERNAL duk_bool_t duk_js_instanceof(duk_hthread *thr, duk_tval *tv_x, duk_
if (DUK_UNLIKELY(sanity == 0)) {
DUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);
+ DUK_WO_NORETURN(return 0;);
}
DUK_UNREACHABLE();
@@ -78284,15 +79441,25 @@ DUK_INTERNAL duk_bool_t duk_js_instanceof(duk_hthread *thr, duk_tval *tv_x, duk_
error_invalid_rval:
DUK_ERROR_TYPE(thr, DUK_STR_INVALID_INSTANCEOF_RVAL);
- return 0;
+ DUK_WO_NORETURN(return 0;);
#if defined(DUK_USE_VERBOSE_ERRORS)
error_invalid_rval_noproto:
DUK_ERROR_TYPE(thr, DUK_STR_INVALID_INSTANCEOF_RVAL_NOPROTO);
- return 0;
+ DUK_WO_NORETURN(return 0;);
#endif
}
+#if defined(DUK_USE_SYMBOL_BUILTIN)
+DUK_INTERNAL duk_bool_t duk_js_instanceof_ordinary(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y) {
+ return duk__js_instanceof_helper(thr, tv_x, tv_y, 1 /*skip_sym_check*/);
+}
+#endif
+
+DUK_INTERNAL duk_bool_t duk_js_instanceof(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y) {
+ return duk__js_instanceof_helper(thr, tv_x, tv_y, 0 /*skip_sym_check*/);
+}
+
/*
* in
*/
@@ -78543,7 +79710,7 @@ DUK_INTERNAL duk_uarridx_t duk_js_to_arrayindex_hstring_fast(duk_hstring *h) {
* be used for most identifier accesses. Consequently, these slow path
* primitives should be optimized for maximum compactness.
*
- * Ecmascript environment records (declarative and object) are represented
+ * ECMAScript environment records (declarative and object) are represented
* as internal objects with control keys. Environment records have a
* parent record ("outer environment reference") which is represented by
* the implicit prototype for technical reasons (in other words, it is a
@@ -78585,7 +79752,7 @@ typedef struct {
* Create a new function object based on a "template function" which contains
* compiled bytecode, constants, etc, but lacks a lexical environment.
*
- * Ecmascript requires that each created closure is a separate object, with
+ * ECMAScript requires that each created closure is a separate object, with
* its own set of editable properties. However, structured property values
* (such as the formal arguments list and the variable map) are shared.
* Also the bytecode, constants, and inner functions are shared.
@@ -79594,6 +80761,7 @@ duk_bool_t duk__get_identifier_reference(duk_hthread *thr,
if (DUK_UNLIKELY(sanity-- == 0)) {
DUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);
+ DUK_WO_NORETURN(return 0;);
}
env = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, env);
}
@@ -79733,6 +80901,7 @@ duk_bool_t duk__getvar_helper(duk_hthread *thr,
DUK_ERROR_FMT1(thr, DUK_ERR_REFERENCE_ERROR,
"identifier '%s' undefined",
(const char *) DUK_HSTRING_GET_DATA(name));
+ DUK_WO_NORETURN(return 0;);
}
return 0;
@@ -79857,6 +81026,7 @@ void duk__putvar_helper(duk_hthread *thr,
DUK_ERROR_FMT1(thr, DUK_ERR_REFERENCE_ERROR,
"identifier '%s' undefined",
(const char *) DUK_HSTRING_GET_DATA(name));
+ DUK_WO_NORETURN(return;);
}
DUK_DDD(DUK_DDDPRINT("identifier binding not found, not strict => set to global"));
@@ -80247,7 +81417,7 @@ duk_bool_t duk__declvar_helper(duk_hthread *thr,
fail_existing_attributes:
fail_not_extensible:
DUK_ERROR_TYPE(thr, "declaration failed");
- return 0;
+ DUK_WO_NORETURN(return 0;);
}
DUK_INTERNAL
@@ -80292,7 +81462,7 @@ duk_bool_t duk_js_declvar_activation(duk_hthread *thr,
* Lexer for source files, ToNumber() string conversions, RegExp expressions,
* and JSON.
*
- * Provides a stream of Ecmascript tokens from an UTF-8/CESU-8 buffer. The
+ * Provides a stream of ECMAScript tokens from an UTF-8/CESU-8 buffer. The
* caller can also rewind the token stream into a certain position which is
* needed by the compiler part for multi-pass scanning. Tokens are
* represented as duk_token structures, and contain line number information.
@@ -80315,14 +81485,14 @@ duk_bool_t duk_js_declvar_activation(duk_hthread *thr,
*
* Token parsing supports the full range of Unicode characters as described
* in the E5 specification. Parsing has been optimized for ASCII characters
- * because ordinary Ecmascript code consists almost entirely of ASCII
+ * because ordinary ECMAScript code consists almost entirely of ASCII
* characters. Matching of complex Unicode codepoint sets (such as in the
* IdentifierStart and IdentifierPart productions) is optimized for size,
* and is done using a linear scan of a bit-packed list of ranges. This is
* very slow, but should never be entered unless the source code actually
* contains Unicode characters.
*
- * Ecmascript tokenization is partially context sensitive. First,
+ * ECMAScript tokenization is partially context sensitive. First,
* additional future reserved words are recognized in strict mode (see E5
* Section 7.6.1.2). Second, a forward slash character ('/') can be
* recognized either as starting a RegExp literal or as a division operator,
@@ -80419,7 +81589,7 @@ duk_bool_t duk_js_declvar_activation(duk_hthread *thr,
*
* * In particular, surrogate pairs are allowed and not combined, which
* allows source files to represent all SourceCharacters with CESU-8.
- * Broken surrogate pairs are allowed, as Ecmascript does not mandate
+ * Broken surrogate pairs are allowed, as ECMAScript does not mandate
* their validation.
*
* * Allow non-shortest UTF-8 encodings.
@@ -80427,20 +81597,20 @@ duk_bool_t duk_js_declvar_activation(duk_hthread *thr,
* Leniency here causes few security concerns because all character data is
* decoded into Unicode codepoints before lexer processing, and is then
* re-encoded into CESU-8. The source can be parsed as strict UTF-8 with
- * a compiler option. However, Ecmascript source characters include -all-
+ * a compiler option. However, ECMAScript source characters include -all-
* 16-bit unsigned integer codepoints, so leniency seems to be appropriate.
*
* Note that codepoints above the BMP are not strictly SourceCharacters,
* but the lexer still accepts them as such. Before ending up in a string
* or an identifier name, codepoints above BMP are converted into surrogate
* pairs and then CESU-8 encoded, resulting in 16-bit Unicode data as
- * expected by Ecmascript.
+ * expected by ECMAScript.
*
* An alternative approach to dealing with invalid or partial sequences
* would be to skip them and replace them with e.g. the Unicode replacement
* character U+FFFD. This has limited utility because a replacement character
* will most likely cause a parse error, unless it occurs inside a string.
- * Further, Ecmascript source is typically pure ASCII.
+ * Further, ECMAScript source is typically pure ASCII.
*
* See:
*
@@ -80603,6 +81773,7 @@ DUK_LOCAL void duk__fill_lexer_buffer(duk_lexer_ctx *lex_ctx, duk_small_uint_t s
lex_ctx->input_line = input_line;
DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_SOURCE_DECODE_FAILED);
+ DUK_WO_NORETURN(return;);
}
DUK_LOCAL void duk__advance_bytes(duk_lexer_ctx *lex_ctx, duk_small_uint_t count_bytes) {
@@ -80625,7 +81796,7 @@ DUK_LOCAL void duk__advance_bytes(duk_lexer_ctx *lex_ctx, duk_small_uint_t count
/* Not enough data to provide a full window, so "scroll" window to
* start of buffer and fill up the rest.
*/
- DUK_MEMMOVE((void *) lex_ctx->buffer,
+ duk_memmove((void *) lex_ctx->buffer,
(const void *) lex_ctx->window,
(size_t) avail_bytes);
lex_ctx->window = lex_ctx->buffer;
@@ -80763,7 +81934,7 @@ DUK_LOCAL duk_codepoint_t duk__read_char(duk_lexer_ctx *lex_ctx) {
error_clipped: /* clipped codepoint */
error_encoding: /* invalid codepoint encoding or codepoint */
DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_SOURCE_DECODE_FAILED);
- return 0;
+ DUK_WO_NORETURN(return 0;);
}
DUK_LOCAL void duk__advance_bytes(duk_lexer_ctx *lex_ctx, duk_small_uint_t count_bytes) {
@@ -80776,7 +81947,7 @@ DUK_LOCAL void duk__advance_bytes(duk_lexer_ctx *lex_ctx, duk_small_uint_t count
/* Zero 'count' is also allowed to make call sites easier. */
keep_bytes = DUK_LEXER_WINDOW_SIZE * sizeof(duk_lexer_codepoint) - count_bytes;
- DUK_MEMMOVE((void *) lex_ctx->window,
+ duk_memmove((void *) lex_ctx->window,
(const void *) ((duk_uint8_t *) lex_ctx->window + count_bytes),
(size_t) keep_bytes);
@@ -80865,7 +82036,7 @@ DUK_LOCAL duk_hstring *duk__internbuffer(duk_lexer_ctx *lex_ctx, duk_idx_t valst
DUK_INTERNAL void duk_lexer_initctx(duk_lexer_ctx *lex_ctx) {
DUK_ASSERT(lex_ctx != NULL);
- DUK_MEMZERO(lex_ctx, sizeof(*lex_ctx));
+ duk_memzero(lex_ctx, sizeof(*lex_ctx));
#if defined(DUK_USE_EXPLICIT_NULL_INIT)
#if defined(DUK_USE_LEXER_SLIDING_WINDOW)
lex_ctx->window = NULL;
@@ -81030,6 +82201,7 @@ DUK_LOCAL duk_codepoint_t duk__lexer_parse_escape(duk_lexer_ctx *lex_ctx, duk_bo
fail_escape:
DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_ESCAPE);
+ DUK_WO_NORETURN(return 0;);
}
/* Parse legacy octal escape of the form \N{1,3}, e.g. \0, \5, \0377. Maximum
@@ -81226,11 +82398,11 @@ DUK_LOCAL void duk__lexer_parse_string_literal(duk_lexer_ctx *lex_ctx, duk_token
fail_escape:
DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_ESCAPE);
- return;
+ DUK_WO_NORETURN(return;);
fail_unterminated:
DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_UNTERMINATED_STRING);
- return;
+ DUK_WO_NORETURN(return;);
}
/* Skip to end-of-line (or end-of-file), used for single line comments. */
@@ -81247,7 +82419,7 @@ DUK_LOCAL void duk__lexer_skip_to_endofline(duk_lexer_ctx *lex_ctx) {
}
/*
- * Parse Ecmascript source InputElementDiv or InputElementRegExp
+ * Parse ECMAScript source InputElementDiv or InputElementRegExp
* (E5 Section 7), skipping whitespace, comments, and line terminators.
*
* Possible results are:
@@ -81274,13 +82446,13 @@ DUK_LOCAL void duk__lexer_skip_to_endofline(duk_lexer_ctx *lex_ctx) {
* lookup window to quickly determine which production is the -longest-
* matching one, and then parse that. The top-level if-else clauses
* match the first character, and the code blocks for each clause
- * handle -all- alternatives for that first character. Ecmascript
+ * handle -all- alternatives for that first character. ECMAScript
* specification uses the "longest match wins" semantics, so the order
* of the if-clauses matters.
*
* Misc notes:
*
- * * Ecmascript numeric literals do not accept a sign character.
+ * * ECMAScript numeric literals do not accept a sign character.
* Consequently e.g. "-1.0" is parsed as two tokens: a negative
* sign and a positive numeric literal. The compiler performs
* the negation during compilation, so this has no adverse impact.
@@ -81790,7 +82962,7 @@ void duk_lexer_parse_js_input_element(duk_lexer_ctx *lex_ctx,
* (the tokens DUK_TOK_GET and DUK_TOK_SET are actually not
* used now). The compiler needs to work around this.
*
- * Strictly speaking, following Ecmascript longest match
+ * Strictly speaking, following ECMAScript longest match
* specification, an invalid escape for the first character
* should cause a syntax error. However, an invalid escape
* for IdentifierParts should just terminate the identifier
@@ -82074,32 +83246,32 @@ void duk_lexer_parse_js_input_element(duk_lexer_ctx *lex_ctx,
fail_token_limit:
DUK_ERROR_RANGE(lex_ctx->thr, DUK_STR_TOKEN_LIMIT);
- return;
+ DUK_WO_NORETURN(return;);
fail_token:
DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_TOKEN);
- return;
+ DUK_WO_NORETURN(return;);
fail_number_literal:
DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_NUMBER_LITERAL);
- return;
+ DUK_WO_NORETURN(return;);
fail_escape:
DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_ESCAPE);
- return;
+ DUK_WO_NORETURN(return;);
fail_unterm_regexp:
DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_UNTERMINATED_REGEXP);
- return;
+ DUK_WO_NORETURN(return;);
fail_unterm_comment:
DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_UNTERMINATED_COMMENT);
- return;
+ DUK_WO_NORETURN(return;);
#if !defined(DUK_USE_REGEXP_SUPPORT)
fail_regexp_support:
DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_REGEXP_SUPPORT_DISABLED);
- return;
+ DUK_WO_NORETURN(return;);
#endif
}
@@ -82122,7 +83294,7 @@ DUK_INTERNAL void duk_lexer_parse_re_token(duk_lexer_ctx *lex_ctx, duk_re_token
goto fail_token_limit;
}
- DUK_MEMZERO(out_token, sizeof(*out_token));
+ duk_memzero(out_token, sizeof(*out_token));
x = DUK__L0();
y = DUK__L1();
@@ -82447,24 +83619,24 @@ DUK_INTERNAL void duk_lexer_parse_re_token(duk_lexer_ctx *lex_ctx, duk_re_token
fail_token_limit:
DUK_ERROR_RANGE(lex_ctx->thr, DUK_STR_TOKEN_LIMIT);
- return;
+ DUK_WO_NORETURN(return;);
fail_escape:
DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_REGEXP_ESCAPE);
- return;
+ DUK_WO_NORETURN(return;);
fail_group:
DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_REGEXP_GROUP);
- return;
+ DUK_WO_NORETURN(return;);
#if !defined(DUK_USE_ES6_REGEXP_SYNTAX)
fail_invalid_char:
DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_REGEXP_CHARACTER);
- return;
+ DUK_WO_NORETURN(return;);
fail_quantifier:
DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_QUANTIFIER);
- return;
+ DUK_WO_NORETURN(return;);
#endif
}
@@ -82713,15 +83885,15 @@ DUK_INTERNAL void duk_lexer_parse_re_ranges(duk_lexer_ctx *lex_ctx, duk_re_range
fail_escape:
DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_REGEXP_ESCAPE);
- return;
+ DUK_WO_NORETURN(return;);
fail_range:
DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_RANGE);
- return;
+ DUK_WO_NORETURN(return;);
fail_unterm_charclass:
DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_UNTERMINATED_CHARCLASS);
- return;
+ DUK_WO_NORETURN(return;);
}
#endif /* DUK_USE_REGEXP_SUPPORT */
@@ -82882,10 +84054,8 @@ DUK_LOCAL void duk__bi_copy(duk__bigint *x, duk__bigint *y) {
n = y->n;
x->n = n;
- if (n == 0) {
- return;
- }
- DUK_MEMCPY((void *) x->v, (const void *) y->v, (size_t) (sizeof(duk_uint32_t) * (size_t) n));
+ /* No need to special case n == 0. */
+ duk_memcpy((void *) x->v, (const void *) y->v, (size_t) (sizeof(duk_uint32_t) * (size_t) n));
}
DUK_LOCAL void duk__bi_set_small(duk__bigint *x, duk_uint32_t v) {
@@ -83161,7 +84331,7 @@ DUK_LOCAL void duk__bi_mul(duk__bigint *x, duk__bigint *y, duk__bigint *z) {
return;
}
- DUK_MEMZERO((void *) x->v, (size_t) (sizeof(duk_uint32_t) * (size_t) nx));
+ duk_memzero((void *) x->v, (size_t) (sizeof(duk_uint32_t) * (size_t) nx));
x->n = nx;
nz = z->n;
@@ -83311,7 +84481,7 @@ DUK_LOCAL void duk__bi_twoexp(duk__bigint *x, duk_small_int_t y) {
n = (y / 32) + 1;
DUK_ASSERT(n > 0);
r = y % 32;
- DUK_MEMZERO((void *) x->v, sizeof(duk_uint32_t) * (size_t) n);
+ duk_memzero((void *) x->v, sizeof(duk_uint32_t) * (size_t) n);
x->n = n;
x->v[n - 1] = (((duk_uint32_t) 1) << r);
}
@@ -83425,6 +84595,7 @@ DUK_LOCAL duk_size_t duk__dragon4_format_uint32(duk_uint8_t *buf, duk_uint32_t x
duk_small_int_t dig;
duk_uint32_t t;
+ DUK_ASSERT(buf != NULL);
DUK_ASSERT(radix >= 2 && radix <= 36);
/* A 32-bit unsigned integer formats to at most 32 digits (the
@@ -83447,7 +84618,7 @@ DUK_LOCAL duk_size_t duk__dragon4_format_uint32(duk_uint8_t *buf, duk_uint32_t x
}
len = (duk_size_t) ((buf + 32) - p);
- DUK_MEMMOVE((void *) buf, (const void *) p, (size_t) len);
+ duk_memmove((void *) buf, (const void *) p, (size_t) len);
return len;
}
@@ -83850,7 +85021,7 @@ DUK_LOCAL void duk__dragon4_generate(duk__numconv_stringify_ctx *nc_ctx) {
{
duk_uint8_t buf[2048];
duk_small_int_t i, t;
- DUK_MEMZERO(buf, sizeof(buf));
+ duk_memzero(buf, sizeof(buf));
for (i = 0; i < nc_ctx->count; i++) {
t = nc_ctx->digits[i];
if (t < 0 || t > 36) {
@@ -83915,7 +85086,7 @@ DUK_LOCAL duk_small_int_t duk__dragon4_fixed_format_round(duk__numconv_stringify
*p = 0;
if (p == &nc_ctx->digits[0]) {
DUK_DDD(DUK_DDDPRINT("carry propagated to first digit -> special case handling"));
- DUK_MEMMOVE((void *) (&nc_ctx->digits[1]),
+ duk_memmove((void *) (&nc_ctx->digits[1]),
(const void *) (&nc_ctx->digits[0]),
(size_t) (sizeof(char) * (size_t) nc_ctx->count));
nc_ctx->digits[0] = 1; /* don't increase 'count' */
@@ -83959,7 +85130,7 @@ DUK_LOCAL void duk__dragon4_convert_and_push(duk__numconv_stringify_ctx *nc_ctx,
duk_uint8_t *buf;
/*
- * The string conversion here incorporates all the necessary Ecmascript
+ * The string conversion here incorporates all the necessary ECMAScript
* semantics without attempting to be generic. nc_ctx->digits contains
* nc_ctx->count digits (>= 1), with the topmost digit's 'position'
* indicated by nc_ctx->k as follows:
@@ -83970,11 +85141,11 @@ DUK_LOCAL void duk__dragon4_convert_and_push(duk__numconv_stringify_ctx *nc_ctx,
* digits="123" count=3 k=-1 --> 0.0123
*
* Note that the identifier names used for format selection are different
- * in Burger-Dybvig paper and Ecmascript specification (quite confusingly
+ * in Burger-Dybvig paper and ECMAScript specification (quite confusingly
* so, because e.g. 'k' has a totally different meaning in each). See
* documentation for discussion.
*
- * Ecmascript doesn't specify any specific behavior for format selection
+ * ECMAScript doesn't specify any specific behavior for format selection
* (e.g. when to use exponent notation) for non-base-10 numbers.
*
* The bigint space in the context is reused for string output, as there
@@ -84058,7 +85229,7 @@ DUK_LOCAL void duk__dragon4_convert_and_push(duk__numconv_stringify_ctx *nc_ctx,
/* Exponent */
if (expt != DUK__NO_EXP) {
/*
- * Exponent notation for non-base-10 numbers isn't specified in Ecmascript
+ * Exponent notation for non-base-10 numbers isn't specified in ECMAScript
* specification, as it never explicitly turns up: non-decimal numbers can
* only be formatted with Number.prototype.toString([radix]) and for that,
* behavior is not explicitly specified.
@@ -84160,7 +85331,7 @@ DUK_LOCAL void duk__dragon4_ctx_to_double(duk__numconv_stringify_ctx *nc_ctx, du
* (perhaps because the low part is set (seemingly) conditionally in a
* loop), so this is here to avoid the bogus warning.
*/
- DUK_MEMZERO((void *) &u, sizeof(u));
+ duk_memzero((void *) &u, sizeof(u));
/*
* Figure out how generated digits match up with the mantissa,
@@ -84343,7 +85514,7 @@ DUK_INTERNAL void duk_numconv_stringify(duk_hthread *thr, duk_small_int_t radix,
* sprintf "%lu" for the fast path and for exponent formatting.
*/
- uval = (unsigned int) x;
+ uval = duk_double_to_uint32_t(x);
if (((double) uval) == x && /* integer number in range */
flags == 0) { /* no special formatting */
/* use bigint area as a temp */
@@ -84375,7 +85546,7 @@ DUK_INTERNAL void duk_numconv_stringify(duk_hthread *thr, duk_small_int_t radix,
* is 1-2 kilobytes and nothing should rely on it being zeroed.
*/
#if 0
- DUK_MEMZERO((void *) nc_ctx, sizeof(*nc_ctx)); /* slow init, do only for slow path cases */
+ duk_memzero((void *) nc_ctx, sizeof(*nc_ctx)); /* slow init, do only for slow path cases */
#endif
nc_ctx->is_s2n = 0;
@@ -84415,7 +85586,7 @@ DUK_INTERNAL void duk_numconv_stringify(duk_hthread *thr, duk_small_int_t radix,
}
DUK_DDD(DUK_DDDPRINT("count=%ld", (long) count));
DUK_ASSERT(count >= 1);
- DUK_MEMZERO((void *) nc_ctx->digits, (size_t) count);
+ duk_memzero((void *) nc_ctx->digits, (size_t) count);
nc_ctx->count = count;
nc_ctx->k = 1; /* 0.000... */
neg = 0;
@@ -84495,8 +85666,8 @@ DUK_INTERNAL void duk_numconv_parse(duk_hthread *thr, duk_small_int_t radix, duk
duk__numconv_stringify_ctx *nc_ctx = &nc_ctx_alloc;
duk_double_t res;
duk_hstring *h_str;
- duk_small_int_t expt;
- duk_small_int_t expt_neg;
+ duk_int_t expt;
+ duk_bool_t expt_neg;
duk_small_int_t expt_adj;
duk_small_int_t neg;
duk_small_int_t dig;
@@ -84632,7 +85803,7 @@ DUK_INTERNAL void duk_numconv_parse(duk_hthread *thr, duk_small_int_t radix, duk
* accuracy, so that Dragon4 will generate enough binary output digits.
* For decimal numbers, this means generating a 20-digit significand,
* which should yield enough practical accuracy to parse IEEE doubles.
- * In fact, the Ecmascript specification explicitly allows an
+ * In fact, the ECMAScript specification explicitly allows an
* implementation to treat digits beyond 20 as zeroes (and even
* to round the 20th digit upwards). For non-decimal numbers, the
* appropriate number of digits has been precomputed for comparable
@@ -84803,9 +85974,10 @@ DUK_INTERNAL void duk_numconv_parse(duk_hthread *thr, duk_small_int_t radix, duk
} else {
/* exponent digit */
+ DUK_ASSERT(radix == 10);
expt = expt * radix + dig;
if (expt > DUK_S2N_MAX_EXPONENT) {
- /* impose a reasonable exponent limit, so that exp
+ /* Impose a reasonable exponent limit, so that exp
* doesn't need to get tracked using a bigint.
*/
DUK_DDD(DUK_DDDPRINT("parse failed: exponent too large"));
@@ -85008,7 +86180,7 @@ DUK_INTERNAL void duk_numconv_parse(duk_hthread *thr, duk_small_int_t radix, duk
parse_explimit_error:
DUK_DDD(DUK_DDDPRINT("parse failed, internal error, can't return a value"));
DUK_ERROR_RANGE(thr, "exponent too large");
- return;
+ DUK_WO_NORETURN(return;);
}
/* automatic undefs */
@@ -85549,6 +86721,7 @@ DUK_LOCAL void duk__parse_disjunction(duk_re_compiler_ctx *re_ctx, duk_bool_t ex
if (re_ctx->recursion_depth >= re_ctx->recursion_limit) {
DUK_ERROR_RANGE(re_ctx->thr, DUK_STR_REGEXP_COMPILER_RECURSION_LIMIT);
+ DUK_WO_NORETURN(return;);
}
re_ctx->recursion_depth++;
@@ -85622,9 +86795,11 @@ DUK_LOCAL void duk__parse_disjunction(duk_re_compiler_ctx *re_ctx, duk_bool_t ex
case DUK_RETOK_QUANTIFIER: {
if (atom_start_offset < 0) {
DUK_ERROR_SYNTAX(re_ctx->thr, DUK_STR_INVALID_QUANTIFIER_NO_ATOM);
+ DUK_WO_NORETURN(return;);
}
if (re_ctx->curr_token.qmin > re_ctx->curr_token.qmax) {
DUK_ERROR_SYNTAX(re_ctx->thr, DUK_STR_INVALID_QUANTIFIER_VALUES);
+ DUK_WO_NORETURN(return;);
}
if (atom_char_length >= 0) {
/*
@@ -85693,6 +86868,7 @@ DUK_LOCAL void duk__parse_disjunction(duk_re_compiler_ctx *re_ctx, duk_bool_t ex
re_ctx->curr_token.qmin : re_ctx->curr_token.qmax;
if (atom_copies > DUK_RE_MAX_ATOM_COPIES) {
DUK_ERROR_RANGE(re_ctx->thr, DUK_STR_QUANTIFIER_TOO_MANY_COPIES);
+ DUK_WO_NORETURN(return;);
}
/* wipe the capture range made by the atom (if any) */
@@ -85956,17 +87132,20 @@ DUK_LOCAL void duk__parse_disjunction(duk_re_compiler_ctx *re_ctx, duk_bool_t ex
case DUK_RETOK_ATOM_END_GROUP: {
if (expect_eof) {
DUK_ERROR_SYNTAX(re_ctx->thr, DUK_STR_UNEXPECTED_CLOSING_PAREN);
+ DUK_WO_NORETURN(return;);
}
goto done;
}
case DUK_RETOK_EOF: {
if (!expect_eof) {
DUK_ERROR_SYNTAX(re_ctx->thr, DUK_STR_UNEXPECTED_END_OF_PATTERN);
+ DUK_WO_NORETURN(return;);
}
goto done;
}
default: {
DUK_ERROR_SYNTAX(re_ctx->thr, DUK_STR_UNEXPECTED_REGEXP_TOKEN);
+ DUK_WO_NORETURN(return;);
}
}
@@ -86061,7 +87240,7 @@ DUK_LOCAL duk_uint32_t duk__parse_regexp_flags(duk_hthread *thr, duk_hstring *h)
flags_error:
DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_REGEXP_FLAGS);
- return 0; /* never here */
+ DUK_WO_NORETURN(return 0U;);
}
/*
@@ -86098,7 +87277,7 @@ DUK_LOCAL void duk__create_escaped_source(duk_hthread *thr, int idx_pattern) {
n = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h);
if (n == 0) {
- duk_push_string(thr, "(?:)");
+ duk_push_literal(thr, "(?:)");
return;
}
@@ -86178,7 +87357,7 @@ DUK_INTERNAL void duk_regexp_compile(duk_hthread *thr) {
/* [ ... pattern flags escaped_source buffer ] */
- DUK_MEMZERO(&re_ctx, sizeof(re_ctx));
+ duk_memzero(&re_ctx, sizeof(re_ctx));
DUK_LEXER_INITCTX(&re_ctx.lex); /* duplicate zeroing, expect for (possible) NULL inits */
re_ctx.thr = thr;
re_ctx.lex.thr = thr;
@@ -86225,6 +87404,7 @@ DUK_INTERNAL void duk_regexp_compile(duk_hthread *thr) {
if (re_ctx.highest_backref > re_ctx.captures) {
DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_BACKREFS);
+ DUK_WO_NORETURN(return;);
}
/*
@@ -86308,7 +87488,7 @@ DUK_INTERNAL void duk_regexp_create_instance(duk_hthread *thr) {
/*
* Regexp executor.
*
- * Safety: the Ecmascript executor should prevent user from reading and
+ * Safety: the ECMAScript executor should prevent user from reading and
* replacing regexp bytecode. Even so, the executor must validate all
* memory accesses etc. When an invalid access is detected (e.g. a 'save'
* opcode to invalid, unallocated index) it should fail with an internal
@@ -86375,7 +87555,7 @@ DUK_LOCAL const duk_uint8_t *duk__utf8_backtrack(duk_hthread *thr, const duk_uin
fail:
DUK_ERROR_INTERNAL(thr);
- return NULL; /* never here */
+ DUK_WO_NORETURN(return NULL;);
}
DUK_LOCAL const duk_uint8_t *duk__utf8_advance(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end, duk_uint_fast32_t count) {
@@ -86406,7 +87586,7 @@ DUK_LOCAL const duk_uint8_t *duk__utf8_advance(duk_hthread *thr, const duk_uint8
fail:
DUK_ERROR_INTERNAL(thr);
- return NULL; /* never here */
+ DUK_WO_NORETURN(return NULL;);
}
/*
@@ -86455,6 +87635,7 @@ DUK_LOCAL duk_codepoint_t duk__inp_get_prev_cp(duk_re_matcher_ctx *re_ctx, const
DUK_LOCAL const duk_uint8_t *duk__match_regexp(duk_re_matcher_ctx *re_ctx, const duk_uint8_t *pc, const duk_uint8_t *sp) {
if (re_ctx->recursion_depth >= re_ctx->recursion_limit) {
DUK_ERROR_RANGE(re_ctx->thr, DUK_STR_REGEXP_EXECUTOR_RECURSION_LIMIT);
+ DUK_WO_NORETURN(return NULL;);
}
re_ctx->recursion_depth++;
@@ -86463,6 +87644,7 @@ DUK_LOCAL const duk_uint8_t *duk__match_regexp(duk_re_matcher_ctx *re_ctx, const
if (re_ctx->steps_count >= re_ctx->steps_limit) {
DUK_ERROR_RANGE(re_ctx->thr, DUK_STR_REGEXP_EXECUTOR_STEP_LIMIT);
+ DUK_WO_NORETURN(return NULL;);
}
re_ctx->steps_count++;
@@ -86808,14 +87990,14 @@ DUK_LOCAL const duk_uint8_t *duk__match_regexp(duk_re_matcher_ctx *re_ctx, const
range_save = (duk_uint8_t **) duk_push_fixed_buffer_nozero(re_ctx->thr,
sizeof(duk_uint8_t *) * idx_count);
DUK_ASSERT(range_save != NULL);
- DUK_MEMCPY(range_save, re_ctx->saved + idx_start, sizeof(duk_uint8_t *) * idx_count);
+ duk_memcpy(range_save, re_ctx->saved + idx_start, sizeof(duk_uint8_t *) * idx_count);
#if defined(DUK_USE_EXPLICIT_NULL_INIT)
idx_end = idx_start + idx_count;
for (idx = idx_start; idx < idx_end; idx++) {
re_ctx->saved[idx] = NULL;
}
#else
- DUK_MEMZERO((void *) (re_ctx->saved + idx_start), sizeof(duk_uint8_t *) * idx_count);
+ duk_memzero((void *) (re_ctx->saved + idx_start), sizeof(duk_uint8_t *) * idx_count);
#endif
sub_sp = duk__match_regexp(re_ctx, pc, sp);
@@ -86833,7 +88015,7 @@ DUK_LOCAL const duk_uint8_t *duk__match_regexp(duk_re_matcher_ctx *re_ctx, const
DUK_DDD(DUK_DDDPRINT("fail: restore wiped/resaved values [%ld,%ld] (captures [%ld,%ld])",
(long) idx_start, (long) (idx_start + idx_count - 1),
(long) (idx_start / 2), (long) ((idx_start + idx_count - 1) / 2)));
- DUK_MEMCPY((void *) (re_ctx->saved + idx_start),
+ duk_memcpy((void *) (re_ctx->saved + idx_start),
(const void *) range_save,
sizeof(duk_uint8_t *) * idx_count);
duk_pop_unsafe(re_ctx->thr);
@@ -86865,7 +88047,7 @@ DUK_LOCAL const duk_uint8_t *duk__match_regexp(duk_re_matcher_ctx *re_ctx, const
full_save = (duk_uint8_t **) duk_push_fixed_buffer_nozero(re_ctx->thr,
sizeof(duk_uint8_t *) * re_ctx->nsaved);
DUK_ASSERT(full_save != NULL);
- DUK_MEMCPY(full_save, re_ctx->saved, sizeof(duk_uint8_t *) * re_ctx->nsaved);
+ duk_memcpy(full_save, re_ctx->saved, sizeof(duk_uint8_t *) * re_ctx->nsaved);
skip = duk__bc_get_i32(re_ctx, &pc);
sub_sp = duk__match_regexp(re_ctx, pc, sp);
@@ -86890,7 +88072,7 @@ DUK_LOCAL const duk_uint8_t *duk__match_regexp(duk_re_matcher_ctx *re_ctx, const
lookahead_fail:
/* fail: restore saves */
- DUK_MEMCPY((void *) re_ctx->saved,
+ duk_memcpy((void *) re_ctx->saved,
(const void *) full_save,
sizeof(duk_uint8_t *) * re_ctx->nsaved);
duk_pop_unsafe(re_ctx->thr);
@@ -86972,7 +88154,7 @@ DUK_LOCAL const duk_uint8_t *duk__match_regexp(duk_re_matcher_ctx *re_ctx, const
internal_error:
DUK_ERROR_INTERNAL(re_ctx->thr);
- return NULL; /* never here */
+ DUK_WO_NORETURN(return NULL;);
}
/*
@@ -87038,7 +88220,7 @@ DUK_LOCAL void duk__regexp_match_helper(duk_hthread *thr, duk_small_int_t force_
/* [ ... re_obj input bc ] */
- DUK_MEMZERO(&re_ctx, sizeof(re_ctx));
+ duk_memzero(&re_ctx, sizeof(re_ctx));
re_ctx.thr = thr;
re_ctx.input = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input);
@@ -87075,7 +88257,7 @@ DUK_LOCAL void duk__regexp_match_helper(duk_hthread *thr, duk_small_int_t force_
#elif defined(DUK_USE_ZERO_BUFFER_DATA)
/* buffer is automatically zeroed */
#else
- DUK_MEMZERO((void *) p_buf, sizeof(duk_uint8_t *) * re_ctx.nsaved);
+ duk_memzero((void *) p_buf, sizeof(duk_uint8_t *) * re_ctx.nsaved);
#endif
DUK_DDD(DUK_DDDPRINT("regexp ctx initialized, flags=0x%08lx, nsaved=%ld, recursion_limit=%ld, steps_limit=%ld",
@@ -87160,7 +88342,7 @@ DUK_LOCAL void duk__regexp_match_helper(duk_hthread *thr, duk_small_int_t force_
* internal/limit error occurs (which causes a longjmp())
*
* - If we supported anchored matches, we would break out here
- * unconditionally; however, Ecmascript regexps don't have anchored
+ * unconditionally; however, ECMAScript regexps don't have anchored
* matches. It might make sense to implement a fast bail-out if
* the regexp begins with '^' and sp is not 0: currently we'll just
* run through the entire input string, trivially failing the match
@@ -87354,13 +88536,13 @@ typedef union {
} while (0)
#define DUK__DBLUNION_CMP_TRUE(a,b) do { \
- if (DUK_MEMCMP((const void *) (a), (const void *) (b), sizeof(duk__test_double_union)) != 0) { \
+ if (duk_memcmp((const void *) (a), (const void *) (b), sizeof(duk__test_double_union)) != 0) { \
DUK__FAILED("double union compares false (expected true)"); \
} \
} while (0)
#define DUK__DBLUNION_CMP_FALSE(a,b) do { \
- if (DUK_MEMCMP((const void *) (a), (const void *) (b), sizeof(duk__test_double_union)) == 0) { \
+ if (duk_memcmp((const void *) (a), (const void *) (b), sizeof(duk__test_double_union)) == 0) { \
DUK__FAILED("double union compares true (expected false)"); \
} \
} while (0)
@@ -87669,7 +88851,7 @@ DUK_LOCAL duk_uint_t duk__selftest_double_rounding(void) {
*/
DUK__DOUBLE_INIT(&a, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
DUK__DOUBLE_INIT(&b, 0x3c, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
- DUK_MEMSET((void *) &c, 0, sizeof(c));
+ duk_memset((void *) &c, 0, sizeof(c));
c.d = a.d + b.d;
if (!DUK__DOUBLE_COMPARE(&c, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)) {
DUK_D(DUK_DPRINT("broken result (native endiannesss): %02x %02x %02x %02x %02x %02x %02x %02x",
@@ -87689,7 +88871,7 @@ DUK_LOCAL duk_uint_t duk__selftest_double_rounding(void) {
*/
DUK__DOUBLE_INIT(&a, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01);
DUK__DOUBLE_INIT(&b, 0x3c, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
- DUK_MEMSET((void *) &c, 0, sizeof(c));
+ duk_memset((void *) &c, 0, sizeof(c));
c.d = a.d + b.d;
if (!DUK__DOUBLE_COMPARE(&c, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02)) {
DUK_D(DUK_DPRINT("broken result (native endiannesss): %02x %02x %02x %02x %02x %02x %02x %02x",
@@ -88126,7 +89308,7 @@ DUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_tval_get_number_unpacked_fastint
* packed format. These tables are used to match non-ASCII
* characters of complex productions by resorting to a linear
* range-by-range comparison. This is very slow, but is expected
- * to be very rare in practical Ecmascript source code, and thus
+ * to be very rare in practical ECMAScript source code, and thus
* compactness is most important.
*
* The tables are matched using uni_range_match() and the format
@@ -88140,54 +89322,55 @@ DUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_tval_get_number_unpacked_fastint
* Automatically generated by extract_chars.py, do not edit!
*/
-const duk_uint8_t duk_unicode_ids_noa[1036] = {
+const duk_uint8_t duk_unicode_ids_noa[1063] = {
249,176,176,80,111,7,47,15,47,254,11,197,191,0,72,2,15,115,66,19,50,7,2,34,
2,240,66,244,50,247,185,249,98,241,99,8,241,127,58,240,182,47,31,241,191,
21,18,245,50,15,1,24,27,35,15,2,2,240,239,15,244,156,15,10,241,26,21,6,240,
-101,10,4,15,9,240,159,57,240,82,127,56,242,100,15,4,8,159,1,240,5,115,19,
-240,98,98,4,52,15,2,14,18,47,0,31,5,85,19,240,98,98,18,18,31,17,50,15,5,47,
-2,130,34,240,98,98,18,68,15,4,15,1,31,9,12,115,19,240,98,98,18,68,15,16,18,
-47,1,15,3,2,84,34,52,18,2,20,20,36,191,8,15,38,114,34,240,114,240,4,15,12,
-38,31,16,5,114,34,240,114,146,68,15,18,2,31,1,31,4,114,34,241,147,15,2,6,
-41,47,10,86,240,36,240,130,130,3,111,44,242,2,29,111,44,18,3,18,3,7,50,98,
-34,2,3,18,50,26,3,66,15,7,63,18,15,49,114,241,79,13,79,101,241,191,6,15,2,
-85,52,4,24,37,205,15,3,241,98,6,3,241,178,255,224,63,35,54,32,35,63,25,35,
-63,17,35,54,32,35,62,47,41,35,63,51,241,127,0,240,47,70,53,79,254,21,227,
-240,18,240,166,243,180,168,194,63,0,240,47,0,240,47,0,194,47,1,242,79,21,5,
-15,53,244,137,67,241,34,6,243,107,240,255,35,240,227,76,241,197,240,175,40,
-240,122,242,95,68,15,79,241,255,3,111,41,240,238,27,241,207,12,241,79,27,
-43,241,67,143,82,50,52,26,251,15,50,255,224,8,53,63,22,53,55,32,32,32,47,
-15,63,37,38,32,66,38,67,53,92,98,38,246,96,224,240,44,245,112,80,57,32,68,
-112,32,32,35,42,51,100,80,240,63,25,255,233,107,241,242,241,242,247,87,52,
-29,241,98,6,3,242,136,15,2,240,122,98,98,98,98,98,98,98,111,66,15,254,12,
-146,240,184,132,52,95,70,114,47,74,35,111,25,79,78,240,63,11,242,127,0,255,
-224,244,255,240,0,138,143,60,255,240,4,12,143,28,255,227,127,243,95,30,63,
-253,79,0,177,240,111,31,240,47,15,63,64,241,152,63,87,63,20,39,243,26,34,
-35,47,7,240,255,36,240,15,34,243,5,64,32,223,12,191,7,240,191,13,143,31,
-240,224,240,36,41,180,47,25,240,146,39,240,111,7,64,79,34,32,65,52,48,32,
-240,162,58,130,213,53,53,166,38,47,27,41,191,99,240,255,255,0,26,150,223,7,
-95,33,255,240,0,255,143,254,6,3,245,175,24,109,70,2,146,194,66,2,18,18,245,
-207,19,255,224,93,240,79,48,63,38,241,171,246,100,47,119,241,111,10,127,10,
-207,73,69,53,53,50,241,91,47,10,47,3,33,46,61,241,79,107,243,127,37,255,
-223,13,79,33,242,31,16,240,47,11,111,22,191,14,63,20,87,36,241,207,142,240,
-79,20,95,20,95,24,159,36,248,239,254,2,154,240,107,127,138,83,2,241,194,20,
-3,240,123,240,122,240,255,51,240,50,27,240,107,240,175,56,242,135,31,50,15,
-1,50,34,240,191,30,240,212,240,223,21,114,240,207,13,242,107,240,107,240,
-62,240,47,96,243,159,41,242,62,242,63,254,32,79,37,243,223,29,241,47,9,240,
-207,20,241,191,19,64,223,32,240,3,240,112,32,241,95,2,47,9,244,102,32,35,
-46,41,143,31,241,135,49,63,6,38,33,36,64,240,64,212,249,15,37,240,67,242,
-127,32,240,97,32,250,175,31,241,179,241,111,32,240,96,242,223,27,244,127,
-10,255,224,122,243,15,17,15,254,11,79,41,255,152,47,21,240,48,242,63,14,
-255,226,100,255,226,140,245,143,95,240,63,180,255,233,176,255,227,33,255,
-238,197,255,225,57,255,240,1,10,223,254,18,184,240,255,99,240,239,4,242,15,
-2,63,17,240,86,240,63,254,38,79,53,192,243,76,243,32,241,31,255,0,6,223,
-240,95,254,30,95,255,0,20,1,31,254,175,47,91,108,72,137,255,240,0,101,175,
-69,47,55,33,48,49,51,43,32,38,47,49,35,55,38,47,12,35,36,32,70,47,254,4,99,
-240,146,240,146,240,242,240,146,240,242,240,146,240,242,240,146,240,242,
-240,146,127,254,242,143,181,242,223,52,255,227,176,50,240,178,18,3,2,146,
-50,2,7,5,2,2,2,34,18,3,2,2,2,2,2,18,3,50,98,50,50,2,146,240,22,34,66,240,
-31,255,0,0,56,255,240,9,92,159,27,255,239,39,207,206,63,255,0,5,116,255,
-240,1,133,47,254,17,0,
+101,10,4,15,9,240,152,175,39,240,82,127,56,242,100,15,4,8,159,1,240,5,115,
+19,240,98,98,4,52,15,2,14,18,47,0,27,9,85,19,240,98,98,18,18,31,17,50,15,5,
+47,2,130,34,240,98,98,18,68,15,4,15,1,31,9,12,115,19,240,98,98,18,68,15,16,
+18,47,1,15,3,2,84,34,52,18,2,20,20,36,191,8,15,38,114,34,240,114,240,4,15,
+12,38,31,16,5,114,34,240,114,146,68,15,18,2,31,1,31,4,114,34,241,147,15,2,
+6,41,47,10,86,240,36,240,130,130,3,111,44,242,2,29,111,44,18,3,18,3,7,50,
+98,34,2,3,18,50,26,3,66,15,7,63,18,15,49,114,241,79,13,79,101,241,191,6,15,
+2,85,52,4,24,37,205,15,3,241,98,6,3,241,178,255,224,63,35,54,32,35,63,25,
+35,63,17,35,54,32,35,62,47,41,35,63,51,241,127,0,240,47,70,53,79,254,21,
+227,240,18,240,166,243,180,168,194,63,0,240,47,0,240,47,0,194,47,1,242,79,
+21,5,15,53,244,137,67,241,34,6,243,107,240,255,35,240,227,76,241,197,240,
+175,40,240,122,242,95,68,15,79,241,255,3,111,41,240,238,27,241,207,12,241,
+79,27,43,241,67,143,82,50,52,26,251,15,50,255,224,8,53,63,22,53,55,32,32,
+32,47,15,63,37,38,32,66,38,67,53,92,98,38,246,96,224,240,44,245,112,80,57,
+32,68,112,32,32,35,42,51,100,80,240,63,25,255,233,107,241,242,241,242,247,
+87,52,29,241,98,6,3,242,136,15,2,240,122,98,98,98,98,98,98,98,111,66,15,
+254,12,146,240,184,132,52,95,70,114,47,74,35,111,26,63,78,240,63,11,242,
+127,0,255,224,244,255,240,0,138,143,60,255,240,4,13,223,7,255,227,127,243,
+95,30,63,253,79,0,177,240,111,31,240,47,15,63,64,241,152,63,87,63,20,39,
+243,26,34,35,47,7,240,255,36,240,15,34,243,5,64,32,223,12,191,7,240,191,13,
+143,31,240,224,240,36,41,180,47,25,240,146,39,240,111,7,64,79,34,32,65,52,
+48,32,240,162,58,130,213,53,53,166,38,47,27,41,191,99,240,255,255,0,26,150,
+223,7,95,33,255,240,0,255,143,254,6,3,245,175,24,109,70,2,146,194,66,2,18,
+18,245,207,19,255,224,93,240,79,48,63,38,241,171,246,100,47,119,241,111,10,
+127,10,207,73,69,53,53,50,241,91,47,10,47,3,33,46,61,241,79,107,243,127,37,
+255,223,13,79,33,242,31,16,239,14,111,22,191,14,63,20,87,36,241,207,142,
+240,79,20,95,20,95,24,159,36,248,239,254,2,154,240,107,127,138,83,2,241,
+194,20,3,240,123,240,122,240,255,51,240,50,27,240,107,240,175,56,242,135,
+31,50,15,1,50,34,240,191,30,240,212,240,223,21,114,240,207,13,242,107,240,
+107,240,62,240,47,96,243,159,41,242,62,242,63,254,32,79,37,243,223,29,241,
+47,9,240,207,20,241,191,19,64,223,32,240,3,240,112,32,241,95,2,47,9,244,
+102,32,35,46,41,143,31,241,135,49,63,6,38,33,36,64,240,64,212,249,15,37,
+240,67,242,127,32,240,97,32,250,175,31,241,179,241,111,32,240,96,242,223,
+27,244,127,10,255,224,122,243,15,17,15,242,11,241,136,15,7,12,241,131,63,
+40,242,159,249,130,241,95,3,15,35,240,239,98,98,18,241,111,7,15,254,26,223,
+254,40,207,88,245,255,3,251,79,254,155,15,254,50,31,254,236,95,254,19,159,
+255,0,16,173,255,225,43,143,15,246,63,14,240,79,32,240,35,241,31,5,111,3,
+255,226,100,243,92,15,52,207,50,31,16,255,240,0,109,255,5,255,225,229,255,
+240,1,64,31,254,1,31,67,255,224,126,255,231,248,245,182,196,136,159,255,0,
+6,90,244,82,243,114,19,3,19,50,178,2,98,243,18,51,114,98,240,194,50,66,4,
+98,255,224,70,63,9,47,9,47,15,47,9,47,15,47,9,47,15,47,9,47,15,47,9,39,255,
+239,40,251,95,45,243,79,254,59,3,47,11,33,32,48,41,35,32,32,112,80,32,32,
+34,33,32,48,32,32,32,32,33,32,51,38,35,35,32,41,47,1,98,36,47,1,255,240,0,
+3,143,255,0,149,201,241,191,254,242,124,252,227,255,240,0,87,79,0,255,240,
+0,194,63,254,177,63,254,17,0,
};
#else
/* IdentifierStart production with ASCII and non-BMP excluded */
@@ -88196,35 +89379,35 @@ const duk_uint8_t duk_unicode_ids_noa[1036] = {
* Automatically generated by extract_chars.py, do not edit!
*/
-const duk_uint8_t duk_unicode_ids_noabmp[625] = {
+const duk_uint8_t duk_unicode_ids_noabmp[626] = {
249,176,176,80,111,7,47,15,47,254,11,197,191,0,72,2,15,115,66,19,50,7,2,34,
2,240,66,244,50,247,185,249,98,241,99,8,241,127,58,240,182,47,31,241,191,
21,18,245,50,15,1,24,27,35,15,2,2,240,239,15,244,156,15,10,241,26,21,6,240,
-101,10,4,15,9,240,159,57,240,82,127,56,242,100,15,4,8,159,1,240,5,115,19,
-240,98,98,4,52,15,2,14,18,47,0,31,5,85,19,240,98,98,18,18,31,17,50,15,5,47,
-2,130,34,240,98,98,18,68,15,4,15,1,31,9,12,115,19,240,98,98,18,68,15,16,18,
-47,1,15,3,2,84,34,52,18,2,20,20,36,191,8,15,38,114,34,240,114,240,4,15,12,
-38,31,16,5,114,34,240,114,146,68,15,18,2,31,1,31,4,114,34,241,147,15,2,6,
-41,47,10,86,240,36,240,130,130,3,111,44,242,2,29,111,44,18,3,18,3,7,50,98,
-34,2,3,18,50,26,3,66,15,7,63,18,15,49,114,241,79,13,79,101,241,191,6,15,2,
-85,52,4,24,37,205,15,3,241,98,6,3,241,178,255,224,63,35,54,32,35,63,25,35,
-63,17,35,54,32,35,62,47,41,35,63,51,241,127,0,240,47,70,53,79,254,21,227,
-240,18,240,166,243,180,168,194,63,0,240,47,0,240,47,0,194,47,1,242,79,21,5,
-15,53,244,137,67,241,34,6,243,107,240,255,35,240,227,76,241,197,240,175,40,
-240,122,242,95,68,15,79,241,255,3,111,41,240,238,27,241,207,12,241,79,27,
-43,241,67,143,82,50,52,26,251,15,50,255,224,8,53,63,22,53,55,32,32,32,47,
-15,63,37,38,32,66,38,67,53,92,98,38,246,96,224,240,44,245,112,80,57,32,68,
-112,32,32,35,42,51,100,80,240,63,25,255,233,107,241,242,241,242,247,87,52,
-29,241,98,6,3,242,136,15,2,240,122,98,98,98,98,98,98,98,111,66,15,254,12,
-146,240,184,132,52,95,70,114,47,74,35,111,25,79,78,240,63,11,242,127,0,255,
-224,244,255,240,0,138,143,60,255,240,4,12,143,28,255,227,127,243,95,30,63,
-253,79,0,177,240,111,31,240,47,15,63,64,241,152,63,87,63,20,39,243,26,34,
-35,47,7,240,255,36,240,15,34,243,5,64,32,223,12,191,7,240,191,13,143,31,
-240,224,240,36,41,180,47,25,240,146,39,240,111,7,64,79,34,32,65,52,48,32,
-240,162,58,130,213,53,53,166,38,47,27,41,191,99,240,255,255,0,26,150,223,7,
-95,33,255,240,0,255,143,254,6,3,245,175,24,109,70,2,146,194,66,2,18,18,245,
-207,19,255,224,93,240,79,48,63,38,241,171,246,100,47,119,241,111,10,127,10,
-207,73,69,53,53,50,0,
+101,10,4,15,9,240,152,175,39,240,82,127,56,242,100,15,4,8,159,1,240,5,115,
+19,240,98,98,4,52,15,2,14,18,47,0,27,9,85,19,240,98,98,18,18,31,17,50,15,5,
+47,2,130,34,240,98,98,18,68,15,4,15,1,31,9,12,115,19,240,98,98,18,68,15,16,
+18,47,1,15,3,2,84,34,52,18,2,20,20,36,191,8,15,38,114,34,240,114,240,4,15,
+12,38,31,16,5,114,34,240,114,146,68,15,18,2,31,1,31,4,114,34,241,147,15,2,
+6,41,47,10,86,240,36,240,130,130,3,111,44,242,2,29,111,44,18,3,18,3,7,50,
+98,34,2,3,18,50,26,3,66,15,7,63,18,15,49,114,241,79,13,79,101,241,191,6,15,
+2,85,52,4,24,37,205,15,3,241,98,6,3,241,178,255,224,63,35,54,32,35,63,25,
+35,63,17,35,54,32,35,62,47,41,35,63,51,241,127,0,240,47,70,53,79,254,21,
+227,240,18,240,166,243,180,168,194,63,0,240,47,0,240,47,0,194,47,1,242,79,
+21,5,15,53,244,137,67,241,34,6,243,107,240,255,35,240,227,76,241,197,240,
+175,40,240,122,242,95,68,15,79,241,255,3,111,41,240,238,27,241,207,12,241,
+79,27,43,241,67,143,82,50,52,26,251,15,50,255,224,8,53,63,22,53,55,32,32,
+32,47,15,63,37,38,32,66,38,67,53,92,98,38,246,96,224,240,44,245,112,80,57,
+32,68,112,32,32,35,42,51,100,80,240,63,25,255,233,107,241,242,241,242,247,
+87,52,29,241,98,6,3,242,136,15,2,240,122,98,98,98,98,98,98,98,111,66,15,
+254,12,146,240,184,132,52,95,70,114,47,74,35,111,26,63,78,240,63,11,242,
+127,0,255,224,244,255,240,0,138,143,60,255,240,4,13,223,7,255,227,127,243,
+95,30,63,253,79,0,177,240,111,31,240,47,15,63,64,241,152,63,87,63,20,39,
+243,26,34,35,47,7,240,255,36,240,15,34,243,5,64,32,223,12,191,7,240,191,13,
+143,31,240,224,240,36,41,180,47,25,240,146,39,240,111,7,64,79,34,32,65,52,
+48,32,240,162,58,130,213,53,53,166,38,47,27,41,191,99,240,255,255,0,26,150,
+223,7,95,33,255,240,0,255,143,254,6,3,245,175,24,109,70,2,146,194,66,2,18,
+18,245,207,19,255,224,93,240,79,48,63,38,241,171,246,100,47,119,241,111,10,
+127,10,207,73,69,53,53,50,0,
};
#endif
@@ -88259,32 +89442,33 @@ const duk_uint8_t duk_unicode_ids_m_let_noabmp[24] = {
* Automatically generated by extract_chars.py, do not edit!
*/
-const duk_uint8_t duk_unicode_idp_m_ids_noa[530] = {
+const duk_uint8_t duk_unicode_idp_m_ids_noa[549] = {
255,225,243,246,15,254,0,116,255,191,29,32,33,33,32,243,170,242,47,15,112,
245,118,53,49,35,57,240,144,241,15,11,244,218,240,25,241,56,241,67,40,34,
36,241,210,246,173,47,17,242,130,47,2,38,177,57,240,50,242,160,38,49,50,
160,177,57,240,50,242,160,36,81,50,64,240,107,64,194,242,160,39,34,34,240,
-97,57,240,50,242,160,38,49,50,145,177,57,240,64,242,212,66,35,160,240,9,
-240,35,242,198,34,35,129,193,57,240,50,242,160,38,34,35,129,193,57,240,50,
-242,198,34,35,160,177,57,240,65,243,128,85,32,39,121,49,242,240,54,215,41,
-244,144,53,33,197,57,243,1,121,192,32,32,81,242,63,4,33,106,47,20,160,245,
-111,4,41,211,82,34,54,67,235,46,255,225,179,47,254,42,98,240,242,240,241,
-241,1,243,47,16,160,57,241,50,57,245,209,241,64,246,139,91,185,247,41,242,
-244,242,185,47,13,58,121,240,141,243,68,242,31,1,201,240,56,210,241,12,57,
-241,237,242,47,4,153,121,246,130,47,5,80,82,65,251,143,38,100,255,225,0,31,
-35,31,5,15,109,197,4,191,254,175,34,247,240,245,47,16,255,225,30,95,91,31,
-255,0,100,121,159,55,5,159,18,31,66,31,254,0,64,64,80,240,148,244,161,242,
-79,2,185,127,2,240,9,240,231,240,188,241,227,242,29,240,25,192,185,242,29,
-208,145,57,241,50,242,64,34,49,97,32,241,180,97,253,231,33,57,255,240,3,
+97,57,181,34,242,160,38,49,50,145,177,57,240,64,242,212,66,35,160,240,9,
+240,35,242,198,34,35,129,193,57,240,50,242,160,38,34,35,129,193,57,240,35,
+242,145,38,34,35,160,177,57,240,65,243,128,85,32,39,121,49,242,240,54,215,
+41,244,144,53,33,197,57,243,1,121,192,32,32,81,242,63,4,33,106,47,20,160,
+245,111,4,41,211,82,34,54,67,235,46,255,225,179,47,254,42,98,240,242,240,
+241,241,1,243,47,16,160,57,241,50,57,245,209,241,64,246,139,91,185,247,41,
+242,244,242,185,47,13,58,121,240,141,243,68,242,31,1,201,240,56,210,241,12,
+57,241,237,242,47,4,153,121,246,130,47,5,80,82,50,251,143,42,36,255,225,0,
+31,35,31,5,15,109,197,4,191,254,175,34,247,240,245,47,16,255,225,30,95,91,
+31,255,0,100,121,159,55,5,159,18,31,66,31,254,0,64,64,80,240,148,244,161,
+242,79,2,185,127,2,240,9,240,231,240,188,241,227,242,29,240,25,192,185,242,
+29,208,145,57,241,50,242,64,34,49,97,32,241,180,97,253,231,33,57,255,240,3,
225,128,255,225,213,240,15,2,240,4,31,10,47,178,159,23,15,254,27,16,253,64,
248,116,255,224,25,159,254,68,178,33,99,241,162,80,249,113,255,228,13,47,
39,239,17,159,1,63,31,175,39,151,47,22,210,159,37,13,47,34,218,36,159,68,
183,15,146,182,151,63,42,2,99,19,42,11,19,100,79,178,240,42,159,72,240,77,
159,199,99,143,13,31,68,240,31,1,159,67,201,159,69,229,159,254,9,169,255,
-226,57,114,127,2,159,42,240,98,223,255,0,60,157,159,120,79,45,111,11,159,
-254,46,191,30,240,35,255,240,3,191,225,255,240,0,59,164,69,151,54,241,3,
-248,98,255,228,125,242,47,254,15,79,39,95,34,144,240,0,240,132,46,255,228,
-68,98,240,19,98,18,79,254,121,150,245,246,105,255,240,192,105,175,224,0,
+224,11,159,26,98,57,10,175,32,240,15,254,8,151,39,240,41,242,175,6,45,246,
+197,64,33,38,32,153,255,240,3,191,169,247,132,242,214,240,185,255,226,235,
+241,239,2,63,255,0,59,254,31,255,0,3,186,68,89,115,111,16,63,134,47,254,71,
+223,34,255,224,244,242,117,242,41,15,0,15,8,66,239,254,68,70,47,1,54,33,36,
+255,231,153,111,95,102,159,255,12,6,154,254,0,
};
#else
/* IdentifierPart production with IdentifierStart, ASCII, and non-BMP excluded */
@@ -88293,23 +89477,23 @@ const duk_uint8_t duk_unicode_idp_m_ids_noa[530] = {
* Automatically generated by extract_chars.py, do not edit!
*/
-const duk_uint8_t duk_unicode_idp_m_ids_noabmp[357] = {
+const duk_uint8_t duk_unicode_idp_m_ids_noabmp[358] = {
255,225,243,246,15,254,0,116,255,191,29,32,33,33,32,243,170,242,47,15,112,
245,118,53,49,35,57,240,144,241,15,11,244,218,240,25,241,56,241,67,40,34,
36,241,210,246,173,47,17,242,130,47,2,38,177,57,240,50,242,160,38,49,50,
160,177,57,240,50,242,160,36,81,50,64,240,107,64,194,242,160,39,34,34,240,
-97,57,240,50,242,160,38,49,50,145,177,57,240,64,242,212,66,35,160,240,9,
-240,35,242,198,34,35,129,193,57,240,50,242,160,38,34,35,129,193,57,240,50,
-242,198,34,35,160,177,57,240,65,243,128,85,32,39,121,49,242,240,54,215,41,
-244,144,53,33,197,57,243,1,121,192,32,32,81,242,63,4,33,106,47,20,160,245,
-111,4,41,211,82,34,54,67,235,46,255,225,179,47,254,42,98,240,242,240,241,
-241,1,243,47,16,160,57,241,50,57,245,209,241,64,246,139,91,185,247,41,242,
-244,242,185,47,13,58,121,240,141,243,68,242,31,1,201,240,56,210,241,12,57,
-241,237,242,47,4,153,121,246,130,47,5,80,82,65,251,143,38,100,255,225,0,31,
-35,31,5,15,109,197,4,191,254,175,34,247,240,245,47,16,255,225,30,95,91,31,
-255,0,100,121,159,55,5,159,18,31,66,31,254,0,64,64,80,240,148,244,161,242,
-79,2,185,127,2,240,9,240,231,240,188,241,227,242,29,240,25,192,185,242,29,
-208,145,57,241,50,242,64,34,49,97,32,241,180,97,253,231,33,57,255,240,3,
+97,57,181,34,242,160,38,49,50,145,177,57,240,64,242,212,66,35,160,240,9,
+240,35,242,198,34,35,129,193,57,240,50,242,160,38,34,35,129,193,57,240,35,
+242,145,38,34,35,160,177,57,240,65,243,128,85,32,39,121,49,242,240,54,215,
+41,244,144,53,33,197,57,243,1,121,192,32,32,81,242,63,4,33,106,47,20,160,
+245,111,4,41,211,82,34,54,67,235,46,255,225,179,47,254,42,98,240,242,240,
+241,241,1,243,47,16,160,57,241,50,57,245,209,241,64,246,139,91,185,247,41,
+242,244,242,185,47,13,58,121,240,141,243,68,242,31,1,201,240,56,210,241,12,
+57,241,237,242,47,4,153,121,246,130,47,5,80,82,50,251,143,42,36,255,225,0,
+31,35,31,5,15,109,197,4,191,254,175,34,247,240,245,47,16,255,225,30,95,91,
+31,255,0,100,121,159,55,5,159,18,31,66,31,254,0,64,64,80,240,148,244,161,
+242,79,2,185,127,2,240,9,240,231,240,188,241,227,242,29,240,25,192,185,242,
+29,208,145,57,241,50,242,64,34,49,97,32,241,180,97,253,231,33,57,255,240,3,
225,128,255,225,213,240,15,2,240,4,31,10,47,178,159,23,0,
};
#endif
@@ -94494,6 +95678,10 @@ DUK_INTERNAL void duk_be_finish(duk_bitencoder_ctx *ctx) {
/* #include duk_internal.h -> already included */
+/* XXX: Avoid duk_{memcmp,memmove}_unsafe() by imposing a minimum length of
+ * >0 for the underlying dynamic buffer.
+ */
+
/*
* Macro support functions (use only macros in calling code)
*/
@@ -94505,6 +95693,9 @@ DUK_LOCAL void duk__bw_update_ptrs(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx,
DUK_ASSERT(bw_ctx != NULL);
DUK_UNREF(thr);
+ /* 'p' might be NULL when the underlying buffer is zero size. If so,
+ * the resulting pointers are not used unsafely.
+ */
p = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, bw_ctx->buf);
DUK_ASSERT(p != NULL || (DUK_HBUFFER_DYNAMIC_GET_SIZE(bw_ctx->buf) == 0 && curr_offset == 0 && new_length == 0));
bw_ctx->p = p + curr_offset;
@@ -94513,7 +95704,6 @@ DUK_LOCAL void duk__bw_update_ptrs(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx,
}
DUK_INTERNAL void duk_bw_init(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_hbuffer_dynamic *h_buf) {
-
DUK_ASSERT(thr != NULL);
DUK_ASSERT(bw_ctx != NULL);
DUK_ASSERT(h_buf != NULL);
@@ -94528,6 +95718,7 @@ DUK_INTERNAL void duk_bw_init_pushbuf(duk_hthread *thr, duk_bufwriter_ctx *bw_ct
(void) duk_push_dynamic_buffer(thr, buf_size);
bw_ctx->buf = (duk_hbuffer_dynamic *) duk_known_hbuffer(thr, -1);
+ DUK_ASSERT(bw_ctx->buf != NULL);
duk__bw_update_ptrs(thr, bw_ctx, 0, buf_size);
}
@@ -94552,7 +95743,7 @@ DUK_INTERNAL duk_uint8_t *duk_bw_resize(duk_hthread *thr, duk_bufwriter_ctx *bw_
if (DUK_UNLIKELY(new_sz < curr_off)) {
/* overflow */
DUK_ERROR_RANGE(thr, DUK_STR_BUFFER_TOO_LONG);
- return NULL; /* not reachable */
+ DUK_WO_NORETURN(return NULL;);
}
#if 0 /* for manual torture testing: tight allocation, useful with valgrind */
new_sz = curr_off + sz;
@@ -94595,9 +95786,9 @@ DUK_INTERNAL void duk_bw_write_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw
DUK_UNREF(thr);
p_base = bw->p_base;
- DUK_MEMCPY((void *) bw->p,
- (const void *) (p_base + src_off),
- (size_t) len);
+ duk_memcpy_unsafe((void *) bw->p,
+ (const void *) (p_base + src_off),
+ (size_t) len);
bw->p += len;
}
@@ -94627,12 +95818,12 @@ DUK_INTERNAL void duk_bw_insert_raw_bytes(duk_hthread *thr, duk_bufwriter_ctx *b
move_sz = buf_sz - dst_off;
DUK_ASSERT(p_base != NULL); /* buffer size is >= 1 */
- DUK_MEMMOVE((void *) (p_base + dst_off + len),
- (const void *) (p_base + dst_off),
- (size_t) move_sz);
- DUK_MEMCPY((void *) (p_base + dst_off),
- (const void *) buf,
- (size_t) len);
+ duk_memmove_unsafe((void *) (p_base + dst_off + len),
+ (const void *) (p_base + dst_off),
+ (size_t) move_sz);
+ duk_memcpy_unsafe((void *) (p_base + dst_off),
+ (const void *) buf,
+ (size_t) len);
bw->p += len;
}
@@ -94674,12 +95865,12 @@ DUK_INTERNAL void duk_bw_insert_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *b
move_sz = buf_sz - dst_off;
DUK_ASSERT(p_base != NULL); /* buffer size is >= 1 */
- DUK_MEMMOVE((void *) (p_base + dst_off + len),
- (const void *) (p_base + dst_off),
- (size_t) move_sz);
- DUK_MEMCPY((void *) (p_base + dst_off),
- (const void *) (p_base + src_off),
- (size_t) len);
+ duk_memmove_unsafe((void *) (p_base + dst_off + len),
+ (const void *) (p_base + dst_off),
+ (size_t) move_sz);
+ duk_memcpy_unsafe((void *) (p_base + dst_off),
+ (const void *) (p_base + src_off),
+ (size_t) len);
bw->p += len;
}
@@ -94712,7 +95903,7 @@ DUK_INTERNAL duk_uint8_t *duk_bw_insert_raw_area(duk_hthread *thr, duk_bufwriter
move_sz = buf_sz - off;
p_dst = p_base + off + len;
p_src = p_base + off;
- DUK_MEMMOVE((void *) p_dst, (const void *) p_src, (size_t) move_sz);
+ duk_memmove_unsafe((void *) p_dst, (const void *) p_src, (size_t) move_sz);
return p_src; /* point to start of 'reserved area' */
}
@@ -94743,9 +95934,9 @@ DUK_INTERNAL void duk_bw_remove_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *b
p_dst = p_base + off;
p_src = p_dst + len;
move_sz = (duk_size_t) (bw->p - p_src);
- DUK_MEMMOVE((void *) p_dst,
- (const void *) p_src,
- (size_t) move_sz);
+ duk_memmove_unsafe((void *) p_dst,
+ (const void *) p_src,
+ (size_t) move_sz);
bw->p -= len;
}
@@ -94766,7 +95957,7 @@ DUK_INTERNAL DUK_ALWAYS_INLINE duk_uint16_t duk_raw_read_u16_be(duk_uint8_t **p)
duk_uint16_t x;
} u;
- DUK_MEMCPY((void *) u.b, (const void *) (*p), (size_t) 2);
+ duk_memcpy((void *) u.b, (const void *) (*p), (size_t) 2);
u.x = DUK_NTOH16(u.x);
*p += 2;
return u.x;
@@ -94778,7 +95969,7 @@ DUK_INTERNAL DUK_ALWAYS_INLINE duk_uint32_t duk_raw_read_u32_be(duk_uint8_t **p)
duk_uint32_t x;
} u;
- DUK_MEMCPY((void *) u.b, (const void *) (*p), (size_t) 4);
+ duk_memcpy((void *) u.b, (const void *) (*p), (size_t) 4);
u.x = DUK_NTOH32(u.x);
*p += 4;
return u.x;
@@ -94791,10 +95982,10 @@ DUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_raw_read_double_be(duk_uint8_t *
duk_uint32_t x;
} u;
- DUK_MEMCPY((void *) u.b, (const void *) (*p), (size_t) 4);
+ duk_memcpy((void *) u.b, (const void *) (*p), (size_t) 4);
u.x = DUK_NTOH32(u.x);
du.ui[DUK_DBL_IDX_UI0] = u.x;
- DUK_MEMCPY((void *) u.b, (const void *) (*p + 4), (size_t) 4);
+ duk_memcpy((void *) u.b, (const void *) (*p + 4), (size_t) 4);
u.x = DUK_NTOH32(u.x);
du.ui[DUK_DBL_IDX_UI1] = u.x;
*p += 8;
@@ -94809,7 +96000,7 @@ DUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_write_u16_be(duk_uint8_t **p, duk_ui
} u;
u.x = DUK_HTON16(val);
- DUK_MEMCPY((void *) (*p), (const void *) u.b, (size_t) 2);
+ duk_memcpy((void *) (*p), (const void *) u.b, (size_t) 2);
*p += 2;
}
@@ -94820,7 +96011,7 @@ DUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_write_u32_be(duk_uint8_t **p, duk_ui
} u;
u.x = DUK_HTON32(val);
- DUK_MEMCPY((void *) (*p), (const void *) u.b, (size_t) 4);
+ duk_memcpy((void *) (*p), (const void *) u.b, (size_t) 4);
*p += 4;
}
@@ -94834,13 +96025,415 @@ DUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_write_double_be(duk_uint8_t **p, duk
du.d = val;
u.x = du.ui[DUK_DBL_IDX_UI0];
u.x = DUK_HTON32(u.x);
- DUK_MEMCPY((void *) (*p), (const void *) u.b, (size_t) 4);
+ duk_memcpy((void *) (*p), (const void *) u.b, (size_t) 4);
u.x = du.ui[DUK_DBL_IDX_UI1];
u.x = DUK_HTON32(u.x);
- DUK_MEMCPY((void *) (*p + 4), (const void *) u.b, (size_t) 4);
+ duk_memcpy((void *) (*p + 4), (const void *) u.b, (size_t) 4);
*p += 8;
}
/*
+ * Cast helpers.
+ *
+ * C99+ coercion is challenging portability-wise because out-of-range casts
+ * may invoke implementation defined or even undefined behavior. See e.g.
+ * http://blog.frama-c.com/index.php?post/2013/10/09/Overflow-float-integer.
+ *
+ * Provide explicit cast helpers which try to avoid implementation defined
+ * or undefined behavior. These helpers can then be simplified in the vast
+ * majority of cases where the implementation defined or undefined behavior
+ * is not problematic.
+ */
+
+/* #include duk_internal.h -> already included */
+
+/* Portable double-to-integer cast which avoids undefined behavior and avoids
+ * relying on fmin(), fmax(), or other intrinsics. Out-of-range results are
+ * not assumed by caller, but here value is clamped, NaN converts to minval.
+ */
+#define DUK__DOUBLE_INT_CAST1(tname,minval,maxval) do { \
+ if (DUK_LIKELY(x >= (duk_double_t) (minval))) { \
+ DUK_ASSERT(!DUK_ISNAN(x)); \
+ if (DUK_LIKELY(x <= (duk_double_t) (maxval))) { \
+ return (tname) x; \
+ } else { \
+ return (tname) (maxval); \
+ } \
+ } else { \
+ /* NaN or below minval. Since we don't care about the result \
+ * for out-of-range values, just return the minimum value for \
+ * both. \
+ */ \
+ return (tname) (minval); \
+ } \
+ } while (0)
+
+/* Rely on specific NaN behavior for duk_double_{fmin,fmax}(): if either
+ * argument is a NaN, return the second argument. This avoids a
+ * NaN-to-integer cast which is undefined behavior.
+ */
+#define DUK__DOUBLE_INT_CAST2(tname,minval,maxval) do { \
+ return (tname) duk_double_fmin(duk_double_fmax(x, (duk_double_t) (minval)), (duk_double_t) (maxval)); \
+ } while (0)
+
+/* Another solution which doesn't need C99+ behavior for fmin() and fmax(). */
+#define DUK__DOUBLE_INT_CAST3(tname,minval,maxval) do { \
+ if (DUK_ISNAN(x)) { \
+ /* 0 or any other value is fine. */ \
+ return (tname) 0; \
+ } else \
+ return (tname) DUK_FMIN(DUK_FMAX(x, (duk_double_t) (minval)), (duk_double_t) (maxval)); \
+ } \
+ } while (0)
+
+/* C99+ solution: relies on specific fmin() and fmax() behavior in C99: if
+ * one argument is NaN but the other isn't, the non-NaN argument is returned.
+ * Because the limits are non-NaN values, explicit NaN check is not needed.
+ * This may not work on all legacy platforms, and also doesn't seem to inline
+ * the fmin() and fmax() calls (unless one uses -ffast-math which we don't
+ * support).
+ */
+#define DUK__DOUBLE_INT_CAST4(tname,minval,maxval) do { \
+ return (tname) DUK_FMIN(DUK_FMAX(x, (duk_double_t) (minval)), (duk_double_t) (maxval)); \
+ } while (0)
+
+DUK_INTERNAL duk_int_t duk_double_to_int_t(duk_double_t x) {
+#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)
+ /* Real world solution: almost any practical platform will provide
+ * an integer value without any guarantees what it is (which is fine).
+ */
+ return (duk_int_t) x;
+#else
+ DUK__DOUBLE_INT_CAST1(duk_int_t, DUK_INT_MIN, DUK_INT_MAX);
+#endif
+}
+
+DUK_INTERNAL duk_uint_t duk_double_to_uint_t(duk_double_t x) {
+#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)
+ return (duk_uint_t) x;
+#else
+ DUK__DOUBLE_INT_CAST1(duk_uint_t, DUK_UINT_MIN, DUK_UINT_MAX);
+#endif
+}
+
+DUK_INTERNAL duk_int32_t duk_double_to_int32_t(duk_double_t x) {
+#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)
+ return (duk_int32_t) x;
+#else
+ DUK__DOUBLE_INT_CAST1(duk_int32_t, DUK_INT32_MIN, DUK_INT32_MAX);
+#endif
+}
+
+DUK_INTERNAL duk_uint32_t duk_double_to_uint32_t(duk_double_t x) {
+#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)
+ return (duk_uint32_t) x;
+#else
+ DUK__DOUBLE_INT_CAST1(duk_uint32_t, DUK_UINT32_MIN, DUK_UINT32_MAX);
+#endif
+}
+
+/* Largest IEEE double that doesn't round to infinity in the default rounding
+ * mode. The exact midpoint between (1 - 2^(-24)) * 2^128 and 2^128 rounds to
+ * infinity, at least on x64. This number is one double unit below that
+ * midpoint. See misc/float_cast.c.
+ */
+#define DUK__FLOAT_ROUND_LIMIT 340282356779733623858607532500980858880.0
+
+/* Maximum IEEE float. Double-to-float conversion above this would be out of
+ * range and thus technically undefined behavior.
+ */
+#define DUK__FLOAT_MAX 340282346638528859811704183484516925440.0
+
+DUK_INTERNAL duk_float_t duk_double_to_float_t(duk_double_t x) {
+ /* Even a double-to-float cast is technically undefined behavior if
+ * the double is out-of-range. C99 Section 6.3.1.5:
+ *
+ * If the value being converted is in the range of values that can
+ * be represented but cannot be represented exactly, the result is
+ * either the nearest higher or nearest lower representable value,
+ * chosen in an implementation-defined manner. If the value being
+ * converted is outside the range of values that can be represented,
+ * the behavior is undefined.
+ */
+#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)
+ return (duk_float_t) x;
+#else
+ duk_double_t t;
+
+ t = DUK_FABS(x);
+ DUK_ASSERT((DUK_ISNAN(x) && DUK_ISNAN(t)) ||
+ (!DUK_ISNAN(x) && !DUK_ISNAN(t)));
+
+ if (DUK_LIKELY(t <= DUK__FLOAT_MAX)) {
+ /* Standard in-range case, try to get here with a minimum
+ * number of checks and branches.
+ */
+ DUK_ASSERT(!DUK_ISNAN(x));
+ return (duk_float_t) x;
+ } else if (t <= DUK__FLOAT_ROUND_LIMIT) {
+ /* Out-of-range, but rounds to min/max float. */
+ DUK_ASSERT(!DUK_ISNAN(x));
+ if (x < 0.0) {
+ return (duk_float_t) -DUK__FLOAT_MAX;
+ } else {
+ return (duk_float_t) DUK__FLOAT_MAX;
+ }
+ } else if (DUK_ISNAN(x)) {
+ /* Assumes double NaN -> float NaN considered "in range". */
+ DUK_ASSERT(DUK_ISNAN(x));
+ return (duk_float_t) x;
+ } else {
+ /* Out-of-range, rounds to +/- Infinity. */
+ if (x < 0.0) {
+ return (duk_float_t) -DUK_DOUBLE_INFINITY;
+ } else {
+ return (duk_float_t) DUK_DOUBLE_INFINITY;
+ }
+ }
+#endif
+}
+
+/* automatic undefs */
+#undef DUK__DOUBLE_INT_CAST1
+#undef DUK__DOUBLE_INT_CAST2
+#undef DUK__DOUBLE_INT_CAST3
+#undef DUK__DOUBLE_INT_CAST4
+#undef DUK__FLOAT_MAX
+#undef DUK__FLOAT_ROUND_LIMIT
+/*
+ * IEEE double helpers.
+ */
+
+/* #include duk_internal.h -> already included */
+
+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] & DUK_U64_CONSTANT(0x000000007ff00000)) == DUK_U64_CONSTANT(0x000000007ff00000);
+#else
+ return (du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7ff0000000000000)) == DUK_U64_CONSTANT(0x7ff0000000000000);
+#endif
+#else
+ return (du.ui[DUK_DBL_IDX_UI0] & 0x7ff00000UL) == 0x7ff00000UL;
+#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] & DUK_U64_CONSTANT(0x000000007ff00000);
+ if (t == DUK_U64_CONSTANT(0x0000000000000000)) {
+ t = du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x0000000080000000);
+ return t == 0;
+ }
+ if (t == DUK_U64_CONSTANT(0x000000007ff00000)) {
+ return 1;
+ }
+#else
+ t = du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7ff0000000000000);
+ if (t == DUK_U64_CONSTANT(0x0000000000000000)) {
+ t = du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x8000000000000000);
+ return t == 0;
+ }
+ if (t == DUK_U64_CONSTANT(0x7ff0000000000000)) {
+ 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_uint_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);
+}
+
+DUK_INTERNAL duk_bool_t duk_double_is_finite(duk_double_t x) {
+ return !duk_double_is_nan_or_inf(x);
+}
+
+DUK_INTERNAL duk_bool_t duk_double_is_integer(duk_double_t x) {
+ if (duk_double_is_nan_or_inf(x)) {
+ return 0;
+ } else {
+ return duk_js_tointeger_number(x) == x;
+ }
+}
+
+DUK_INTERNAL duk_bool_t duk_double_is_safe_integer(duk_double_t x) {
+ /* >>> 2**53-1
+ * 9007199254740991
+ */
+ return duk_double_is_integer(x) && DUK_FABS(x) <= 9007199254740991.0;
+}
+
+/* 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_double_to_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_double_to_int32_t(x);
+ if (!((duk_double_t) t == x)) {
+ return 0;
+ }
+ *ival = t;
+ return 1;
+}
+
+/* Division: division by zero is undefined behavior (and may in fact trap)
+ * so it needs special handling for portability.
+ */
+
+DUK_INTERNAL DUK_INLINE duk_double_t duk_double_div(duk_double_t x, duk_double_t y) {
+#if !defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)
+ if (DUK_UNLIKELY(y == 0.0)) {
+ /* In C99+ division by zero is undefined behavior so
+ * avoid it entirely. Hopefully the compiler is
+ * smart enough to avoid emitting any actual code
+ * because almost all practical platforms behave as
+ * expected.
+ */
+ if (x > 0.0) {
+ if (DUK_SIGNBIT(y)) {
+ return -DUK_DOUBLE_INFINITY;
+ } else {
+ return DUK_DOUBLE_INFINITY;
+ }
+ } else if (x < 0.0) {
+ if (DUK_SIGNBIT(y)) {
+ return DUK_DOUBLE_INFINITY;
+ } else {
+ return -DUK_DOUBLE_INFINITY;
+ }
+ } else {
+ /* +/- 0, NaN */
+ return DUK_DOUBLE_NAN;
+ }
+ }
+#endif
+
+ return x / y;
+}
+/*
* Hash function duk_util_hashbytes().
*
* Currently, 32-bit MurmurHash2.
@@ -94902,6 +96495,42 @@ DUK_INTERNAL duk_uint32_t duk_util_hashbytes(const duk_uint8_t *data, duk_size_t
#undef DUK__MAGIC_M
#undef DUK__MAGIC_R
/*
+ * Memory utils.
+ */
+
+/* #include duk_internal.h -> already included */
+
+#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)
+DUK_INTERNAL DUK_INLINE duk_small_int_t duk_memcmp_unsafe(const void *s1, const void *s2, duk_size_t len) {
+ DUK_ASSERT(s1 != NULL || len == 0U);
+ DUK_ASSERT(s2 != NULL || len == 0U);
+ return DUK_MEMCMP(s1, s2, (size_t) len);
+}
+
+DUK_INTERNAL DUK_INLINE duk_small_int_t duk_memcmp(const void *s1, const void *s2, duk_size_t len) {
+ DUK_ASSERT(s1 != NULL);
+ DUK_ASSERT(s2 != NULL);
+ return DUK_MEMCMP(s1, s2, (size_t) len);
+}
+#else /* DUK_USE_ALLOW_UNDEFINED_BEHAVIOR */
+DUK_INTERNAL DUK_INLINE duk_small_int_t duk_memcmp_unsafe(const void *s1, const void *s2, duk_size_t len) {
+ DUK_ASSERT(s1 != NULL || len == 0U);
+ DUK_ASSERT(s2 != NULL || len == 0U);
+ if (DUK_UNLIKELY(len == 0U)) {
+ return 0;
+ }
+ DUK_ASSERT(s1 != NULL);
+ DUK_ASSERT(s2 != NULL);
+ return duk_memcmp(s1, s2, len);
+}
+
+DUK_INTERNAL DUK_INLINE duk_small_int_t duk_memcmp(const void *s1, const void *s2, duk_size_t len) {
+ DUK_ASSERT(s1 != NULL);
+ DUK_ASSERT(s2 != NULL);
+ return DUK_MEMCMP(s1, s2, (size_t) len);
+}
+#endif /* DUK_USE_ALLOW_UNDEFINED_BEHAVIOR */
+/*
* A tiny random number generator used for Math.random() and other internals.
*
* Default algorithm is xoroshiro128+: http://xoroshiro.di.unimi.it/xoroshiro128plus.c
@@ -95032,4 +96661,3 @@ DUK_INTERNAL duk_double_t duk_util_tinyrandom_get_double(duk_hthread *thr) {
#undef DUK__RANDOM_XOROSHIRO128PLUS
#undef DUK__RND_BIT
#undef DUK__UPDATE_RND
-#endif
diff --git a/content/handlers/javascript/duktape/duktape.h b/content/handlers/javascript/duktape/duktape.h
index e97e46269..43e2966c1 100644
--- a/content/handlers/javascript/duktape/duktape.h
+++ b/content/handlers/javascript/duktape/duktape.h
@@ -1,5 +1,5 @@
/*
- * Duktape public API for Duktape 2.2.1.
+ * Duktape public API for Duktape 2.3.0.
*
* See the API reference for documentation on call semantics. The exposed,
* supported API is between the "BEGIN PUBLIC API" and "END PUBLIC API"
@@ -21,7 +21,7 @@
*
* (http://opensource.org/licenses/MIT)
*
- * Copyright (c) 2013-2017 by Duktape authors (see AUTHORS.rst)
+ * Copyright (c) 2013-2018 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
@@ -92,6 +92,14 @@
* * Steven Don (https://github.com/shdon)
* * Simon Stone (https://github.com/sstone1)
* * \J. McC. (https://github.com/jmhmccr)
+ * * Jakub Nowakowski (https://github.com/jimvonmoon)
+ * * Tommy Nguyen (https://github.com/tn0502)
+ * * Fabrice Fontaine (https://github.com/ffontaine)
+ * * Christopher Hiller (https://github.com/boneskull)
+ * * Gonzalo Diethelm (https://github.com/gonzus)
+ * * Michal Kasperek (https://github.com/michalkas)
+ * * Andrew Janke (https://github.com/apjanke)
+ * * Steve Fan (https://github.com/stevefan1999)
*
* Other contributions
* ===================
@@ -130,6 +138,8 @@
* * https://github.com/chris-y
* * Laurent Zubiaur (https://github.com/lzubiaur)
* * Neil Kolban (https://github.com/nkolban)
+ * * Wilhelm Wanecek (https://github.com/wanecek)
+ * * Andrew Janke (https://github.com/apjanke)
*
* If you are accidentally missing from this list, send me an e-mail
* (``sami.vaarala@iki.fi``) and I'll fix the omission.
@@ -150,15 +160,15 @@
/* Duktape version, (major * 10000) + (minor * 100) + patch. Allows C code
* to #if (DUK_VERSION >= NNN) against Duktape API version. The same value
- * is also available to Ecmascript code in Duktape.version. Unofficial
+ * is also available to ECMAScript code in Duktape.version. Unofficial
* development snapshots have 99 for patch level (e.g. 0.10.99 would be a
* development version after 0.10.0 but before the next official release).
*/
-#define DUK_VERSION 20201L
+#define DUK_VERSION 20300L
/* Git commit, describe, and branch for Duktape build. Useful for
* non-official snapshot builds so that application code can easily log
- * which Duktape snapshot was used. Not available in the Ecmascript
+ * which Duktape snapshot was used. Not available in the ECMAScript
* environment.
*/
#define DUK_GIT_COMMIT "external"
@@ -258,7 +268,7 @@ struct duk_number_list_entry {
};
struct duk_time_components {
- duk_double_t year; /* year, e.g. 2016, Ecmascript year range */
+ duk_double_t year; /* year, e.g. 2016, ECMAScript year range */
duk_double_t month; /* month: 1-12 */
duk_double_t day; /* day: 1-31 */
duk_double_t hours; /* hour: 0-59 */
@@ -294,12 +304,12 @@ struct duk_time_components {
/* Value types, used by e.g. duk_get_type() */
#define DUK_TYPE_MIN 0U
#define DUK_TYPE_NONE 0U /* no value, e.g. invalid index */
-#define DUK_TYPE_UNDEFINED 1U /* Ecmascript undefined */
-#define DUK_TYPE_NULL 2U /* Ecmascript null */
-#define DUK_TYPE_BOOLEAN 3U /* Ecmascript boolean: 0 or 1 */
-#define DUK_TYPE_NUMBER 4U /* Ecmascript number: double */
-#define DUK_TYPE_STRING 5U /* Ecmascript string: CESU-8 / extended UTF-8 encoded */
-#define DUK_TYPE_OBJECT 6U /* Ecmascript object: includes objects, arrays, functions, threads */
+#define DUK_TYPE_UNDEFINED 1U /* ECMAScript undefined */
+#define DUK_TYPE_NULL 2U /* ECMAScript null */
+#define DUK_TYPE_BOOLEAN 3U /* ECMAScript boolean: 0 or 1 */
+#define DUK_TYPE_NUMBER 4U /* ECMAScript number: double */
+#define DUK_TYPE_STRING 5U /* ECMAScript string: CESU-8 / extended UTF-8 encoded */
+#define DUK_TYPE_OBJECT 6U /* ECMAScript object: includes objects, arrays, functions, threads */
#define DUK_TYPE_BUFFER 7U /* fixed or dynamic, garbage collected byte buffer */
#define DUK_TYPE_POINTER 8U /* raw void pointer */
#define DUK_TYPE_LIGHTFUNC 9U /* lightweight function pointer */
@@ -668,7 +678,21 @@ DUK_EXTERNAL_DECL void duk_push_pointer(duk_context *ctx, void *p);
DUK_EXTERNAL_DECL const char *duk_push_sprintf(duk_context *ctx, const char *fmt, ...);
DUK_EXTERNAL_DECL const char *duk_push_vsprintf(duk_context *ctx, const char *fmt, va_list ap);
+/* duk_push_literal() may evaluate its argument (a C string literal) more than
+ * once on purpose. When speed is preferred, sizeof() avoids an unnecessary
+ * strlen() at runtime. Sizeof("foo") == 4, so subtract 1. The argument
+ * must be non-NULL and should not contain internal NUL characters as the
+ * behavior will then depend on config options.
+ */
+#if defined(DUK_USE_PREFER_SIZE)
+#define duk_push_literal(ctx,cstring) duk_push_string((ctx), (cstring))
+#else
+DUK_EXTERNAL_DECL const char *duk_push_literal_raw(duk_context *ctx, const char *str, duk_size_t len);
+#define duk_push_literal(ctx,cstring) duk_push_literal_raw((ctx), (cstring), sizeof((cstring)) - 1U)
+#endif
+
DUK_EXTERNAL_DECL void duk_push_this(duk_context *ctx);
+DUK_EXTERNAL_DECL void duk_push_new_target(duk_context *ctx);
DUK_EXTERNAL_DECL void duk_push_current_function(duk_context *ctx);
DUK_EXTERNAL_DECL void duk_push_current_thread(duk_context *ctx);
DUK_EXTERNAL_DECL void duk_push_global_object(duk_context *ctx);
@@ -1000,29 +1024,55 @@ DUK_EXTERNAL_DECL void duk_config_buffer(duk_context *ctx, duk_idx_t idx, void *
/*
* Property access
*
- * The basic function assumes key is on stack. The _string variant takes
- * a C string as a property name, while the _index variant takes an array
- * index as a property name (e.g. 123 is equivalent to the key "123").
+ * The basic function assumes key is on stack. The _(l)string variant takes
+ * a C string as a property name; the _literal variant takes a C literal.
+ * The _index variant takes an array index as a property name (e.g. 123 is
+ * equivalent to the key "123"). The _heapptr variant takes a raw, borrowed
+ * heap pointer.
*/
DUK_EXTERNAL_DECL duk_bool_t duk_get_prop(duk_context *ctx, duk_idx_t obj_idx);
DUK_EXTERNAL_DECL duk_bool_t duk_get_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key);
DUK_EXTERNAL_DECL duk_bool_t duk_get_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);
+#if defined(DUK_USE_PREFER_SIZE)
+#define duk_get_prop_literal(ctx,obj_idx,key) duk_get_prop_string((ctx), (obj_idx), (key))
+#else
+DUK_EXTERNAL_DECL duk_bool_t duk_get_prop_literal_raw(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);
+#define duk_get_prop_literal(ctx,obj_idx,key) duk_get_prop_literal_raw((ctx), (obj_idx), (key), sizeof((key)) - 1U)
+#endif
DUK_EXTERNAL_DECL duk_bool_t duk_get_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx);
DUK_EXTERNAL_DECL duk_bool_t duk_get_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr);
DUK_EXTERNAL_DECL duk_bool_t duk_put_prop(duk_context *ctx, duk_idx_t obj_idx);
DUK_EXTERNAL_DECL duk_bool_t duk_put_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key);
DUK_EXTERNAL_DECL duk_bool_t duk_put_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);
+#if defined(DUK_USE_PREFER_SIZE)
+#define duk_put_prop_literal(ctx,obj_idx,key) duk_put_prop_string((ctx), (obj_idx), (key))
+#else
+DUK_EXTERNAL_DECL duk_bool_t duk_put_prop_literal_raw(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);
+#define duk_put_prop_literal(ctx,obj_idx,key) duk_put_prop_literal_raw((ctx), (obj_idx), (key), sizeof((key)) - 1U)
+#endif
DUK_EXTERNAL_DECL duk_bool_t duk_put_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx);
DUK_EXTERNAL_DECL duk_bool_t duk_put_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr);
DUK_EXTERNAL_DECL duk_bool_t duk_del_prop(duk_context *ctx, duk_idx_t obj_idx);
DUK_EXTERNAL_DECL duk_bool_t duk_del_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key);
DUK_EXTERNAL_DECL duk_bool_t duk_del_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);
+#if defined(DUK_USE_PREFER_SIZE)
+#define duk_del_prop_literal(ctx,obj_idx,key) duk_del_prop_string((ctx), (obj_idx), (key))
+#else
+DUK_EXTERNAL_DECL duk_bool_t duk_del_prop_literal_raw(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);
+#define duk_del_prop_literal(ctx,obj_idx,key) duk_del_prop_literal_raw((ctx), (obj_idx), (key), sizeof((key)) - 1U)
+#endif
DUK_EXTERNAL_DECL duk_bool_t duk_del_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx);
DUK_EXTERNAL_DECL duk_bool_t duk_del_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr);
DUK_EXTERNAL_DECL duk_bool_t duk_has_prop(duk_context *ctx, duk_idx_t obj_idx);
DUK_EXTERNAL_DECL duk_bool_t duk_has_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key);
DUK_EXTERNAL_DECL duk_bool_t duk_has_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);
+#if defined(DUK_USE_PREFER_SIZE)
+#define duk_has_prop_literal(ctx,obj_idx,key) duk_has_prop_string((ctx), (obj_idx), (key))
+#else
+DUK_EXTERNAL_DECL duk_bool_t duk_has_prop_literal_raw(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);
+#define duk_has_prop_literal(ctx,obj_idx,key) duk_has_prop_literal_raw((ctx), (obj_idx), (key), sizeof((key)) - 1U)
+#endif
DUK_EXTERNAL_DECL duk_bool_t duk_has_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx);
DUK_EXTERNAL_DECL duk_bool_t duk_has_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr);
@@ -1031,8 +1081,22 @@ DUK_EXTERNAL_DECL void duk_def_prop(duk_context *ctx, duk_idx_t obj_idx, duk_uin
DUK_EXTERNAL_DECL duk_bool_t duk_get_global_string(duk_context *ctx, const char *key);
DUK_EXTERNAL_DECL duk_bool_t duk_get_global_lstring(duk_context *ctx, const char *key, duk_size_t key_len);
+#if defined(DUK_USE_PREFER_SIZE)
+#define duk_get_global_literal(ctx,key) duk_get_global_string((ctx), (key))
+#else
+DUK_EXTERNAL_DECL duk_bool_t duk_get_global_literal_raw(duk_context *ctx, const char *key, duk_size_t key_len);
+#define duk_get_global_literal(ctx,key) duk_get_global_literal_raw((ctx), (key), sizeof((key)) - 1U)
+#endif
+DUK_EXTERNAL_DECL duk_bool_t duk_get_global_heapptr(duk_context *ctx, void *ptr);
DUK_EXTERNAL_DECL duk_bool_t duk_put_global_string(duk_context *ctx, const char *key);
DUK_EXTERNAL_DECL duk_bool_t duk_put_global_lstring(duk_context *ctx, const char *key, duk_size_t key_len);
+#if defined(DUK_USE_PREFER_SIZE)
+#define duk_put_global_literal(ctx,key) duk_put_global_string((ctx), (key))
+#else
+DUK_EXTERNAL_DECL duk_bool_t duk_put_global_literal_raw(duk_context *ctx, const char *key, duk_size_t key_len);
+#define duk_put_global_literal(ctx,key) duk_put_global_literal_raw((ctx), (key), sizeof((key)) - 1U)
+#endif
+DUK_EXTERNAL_DECL duk_bool_t duk_put_global_heapptr(duk_context *ctx, void *ptr);
/*
* Inspection
@@ -1099,7 +1163,7 @@ DUK_EXTERNAL_DECL void duk_trim(duk_context *ctx, duk_idx_t idx);
DUK_EXTERNAL_DECL duk_codepoint_t duk_char_code_at(duk_context *ctx, duk_idx_t idx, duk_size_t char_offset);
/*
- * Ecmascript operators
+ * ECMAScript operators
*/
DUK_EXTERNAL_DECL duk_bool_t duk_equals(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2);
@@ -1108,6 +1172,12 @@ DUK_EXTERNAL_DECL duk_bool_t duk_samevalue(duk_context *ctx, duk_idx_t idx1, duk
DUK_EXTERNAL_DECL duk_bool_t duk_instanceof(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2);
/*
+ * Random
+ */
+
+DUK_EXTERNAL_DECL duk_double_t duk_random(duk_context *ctx);
+
+/*
* Function (method) calls
*/
@@ -1257,7 +1327,7 @@ DUK_EXTERNAL_DECL duk_double_t duk_components_to_time(duk_context *ctx, duk_time
#define DUK_DATE_MSEC_HOUR (60L * 60L * 1000L)
#define DUK_DATE_MSEC_DAY (24L * 60L * 60L * 1000L)
-/* Ecmascript date range is 100 million days from Epoch:
+/* ECMAScript date range is 100 million days from Epoch:
* > 100e6 * 24 * 60 * 60 * 1000 // 100M days in millisecs
* 8640000000000000
* (= 8.64e15)
@@ -1265,7 +1335,7 @@ DUK_EXTERNAL_DECL duk_double_t duk_components_to_time(duk_context *ctx, duk_time
#define DUK_DATE_MSEC_100M_DAYS (8.64e15)
#define DUK_DATE_MSEC_100M_DAYS_LEEWAY (8.64e15 + 24 * 3600e3)
-/* Ecmascript year range:
+/* ECMAScript year range:
* > new Date(100e6 * 24 * 3600e3).toISOString()
* '+275760-09-13T00:00:00.000Z'
* > new Date(-100e6 * 24 * 3600e3).toISOString()
@@ -1275,7 +1345,7 @@ DUK_EXTERNAL_DECL duk_double_t duk_components_to_time(duk_context *ctx, duk_time
#define DUK_DATE_MAX_ECMA_YEAR 275760L
/* Part indices for internal breakdowns. Part order from DUK_DATE_IDX_YEAR
- * to DUK_DATE_IDX_MILLISECOND matches argument ordering of Ecmascript API
+ * to DUK_DATE_IDX_MILLISECOND matches argument ordering of ECMAScript API
* calls (like Date constructor call). Some functions in duk_bi_date.c
* depend on the specific ordering, so change with care. 16 bits are not
* enough for all parts (year, specifically).