duktape: Import v2.3.0
diff --git a/duktape/duk_config.h b/duktape/duk_config.h
index 51e973f..141414a 100644
--- a/duktape/duk_config.h
+++ b/duktape/duk_config.h
@@ -1,9 +1,9 @@
 /*
  *  duk_config.h configuration header generated by genconfig.py.
  *
- *  Git commit: 25420e773c5fbc50d5b46bf487fc45717e35b94f
- *  Git describe: v2.2.1
- *  Git branch: v2.2-maintenance
+ *  Git commit: d7fdb67f18561a50e06bafd196c6b423af9ad6fe
+ *  Git describe: v2.3.0
+ *  Git branch: master
  *
  *  Supported platforms:
  *      - Mac OSX, iPhone, Darwin
@@ -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.
- */
-#if !defined(DUK_USE_ALIGN_BY)
-#define DUK_USE_ALIGN_BY 1
-#endif
+
 #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_F_FREEBSD) && defined(DUK_F_X86) && \
+    defined(__clang__) && defined(__clang_major__) && (__clang_major__ < 5)
+#undef DUK_USE_PACKED_TVAL
+#endif
 #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 4
-#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 @@
  *
  *  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 @@
  */
 #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 @@
  */
 #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 @@
  */
 #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 @@
 #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 @@
  *  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 @@
 #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 @@
 #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 @@
 #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
@@ -3012,6 +2987,15 @@
 /* __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
@@ -3552,6 +3536,12 @@
 #if defined(DUK_USE_MS_STRINGTABLE_RESIZE)
 #error unsupported config option used (option has been removed): DUK_USE_MS_STRINGTABLE_RESIZE
 #endif
+#if defined(DUK_USE_NONSTD_ARRAY_CONCAT_TRAILER)
+#error unsupported config option used (option has been removed): DUK_USE_NONSTD_ARRAY_CONCAT_TRAILER
+#endif
+#if defined(DUK_USE_NONSTD_ARRAY_MAP_TRAILER)
+#error unsupported config option used (option has been removed): DUK_USE_NONSTD_ARRAY_MAP_TRAILER
+#endif
 #if defined(DUK_USE_NONSTD_REGEXP_DOLLAR_ESCAPE)
 #error unsupported config option used (option has been removed): DUK_USE_NONSTD_REGEXP_DOLLAR_ESCAPE
 #endif
diff --git a/duktape/duktape.c b/duktape/duktape.c
index ba55550..c3781f7 100644
--- a/duktape/duktape.c
+++ b/duktape/duktape.c
@@ -1,8 +1,8 @@
 /*
- *  Single source autogenerated distributable for Duktape 2.2.1.
+ *  Single source autogenerated distributable for Duktape 2.3.0.
  *
- *  Git commit 25420e773c5fbc50d5b46bf487fc45717e35b94f (v2.2.1).
- *  Git branch v2.2-maintenance.
+ *  Git commit d7fdb67f18561a50e06bafd196c6b423af9ad6fe (v2.3.0).
+ *  Git branch master.
  *
  *  See Duktape AUTHORS.rst and LICENSE.txt for copyright and
  *  licensing information.
@@ -16,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
@@ -87,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
 *  ===================
@@ -125,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.
@@ -669,20 +679,32 @@
 /* #include duk_exception.h */
 #line 1 "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 */
@@ -734,8 +756,9 @@
 
 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)
@@ -794,8 +817,9 @@
 
 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)
@@ -1694,278 +1718,290 @@
 #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)
@@ -1982,6 +2018,8 @@
 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);
@@ -1992,8 +2030,6 @@
 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);
@@ -2065,6 +2101,7 @@
 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);
@@ -2147,7 +2184,7 @@
 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
@@ -2202,22 +2239,22 @@
 #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
@@ -2544,12 +2581,13 @@
 		(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 { \
@@ -2557,31 +2595,31 @@
 		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)
 
@@ -2645,13 +2683,14 @@
 		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 { \
@@ -2660,35 +2699,35 @@
 		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)
 
@@ -2717,10 +2756,6 @@
 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 */
@@ -2775,6 +2810,127 @@
 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);
@@ -2789,6 +2945,33 @@
 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 */
@@ -2963,7 +3146,7 @@
 /* #include duk_js_bytecode.h */
 #line 1 "duk_js_bytecode.h"
 /*
- *  Ecmascript bytecode
+ *  ECMAScript bytecode
  */
 
 #if !defined(DUK_JS_BYTECODE_H_INCLUDED)
@@ -3836,7 +4019,7 @@
 	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' */
@@ -3887,13 +4070,13 @@
 /* #include duk_js_compiler.h */
 #line 1 "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 */
@@ -4075,6 +4258,7 @@
 	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 {
@@ -5378,10 +5562,12 @@
 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);
@@ -5519,6 +5705,8 @@
 
 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
@@ -5555,6 +5743,10 @@
 
 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().
@@ -5594,7 +5786,7 @@
  *  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.
@@ -5618,12 +5810,15 @@
 #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) */
@@ -5632,6 +5827,7 @@
 #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)
@@ -5641,6 +5837,7 @@
 #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)
@@ -5650,6 +5847,7 @@
 #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)
@@ -5659,6 +5857,7 @@
 #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.
@@ -5827,12 +6026,12 @@
 /*
  *  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:
@@ -6461,7 +6660,7 @@
 #define DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY      10000L
 
 /*
- *  Ecmascript [[Class]]
+ *  ECMAScript [[Class]]
  */
 
 /* range check not necessary because all 4-bit values are mapped */
@@ -6825,9 +7024,9 @@
 /* #include duk_hcompfunc.h */
 #line 1 "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.
  */
 
@@ -7221,7 +7420,8 @@
 	} 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 +7740,14 @@
 	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;
@@ -7934,7 +8134,7 @@
 #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) \
@@ -7989,7 +8189,7 @@
 				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
@@ -7998,7 +8198,7 @@
 #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
 
@@ -8072,7 +8272,10 @@
 #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
@@ -8489,7 +8692,7 @@
  *  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;
@@ -8521,6 +8724,15 @@
 	} while (0)
 
 /*
+ *  Literal intern cache
+ */
+
+struct duk_litcache_entry {
+	const duk_uint8_t *addr;
+	duk_hstring *h;
+};
+
+/*
  *  Main heap structure
  */
 
@@ -8746,7 +8958,15 @@
 	/* 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)
@@ -8778,6 +8998,9 @@
 	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;
@@ -8838,6 +9061,9 @@
 
 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)
@@ -9242,8 +9468,8 @@
  *  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.
  */
@@ -9645,7 +9871,7 @@
 
 #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)
@@ -9924,13 +10150,13 @@
  *  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)
@@ -9952,13 +10178,13 @@
  *  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
 
 /*
@@ -10101,7 +10327,7 @@
 /* #include duk_js.h */
 #line 1 "duk_js.h"
 /*
- *  Ecmascript execution, support primitives.
+ *  ECMAScript execution, support primitives.
  */
 
 #if !defined(DUK_JS_H_INCLUDED)
@@ -10145,6 +10371,9 @@
 #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);
 
@@ -10214,7 +10443,7 @@
 #line 1 "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)
@@ -10247,9 +10476,13 @@
 
 /* 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)
@@ -10525,7 +10758,7 @@
 
 	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;
@@ -10556,7 +10789,7 @@
 
 	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;
@@ -10597,7 +10830,7 @@
 #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,
@@ -10619,36 +10852,40 @@
 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,
@@ -10741,6 +10978,7 @@
 	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,
@@ -10827,556 +11065,577 @@
 	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
@@ -11501,10 +11760,18 @@
 	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
@@ -11521,7 +11788,7 @@
 	 *   - 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
 
@@ -11677,7 +11944,7 @@
 		/*
 		 *  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
 		 *
@@ -11816,8 +12083,7 @@
 		return cp;
 	}
 	DUK_ERROR_INTERNAL(thr);
-	DUK_UNREACHABLE();
-	return 0;
+	DUK_WO_NORETURN(return 0;);
 }
 
 /* Compute (extended) utf-8 length without codepoint encoding validation,
@@ -11966,7 +12232,7 @@
 	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;
 
@@ -12518,7 +12784,7 @@
 	}
 
 	/* 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);
@@ -12718,7 +12984,7 @@
 #endif  /* DUK_USE_REGEXP_SUPPORT */
 #line 1 "duk_util_misc.c"
 /*
- *  Misc util stuff
+ *  Misc util stuff.
  */
 
 /* #include duk_internal.h -> already included */
@@ -12881,45 +13147,6 @@
 #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.
@@ -12939,192 +13166,9 @@
 	}
 }
 #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);
-}
 #line 1 "duk_hobject_class.c"
 /*
- *  Hobject Ecmascript [[Class]].
+ *  Hobject ECMAScript [[Class]].
  */
 
 /* #include duk_internal.h -> already included */
@@ -13304,9 +13348,10 @@
 
 	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);
@@ -13324,6 +13369,7 @@
 
 	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
@@ -13352,6 +13398,7 @@
 
 	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));
 
@@ -13401,7 +13448,7 @@
 	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;
 }
@@ -13416,7 +13463,7 @@
 	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;
@@ -13435,9 +13482,10 @@
 	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;
 }
