]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/jaegertracing/opentelemetry-cpp/third_party/prometheus-cpp/3rdparty/civetweb/src/third_party/duktape-1.5.2/src-separate/duk_hthread_builtins.c
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / jaegertracing / opentelemetry-cpp / third_party / prometheus-cpp / 3rdparty / civetweb / src / third_party / duktape-1.5.2 / src-separate / duk_hthread_builtins.c
diff --git a/ceph/src/jaegertracing/opentelemetry-cpp/third_party/prometheus-cpp/3rdparty/civetweb/src/third_party/duktape-1.5.2/src-separate/duk_hthread_builtins.c b/ceph/src/jaegertracing/opentelemetry-cpp/third_party/prometheus-cpp/3rdparty/civetweb/src/third_party/duktape-1.5.2/src-separate/duk_hthread_builtins.c
new file mode 100644 (file)
index 0000000..e8d57d8
--- /dev/null
@@ -0,0 +1,836 @@
+/*
+ *  Initialize built-in objects.  Current thread must have a valstack
+ *  and initialization errors may longjmp, so a setjmp() catch point
+ *  must exist.
+ */
+
+#include "duk_internal.h"
+
+/*
+ *  Encoding constants, must match genbuiltins.py
+ */
+
+#define DUK__CLASS_BITS                  5
+#define DUK__BIDX_BITS                   7
+#define DUK__STRIDX_BITS                 9  /* XXX: try to optimize to 8 (would now be possible, <200 used) */
+#define DUK__NATIDX_BITS                 8
+#define DUK__NUM_NORMAL_PROPS_BITS       6
+#define DUK__NUM_FUNC_PROPS_BITS         6
+#define DUK__PROP_FLAGS_BITS             3
+#define DUK__STRING_LENGTH_BITS          8
+#define DUK__STRING_CHAR_BITS            7
+#define DUK__LENGTH_PROP_BITS            3
+#define DUK__NARGS_BITS                  3
+#define DUK__PROP_TYPE_BITS              3
+#define DUK__MAGIC_BITS                  16
+
+#define DUK__NARGS_VARARGS_MARKER        0x07
+#define DUK__NO_CLASS_MARKER             0x00   /* 0 = DUK_HOBJECT_CLASS_UNUSED */
+#define DUK__NO_BIDX_MARKER              0x7f
+#define DUK__NO_STRIDX_MARKER            0xff
+
+#define DUK__PROP_TYPE_DOUBLE            0
+#define DUK__PROP_TYPE_STRING            1
+#define DUK__PROP_TYPE_STRIDX            2
+#define DUK__PROP_TYPE_BUILTIN           3
+#define DUK__PROP_TYPE_UNDEFINED         4
+#define DUK__PROP_TYPE_BOOLEAN_TRUE      5
+#define DUK__PROP_TYPE_BOOLEAN_FALSE     6
+#define DUK__PROP_TYPE_ACCESSOR          7
+
+/*
+ *  Create built-in objects by parsing an init bitstream generated
+ *  by genbuiltins.py.
+ */
+
+#if defined(DUK_USE_ROM_OBJECTS)
+#if defined(DUK_USE_ROM_GLOBAL_CLONE) || defined(DUK_USE_ROM_GLOBAL_INHERIT)
+DUK_LOCAL void duk__duplicate_ram_global_object(duk_hthread *thr) {
+       duk_context *ctx;
+       duk_hobject *h1;
+#if defined(DUK_USE_ROM_GLOBAL_CLONE)
+       duk_hobject *h2;
+       duk_uint8_t *props;
+       duk_size_t alloc_size;
+#endif
+
+       ctx = (duk_context *) thr;
+
+       /* XXX: refactor into internal helper, duk_clone_hobject() */
+
+#if defined(DUK_USE_ROM_GLOBAL_INHERIT)
+       /* Inherit from ROM-based global object: less RAM usage, less transparent. */
+       duk_push_object_helper(ctx,
+                              DUK_HOBJECT_FLAG_EXTENSIBLE |
+                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_GLOBAL),
+                              DUK_BIDX_GLOBAL);
+       h1 = duk_get_hobject(ctx, -1);
+       DUK_ASSERT(h1 != NULL);
+#elif defined(DUK_USE_ROM_GLOBAL_CLONE)
+       /* Clone the properties of the ROM-based global object to create a
+        * fully RAM-based global object.  Uses more memory than the inherit
+        * model but more compliant.
+        */
+       duk_push_object_helper(ctx,
+                              DUK_HOBJECT_FLAG_EXTENSIBLE |
+                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_GLOBAL),
+                              DUK_BIDX_OBJECT_PROTOTYPE);
+       h1 = duk_get_hobject(ctx, -1);
+       DUK_ASSERT(h1 != NULL);
+       h2 = thr->builtins[DUK_BIDX_GLOBAL];
+       DUK_ASSERT(h2 != NULL);
+
+       /* Copy the property table verbatim; this handles attributes etc.
+        * For ROM objects it's not necessary (or possible) to update
+        * refcounts so leave them as is.
+        */
+       alloc_size = DUK_HOBJECT_P_ALLOC_SIZE(h2);
+       DUK_ASSERT(alloc_size > 0);
+       props = DUK_ALLOC(thr->heap, alloc_size);
+       if (!props) {
+               DUK_ERROR_ALLOC_DEFMSG(thr);
+               return;
+       }
+       DUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, h2) != NULL);
+       DUK_MEMCPY((void *) props, (const void *) DUK_HOBJECT_GET_PROPS(thr->heap, h2), alloc_size);
+
+       /* XXX: keep property attributes or tweak them here?
+        * Properties will now be non-configurable even when they're
+        * normally configurable for the global object.
+        */
+
+       DUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, h1) == NULL);
+       DUK_HOBJECT_SET_PROPS(thr->heap, h1, props);
+       DUK_HOBJECT_SET_ESIZE(h1, DUK_HOBJECT_GET_ESIZE(h2));
+       DUK_HOBJECT_SET_ENEXT(h1, DUK_HOBJECT_GET_ENEXT(h2));
+       DUK_HOBJECT_SET_ASIZE(h1, DUK_HOBJECT_GET_ASIZE(h2));
+       DUK_HOBJECT_SET_HSIZE(h1, DUK_HOBJECT_GET_HSIZE(h2));
+#else
+#error internal error in defines
+#endif
+
+       duk_hobject_compact_props(thr, h1);
+       DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);
+       DUK_ASSERT(!DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE((duk_heaphdr *) thr->builtins[DUK_BIDX_GLOBAL]));  /* no need to decref */
+       thr->builtins[DUK_BIDX_GLOBAL] = h1;
+       DUK_HOBJECT_INCREF(thr, h1);
+       DUK_D(DUK_DPRINT("duplicated global object: %!O", h1));
+
+
+       /* Create a fresh object environment for the global scope.  This is
+        * needed so that the global scope points to the newly created RAM-based
+        * global object.
+        */
+       duk_push_object_helper(ctx,
+                              DUK_HOBJECT_FLAG_EXTENSIBLE |
+                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJENV),
+                              -1);  /* no prototype */
+       h1 = duk_get_hobject(ctx, -1);
+       DUK_ASSERT(h1 != NULL);
+       duk_dup(ctx, -2);
+       duk_dup(ctx, -1);  /* -> [ ... new_global new_globalenv new_global new_global ] */
+       duk_xdef_prop_stridx(thr, -3, DUK_STRIDX_INT_TARGET, DUK_PROPDESC_FLAGS_NONE);
+       duk_xdef_prop_stridx(thr, -2, DUK_STRIDX_INT_THIS, DUK_PROPDESC_FLAGS_NONE);  /* always provideThis=true */
+
+       duk_hobject_compact_props(thr, h1);
+       DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL_ENV] != NULL);
+       DUK_ASSERT(!DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE((duk_heaphdr *) thr->builtins[DUK_BIDX_GLOBAL_ENV]));  /* no need to decref */
+       thr->builtins[DUK_BIDX_GLOBAL_ENV] = h1;
+       DUK_HOBJECT_INCREF(thr, h1);
+       DUK_D(DUK_DPRINT("duplicated global env: %!O", h1));
+
+       duk_pop_2(ctx);
+}
+#endif  /* DUK_USE_ROM_GLOBAL_CLONE || DUK_USE_ROM_GLOBAL_INHERIT */
+
+DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
+       /* Setup builtins from ROM objects.  All heaps/threads will share
+        * the same readonly objects.
+        */
+       duk_small_uint_t i;
+
+       for (i = 0; i < DUK_NUM_BUILTINS; i++) {
+               duk_hobject *h;
+               h = (duk_hobject *) DUK_LOSE_CONST(duk_rom_builtins_bidx[i]);
+               DUK_ASSERT(h != NULL);
+               thr->builtins[i] = h;
+       }
+
+#if defined(DUK_USE_ROM_GLOBAL_CLONE) || defined(DUK_USE_ROM_GLOBAL_INHERIT)
+       /* By default the global object is read-only which is often much
+        * more of an issue than having read-only built-in objects (like
+        * RegExp, Date, etc).  Use a RAM-based copy of the global object
+        * and the global environment object for convenience.
+        */
+       duk__duplicate_ram_global_object(thr);
+#endif
+}
+#else  /* DUK_USE_ROM_OBJECTS */
+DUK_LOCAL void duk__push_stridx(duk_context *ctx, duk_bitdecoder_ctx *bd) {
+       duk_small_uint_t n;
+
+       n = (duk_small_uint_t) duk_bd_decode(bd, DUK__STRIDX_BITS);
+       DUK_ASSERT_DISABLE(n >= 0);  /* unsigned */
+       DUK_ASSERT(n < DUK_HEAP_NUM_STRINGS);
+       duk_push_hstring_stridx(ctx, n);
+}
+DUK_LOCAL void duk__push_string(duk_context *ctx, duk_bitdecoder_ctx *bd) {
+       duk_small_uint_t n;
+       duk_small_uint_t i;
+       duk_uint8_t *p;
+
+       n = (duk_small_uint_t) duk_bd_decode(bd, DUK__STRING_LENGTH_BITS);
+       p = (duk_uint8_t *) duk_push_fixed_buffer(ctx, n);
+       for (i = 0; i < n; i++) {
+               *p++ = (duk_uint8_t) duk_bd_decode(bd, DUK__STRING_CHAR_BITS);
+       }
+       duk_to_string(ctx, -1);
+}
+DUK_LOCAL void duk__push_stridx_or_string(duk_context *ctx, duk_bitdecoder_ctx *bd) {
+       if (duk_bd_decode_flag(bd)) {
+               duk__push_string(ctx, bd);
+       } else {
+               duk__push_stridx(ctx, bd);
+       }
+}
+DUK_LOCAL void duk__push_double(duk_context *ctx, duk_bitdecoder_ctx *bd) {
+       duk_double_union du;
+       duk_small_uint_t i;
+
+       for (i = 0; i < 8; i++) {
+               /* Encoding endianness must match target memory layout,
+                * build scripts and genbuiltins.py must ensure this.
+                */
+               du.uc[i] = (duk_uint8_t) duk_bd_decode(bd, 8);
+       }
+
+       duk_push_number(ctx, du.d);  /* push operation normalizes NaNs */
+}
+
+DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
+       duk_context *ctx = (duk_context *) thr;
+       duk_bitdecoder_ctx bd_ctx;
+       duk_bitdecoder_ctx *bd = &bd_ctx;  /* convenience */
+       duk_hobject *h;
+       duk_small_uint_t i, j;
+
+       DUK_D(DUK_DPRINT("INITBUILTINS BEGIN: DUK_NUM_BUILTINS=%d, DUK_NUM_BUILTINS_ALL=%d", (int) DUK_NUM_BUILTINS, (int) DUK_NUM_ALL_BUILTINS));
+
+       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;
+
+       /*
+        *  First create all built-in bare objects on the empty valstack.
+        *
+        *  Built-ins in the index range [0,DUK_NUM_BUILTINS-1] have value
+        *  stack indices matching their eventual thr->builtins[] index.
+        *
+        *  Built-ins in the index range [DUK_NUM_BUILTINS,DUK_NUM_ALL_BUILTINS]
+        *  will exist on the value stack during init but won't be placed
+        *  into thr->builtins[].  These are objects referenced in some way
+        *  from thr->builtins[] roots but which don't need to be indexed by
+        *  Duktape through thr->builtins[] (e.g. user custom objects).
+        */
+
+       duk_require_stack(ctx, DUK_NUM_ALL_BUILTINS);
+
+       DUK_DD(DUK_DDPRINT("create empty built-ins"));
+       DUK_ASSERT_TOP(ctx, 0);
+       for (i = 0; i < DUK_NUM_ALL_BUILTINS; i++) {
+               duk_small_uint_t class_num;
+               duk_small_int_t len = -1;  /* must be signed */
+
+               class_num = (duk_small_uint_t) duk_bd_decode(bd, DUK__CLASS_BITS);
+               len = (duk_small_int_t) duk_bd_decode_flagged(bd, DUK__LENGTH_PROP_BITS, (duk_int32_t) -1 /*def_value*/);
+
+               if (class_num == DUK_HOBJECT_CLASS_FUNCTION) {
+                       duk_small_uint_t natidx;
+                       duk_int_t c_nargs;  /* must hold DUK_VARARGS */
+                       duk_c_function c_func;
+                       duk_int16_t magic;
+
+                       DUK_DDD(DUK_DDDPRINT("len=%ld", (long) len));
+                       DUK_ASSERT(len >= 0);
+
+                       natidx = (duk_small_uint_t) duk_bd_decode(bd, DUK__NATIDX_BITS);
+                       c_func = duk_bi_native_functions[natidx];
+
+                       c_nargs = (duk_small_uint_t) duk_bd_decode_flagged(bd, DUK__NARGS_BITS, len /*def_value*/);
+                       if (c_nargs == DUK__NARGS_VARARGS_MARKER) {
+                               c_nargs = DUK_VARARGS;
+                       }
+
+                       /* XXX: set magic directly here? (it could share the c_nargs arg) */
+                       duk_push_c_function_noexotic(ctx, c_func, c_nargs);
+
+                       h = duk_require_hobject(ctx, -1);
+                       DUK_ASSERT(h != NULL);
+
+                       /* Currently all built-in native functions are strict.
+                        * duk_push_c_function() now sets strict flag, so
+                        * assert for it.
+                        */
+                       DUK_ASSERT(DUK_HOBJECT_HAS_STRICT(h));
+
+                       /* XXX: function properties */
+
+                       /* Built-in 'name' is not writable by default.  Function '.name'
+                        * is writable to allow user code to set a '.name' on a native
+                        * function.
+                        */
+                       duk__push_stridx_or_string(ctx, bd);
+                       duk_xdef_prop_stridx(ctx,
+                                            -2,
+                                            DUK_STRIDX_NAME,
+                                            (i == DUK_BIDX_FUNCTION_PROTOTYPE) ?
+                                                DUK_PROPDESC_FLAGS_W : DUK_PROPDESC_FLAGS_NONE);
+
+                       /* Almost all global level Function objects are constructable
+                        * but not all: Function.prototype is a non-constructable,
+                        * callable Function.
+                        */
+                       if (duk_bd_decode_flag(bd)) {
+                               DUK_ASSERT(DUK_HOBJECT_HAS_CONSTRUCTABLE(h));
+                       } else {
+                               DUK_HOBJECT_CLEAR_CONSTRUCTABLE(h);
+                       }
+
+                       /* Cast converts magic to 16-bit signed value */
+                       magic = (duk_int16_t) duk_bd_decode_flagged(bd, DUK__MAGIC_BITS, 0 /*def_value*/);
+                       ((duk_hnativefunction *) h)->magic = magic;
+               } else {
+                       /* XXX: ARRAY_PART for Array prototype? */
+
+                       duk_push_object_helper(ctx,
+                                              DUK_HOBJECT_FLAG_EXTENSIBLE,
+                                              -1);  /* no prototype or class yet */
+
+                       h = duk_require_hobject(ctx, -1);
+                       DUK_ASSERT(h != NULL);
+               }
+
+               DUK_HOBJECT_SET_CLASS_NUMBER(h, class_num);
+
+               if (i < DUK_NUM_BUILTINS) {
+                       thr->builtins[i] = h;
+                       DUK_HOBJECT_INCREF(thr, &h->hdr);
+               }
+
+               if (len >= 0) {
+                       /*
+                        *  For top-level objects, 'length' property has the following
+                        *  default attributes: non-writable, non-enumerable, non-configurable
+                        *  (E5 Section 15).
+                        *
+                        *  However, 'length' property for Array.prototype has attributes
+                        *  expected of an Array instance which are different: writable,
+                        *  non-enumerable, non-configurable (E5 Section 15.4.5.2).
+                        *
+                        *  This is currently determined implicitly based on class; there are
+                        *  no attribute flags in the init data.
+                        */
+
+                       duk_push_int(ctx, len);
+                       duk_xdef_prop_stridx(ctx,
+                                            -2,
+                                            DUK_STRIDX_LENGTH,
+                                            (class_num == DUK_HOBJECT_CLASS_ARRAY ?  /* only Array.prototype matches */
+                                             DUK_PROPDESC_FLAGS_W : DUK_PROPDESC_FLAGS_NONE));
+               }
+
+               /* enable exotic behaviors last */
+
+               if (class_num == DUK_HOBJECT_CLASS_ARRAY) {
+                       DUK_HOBJECT_SET_EXOTIC_ARRAY(h);
+               }
+               if (class_num == DUK_HOBJECT_CLASS_STRING) {
+                       DUK_HOBJECT_SET_EXOTIC_STRINGOBJ(h);
+               }
+
+               /* some assertions */
+
+               DUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(h));
+               /* DUK_HOBJECT_FLAG_CONSTRUCTABLE varies */
+               DUK_ASSERT(!DUK_HOBJECT_HAS_BOUND(h));
+               DUK_ASSERT(!DUK_HOBJECT_HAS_COMPILEDFUNCTION(h));
+               /* DUK_HOBJECT_FLAG_NATIVEFUNCTION varies */
+               DUK_ASSERT(!DUK_HOBJECT_HAS_THREAD(h));
+               DUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(h));       /* currently, even for Array.prototype */
+               /* DUK_HOBJECT_FLAG_STRICT varies */
+               DUK_ASSERT(!DUK_HOBJECT_HAS_NATIVEFUNCTION(h) ||  /* all native functions have NEWENV */
+                          DUK_HOBJECT_HAS_NEWENV(h));
+               DUK_ASSERT(!DUK_HOBJECT_HAS_NAMEBINDING(h));
+               DUK_ASSERT(!DUK_HOBJECT_HAS_CREATEARGS(h));
+               DUK_ASSERT(!DUK_HOBJECT_HAS_ENVRECCLOSED(h));
+               /* DUK_HOBJECT_FLAG_EXOTIC_ARRAY varies */
+               /* DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ varies */
+               DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(h));
+
+               DUK_DDD(DUK_DDDPRINT("created built-in %ld, class=%ld, length=%ld", (long) i, (long) class_num, (long) len));
+       }
+
+       /*
+        *  Then decode the builtins init data (see genbuiltins.py) to
+        *  init objects
+        */
+
+       DUK_DD(DUK_DDPRINT("initialize built-in object properties"));
+       for (i = 0; i < DUK_NUM_ALL_BUILTINS; i++) {
+               duk_small_uint_t t;
+               duk_small_uint_t num;
+
+               DUK_DDD(DUK_DDDPRINT("initializing built-in object at index %ld", (long) i));
+               h = duk_require_hobject(ctx, i);
+               DUK_ASSERT(h != NULL);
+
+               t = (duk_small_uint_t) duk_bd_decode(bd, DUK__BIDX_BITS);
+               if (t != DUK__NO_BIDX_MARKER) {
+                       DUK_DDD(DUK_DDDPRINT("set internal prototype: built-in %ld", (long) t));
+                       DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h, duk_require_hobject(ctx, t));
+               }
+
+               t = (duk_small_uint_t) duk_bd_decode(bd, DUK__BIDX_BITS);
+               if (t != DUK__NO_BIDX_MARKER) {
+                       /* 'prototype' property for all built-in objects (which have it) has attributes:
+                        *  [[Writable]] = false,
+                        *  [[Enumerable]] = false,
+                        *  [[Configurable]] = false
+                        */
+                       DUK_DDD(DUK_DDDPRINT("set external prototype: built-in %ld", (long) t));
+                       duk_xdef_prop_stridx_builtin(ctx, i, DUK_STRIDX_PROTOTYPE, t, DUK_PROPDESC_FLAGS_NONE);
+               }
+
+               t = (duk_small_uint_t) duk_bd_decode(bd, DUK__BIDX_BITS);
+               if (t != DUK__NO_BIDX_MARKER) {
+                       /* 'constructor' property for all built-in objects (which have it) has attributes:
+                        *  [[Writable]] = true,
+                        *  [[Enumerable]] = false,
+                        *  [[Configurable]] = true
+                        */
+                       DUK_DDD(DUK_DDDPRINT("set external constructor: built-in %ld", (long) t));
+                       duk_xdef_prop_stridx_builtin(ctx, i, DUK_STRIDX_CONSTRUCTOR, t, DUK_PROPDESC_FLAGS_WC);
+               }
+
+               /* normal valued properties */
+               num = (duk_small_uint_t) duk_bd_decode(bd, DUK__NUM_NORMAL_PROPS_BITS);
+               DUK_DDD(DUK_DDDPRINT("built-in object %ld, %ld normal valued properties", (long) i, (long) num));
+               for (j = 0; j < num; j++) {
+                       duk_small_uint_t prop_flags;
+
+                       duk__push_stridx_or_string(ctx, bd);
+
+                       /*
+                        *  Property attribute defaults are defined in E5 Section 15 (first
+                        *  few pages); there is a default for all properties and a special
+                        *  default for 'length' properties.  Variation from the defaults is
+                        *  signaled using a single flag bit in the bitstream.
+                        */
+
+                       if (duk_bd_decode_flag(bd)) {
+                               prop_flags = (duk_small_uint_t) duk_bd_decode(bd, DUK__PROP_FLAGS_BITS);
+                       } else {
+                               prop_flags = DUK_PROPDESC_FLAGS_WC;
+                       }
+
+                       t = (duk_small_uint_t) duk_bd_decode(bd, DUK__PROP_TYPE_BITS);
+
+                       DUK_DDD(DUK_DDDPRINT("built-in %ld, normal-valued property %ld, key %!T, flags 0x%02lx, type %ld",
+                                            (long) i, (long) j, duk_get_tval(ctx, -1), (unsigned long) prop_flags, (long) t));
+
+                       switch (t) {
+                       case DUK__PROP_TYPE_DOUBLE: {
+                               duk__push_double(ctx, bd);
+                               break;
+                       }
+                       case DUK__PROP_TYPE_STRING: {
+                               duk__push_string(ctx, bd);
+                               break;
+                       }
+                       case DUK__PROP_TYPE_STRIDX: {
+                               duk__push_stridx(ctx, bd);
+                               break;
+                       }
+                       case DUK__PROP_TYPE_BUILTIN: {
+                               duk_small_uint_t bidx;
+
+                               bidx = (duk_small_uint_t) duk_bd_decode(bd, DUK__BIDX_BITS);
+                               DUK_ASSERT(bidx != DUK__NO_BIDX_MARKER);
+                               duk_dup(ctx, (duk_idx_t) bidx);
+                               break;
+                       }
+                       case DUK__PROP_TYPE_UNDEFINED: {
+                               duk_push_undefined(ctx);
+                               break;
+                       }
+                       case DUK__PROP_TYPE_BOOLEAN_TRUE: {
+                               duk_push_true(ctx);
+                               break;
+                       }
+                       case DUK__PROP_TYPE_BOOLEAN_FALSE: {
+                               duk_push_false(ctx);
+                               break;
+                       }
+                       case DUK__PROP_TYPE_ACCESSOR: {
+                               duk_small_uint_t natidx_getter = (duk_small_uint_t) duk_bd_decode(bd, DUK__NATIDX_BITS);
+                               duk_small_uint_t natidx_setter = (duk_small_uint_t) duk_bd_decode(bd, DUK__NATIDX_BITS);
+                               duk_c_function c_func_getter;
+                               duk_c_function c_func_setter;
+
+                               /* XXX: this is a bit awkward because there is no exposed helper
+                                * in the API style, only this internal helper.
+                                */
+                               DUK_DDD(DUK_DDDPRINT("built-in accessor property: objidx=%ld, key=%!T, getteridx=%ld, setteridx=%ld, flags=0x%04lx",
+                                                    (long) i, duk_get_tval(ctx, -1), (long) natidx_getter, (long) natidx_setter, (unsigned long) prop_flags));
+
+                               c_func_getter = duk_bi_native_functions[natidx_getter];
+                               c_func_setter = duk_bi_native_functions[natidx_setter];
+                               duk_push_c_function_noconstruct_noexotic(ctx, c_func_getter, 0);  /* always 0 args */
+                               duk_push_c_function_noconstruct_noexotic(ctx, c_func_setter, 1);  /* always 1 arg */
+
+                               /* XXX: magic for getter/setter? use duk_def_prop()? */
+
+                               DUK_ASSERT((prop_flags & DUK_PROPDESC_FLAG_WRITABLE) == 0);  /* genbuiltins.py ensures */
+
+                               prop_flags |= DUK_PROPDESC_FLAG_ACCESSOR;  /* accessor flag not encoded explicitly */
+                               duk_hobject_define_accessor_internal(thr,
+                                                                    duk_require_hobject(ctx, i),
+                                                                    duk_get_hstring(ctx, -3),
+                                                                    duk_require_hobject(ctx, -2),
+                                                                    duk_require_hobject(ctx, -1),
+                                                                    prop_flags);
+                               duk_pop_3(ctx);  /* key, getter and setter, now reachable through object */
+                               goto skip_value;
+                       }
+                       default: {
+                               /* exhaustive */
+                               DUK_UNREACHABLE();
+                       }
+                       }
+
+                       DUK_ASSERT((prop_flags & DUK_PROPDESC_FLAG_ACCESSOR) == 0);
+                       duk_xdef_prop(ctx, i, prop_flags);
+
+                skip_value:
+                       continue;  /* avoid empty label at the end of a compound statement */
+               }
+
+               /* native function properties */
+               num = (duk_small_uint_t) duk_bd_decode(bd, DUK__NUM_FUNC_PROPS_BITS);
+               DUK_DDD(DUK_DDDPRINT("built-in object %ld, %ld function valued properties", (long) i, (long) num));
+               for (j = 0; j < num; j++) {
+                       duk_hstring *h_key;
+                       duk_small_uint_t natidx;
+                       duk_int_t c_nargs;  /* must hold DUK_VARARGS */
+                       duk_small_uint_t c_length;
+                       duk_int16_t magic;
+                       duk_c_function c_func;
+                       duk_hnativefunction *h_func;
+#if defined(DUK_USE_LIGHTFUNC_BUILTINS)
+                       duk_small_int_t lightfunc_eligible;
+#endif
+
+                       duk__push_stridx_or_string(ctx, bd);
+                       h_key = duk_get_hstring(ctx, -1);
+                       DUK_ASSERT(h_key != NULL);
+                       DUK_UNREF(h_key);
+                       natidx = (duk_small_uint_t) duk_bd_decode(bd, DUK__NATIDX_BITS);
+
+                       c_length = (duk_small_uint_t) duk_bd_decode(bd, DUK__LENGTH_PROP_BITS);
+                       c_nargs = (duk_int_t) duk_bd_decode_flagged(bd, DUK__NARGS_BITS, (duk_int32_t) c_length /*def_value*/);
+                       if (c_nargs == DUK__NARGS_VARARGS_MARKER) {
+                               c_nargs = DUK_VARARGS;
+                       }
+
+                       c_func = duk_bi_native_functions[natidx];
+
+                       DUK_DDD(DUK_DDDPRINT("built-in %ld, function-valued property %ld, key %!O, natidx %ld, length %ld, nargs %ld",
+                                            (long) i, (long) j, (duk_heaphdr *) h_key, (long) natidx, (long) c_length,
+                                            (c_nargs == DUK_VARARGS ? (long) -1 : (long) c_nargs)));
+
+                       /* Cast converts magic to 16-bit signed value */
+                       magic = (duk_int16_t) duk_bd_decode_flagged(bd, DUK__MAGIC_BITS, 0);
+
+#if defined(DUK_USE_LIGHTFUNC_BUILTINS)
+                       lightfunc_eligible =
+                               ((c_nargs >= DUK_LFUNC_NARGS_MIN && c_nargs <= DUK_LFUNC_NARGS_MAX) || (c_nargs == DUK_VARARGS)) &&
+                               (c_length <= DUK_LFUNC_LENGTH_MAX) &&
+                               (magic >= DUK_LFUNC_MAGIC_MIN && magic <= DUK_LFUNC_MAGIC_MAX);
+
+                       if (h_key == DUK_HTHREAD_STRING_EVAL(thr) ||
+                           h_key == DUK_HTHREAD_STRING_YIELD(thr) ||
+                           h_key == DUK_HTHREAD_STRING_RESUME(thr) ||
+                           h_key == DUK_HTHREAD_STRING_REQUIRE(thr)) {
+                               /* These functions have trouble working as lightfuncs.
+                                * Some of them have specific asserts and some may have
+                                * additional properties (e.g. 'require.id' may be written).
+                                */
+                               DUK_D(DUK_DPRINT("reject as lightfunc: key=%!O, i=%d, j=%d", (duk_heaphdr *) h_key, (int) i, (int) j));
+                               lightfunc_eligible = 0;
+                       }
+
+                       if (lightfunc_eligible) {
+                               duk_tval tv_lfunc;
+                               duk_small_uint_t lf_nargs = (c_nargs == DUK_VARARGS ? DUK_LFUNC_NARGS_VARARGS : c_nargs);
+                               duk_small_uint_t lf_flags = DUK_LFUNC_FLAGS_PACK(magic, c_length, lf_nargs);
+                               DUK_TVAL_SET_LIGHTFUNC(&tv_lfunc, c_func, lf_flags);
+                               duk_push_tval(ctx, &tv_lfunc);
+                               DUK_D(DUK_DPRINT("built-in function eligible as light function: i=%d, j=%d c_length=%ld, c_nargs=%ld, magic=%ld -> %!iT", (int) i, (int) j, (long) c_length, (long) c_nargs, (long) magic, duk_get_tval(ctx, -1)));
+                               goto lightfunc_skip;
+                       }
+
+                       DUK_D(DUK_DPRINT("built-in function NOT ELIGIBLE as light function: i=%d, j=%d c_length=%ld, c_nargs=%ld, magic=%ld", (int) i, (int) j, (long) c_length, (long) c_nargs, (long) magic));
+#endif  /* DUK_USE_LIGHTFUNC_BUILTINS */
+
+                       /* [ (builtin objects) name ] */
+
+                       duk_push_c_function_noconstruct_noexotic(ctx, c_func, c_nargs);
+                       h_func = duk_require_hnativefunction(ctx, -1);
+                       DUK_UNREF(h_func);
+
+                       /* Currently all built-in native functions are strict.
+                        * This doesn't matter for many functions, but e.g.
+                        * String.prototype.charAt (and other string functions)
+                        * rely on being strict so that their 'this' binding is
+                        * not automatically coerced.
+                        */
+                       DUK_HOBJECT_SET_STRICT((duk_hobject *) h_func);
+
+                       /* No built-in functions are constructable except the top
+                        * level ones (Number, etc).
+                        */
+                       DUK_ASSERT(!DUK_HOBJECT_HAS_CONSTRUCTABLE((duk_hobject *) h_func));
+
+                       /* XXX: any way to avoid decoding magic bit; there are quite
+                        * many function properties and relatively few with magic values.
+                        */
+                       h_func->magic = magic;
+
+                       /* [ (builtin objects) name func ] */
+
+                       duk_push_int(ctx, c_length);
+                       duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_NONE);
+
+                       duk_dup(ctx, -2);
+                       duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_NONE);
+
+                       /* XXX: other properties of function instances; 'arguments', 'caller'. */
+
+                       DUK_DD(DUK_DDPRINT("built-in object %ld, function property %ld -> %!T",
+                                          (long) i, (long) j, (duk_tval *) duk_get_tval(ctx, -1)));
+
+                       /* [ (builtin objects) name func ] */
+
+                       /*
+                        *  The default property attributes are correct for all
+                        *  function valued properties of built-in objects now.
+                        */
+
+#if defined(DUK_USE_LIGHTFUNC_BUILTINS)
+                lightfunc_skip:
+#endif
+
+                       duk_xdef_prop(ctx, i, DUK_PROPDESC_FLAGS_WC);
+
+                       /* [ (builtin objects) ] */
+               }
+       }
+
+       /*
+        *  Special post-tweaks, for cases not covered by the init data format.
+        *
+        *  - Set Date.prototype.toGMTString to Date.prototype.toUTCString.
+        *    toGMTString is required to have the same Function object as
+        *    toUTCString in E5 Section B.2.6.  Note that while Smjs respects
+        *    this, V8 does not (the Function objects are distinct).
+        *
+        *  - Make DoubleError non-extensible.
+        *
+        *  - Add info about most important effective compile options to Duktape.
+        *
+        *  - Possibly remove some properties (values or methods) which are not
+        *    desirable with current feature options but are not currently
+        *    conditional in init data.
+        */
+
+       duk_get_prop_stridx(ctx, DUK_BIDX_DATE_PROTOTYPE, DUK_STRIDX_TO_UTC_STRING);
+       duk_xdef_prop_stridx(ctx, DUK_BIDX_DATE_PROTOTYPE, DUK_STRIDX_TO_GMT_STRING, DUK_PROPDESC_FLAGS_WC);
+
+       h = duk_require_hobject(ctx, DUK_BIDX_DOUBLE_ERROR);
+       DUK_ASSERT(h != NULL);
+       DUK_HOBJECT_CLEAR_EXTENSIBLE(h);
+
+#if !defined(DUK_USE_ES6_OBJECT_PROTO_PROPERTY)
+       DUK_DD(DUK_DDPRINT("delete Object.prototype.__proto__ built-in which is not enabled in features"));
+       (void) duk_hobject_delprop_raw(thr, thr->builtins[DUK_BIDX_OBJECT_PROTOTYPE], DUK_HTHREAD_STRING___PROTO__(thr), DUK_DELPROP_FLAG_THROW);
+#endif
+
+#if !defined(DUK_USE_ES6_OBJECT_SETPROTOTYPEOF)
+       DUK_DD(DUK_DDPRINT("delete Object.setPrototypeOf built-in which is not enabled in features"));
+       (void) duk_hobject_delprop_raw(thr, thr->builtins[DUK_BIDX_OBJECT_CONSTRUCTOR], DUK_HTHREAD_STRING_SET_PROTOTYPE_OF(thr), DUK_DELPROP_FLAG_THROW);
+#endif
+
+       /* XXX: relocate */
+       duk_push_string(ctx,
+                       /* Endianness indicator */
+#if defined(DUK_USE_INTEGER_LE)
+                       "l"
+#elif defined(DUK_USE_INTEGER_BE)
+                       "b"
+#elif defined(DUK_USE_INTEGER_ME)  /* integer mixed endian not really used now */
+                       "m"
+#else
+                       "?"
+#endif
+#if defined(DUK_USE_DOUBLE_LE)
+                       "l"
+#elif defined(DUK_USE_DOUBLE_BE)
+                       "b"
+#elif defined(DUK_USE_DOUBLE_ME)
+                       "m"
+#else
+                       "?"
+#endif
+                       " "
+                       /* Packed or unpacked tval */
+#if defined(DUK_USE_PACKED_TVAL)
+                       "p"
+#else
+                       "u"
+#endif
+#if defined(DUK_USE_FASTINT)
+                       "f"
+#endif
+                       " "
+                       /* Low memory options */
+#if defined(DUK_USE_STRTAB_CHAIN)
+                       "c"  /* chain */
+#elif defined(DUK_USE_STRTAB_PROBE)
+                       "p"  /* probe */
+#else
+                       "?"
+#endif
+#if !defined(DUK_USE_HEAPPTR16) && !defined(DUK_DATAPTR16) && !defined(DUK_FUNCPTR16)
+                       "n"
+#endif
+#if defined(DUK_USE_HEAPPTR16)
+                       "h"
+#endif
+#if defined(DUK_USE_DATAPTR16)
+                       "d"
+#endif
+#if defined(DUK_USE_FUNCPTR16)
+                       "f"
+#endif
+#if defined(DUK_USE_REFCOUNT16)
+                       "R"
+#endif
+#if defined(DUK_USE_STRHASH16)
+                       "H"
+#endif
+#if defined(DUK_USE_STRLEN16)
+                       "S"
+#endif
+#if defined(DUK_USE_BUFLEN16)
+                       "B"
+#endif
+#if defined(DUK_USE_OBJSIZES16)
+                       "O"
+#endif
+#if defined(DUK_USE_LIGHTFUNC_BUILTINS)
+                       "L"
+#endif
+#if defined(DUK_USE_ROM_STRINGS) || defined(DUK_USE_ROM_OBJECTS)
+                       /* XXX: This won't be shown in practice now
+                        * because this code is not run when builtins
+                        * are in ROM.
+                        */
+                       "Z"
+#endif
+                       " "
+                       /* Object property allocation layout */
+#if defined(DUK_USE_HOBJECT_LAYOUT_1)
+                       "p1"
+#elif defined(DUK_USE_HOBJECT_LAYOUT_2)
+                       "p2"
+#elif defined(DUK_USE_HOBJECT_LAYOUT_3)
+                       "p3"
+#else
+                       "p?"
+#endif
+                       " "
+                       /* Alignment guarantee */
+#if (DUK_USE_ALIGN_BY == 4)
+                       "a4"
+#elif (DUK_USE_ALIGN_BY == 8)
+                       "a8"
+#elif (DUK_USE_ALIGN_BY == 1)
+                       "a1"
+#else
+#error invalid DUK_USE_ALIGN_BY
+#endif
+                       " "
+                       /* Architecture, OS, and compiler strings */
+                       DUK_USE_ARCH_STRING
+                       " "
+                       DUK_USE_OS_STRING
+                       " "
+                       DUK_USE_COMPILER_STRING);
+       duk_xdef_prop_stridx(ctx, DUK_BIDX_DUKTAPE, DUK_STRIDX_ENV, DUK_PROPDESC_FLAGS_WC);
+
+       /*
+        *  InitJS code - Ecmascript code evaluated from a built-in source
+        *  which provides e.g. backward compatibility.  User can also provide
+        *  JS code to be evaluated at startup.
+        */
+
+#ifdef DUK_USE_BUILTIN_INITJS
+       /* XXX: compression */
+       DUK_DD(DUK_DDPRINT("running built-in initjs"));
+       duk_eval_string(ctx, (const char *) duk_initjs_data);  /* initjs data is NUL terminated */
+       duk_pop(ctx);
+#endif  /* DUK_USE_BUILTIN_INITJS */
+
+#ifdef DUK_USE_USER_INITJS
+       /* XXX: compression (as an option) */
+       DUK_DD(DUK_DDPRINT("running user initjs"));
+       duk_eval_string_noresult(ctx, (const char *) DUK_USE_USER_INITJS);
+#endif  /* DUK_USE_USER_INITJS */
+
+       /*
+        *  Since built-ins are not often extended, compact them.
+        */
+
+       DUK_DD(DUK_DDPRINT("compact built-ins"));
+       for (i = 0; i < DUK_NUM_ALL_BUILTINS; i++) {
+               duk_hobject_compact_props(thr, duk_require_hobject(ctx, i));
+       }
+
+       DUK_D(DUK_DPRINT("INITBUILTINS END"));
+
+#ifdef DUK_USE_DDPRINT
+       for (i = 0; i < DUK_NUM_ALL_BUILTINS; i++) {
+               DUK_DD(DUK_DDPRINT("built-in object %ld after initialization and compacting: %!@iO",
+                                  (long) i, (duk_heaphdr *) duk_require_hobject(ctx, i)));
+       }
+#endif
+
+       /*
+        *  Pop built-ins from stack: they are now INCREF'd and
+        *  reachable from the builtins[] array or indirectly
+        *  through builtins[].
+        */
+
+       duk_set_top(ctx, 0);
+       DUK_ASSERT_TOP(ctx, 0);
+}
+#endif  /* DUK_USE_ROM_OBJECTS */
+
+DUK_INTERNAL void duk_hthread_copy_builtin_objects(duk_hthread *thr_from, duk_hthread *thr_to) {
+       duk_small_uint_t i;
+
+       for (i = 0; i < DUK_NUM_BUILTINS; i++) {
+               thr_to->builtins[i] = thr_from->builtins[i];
+               DUK_HOBJECT_INCREF_ALLOWNULL(thr_to, thr_to->builtins[i]);  /* side effect free */
+       }
+}