@@ -13649,7 +13697,7 @@
 	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) {
@@ -13671,7 +13719,7 @@
 			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 {
@@ -13835,7 +13883,7 @@
 	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;
@@ -13900,15 +13948,12 @@
 	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--) {
@@ -14109,6 +14154,7 @@
 
  format_error:
 	DUK_ERROR_TYPE(thr, DUK_STR_INVALID_BYTECODE);
+	DUK_WO_NORETURN(return;);
 }
 
 #else  /* DUK_USE_BYTECODE_DUMP_SUPPORT */
@@ -14116,11 +14162,13 @@
 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 */
@@ -14188,7 +14236,7 @@
 	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;
@@ -14300,6 +14348,7 @@
 	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);
@@ -14336,7 +14385,7 @@
 	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;
 
@@ -14371,7 +14420,7 @@
 	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;
 
@@ -14412,7 +14461,7 @@
 	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;
 
@@ -14448,7 +14497,7 @@
 		                  (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 */
@@ -14496,7 +14545,7 @@
 
 	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*/);
@@ -14523,6 +14572,7 @@
 
 	if (!duk_is_constructor_call(thr)) {
 		DUK_ERROR_TYPE(thr, DUK_STR_CONSTRUCT_ONLY);
+		DUK_WO_NORETURN(return;);
 	}
 }
 
@@ -14533,7 +14583,7 @@
 	 * 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.
 	 */
@@ -14600,7 +14650,7 @@
 	/* 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) {
@@ -14632,7 +14682,7 @@
 		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);
@@ -14663,6 +14713,10 @@
 
 /* #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.
@@ -14684,250 +14738,425 @@
 	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);
+	t = (duk_uint_t) src[0];
+	t = (t << 8) + (duk_uint_t) src[1];
+	t = (t << 8) + (duk_uint_t) src[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[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];
 
-		*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;
+#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);
 	}
 
-	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;
+	/* Remainder. */
+	while (n >= 3U) {
+		duk__base64_encode_fast_3(p, q);
+		p += 3;
+		q += 4;
+		n -= 3U;
 	}
-	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;
-	}
+	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. */
+		/* 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;
 
-		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.
+			/* 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));
+			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));
 
-			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++];
+			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]];
 
-			if (DUK_UNLIKELY(t < 0)) {
-				DUK_DDD(DUK_DDDPRINT("fast loop unit was not clean, process one slow path unit"));
-				src -= 4;
+			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;
-		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) {
-					continue;  /* allowed ascii whitespace */
-				} else if (x == -3) {
-					n_equal++;
-					t <<= 6;
-				} else {
-					DUK_ASSERT(x == -1);
-					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;
-			}
-
-			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 */
-					}
-
-					/* Continue parsing after padding, allows concatenated,
-					 * padded base64.
-					 */
-				}
-				break;  /* back to fast loop */
-			} else {
-				n_chars++;
-			}
-		}
-	}
- done:
-	DUK_DDD(DUK_DDDPRINT("done; src=%p, src_end=%p, n_chars=%ld",
-	                     (const void *) src, (const void *) src_end, (long) n_chars));
-
-	DUK_ASSERT(src == src_end);
-
-	if (n_chars != 0) {
-		/* Here we'd have the option of decoding unpadded base64
-		 * (e.g. "xxxxyy" instead of "xxxxyy==".  Currently not
-		 * accepted.
+		/* 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.
 		 */
-		goto decode_error;
-	}
+		t = 1UL;
+		for (;;) {
+			DUK_DDD(DUK_DDDPRINT("slow loop: p=%p, p_end=%p, t=%lu",
+			                     (const void *) p, (const void *) p_end, (unsigned long) t));
 
-	*out_dst_final = dst;
+			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 == -2) {
+					p--;
+					break;  /* start of padding */
+				} else {
+					DUK_ASSERT(x == -3);
+					goto decode_error;
+				}
+			} else {
+				break;  /* end of input */
+			}
+		}  /* slow path step 1 */
+
+		/* 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++;
+		}
+
+		/* 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 {
+				p--;
+				break;  /* backtrack and go back to fast path, even for -1 */
+			}
+		}  /* slow path step 3 */
+	}  /* outer fast+slow path loop */
+
+ done:
+	DUK_DDD(DUK_DDDPRINT("done; p=%p, p_end=%p",
+	                     (const void *) p, (const void *) p_end));
+
+	DUK_ASSERT(p == p_end);
+
+	*out_dst_final = q;
 	return 1;
 
  decode_error:
@@ -14935,94 +15164,138 @@
 }
 #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;
+	/* '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;
 
-	while (src < src_end) {
-		x = *src++;
+	for (;;) {
+		duk_small_uint_t n_equal;
 
-		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.
+		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.
 			 */
-
-			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;
-		} else {
-			goto decode_error;
-		}
-
-		if (n_equal > 0) {
-			/* Don't allow mixed padding and actual chars. */
-			goto decode_error;
-		}
-		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 */
-				}
-
-				/* 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;
+			if (t == 1U) {
+				break;
+			} else {
+				goto simulate_padding;
 			}
-
-			t = 0;
-			group_idx = 0;
-		} else {
-			group_idx++;
 		}
-	}
 
-	if (group_idx != 0) {
-		/* Here we'd have the option of decoding unpadded base64
-		 * (e.g. "xxxxyy" instead of "xxxxyy==".  Currently not
-		 * accepted.
+		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 {
+			/* 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;
+			}
+		}
+
+		DUK_ASSERT(y >= 0 && y <= 63);
+		t = (t << 6) + (duk_uint_t) y;
+		if (t < 0x1000000UL) {
+			continue;
+		}
+		/* fall through; no padding will be added */
+
+	 simulate_padding:
+		n_equal = 0;
+		while (t < 0x1000000UL) {
+			t = (t << 6) + 0U;
+			n_equal++;
+		}
+
+		/* 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;
+
+		/* 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:
@@ -15039,15 +15312,12 @@
 
 	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'
@@ -15055,7 +15325,7 @@
 	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);
@@ -15066,7 +15336,7 @@
 
  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) {
@@ -15075,31 +15345,24 @@
 	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;
 	}
 
@@ -15110,8 +15373,27 @@
 
  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;
@@ -15222,8 +15504,12 @@
 		}
 	}
 	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;
 		}
@@ -15235,8 +15521,8 @@
 		 * 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;
 		}
@@ -15249,7 +15535,24 @@
 
  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) {
@@ -15302,12 +15605,14 @@
 	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 */
 #line 1 "duk_api_compile.c"
@@ -15402,6 +15707,7 @@
 		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);
@@ -15527,6 +15833,7 @@
 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 */
 
@@ -15638,7 +15945,7 @@
 	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);
@@ -15705,11 +16012,13 @@
 	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) {
@@ -15726,7 +16035,7 @@
 	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. */
@@ -15849,7 +16158,7 @@
 	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;
@@ -15879,7 +16188,7 @@
 
 	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;
@@ -16016,7 +16325,7 @@
 	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);
@@ -16032,12 +16341,12 @@
 		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)
@@ -16082,7 +16391,7 @@
 		}
 
 		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);
@@ -16285,7 +16594,7 @@
  *  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).
  */
 
@@ -16317,7 +16626,7 @@
 	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);
 }
 
@@ -16326,10 +16635,22 @@
 	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);
 
@@ -16342,7 +16663,7 @@
 	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);
 }
 
@@ -16351,7 +16672,7 @@
 	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);
 }
 
@@ -16370,10 +16691,7 @@
 	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) {
@@ -16433,6 +16751,18 @@
 	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);
 
@@ -16445,7 +16775,7 @@
 	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);
 }
 
@@ -16492,7 +16822,7 @@
 	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);
 }
 
@@ -16501,10 +16831,22 @@
 	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);
 
@@ -16517,7 +16859,7 @@
 	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);
 }
 
@@ -16563,7 +16905,7 @@
 	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);
 }
 
@@ -16572,10 +16914,22 @@
 	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);
 
@@ -16588,7 +16942,7 @@
 	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);
 }
 
@@ -16788,17 +17142,17 @@
 
  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.
  */
 
@@ -16890,6 +17244,7 @@
 
  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) {
@@ -16973,6 +17328,38 @@
 	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;
 
@@ -17003,6 +17390,56 @@
 	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
  */
@@ -17041,7 +17478,7 @@
 #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
 
@@ -17098,14 +17535,26 @@
 	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 */
+#line 1 "duk_api_random.c"
+/*
+ *  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);
+}
 #line 1 "duk_api_stack.c"
 /*
  *  API calls related to general value stack manipulation: resizing the value
@@ -17281,7 +17730,7 @@
 
 	if (require) {
 		DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "number", DUK_STR_NOT_NUMBER);
-		/* not reachable */
+		DUK_WO_NORETURN(return 0;);
 	}
 
 	return def_value;
@@ -17332,7 +17781,7 @@
 
 	if (require) {
 		DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "number", DUK_STR_NOT_NUMBER);
-		/* not reachable */
+		DUK_WO_NORETURN(return 0;);
 	}
 
 	return def_value;
@@ -17407,7 +17856,7 @@
 		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) {
@@ -17483,7 +17932,7 @@
 		return thr->valstack_bottom + uidx;
 	}
 	DUK_ERROR_RANGE_INDEX(thr, idx);
-	return NULL;
+	DUK_WO_NORETURN(return NULL;);
 }
 
 /* Non-critical. */
@@ -17501,7 +17950,7 @@
 
 	if (DUK_UNLIKELY(duk_normalize_index(thr, idx) < 0)) {
 		DUK_ERROR_RANGE_INDEX(thr, idx);
-		return;  /* unreachable */
+		DUK_WO_NORETURN(return;);
 	}
 }
 
@@ -17526,6 +17975,7 @@
 	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;
 }
@@ -17570,7 +18020,7 @@
 #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);
@@ -17753,7 +18203,7 @@
 	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;
 }
@@ -17954,6 +18404,7 @@
 		 */
 		if (throw_on_error) {
 			DUK_ERROR_RANGE(thr, DUK_STR_VALSTACK_LIMIT);
+			DUK_WO_NORETURN(return 0;);
 		}
 		return 0;
 	}
@@ -17961,6 +18412,7 @@
 	if (duk__resize_valstack(thr, new_size) == 0) {
 		if (throw_on_error) {
 			DUK_ERROR_ALLOC_FAILED(thr);
+			DUK_WO_NORETURN(return 0;);
 		}
 		return 0;
 	}
@@ -18221,7 +18673,7 @@
 
 	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++;
@@ -18283,18 +18735,12 @@
 	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) {
@@ -18386,7 +18832,7 @@
 #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--;
@@ -18439,7 +18885,7 @@
 		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++) {
@@ -18478,14 +18924,14 @@
 
 	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);
 
@@ -18496,17 +18942,19 @@
 	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);
@@ -18555,7 +19003,7 @@
 	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.
@@ -18576,6 +19024,7 @@
 	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;);
 	}
 }
 
@@ -18588,6 +19037,7 @@
 	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;);
 	}
 }
 
@@ -18636,6 +19086,7 @@
 		return ret;
 	} else {
 		DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "boolean", DUK_STR_NOT_BOOLEAN);
+		DUK_WO_NORETURN(return 0;);
 	}
 }
 
@@ -18697,6 +19148,7 @@
 	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);
@@ -18928,6 +19380,7 @@
 	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;);
 	}
 }
 
@@ -18979,6 +19432,7 @@
 	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;
@@ -19026,6 +19480,7 @@
 	} 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;
@@ -19129,6 +19584,7 @@
 
 	if (throw_flag) {
 		DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "buffer", DUK_STR_NOT_BUFFER);
+		DUK_WO_NORETURN(return NULL;);
 	}
 	return def_ptr;
 }
@@ -19208,6 +19664,7 @@
 	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;
 }
@@ -19220,6 +19677,7 @@
 	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;
 }
@@ -19237,6 +19695,7 @@
 	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;
 }
@@ -19254,6 +19713,7 @@
 	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;
 }
@@ -19278,6 +19738,7 @@
 	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;
 }
@@ -19302,6 +19763,7 @@
 	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;
 }
@@ -19326,6 +19788,7 @@
 	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;
 }
@@ -19384,6 +19847,7 @@
 	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;
 }
@@ -19392,6 +19856,7 @@
 	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;);
 	}
 }
 
@@ -19403,6 +19868,7 @@
 	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. */
 }
@@ -19490,6 +19956,7 @@
 	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);
@@ -19523,6 +19990,7 @@
 
 	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;
 }
@@ -19583,6 +20051,7 @@
 		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;
 }
@@ -19775,49 +20244,43 @@
 }
 
 /* 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
@@ -19825,17 +20288,29 @@
 	 * 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;
@@ -19851,9 +20326,21 @@
 		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;
@@ -19874,6 +20361,22 @@
 	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;
@@ -20153,68 +20656,67 @@
 #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:
@@ -20222,14 +20724,142 @@
 #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;
 	}
 	}
-	h_strclass = DUK_HTHREAD_GET_STRING(thr, stridx);
-	DUK_ASSERT(h_strclass != NULL);
+	DUK_ASSERT(0);  /* Never here. */
 
-	duk_push_sprintf(thr, "[object %s]", (const char *) DUK_HSTRING_GET_DATA(h_strclass));
+ 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. */
+		;
+	}
+	duk_pop_unsafe(thr);
+	/* Fall through. */
+
+ use_stridx:
+	/* [ ... "[object" ] */
+	duk_push_hstring_stridx(thr, stridx_bidx & 0xffffUL);
+
+ 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 */
@@ -20289,6 +20919,7 @@
 		/* 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;);
 		}
 	}
 
@@ -20346,12 +20977,14 @@
 		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: {
@@ -20502,14 +21135,9 @@
 	}
 
 	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:
 
@@ -20625,6 +21253,7 @@
 	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: {
@@ -20932,7 +21561,7 @@
 	}
 	if (mask & DUK_TYPE_MASK_THROW) {
 		DUK_ERROR_TYPE(thr, DUK_STR_UNEXPECTED_TYPE);
-		DUK_UNREACHABLE();
+		DUK_WO_NORETURN(return 0;);
 	}
 	return 0;
 }
@@ -21405,21 +22034,22 @@
 
 	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);
@@ -21443,6 +22073,42 @@
 	}
 }
 
+#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;
 
@@ -21496,6 +22162,7 @@
 
  type_error:
 	DUK_ERROR_TYPE(thr, DUK_STR_NOT_OBJECT_COERCIBLE);
+	DUK_WO_NORETURN(return;);
 }
 
 DUK_EXTERNAL void duk_push_this(duk_hthread *thr) {
@@ -21539,6 +22206,46 @@
 	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;
 
@@ -21599,7 +22306,7 @@
 	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);
@@ -21675,6 +22382,7 @@
 		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;);
 		}
 	}
 
@@ -21863,6 +22571,7 @@
 	/* 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 */
@@ -21904,6 +22613,7 @@
 	                          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));
@@ -21935,6 +22645,7 @@
 	                           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++;
@@ -21991,7 +22702,7 @@
 
  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) {
@@ -22083,7 +22794,7 @@
 
  api_error:
 	DUK_ERROR_TYPE_INVALID_ARGS(thr);
-	return 0;  /* not reached */
+	DUK_WO_NORETURN(return 0;);
 }
 
 #if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
@@ -22235,11 +22946,11 @@
 
  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) {
@@ -22249,6 +22960,7 @@
 	DUK_UNREF(byte_length);
 	DUK_UNREF(flags);
 	DUK_ERROR_UNSUPPORTED(thr);
+	DUK_WO_NORETURN(return;);
 }
 #endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */
 
@@ -22286,7 +22998,7 @@
 		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.
@@ -22348,11 +23060,13 @@
 	/* 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;
@@ -22374,11 +23088,12 @@
 	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;
 }
@@ -22475,12 +23190,14 @@
 
  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 */
 
@@ -22778,7 +23495,7 @@
 
 	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);
 
@@ -22866,6 +23583,7 @@
 	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);
@@ -22954,6 +23672,7 @@
 	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);
@@ -23011,7 +23730,7 @@
 	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);
 
@@ -23028,9 +23747,8 @@
 	/* 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.
@@ -23148,11 +23866,11 @@
 	}
 
 	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;);
 }
 
 /*
@@ -23169,6 +23887,7 @@
 
 	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
@@ -23232,6 +23951,7 @@
 
 	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, ...) {
@@ -23243,6 +23963,7 @@
 	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)
@@ -23261,6 +23982,7 @@
 
 	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 { \
@@ -23268,7 +23990,7 @@
 		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, ...) {
@@ -23398,7 +24120,7 @@
 
 	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);
@@ -23423,9 +24145,9 @@
 	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);
 }
 
@@ -23537,7 +24259,7 @@
 	/* '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: {
@@ -23546,11 +24268,11 @@
 				/* 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;
 			}
@@ -23580,7 +24302,7 @@
 					break;
 				}
 			}
-			duk_push_class_string_tval(thr, tv);
+			duk_push_class_string_tval(thr, tv, 1 /*avoid_side_effects*/);
 			break;
 		}
 		case DUK_TAG_BUFFER: {
@@ -23635,7 +24357,7 @@
 	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);
@@ -23651,7 +24373,7 @@
 		}
 	}
 	duk_push_lstring(thr, (const char *) p, (duk_size_t) (q - p));
-	duk_push_string(thr, ")");
+	duk_push_literal(thr, ")");
 	duk_concat(thr, 3);
 }
 
@@ -23687,7 +24409,8 @@
 	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) {
@@ -23724,7 +24447,7 @@
 	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);
@@ -23780,11 +24503,11 @@
 	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);
 	}
 
@@ -23811,6 +24534,7 @@
 
  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) {
@@ -23848,8 +24572,8 @@
 	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 ] */
@@ -23860,6 +24584,7 @@
 
  error_overflow:
 	DUK_ERROR_RANGE(thr, DUK_STR_RESULT_TOO_LONG);
+	DUK_WO_NORETURN(return;);
 }
 #endif  /* DUK_USE_PREFER_SIZE */
 
@@ -24089,7 +24814,7 @@
 /* #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);
@@ -24097,7 +24822,7 @@
 }
 
 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);
@@ -24140,7 +24865,7 @@
 	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;
 
@@ -24196,9 +24921,9 @@
 /*
  *  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
@@ -24272,6 +24997,7 @@
 	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;
 }
@@ -24424,11 +25150,17 @@
 
 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).
 	 */
@@ -24446,59 +25178,97 @@
 	 */
 
 	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);
-		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;
-			} 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
-			}
+		/* [ 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;
 		}
-		duk_pop_unsafe(thr);
+		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++) {
+			/* 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 {
+				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. */
+		}
 	}
 
-	/* 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;);
 }
 
 /*
@@ -25620,20 +26390,12 @@
 		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;
 		}
@@ -26060,6 +26822,7 @@
 
 	if (flags & DUK__BUFOBJ_FLAG_THROW) {
 		DUK_ERROR_TYPE(thr, DUK_STR_NOT_BUFFER);
+		DUK_WO_NORETURN(return NULL;);
 	}
 	return NULL;
 }
@@ -26101,7 +26864,7 @@
 	}
 
 	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) {
@@ -26176,6 +26939,7 @@
 
  fail_range:
 	DUK_ERROR_RANGE(thr, DUK_STR_INVALID_ARGS);
+	DUK_WO_NORETURN(return;);
 }
 
 /* Shared lenient buffer length clamping helper.  No negative indices, no
@@ -26326,7 +27090,8 @@
 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:
@@ -26394,7 +27159,11 @@
 		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);
@@ -26403,7 +27172,8 @@
 		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.
@@ -26439,12 +27209,14 @@
 			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;
@@ -26460,6 +27232,7 @@
 	}
 	default:
 		DUK_ERROR_TYPE_INVALID_ARGS(thr);
+		DUK_WO_NORETURN(return NULL;);
 	}
 
  done:
@@ -26501,7 +27274,7 @@
 	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);
@@ -26829,7 +27602,7 @@
 		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: {
@@ -27065,7 +27838,7 @@
 	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);
@@ -27096,9 +27869,9 @@
 	 */
 
 	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
@@ -27260,7 +28033,7 @@
 		/* 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;
 
@@ -27311,9 +28084,9 @@
 
 	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"));
 	}
@@ -27409,9 +28182,9 @@
 		/* 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"));
 	}
@@ -27597,7 +28370,7 @@
 			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"));
@@ -27640,7 +28413,7 @@
 			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 */
 		}
@@ -27767,9 +28540,9 @@
 	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 */
 
@@ -27891,9 +28664,9 @@
 		 * 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);
 
@@ -28085,9 +28858,9 @@
 
 		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. */
 			;
@@ -28237,7 +29010,7 @@
 		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);
@@ -28254,7 +29027,7 @@
 		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);
@@ -28271,7 +29044,7 @@
 		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);
@@ -28284,7 +29057,7 @@
 		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);
 		}
@@ -28341,9 +29114,12 @@
 		} 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);
@@ -28519,7 +29295,7 @@
 		}
 		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: {
@@ -28533,7 +29309,7 @@
 		}
 		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: {
@@ -28548,7 +29324,7 @@
 			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: {
@@ -28560,7 +29336,7 @@
 			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: {
@@ -29007,7 +29783,7 @@
 	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;
@@ -29234,13 +30010,13 @@
 };
 
 /* 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.
  */
@@ -29431,10 +30207,10 @@
 	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));
@@ -29477,7 +30253,7 @@
 	                     (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 */
@@ -29597,7 +30373,7 @@
 	 * 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
@@ -29704,6 +30480,7 @@
 	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);
@@ -29716,6 +30493,7 @@
 		}
 		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 */
@@ -30332,7 +31110,7 @@
  *  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
@@ -30528,6 +31306,41 @@
 	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 */
@@ -30596,7 +31409,7 @@
 #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;
@@ -30644,7 +31457,7 @@
 		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
@@ -30695,10 +31508,10 @@
 	 *  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:
 	 *
@@ -30713,7 +31526,7 @@
 	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]);
@@ -30723,9 +31536,9 @@
 	(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
@@ -30786,13 +31599,13 @@
 
 	/* 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}",
@@ -30823,7 +31636,7 @@
 	 * 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));
 
@@ -30848,16 +31661,16 @@
 
 	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)) {
@@ -30865,7 +31678,7 @@
 		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];
@@ -30875,7 +31688,7 @@
 	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) {
@@ -30934,13 +31747,15 @@
 	}
 }
 
+#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 */
@@ -31005,10 +31820,11 @@
 	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).
 	 */
@@ -31024,7 +31840,11 @@
 
 	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;
@@ -31044,6 +31864,7 @@
 	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
@@ -31059,9 +31880,17 @@
 
 	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 */
@@ -31098,7 +31927,7 @@
  *
  *  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.
@@ -31493,7 +32322,7 @@
 	                                      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);
 		}
 	}
@@ -31508,6 +32337,7 @@
 	 */
 	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 */
 
@@ -31585,7 +32415,7 @@
 
  fail_type:
 	DUK_ERROR_TYPE(thr, DUK_STR_UTF8_DECODE_FAILED);
-	DUK_UNREACHABLE();
+	DUK_WO_NORETURN(return 0;);
 }
 
 /*
@@ -31603,7 +32433,7 @@
 }
 
 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;
 }
 
@@ -31625,6 +32455,7 @@
 		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;);
 		}
 	}
 
@@ -31644,14 +32475,14 @@
 		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?
 		 */
@@ -31679,7 +32510,7 @@
 
 	/* 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.
 	 */
@@ -31701,10 +32532,10 @@
 		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);
 		}
 	}
@@ -31719,7 +32550,7 @@
 	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;
 }
 
@@ -31727,7 +32558,7 @@
 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;
@@ -31744,7 +32575,7 @@
 		/* 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);
@@ -31845,7 +32676,7 @@
 	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);
 	}
@@ -31875,7 +32706,7 @@
 		duk_pop(thr);
 		return 1;
 	}
-	duk_push_string(thr, ": ");
+	duk_push_literal(thr, ": ");
 	duk_insert(thr, -2);  /* ... name ': ' message */
 	duk_concat(thr, 3);
 
@@ -31944,13 +32775,13 @@
 			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++;
@@ -32220,7 +33051,7 @@
 		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);
 	}
@@ -32232,11 +33063,11 @@
 	/* 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 ] */
@@ -32254,7 +33085,7 @@
 	               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);
@@ -32466,7 +33297,7 @@
 		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.
@@ -32500,7 +33331,7 @@
 		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;
@@ -32540,7 +33371,7 @@
 	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
@@ -32624,6 +33455,17 @@
  fail_type:
 	DUK_DCERROR_TYPE_INVALID_ARGS(thr);
 }
+
+#if defined(DUK_USE_SYMBOL_BUILTIN)
+DUK_INTERNAL duk_ret_t duk_bi_function_prototype_hasinstance(duk_hthread *thr) {
+	/* This binding: RHS, stack index 0: LHS. */
+	duk_bool_t ret;
+
+	ret = duk_js_instanceof_ordinary(thr, DUK_GET_TVAL_POSIDX(thr, 0), DUK_GET_THIS_TVAL_PTR(thr));
+	duk_push_boolean(thr, ret);
+	return 1;
+}
+#endif  /* DUK_USE_SYMBOL_BUILTIN */
 #line 1 "duk_bi_global.c"
 /*
  *  Global object built-ins
@@ -32827,6 +33669,7 @@
 
  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) {
@@ -32965,6 +33808,7 @@
 
  uri_error:
 	DUK_ERROR_URI(tfm_ctx->thr, DUK_STR_INVALID_INPUT);
+	DUK_WO_NORETURN(return;);
 }
 
 #if defined(DUK_USE_SECTION_B)
@@ -33005,6 +33849,7 @@
 
  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) {
@@ -33037,7 +33882,7 @@
  *  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.
  */
@@ -33076,7 +33921,7 @@
 
 #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)) {
@@ -33570,6 +34415,7 @@
 	 */
 	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) {
@@ -33985,7 +34831,7 @@
 	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 '|' */
@@ -34076,6 +34922,7 @@
 	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++;
 }
@@ -34652,9 +35499,9 @@
 				/* 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.
 				 *
@@ -34791,7 +35638,7 @@
 
 	/* 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.
@@ -34824,7 +35671,7 @@
 #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
@@ -34900,7 +35747,7 @@
 #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;
@@ -34973,7 +35820,7 @@
 	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.
@@ -35063,21 +35910,21 @@
 	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*/
 
@@ -35109,6 +35956,7 @@
 		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) {
@@ -35118,6 +35966,7 @@
 		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);  /* -> [ ... ] */
@@ -35129,6 +35978,7 @@
 	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++;
 
@@ -35726,12 +36576,14 @@
 		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;);
 			}
 		}
 
@@ -36112,7 +36964,7 @@
 	/* 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) {
@@ -36161,7 +37013,7 @@
 	                     (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 */
@@ -36271,7 +37123,7 @@
 	 *  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;
@@ -36670,7 +37522,7 @@
 
 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;
@@ -36697,7 +37549,7 @@
 
 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) {
@@ -37161,6 +38013,7 @@
 	    (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));
@@ -37267,8 +38120,11 @@
 	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) {
@@ -37375,6 +38231,42 @@
 	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 */
 #line 1 "duk_bi_object.c"
 /*
@@ -37386,12 +38278,9 @@
 /* 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;
 }
 
@@ -37896,7 +38785,7 @@
 	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.
 	 *
@@ -38174,6 +39063,7 @@
 
 		if (DUK_UNLIKELY(sanity-- == 0)) {
 			DUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);
+			DUK_WO_NORETURN(return 0;);
 		}
 
 		duk_get_prototype(thr, -1);
@@ -38301,37 +39191,37 @@
 
 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 */
@@ -38366,6 +39256,7 @@
 		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)) {
@@ -38474,6 +39365,7 @@
 	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? ...? ] */
@@ -38517,6 +39409,7 @@
 	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? ...? ] */
@@ -38651,7 +39544,7 @@
 	/* 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);
@@ -38715,7 +39608,7 @@
 		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);
@@ -38787,6 +39680,7 @@
 
 	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);
@@ -38833,14 +39727,14 @@
 	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;
 			}
 		}
@@ -39022,13 +39916,37 @@
  */
 
 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;
 }
 
@@ -39418,7 +40336,7 @@
 
 			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)
@@ -39799,7 +40717,7 @@
 			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;
 				}
@@ -40112,12 +41030,14 @@
 
 	/* 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 */
@@ -40134,12 +41054,12 @@
 		                     (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;
 		}
 
@@ -40194,8 +41114,7 @@
 	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);
 
@@ -40245,7 +41164,7 @@
 
 	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 */
 		}
@@ -40276,7 +41195,7 @@
 	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;
@@ -40351,9 +41270,10 @@
 	 *   +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
@@ -40525,7 +41445,7 @@
  *
  *  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
@@ -40551,8 +41471,9 @@
 	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 ] */
 
@@ -40572,7 +41493,7 @@
 
 	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;
 	}
 
@@ -40600,7 +41521,7 @@
 
 		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.
@@ -40679,7 +41600,7 @@
  *  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
@@ -40700,8 +41621,9 @@
 	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 ] */
 
@@ -40727,7 +41649,7 @@
 
 	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;
 	}
 
@@ -40826,7 +41748,7 @@
 	} else {
 		copylen = length;
 	}
-	DUK_MEMCPY(fb->buffer + fb->offset, buffer, copylen);
+	duk_memcpy_unsafe(fb->buffer + fb->offset, buffer, copylen);
 	fb->offset += copylen;
 }
 
@@ -40913,7 +41835,7 @@
  *      (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.
  *
@@ -41699,7 +42621,7 @@
 	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;
@@ -41724,7 +42646,7 @@
 		 *  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;
@@ -41791,8 +42713,8 @@
 					/* 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.
@@ -41897,7 +42819,8 @@
 	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);
@@ -42236,6 +43159,7 @@
 	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));
@@ -42273,7 +43197,7 @@
 	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) {
@@ -42886,7 +43810,7 @@
 		                   (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);
@@ -42995,9 +43919,9 @@
 		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. */
@@ -43042,7 +43966,7 @@
 		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));
@@ -43519,7 +44443,7 @@
 			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.
 				 */
@@ -44185,7 +45109,7 @@
 
 		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);
@@ -44662,7 +45586,7 @@
 		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)));
@@ -44758,11 +45682,10 @@
 	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;
 
@@ -44849,7 +45772,7 @@
  *
  *  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
@@ -45189,7 +46112,6 @@
 			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);
 
@@ -45405,12 +46327,15 @@
 /* #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];
@@ -45419,10 +46344,12 @@
 	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];
@@ -45432,6 +46359,7 @@
 	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
 
@@ -45469,14 +46397,9 @@
 
 	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",
@@ -45490,16 +46413,12 @@
 #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();
 }
@@ -45680,10 +46599,10 @@
 }
 #line 1 "duk_error_throw.c"
 /*
- *  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.
  */
 
@@ -45839,7 +46758,7 @@
 	 */
 
 	duk_error_raw(thr, -rc, NULL, 0, "error (rc %ld)", (long) rc);
-	DUK_UNREACHABLE();
+	DUK_WO_NORETURN(return;);
 }
 #line 1 "duk_hbuffer_alloc.c"
 /*
@@ -45891,10 +46810,10 @@
 
 	/* 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) {
@@ -45941,7 +46860,7 @@
 			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);
@@ -46001,6 +46920,7 @@
 
 	if (new_size > DUK_HBUFFER_MAX_BYTELEN) {
 		DUK_ERROR_RANGE(thr, "buffer too long");
+		DUK_WO_NORETURN(return;);
 	}
 
 	/*
@@ -46029,7 +46949,7 @@
 		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
 		}
@@ -46038,6 +46958,7 @@
 		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);
@@ -46141,7 +47062,7 @@
 		 * 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);
 	}
@@ -46539,7 +47460,7 @@
 	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;
 
@@ -46760,7 +47681,8 @@
 	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);
@@ -46969,7 +47891,7 @@
 	 *  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
@@ -47054,7 +47976,7 @@
 
 	/* 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]
 	 *
@@ -47065,7 +47987,7 @@
 	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
@@ -47105,17 +48027,17 @@
 
 #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 */
 
@@ -47125,13 +48047,30 @@
 
 #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
@@ -47203,7 +48142,7 @@
 	{
 		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;
@@ -47961,7 +48900,7 @@
 		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);
@@ -48435,7 +49374,8 @@
 			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;
@@ -48444,13 +49384,26 @@
 				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. */
@@ -48654,6 +49607,26 @@
 }
 
 /*
+ *  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.
@@ -48837,6 +49810,7 @@
 
 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
@@ -48853,7 +49827,11 @@
 	 */
 	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),
@@ -48890,6 +49868,22 @@
 	}
 }
 #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 */
 
 /*
@@ -48910,10 +49904,13 @@
 	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",
@@ -49054,6 +50051,9 @@
 #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. */
@@ -49159,6 +50159,9 @@
 	 */
 	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 */
 
 	/*
@@ -49349,8 +50352,7 @@
 
 	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;
 }
@@ -49364,7 +50366,7 @@
 		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) {
@@ -49376,7 +50378,7 @@
 		return res;
 	}
 	DUK_ERROR_ALLOC_FAILED(thr);
-	return NULL;
+	DUK_WO_NORETURN(return NULL;);
 }
 
 /*
@@ -49941,7 +50943,7 @@
 		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);
@@ -50632,9 +51634,9 @@
  */
 
 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));
@@ -50706,9 +51708,9 @@
 
 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;
@@ -50759,14 +51761,14 @@
 #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;
@@ -50895,10 +51897,10 @@
 			 *   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;
@@ -50908,7 +51910,7 @@
 #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));
 		}
@@ -50919,7 +51921,7 @@
 
  scan_error:
 	DUK_ERROR_INTERNAL(thr);
-	return 0;
+	DUK_WO_NORETURN(return 0;);
 }
 #line 1 "duk_heap_stringtable.c"
 /*
@@ -50978,7 +51980,7 @@
 		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;
@@ -51090,7 +52092,7 @@
 		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
@@ -51110,14 +52112,14 @@
 		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;
 	}
@@ -51610,11 +52612,12 @@
 	}
 	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;
@@ -51634,6 +52637,7 @@
 
 	/* 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. */
@@ -51652,7 +52656,7 @@
 	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;
@@ -51725,10 +52729,67 @@
 	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;
 
@@ -51738,6 +52799,7 @@
 	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;
 }
@@ -52044,7 +53106,7 @@
 	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);
 
@@ -52086,7 +53148,7 @@
 	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);
 
@@ -52128,6 +53190,7 @@
 	res = duk_hthread_alloc_unchecked(thr->heap, hobject_flags);
 	if (res == NULL) {
 		DUK_ERROR_ALLOC_FAILED(thr);
+		DUK_WO_NORETURN(return NULL;);
 	}
 	return res;
 }
@@ -52344,7 +53407,7 @@
 		 * 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;
@@ -52828,7 +53891,7 @@
 }
 
 /*
- *  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.
  */
 
@@ -52915,6 +53978,7 @@
 				break;
 			} else {
 				DUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);
+				DUK_WO_NORETURN(return 0;);
 			}
 		}
 		h = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h);
@@ -52999,7 +54063,7 @@
 		                     (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;
 
@@ -53110,7 +54174,7 @@
 	 *  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);
 
@@ -53170,7 +54234,7 @@
 	 */
 
 	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);
@@ -53239,7 +54303,7 @@
 #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
 
@@ -53789,6 +54853,7 @@
 
 	if (new_e_size_adjusted + new_a_size > DUK_HOBJECT_MAX_PROPERTIES) {
 		DUK_ERROR_ALLOC_FAILED(thr);
+		DUK_WO_NORETURN(return;);
 	}
 
 	/*
@@ -53992,18 +55057,14 @@
 	} 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);
@@ -54028,7 +55089,7 @@
 
 		/* 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 */
 
@@ -54138,6 +55199,7 @@
 #endif
 
 	DUK_ERROR_ALLOC_FAILED(thr);
+	DUK_WO_NORETURN(return;);
 }
 
 /*
@@ -54615,7 +55677,7 @@
 	/* 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;
@@ -54803,7 +55865,7 @@
 }
 
 /*
- *  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'
@@ -55178,7 +56240,7 @@
 }
 
 /*
- *  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'
@@ -55235,6 +56297,7 @@
 				break;
 			} else {
 				DUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);
+				DUK_WO_NORETURN(return 0;);
 			}
 		}
 		curr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);
@@ -55516,7 +56579,7 @@
 #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) {
@@ -55570,7 +56633,8 @@
 		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: {
@@ -55726,6 +56790,7 @@
 					                 !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);
@@ -55917,6 +56982,7 @@
 		 */
 		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);
@@ -55987,6 +57053,7 @@
 			    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;);
 			}
 		}
 	}
@@ -55999,7 +57066,7 @@
 }
 
 /*
- *  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.
@@ -56065,6 +57132,7 @@
 		/* 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? */
@@ -56089,7 +57157,7 @@
 			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.
@@ -56108,11 +57176,12 @@
 					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;
 		}
 
@@ -56204,7 +57273,7 @@
 	/* 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;
 	}
@@ -56213,7 +57282,7 @@
 
  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
@@ -56482,9 +57551,9 @@
 }
 
 /*
- *  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:
@@ -56571,7 +57640,8 @@
 		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: {
@@ -56675,8 +57745,7 @@
 				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;
 				}
@@ -56708,6 +57777,7 @@
 					                 (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);
@@ -57007,6 +58077,7 @@
 		 */
 		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);
@@ -57356,6 +58427,7 @@
 	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;
@@ -57370,6 +58442,7 @@
 		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;
@@ -57378,6 +58451,7 @@
 	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;
@@ -57386,6 +58460,7 @@
 	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;
@@ -57395,6 +58470,7 @@
 	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
@@ -57403,6 +58479,7 @@
 	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;
@@ -57411,6 +58488,7 @@
 	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;
@@ -57419,13 +58497,14 @@
 	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) {
@@ -57579,12 +58658,13 @@
 
 	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) {
@@ -57639,8 +58719,7 @@
 				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 */
 				}
@@ -57665,6 +58744,7 @@
 					if (desc_reject) {
 						/* unconditional */
 						DUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);
+						DUK_WO_NORETURN(return 0;);
 					}
 				}
 				rc = 1;  /* success */
@@ -57748,12 +58828,13 @@
 	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;
@@ -57762,6 +58843,7 @@
  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;
@@ -57901,7 +58983,7 @@
  error_virtual:  /* share error message */
  error_internal:
 	DUK_ERROR_INTERNAL(thr);
-	return;
+	DUK_WO_NORETURN(return;);
 }
 
 /*
@@ -57981,7 +59063,7 @@
 	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) {
@@ -58092,7 +59174,7 @@
  *  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.
@@ -58142,7 +59224,7 @@
 
 	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;
@@ -58194,7 +59276,7 @@
 	}
 
 	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;
@@ -58202,7 +59284,7 @@
 	}
 
 	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;
@@ -58223,6 +59305,7 @@
 
  type_error:
 	DUK_ERROR_TYPE(thr, DUK_STR_INVALID_DESCRIPTOR);
+	DUK_WO_NORETURN(return;);
 }
 
 /*
@@ -58231,7 +59314,7 @@
  *
  *  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
@@ -59104,6 +60187,7 @@
  fail_not_extensible:
 	if (throw_flag) {
 		DUK_ERROR_TYPE(thr, DUK_STR_NOT_EXTENSIBLE);
+		DUK_WO_NORETURN(return 0;);
 	}
 	return 0;
 
@@ -59111,6 +60195,7 @@
  fail_not_configurable:
 	if (throw_flag) {
 		DUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);
+		DUK_WO_NORETURN(return 0;);
 	}
 	return 0;
 }
@@ -59166,6 +60251,7 @@
 	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
 
@@ -59314,7 +60400,7 @@
 	                     (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)) {
@@ -59470,7 +60556,7 @@
 	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;
@@ -59508,7 +60594,7 @@
 	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;
@@ -59613,7 +60699,7 @@
 	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
@@ -59740,7 +60826,7 @@
 
 	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;
 
@@ -59982,11 +61068,9 @@
 			 *  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 |
@@ -60091,6 +61175,7 @@
 #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);
@@ -60210,10 +61295,19 @@
 		 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) ] */
 		}
@@ -60286,7 +61380,7 @@
 			"f"
 #endif
 			" "
-			/* Low memory options */
+			/* Low memory/performance options */
 #if defined(DUK_USE_STRTAB_PTRCOMP)
 			"s"
 #endif
@@ -60327,6 +61421,9 @@
 			 */
 			"Z"
 #endif
+#if defined(DUK_USE_LITCACHE_SIZE)
+			"l"
+#endif
 	                " "
 			/* Object property allocation layout */
 #if defined(DUK_USE_HOBJECT_LAYOUT_1)
@@ -60903,8 +62000,8 @@
 	/* 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);
@@ -60923,7 +62020,7 @@
 
 /* #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".
  */
@@ -60977,9 +62074,9 @@
 
 /* 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.
 	 */
 
@@ -61060,7 +62157,7 @@
  *
  *  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
@@ -61114,6 +62211,7 @@
 
 	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) {
@@ -61149,6 +62247,7 @@
 	 */
 	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) {
@@ -61562,6 +62661,7 @@
 		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);
@@ -61622,7 +62722,7 @@
 			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);
@@ -61662,6 +62762,7 @@
 	} 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);
@@ -61837,11 +62938,13 @@
 		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 */
 		}
@@ -62378,6 +63481,7 @@
 		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
@@ -62391,8 +63495,7 @@
 #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. */
@@ -62405,8 +63508,7 @@
 #else
 	DUK_ERROR_TYPE(thr, DUK_STR_NOT_CONSTRUCTABLE);
 #endif
-	DUK_UNREACHABLE();
-	return NULL;  /* never executed */
+	DUK_WO_NORETURN(return NULL;);
 }
 
 /*
@@ -62430,6 +63532,7 @@
 	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: "
@@ -62733,10 +63836,10 @@
 		 *  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);
@@ -62943,16 +64046,16 @@
 
  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.
  *
@@ -63001,7 +64104,7 @@
 	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
 	 */
@@ -63106,6 +64209,12 @@
 	 *  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) {
@@ -63153,7 +64262,7 @@
 	 *  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).
 	 *
@@ -63200,7 +64309,7 @@
 
 	if (func != NULL && DUK_HOBJECT_IS_COMPFUNC(func)) {
 		/*
-		 *  Ecmascript call.
+		 *  ECMAScript call.
 		 */
 
 		DUK_ASSERT(func != NULL);
@@ -63294,9 +64403,10 @@
 			;
 		} 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);
@@ -63384,7 +64494,7 @@
 	 * 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)
@@ -63496,6 +64606,7 @@
 
 	if (DUK_UNLIKELY(rc < 0)) {
 		duk_error_throw_from_negative_rc(thr, rc);
+		DUK_WO_NORETURN(return;);
 	}
 	DUK_ASSERT(rc >= 0);
 
@@ -63773,7 +64884,10 @@
 		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);
@@ -63783,6 +64897,7 @@
 		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);
@@ -63805,6 +64920,7 @@
 		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);
@@ -63864,7 +64980,7 @@
 /*
  *  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)
@@ -63923,7 +65039,7 @@
 #undef DUK__AUGMENT_CALL_RELAX_COUNT
 #line 1 "duk_js_compiler.c"
 /*
- *  Ecmascript compiler.
+ *  ECMAScript compiler.
  *
  *  Parses an input string and generates a function template result.
  *  Compilation may happen in multiple contexts (global code, eval
@@ -64159,9 +65275,9 @@
 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);
@@ -64333,6 +65449,7 @@
 	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++;
 }
@@ -64387,15 +65504,20 @@
 		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);
 
@@ -64443,7 +65565,7 @@
 
 	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;
@@ -64690,7 +65812,7 @@
 	                     (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);
@@ -64895,7 +66017,7 @@
 		 */
 
 #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
 	}
@@ -65094,6 +66216,7 @@
 
   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
@@ -65378,6 +66501,7 @@
 
  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
@@ -65476,6 +66600,7 @@
 
  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) {
@@ -65510,6 +66635,7 @@
 
  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) {
@@ -65607,6 +66733,7 @@
 
   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
@@ -65662,6 +66789,7 @@
 			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 {
@@ -65853,6 +66981,7 @@
 
 	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 */
@@ -65912,6 +67041,7 @@
 
 	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",
@@ -66085,6 +67215,7 @@
 			}
 		}
 		}  /* end switch */
+		goto fail_internal;  /* never here */
 	}
 	case DUK_ISPEC_REGCONST: {
 		if (forced_reg >= 0) {
@@ -66117,12 +67248,13 @@
 		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) {
@@ -66195,7 +67327,10 @@
 					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: {
@@ -66222,7 +67357,7 @@
 				}
 			} 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);
@@ -66320,7 +67455,7 @@
 	}
 
 	DUK_ERROR_INTERNAL(thr);
-	return;
+	DUK_WO_NORETURN(return;);
 }
 
 /* evaluate to plain value, no forced register (temp/bound reg both ok) */
@@ -66552,6 +67687,7 @@
 
 		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;);
 		}
 	}
 
@@ -66681,6 +67817,7 @@
 			 */
 			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"));
@@ -66690,6 +67827,7 @@
 	/* 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",
@@ -66879,6 +68017,7 @@
 
  syntax_error:
 	DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_ARRAY_LITERAL);
+	DUK_WO_NORETURN(return;);
 }
 
 typedef struct {
@@ -67155,13 +68294,14 @@
 #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
@@ -67205,7 +68345,7 @@
 	}
 
 	/* 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"));
 
@@ -67338,7 +68478,7 @@
 
 		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;
@@ -67473,6 +68613,7 @@
 
 			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);
@@ -67637,7 +68778,7 @@
 	}  /* end switch */
 
 	DUK_ERROR_SYNTAX(thr, DUK_STR_PARSE_ERROR);
-	return;
+	DUK_WO_NORETURN(return;);
 
  unary:
 	{
@@ -67741,10 +68882,12 @@
 #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
@@ -67799,6 +68942,7 @@
 		/* 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;
@@ -68228,7 +69372,7 @@
 
 	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'? */
@@ -68458,7 +69602,7 @@
 						 * 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"));
@@ -68718,11 +69862,11 @@
 
  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) {
@@ -68787,7 +69931,7 @@
 	                     (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);
@@ -68807,6 +69951,7 @@
 		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);
@@ -68845,6 +69990,7 @@
 
 	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;);
 	}
 }
 
@@ -69037,6 +70183,7 @@
 
  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) {
@@ -69268,7 +70415,8 @@
 		}
 		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*/);
@@ -69359,7 +70507,8 @@
 		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*/);
@@ -69408,6 +70557,7 @@
 
  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) {
@@ -69449,7 +70599,7 @@
 	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));
@@ -69574,7 +70724,8 @@
 	}
 
 	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.
@@ -69607,6 +70758,7 @@
 
  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) {
@@ -69626,7 +70778,8 @@
 	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*/);
 
@@ -69662,7 +70815,7 @@
 
 	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*/);
@@ -69676,6 +70829,7 @@
 	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 */
@@ -69705,7 +70859,8 @@
 	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);
@@ -69741,6 +70896,7 @@
 		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
@@ -69782,6 +70938,7 @@
 	 */
 	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 */
@@ -69883,6 +71040,7 @@
 
 	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*/);
@@ -69939,10 +71097,9 @@
 
 	/* 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) {
 		/*
@@ -70038,7 +71195,7 @@
 		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) {
@@ -70080,7 +71237,7 @@
 		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,
@@ -70123,6 +71280,7 @@
 
  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) {
@@ -70133,6 +71291,7 @@
 
 	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++;
@@ -70143,7 +71302,8 @@
 
 	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;
@@ -70155,8 +71315,7 @@
 	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);
 
@@ -70323,13 +71482,14 @@
 			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 */
@@ -70583,7 +71743,7 @@
 				 */
 
 				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));
@@ -70592,7 +71752,7 @@
 					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;
@@ -70660,6 +71820,7 @@
 				                     "even though no lineterm present before next token)"));
 			} else {
 				DUK_ERROR_SYNTAX(thr, DUK_STR_UNTERMINATED_STMT);
+				DUK_WO_NORETURN(return;);
 			}
 		}
 	} else {
@@ -70708,7 +71869,7 @@
  *  (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;
@@ -70722,7 +71883,7 @@
 	 * 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);
@@ -70756,6 +71917,15 @@
 		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. */
@@ -71079,13 +72249,11 @@
 
  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;);
 }
 
 /*
@@ -71122,7 +72290,7 @@
  *  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;
@@ -71194,7 +72362,9 @@
 	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.
@@ -71213,7 +72383,8 @@
 	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"));
 
 	/*
@@ -71320,7 +72491,8 @@
 		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);
@@ -71333,6 +72505,7 @@
 			/* 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));
 	}
@@ -71376,6 +72549,7 @@
 
  error_funcname:
 	DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_FUNC_NAME);
+	DUK_WO_NORETURN(return;);
 }
 
 /*
@@ -71424,6 +72598,7 @@
 
 		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);
@@ -71489,6 +72664,7 @@
 			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 {
@@ -71506,6 +72682,7 @@
 			no_advance = 1;
 			if (flags & DUK__FUNC_FLAG_DECL) {
 				DUK_ERROR_SYNTAX(thr, DUK_STR_FUNC_NAME_REQUIRED);
+				DUK_WO_NORETURN(return;);
 			}
 		}
 	}
@@ -71539,6 +72716,7 @@
 	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 */
 
 	/*
@@ -71591,6 +72769,14 @@
 		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;
@@ -71605,9 +72791,9 @@
 	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);
 
@@ -71649,6 +72835,7 @@
 
 	if (fnum > DUK__MAX_FUNCS) {
 		DUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_FUNC_LIMIT);
+		DUK_WO_NORETURN(return 0;);
 	}
 
 	/* array writes autoincrement length */
@@ -71673,7 +72860,7 @@
 	} 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;
 }
@@ -71682,7 +72869,7 @@
  *  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).
  *
@@ -71823,6 +73010,7 @@
 		duk__parse_func_body(comp_ctx,
 		                     1,             /* expect_eof */
 		                     1,             /* implicit_return_value */
+		                     1,             /* regexp_after (does not matter) */
 		                     -1);           /* expect_token */
 	}
 
@@ -71850,7 +73038,7 @@
 	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;
@@ -71867,6 +73055,7 @@
 	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 ] */
@@ -71958,7 +73147,7 @@
 #undef DUK__TOKEN_LBP_GET_BP
 #line 1 "duk_js_executor.c"
 /*
- *  Ecmascript bytecode executor.
+ *  ECMAScript bytecode executor.
  */
 
 /* #include duk_internal.h -> already included */
@@ -72009,7 +73198,7 @@
 
 	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++;
@@ -72273,7 +73462,10 @@
 		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: {
@@ -72730,7 +73922,7 @@
  * 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) {
@@ -72746,7 +73938,7 @@
 
 	/* 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);
@@ -72762,7 +73954,7 @@
 	/* 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) {
@@ -72998,7 +74190,7 @@
 	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 */
@@ -73054,7 +74246,7 @@
 		/* 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 &&
@@ -73072,7 +74264,7 @@
 		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)) &&
@@ -73110,8 +74302,8 @@
 			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;
@@ -73119,7 +74311,7 @@
 			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() */
@@ -73167,6 +74359,7 @@
 				 * executor which can be quite misleading.
 				 */
 				DUK_ERROR_INTERNAL(thr);
+				DUK_WO_NORETURN(return 0;);
 			}
 
 			DUK_ASSERT(resumee->resumer == NULL);
@@ -73189,7 +74382,7 @@
 	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.
 		 *
@@ -73205,27 +74398,27 @@
 		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;
@@ -73279,7 +74472,7 @@
 		 *      resumer in this case.)
 		 *
 		 *  Note: until we hit the entry level, there can only be
-		 *  Ecmascript activations.
+		 *  ECMAScript activations.
 		 */
 
 		duk_activation *act;
@@ -73346,11 +74539,11 @@
 		 */
 
 		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;
 
@@ -73403,8 +74596,7 @@
 	 * 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
@@ -73468,7 +74660,7 @@
 	/* 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
@@ -73503,7 +74695,7 @@
 	 *    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
@@ -73548,16 +74740,16 @@
 	}
 
 	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)) {
@@ -73587,14 +74779,14 @@
 	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);
 
@@ -73641,7 +74833,7 @@
 #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
 }
 
@@ -73791,7 +74983,7 @@
 		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
@@ -73940,6 +75132,7 @@
 		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 */
 
@@ -74625,7 +75818,7 @@
 }
 
 /*
- *  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,
@@ -74634,7 +75827,7 @@
  *  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.
@@ -74727,6 +75920,7 @@
 #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 { \
@@ -74891,7 +76085,10 @@
 			                           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";
@@ -74901,6 +76098,7 @@
 			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);
@@ -74915,6 +76113,7 @@
 			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);
@@ -74927,7 +76126,7 @@
 #endif
 	}
 
-	DUK_UNREACHABLE();
+	DUK_WO_NORETURN(return;);
 }
 
 /* Inner executor, performance critical. */
@@ -75296,7 +76495,7 @@
 			/* 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;
 		}
@@ -76951,7 +78150,7 @@
 
 		case DUK_OP_INVLHS: {
 			DUK_ERROR_REFERENCE(thr, DUK_STR_INVALID_LVALUE);
-			DUK_UNREACHABLE();
+			DUK_WO_NORETURN(return;);
 			break;
 		}
 
@@ -76986,45 +78185,13 @@
 
 		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 */
@@ -77126,11 +78293,12 @@
 		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
 }
 
@@ -77200,9 +78368,9 @@
 #undef DUK__TVAL_SHIFT
 #line 1 "duk_js_ops.c"
 /*
- *  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
@@ -77418,6 +78586,7 @@
 		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);
@@ -77633,7 +78802,7 @@
 	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).
@@ -77926,12 +79095,12 @@
 
 	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;
@@ -78198,22 +79367,19 @@
  */
 
 /*
- *  E5 Section 11.8.6 describes the main algorithm, which uses
- *  [[HasInstance]].  [[HasInstance]] is defined for only
- *  function objects:
+ *  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.
  *
- *    - Normal functions:
- *      E5 Section 15.3.5.3
- *    - Functions established with Function.prototype.bind():
- *      E5 Section 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;
@@ -78236,6 +79402,23 @@
 	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
@@ -78247,7 +79430,7 @@
 
 	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.
 		 *
@@ -78257,7 +79440,7 @@
 	}
 
 	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 */
 
@@ -78362,6 +79545,7 @@
 
 	if (DUK_UNLIKELY(sanity == 0)) {
 		DUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);
+		DUK_WO_NORETURN(return 0;);
 	}
 	DUK_UNREACHABLE();
 
@@ -78379,15 +79563,25 @@
 
  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
  */
@@ -78639,7 +79833,7 @@
  *  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
@@ -78681,7 +79875,7 @@
  *  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.
@@ -79690,6 +80884,7 @@
 
                 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);
 	}
@@ -79829,6 +81024,7 @@
 			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;
@@ -79953,6 +81149,7 @@
 		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"));
@@ -80343,7 +81540,7 @@
  fail_existing_attributes:
  fail_not_extensible:
 	DUK_ERROR_TYPE(thr, "declaration failed");
-	return 0;
+	DUK_WO_NORETURN(return 0;);
 }
 
 DUK_INTERNAL
@@ -80389,7 +81586,7 @@
  *  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.
@@ -80412,14 +81609,14 @@
  *
  *  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,
@@ -80516,7 +81713,7 @@
  *
  *    * 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.
@@ -80524,20 +81721,20 @@
  *  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:
  *
@@ -80700,6 +81897,7 @@
 	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) {
@@ -80722,7 +81920,7 @@
 		/* 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;
@@ -80860,7 +82058,7 @@
  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) {
@@ -80873,7 +82071,7 @@
 	/* 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);
 
@@ -80962,7 +82160,7 @@
 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;
@@ -81127,6 +82325,7 @@
 
  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
@@ -81323,11 +82522,11 @@
 
  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. */
@@ -81344,7 +82543,7 @@
 }
 
 /*
- *  Parse Ecmascript source InputElementDiv or InputElementRegExp
+ *  Parse ECMAScript source InputElementDiv or InputElementRegExp
  *  (E5 Section 7), skipping whitespace, comments, and line terminators.
  *
  *  Possible results are:
@@ -81371,13 +82570,13 @@
  *  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.
@@ -81887,7 +83086,7 @@
 		 *  (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
@@ -82171,32 +83370,32 @@
 
  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
 }
 
@@ -82219,7 +83418,7 @@
 		goto fail_token_limit;
 	}
 
-	DUK_MEMZERO(out_token, sizeof(*out_token));
+	duk_memzero(out_token, sizeof(*out_token));
 
 	x = DUK__L0();
 	y = DUK__L1();
@@ -82544,24 +83743,24 @@
 
  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
 }
 
@@ -82810,15 +84009,15 @@
 
  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 */
@@ -82980,10 +84179,8 @@
 
 	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) {
@@ -83259,7 +84456,7 @@
 		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;
@@ -83409,7 +84606,7 @@
 	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);
 }
@@ -83523,6 +84720,7 @@
 	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
@@ -83545,7 +84743,7 @@
 	}
 	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;
 }
@@ -83948,7 +85146,7 @@
 	{
 		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) {
@@ -84013,7 +85211,7 @@
 			*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' */
@@ -84057,7 +85255,7 @@
 	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:
@@ -84068,11 +85266,11 @@
 	 *    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
@@ -84156,7 +85354,7 @@
 	/* 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.
@@ -84258,7 +85456,7 @@
 	 * (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,
@@ -84441,7 +85639,7 @@
 	 *  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 */
@@ -84473,7 +85671,7 @@
 	 * 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;
@@ -84513,7 +85711,7 @@
 		}
 		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;
@@ -84593,8 +85791,8 @@
 	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;
@@ -84730,7 +85928,7 @@
 	 *  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
@@ -84901,9 +86099,10 @@
 		} 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"));
@@ -85106,7 +86305,7 @@
  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 */
@@ -85648,6 +86847,7 @@
 
 	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++;
 
@@ -85721,9 +86921,11 @@
 		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) {
 				/*
@@ -85792,6 +86994,7 @@
 				              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) */
@@ -86055,17 +87258,20 @@
 		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;);
 		}
 		}
 
@@ -86160,7 +87366,7 @@
 
  flags_error:
 	DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_REGEXP_FLAGS);
-	return 0;  /* never here */
+	DUK_WO_NORETURN(return 0U;);
 }
 
 /*
@@ -86197,7 +87403,7 @@
 	n = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h);
 
 	if (n == 0) {
-		duk_push_string(thr, "(?:)");
+		duk_push_literal(thr, "(?:)");
 		return;
 	}
 
@@ -86277,7 +87483,7 @@
 
 	/* [ ... 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;
@@ -86324,6 +87530,7 @@
 
 	if (re_ctx.highest_backref > re_ctx.captures) {
 		DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_BACKREFS);
+		DUK_WO_NORETURN(return;);
 	}
 
 	/*
@@ -86408,7 +87615,7 @@
 /*
  *  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
@@ -86475,7 +87682,7 @@
 
  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) {
@@ -86506,7 +87713,7 @@
 
  fail:
 	DUK_ERROR_INTERNAL(thr);
-	return NULL;  /* never here */
+	DUK_WO_NORETURN(return NULL;);
 }
 
 /*
@@ -86555,6 +87762,7 @@
 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++;
 
@@ -86563,6 +87771,7 @@
 
 		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++;
 
@@ -86908,14 +88117,14 @@
 			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);
@@ -86933,7 +88142,7 @@
 			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);
@@ -86965,7 +88174,7 @@
 			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);
@@ -86990,7 +88199,7 @@
 
 		 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);
@@ -87072,7 +88281,7 @@
 
  internal_error:
 	DUK_ERROR_INTERNAL(re_ctx->thr);
-	return NULL;  /* never here */
+	DUK_WO_NORETURN(return NULL;);
 }
 
 /*
@@ -87138,7 +88347,7 @@
 
 	/* [ ... 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);
@@ -87175,7 +88384,7 @@
 #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",
@@ -87260,7 +88469,7 @@
 		 *      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
@@ -87455,13 +88664,13 @@
 	} 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)
@@ -87770,7 +88979,7 @@
 	 */
 	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",
@@ -87790,7 +88999,7 @@
 	 */
 	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",
@@ -88229,7 +89438,7 @@
  *  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
@@ -88243,54 +89452,55 @@
  *  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 */
@@ -88299,35 +89509,35 @@
  *  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
 
@@ -88362,32 +89572,33 @@
  *  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 */
@@ -88396,23 +89607,23 @@
  *  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
@@ -94600,6 +95811,10 @@
 
 /* #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)
  */
@@ -94611,6 +95826,9 @@
 	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;
@@ -94619,7 +95837,6 @@
 }
 
 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);
@@ -94634,6 +95851,7 @@
 
 	(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);
 }
 
@@ -94658,7 +95876,7 @@
 	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;
@@ -94701,9 +95919,9 @@
 	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;
 }
 
@@ -94733,12 +95951,12 @@
 	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;
 }
 
@@ -94780,12 +95998,12 @@
 	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;
 }
 
@@ -94818,7 +96036,7 @@
 	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' */
 }
 
@@ -94849,9 +96067,9 @@
 	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;
 }
 
@@ -94872,7 +96090,7 @@
 		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;
@@ -94884,7 +96102,7 @@
 		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;
@@ -94897,10 +96115,10 @@
 		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;
@@ -94915,7 +96133,7 @@
 	} 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;
 }
 
@@ -94926,7 +96144,7 @@
 	} 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;
 }
 
@@ -94940,12 +96158,416 @@
 	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;
 }
+#line 1 "duk_util_cast.c"
+/*
+ *  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
+#line 1 "duk_util_double.c"
+/*
+ *  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;
+}
 #line 1 "duk_util_hashbytes.c"
 /*
  *  Hash function duk_util_hashbytes().
@@ -95008,6 +96630,43 @@
 /* automatic undefs */
 #undef DUK__MAGIC_M
 #undef DUK__MAGIC_R
+#line 1 "duk_util_memory.c"
+/*
+ *  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 */
 #line 1 "duk_util_tinyrandom.c"
 /*
  *  A tiny random number generator used for Math.random() and other internals.
diff --git a/duktape/duktape.h b/duktape/duktape.h
index bf330a1..36f8060 100644
--- a/duktape/duktape.h
+++ b/duktape/duktape.h
@@ -1,13 +1,13 @@
 /*
- *  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"
  *  comments.  Other parts of the header are Duktape internal and related to
  *  e.g. platform/compiler/feature detection.
  *
- *  Git commit 25420e773c5fbc50d5b46bf487fc45717e35b94f (v2.2.1).
- *  Git branch v2.2-maintenance.
+ *  Git commit d7fdb67f18561a50e06bafd196c6b423af9ad6fe (v2.3.0).
+ *  Git branch master.
  *
  *  See Duktape AUTHORS.rst and LICENSE.txt for copyright and
  *  licensing information.
@@ -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,20 +160,20 @@
 
 /* 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                    "25420e773c5fbc50d5b46bf487fc45717e35b94f"
-#define DUK_GIT_DESCRIBE                  "v2.2.1"
-#define DUK_GIT_BRANCH                    "v2.2-maintenance"
+#define DUK_GIT_COMMIT                    "d7fdb67f18561a50e06bafd196c6b423af9ad6fe"
+#define DUK_GIT_DESCRIBE                  "v2.3.0"
+#define DUK_GIT_BRANCH                    "master"
 
 /* External duk_config.h provides platform/compiler/OS dependent
  * typedefs and macros, and DUK_USE_xxx config options so that
@@ -258,7 +268,7 @@
 };
 
 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 @@
 /* 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 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 @@
 /*
  *  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 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 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_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 @@
 #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 @@
 #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 @@
 #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).