/*
 *  Hobject property set/get functionality.
 *
 *  This is very central functionality for size, performance, and compliance.
 *  It is also rather intricate; see hobject-algorithms.rst for discussion on
 *  the algorithms and memory-management.rst for discussion on refcounts and
 *  side effect issues.
 *
 *  Notes:
 *
 *    - It might be tempting to assert "refcount nonzero" for objects
 *      being operated on, but that's not always correct: objects with
 *      a zero refcount may be operated on by the refcount implementation
 *      (finalization) for instance.  Hence, no refcount assertions are made.
 *
 *    - Many operations (memory allocation, identifier operations, etc)
 *      may cause arbitrary side effects (e.g. through GC and finalization).
 *      These side effects may invalidate duk_tval pointers which point to
 *      areas subject to reallocation (like value stack).  Heap objects
 *      themselves have stable pointers.  Holding heap object pointers or
 *      duk_tval copies is not problematic with respect to side effects;
 *      care must be taken when holding and using argument duk_tval pointers.
 *
 *    - If a finalizer is executed, it may operate on the the same object
 *      we're currently dealing with.  For instance, the finalizer might
 *      delete a certain property which has already been looked up and
 *      confirmed to exist.  Ideally finalizers would be disabled if GC
 *      happens during property access.  At the moment property table realloc
 *      disables finalizers, and all DECREFs may cause arbitrary changes so
 *      handle DECREF carefully.
 *
 *    - The order of operations for a DECREF matters.  When DECREF is executed,
 *      the entire object graph must be consistent; note that a refzero may
 *      lead to a mark-and-sweep through a refcount finalizer.
 */

/*
 *  XXX: array indices are mostly typed as duk_uint32_t here; duk_uarridx_t
 *  might be more appropriate.
 */

/*
 *  XXX: duk_uint_fast32_t should probably be used in many places here.
 */

#include "duk_internal.h"

/*
 *  Local defines
 */

#define DUK__NO_ARRAY_INDEX             DUK_HSTRING_NO_ARRAY_INDEX

/* hash probe sequence */
#define DUK__HASH_INITIAL(hash,h_size)  DUK_HOBJECT_HASH_INITIAL((hash),(h_size))
#define DUK__HASH_PROBE_STEP(hash)      DUK_HOBJECT_HASH_PROBE_STEP((hash))

/* marker values for hash part */
#define DUK__HASH_UNUSED                DUK_HOBJECT_HASHIDX_UNUSED
#define DUK__HASH_DELETED               DUK_HOBJECT_HASHIDX_DELETED

/* valstack space that suffices for all local calls, including recursion
 * of other than Duktape calls (getters etc)
 */
#define DUK__VALSTACK_SPACE             10

/* valstack space allocated especially for proxy lookup which does a
 * recursive property lookup
 */
#define DUK__VALSTACK_PROXY_LOOKUP      20

/*
 *  Local prototypes
 */

DUK_LOCAL_DECL duk_bool_t duk__check_arguments_map_for_get(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc);
DUK_LOCAL_DECL void duk__check_arguments_map_for_put(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc, duk_bool_t throw_flag);
DUK_LOCAL_DECL void duk__check_arguments_map_for_delete(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc);

DUK_LOCAL_DECL duk_bool_t duk__handle_put_array_length_smaller(duk_hthread *thr, duk_hobject *obj, duk_uint32_t old_len, duk_uint32_t new_len, duk_bool_t force_flag, duk_uint32_t *out_result_len);
DUK_LOCAL_DECL duk_bool_t duk__handle_put_array_length(duk_hthread *thr, duk_hobject *obj);

DUK_LOCAL_DECL duk_bool_t duk__get_propdesc(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *out_desc, duk_small_uint_t flags);
DUK_LOCAL_DECL duk_bool_t duk__get_own_propdesc_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_uint32_t arr_idx, duk_propdesc *out_desc, duk_small_uint_t flags);
DUK_LOCAL duk_uint32_t duk__get_old_array_length(duk_hthread *thr, duk_hobject *obj, duk_propdesc *temp_desc);

/*
 *  Misc helpers
 */

/* Convert a duk_tval number (caller checks) to a 32-bit index.  Returns
 * DUK__NO_ARRAY_INDEX if the number is not whole or not a valid array
 * index.
 */
/* XXX: for fastints, could use a variant which assumes a double duk_tval
 * (and doesn't need to check for fastint again).
 */
DUK_LOCAL duk_uint32_t duk__tval_number_to_arr_idx(duk_tval *tv) {
	duk_double_t dbl;
	duk_uint32_t idx;

	DUK_ASSERT(tv != NULL);
	DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));

	/* -0 is accepted here as index 0 because ToString(-0) == "0" which is
	 * in canonical form and thus an array index.
	 */
	dbl = DUK_TVAL_GET_NUMBER(tv);
	idx = (duk_uint32_t) dbl;
	if ((duk_double_t) idx == dbl) {
	        /* Is whole and within 32 bit range.  If the value happens to be 0xFFFFFFFF,
		 * it's not a valid array index but will then match DUK__NO_ARRAY_INDEX.
		 */
		return idx;
	}
	return DUK__NO_ARRAY_INDEX;
}

#if defined(DUK_USE_FASTINT)
/* Convert a duk_tval fastint (caller checks) to a 32-bit index. */
DUK_LOCAL duk_uint32_t duk__tval_fastint_to_arr_idx(duk_tval *tv) {
	duk_int64_t t;

	DUK_ASSERT(tv != NULL);
	DUK_ASSERT(DUK_TVAL_IS_FASTINT(tv));

	t = DUK_TVAL_GET_FASTINT(tv);
	if ((t & ~0xffffffffULL) != 0) {
		/* Catches >0x100000000 and negative values. */
		return DUK__NO_ARRAY_INDEX;
	}

	/* If the value happens to be 0xFFFFFFFF, it's not a valid array index
	 * but will then match DUK__NO_ARRAY_INDEX.
	 */
	return (duk_uint32_t) t;
}
#endif  /* DUK_USE_FASTINT */

/* Push an arbitrary duk_tval to the stack, coerce it to string, and return
 * both a duk_hstring pointer and an array index (or DUK__NO_ARRAY_INDEX).
 */
DUK_LOCAL duk_uint32_t duk__push_tval_to_hstring_arr_idx(duk_context *ctx, duk_tval *tv, duk_hstring **out_h) {
	duk_uint32_t arr_idx;
	duk_hstring *h;

	DUK_ASSERT(ctx != NULL);
	DUK_ASSERT(tv != NULL);
	DUK_ASSERT(out_h != NULL);

	duk_push_tval(ctx, tv);
	duk_to_string(ctx, -1);
	h = duk_get_hstring(ctx, -1);
	DUK_ASSERT(h != NULL);
	*out_h = h;

	arr_idx = DUK_HSTRING_GET_ARRIDX_FAST(h);
	return arr_idx;
}

/* String is an own (virtual) property of a lightfunc. */
DUK_LOCAL duk_bool_t duk__key_is_lightfunc_ownprop(duk_hthread *thr, duk_hstring *key) {
	DUK_UNREF(thr);
	return (key == DUK_HTHREAD_STRING_LENGTH(thr) ||
	        key == DUK_HTHREAD_STRING_NAME(thr));
}

/*
 *  Helpers for managing property storage size
 */

/* Get default hash part size for a certain entry part size. */
#if defined(DUK_USE_HOBJECT_HASH_PART)
DUK_LOCAL duk_uint32_t duk__get_default_h_size(duk_uint32_t e_size) {
	DUK_ASSERT(e_size <= DUK_HOBJECT_MAX_PROPERTIES);

	if (e_size >= DUK_HOBJECT_E_USE_HASH_LIMIT) {
		duk_uint32_t res;

		/* result: hash_prime(floor(1.2 * e_size)) */
		res = duk_util_get_hash_prime(e_size + e_size / DUK_HOBJECT_H_SIZE_DIVISOR);

		/* if fails, e_size will be zero = not an issue, except performance-wise */
		DUK_ASSERT(res == 0 || res > e_size);
		return res;
	} else {
		return 0;
	}
}
#endif  /* USE_PROP_HASH_PART */

/* Get minimum entry part growth for a certain size. */
DUK_LOCAL duk_uint32_t duk__get_min_grow_e(duk_uint32_t e_size) {
	duk_uint32_t res;

	DUK_ASSERT(e_size <= DUK_HOBJECT_MAX_PROPERTIES);

	res = (e_size + DUK_HOBJECT_E_MIN_GROW_ADD) / DUK_HOBJECT_E_MIN_GROW_DIVISOR;
	DUK_ASSERT(res >= 1);  /* important for callers */
	return res;
}

/* Get minimum array part growth for a certain size. */
DUK_LOCAL duk_uint32_t duk__get_min_grow_a(duk_uint32_t a_size) {
	duk_uint32_t res;

	DUK_ASSERT((duk_size_t) a_size <= DUK_HOBJECT_MAX_PROPERTIES);

	res = (a_size + DUK_HOBJECT_A_MIN_GROW_ADD) / DUK_HOBJECT_A_MIN_GROW_DIVISOR;
	DUK_ASSERT(res >= 1);  /* important for callers */
	return res;
}

/* Count actually used entry part entries (non-NULL keys). */
DUK_LOCAL duk_uint32_t duk__count_used_e_keys(duk_hthread *thr, duk_hobject *obj) {
	duk_uint_fast32_t i;
	duk_uint_fast32_t n = 0;
	duk_hstring **e;

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

	e = DUK_HOBJECT_E_GET_KEY_BASE(thr->heap, obj);
	for (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {
		if (*e++) {
			n++;
		}
	}
	return (duk_uint32_t) n;
}

/* Count actually used array part entries and array minimum size.
 * NOTE: 'out_min_size' can be computed much faster by starting from the
 * end and breaking out early when finding first used entry, but this is
 * not needed now.
 */
DUK_LOCAL void duk__compute_a_stats(duk_hthread *thr, duk_hobject *obj, duk_uint32_t *out_used, duk_uint32_t *out_min_size) {
	duk_uint_fast32_t i;
	duk_uint_fast32_t used = 0;
	duk_uint_fast32_t highest_idx = (duk_uint_fast32_t) -1;  /* see below */
	duk_tval *a;

	DUK_ASSERT(obj != NULL);
	DUK_ASSERT(out_used != NULL);
	DUK_ASSERT(out_min_size != NULL);
	DUK_UNREF(thr);

	a = DUK_HOBJECT_A_GET_BASE(thr->heap, obj);
	for (i = 0; i < DUK_HOBJECT_GET_ASIZE(obj); i++) {
		duk_tval *tv = a++;
		if (!DUK_TVAL_IS_UNUSED(tv)) {
			used++;
			highest_idx = i;
		}
	}

	/* Initial value for highest_idx is -1 coerced to unsigned.  This
	 * is a bit odd, but (highest_idx + 1) will then wrap to 0 below
	 * for out_min_size as intended.
	 */

	*out_used = used;
	*out_min_size = highest_idx + 1;  /* 0 if no used entries */
}

/* Check array density and indicate whether or not the array part should be abandoned. */
DUK_LOCAL duk_bool_t duk__abandon_array_density_check(duk_uint32_t a_used, duk_uint32_t a_size) {
	/*
	 *  Array abandon check; abandon if:
	 *
	 *    new_used / new_size < limit
	 *    new_used < limit * new_size        || limit is 3 bits fixed point
	 *    new_used < limit' / 8 * new_size   || *8
	 *    8*new_used < limit' * new_size     || :8
	 *    new_used < limit' * (new_size / 8)
	 *
	 *  Here, new_used = a_used, new_size = a_size.
	 *
	 *  Note: some callers use approximate values for a_used and/or a_size
	 *  (e.g. dropping a '+1' term).  This doesn't affect the usefulness
	 *  of the check, but may confuse debugging.
	 */

	return (a_used < DUK_HOBJECT_A_ABANDON_LIMIT * (a_size >> 3));
}

/* Fast check for extending array: check whether or not a slow density check is required. */
DUK_LOCAL duk_bool_t duk__abandon_array_slow_check_required(duk_uint32_t arr_idx, duk_uint32_t old_size) {
	/*
	 *  In a fast check we assume old_size equals old_used (i.e., existing
	 *  array is fully dense).
	 *
	 *  Slow check if:
	 *
	 *    (new_size - old_size) / old_size > limit
	 *    new_size - old_size > limit * old_size
	 *    new_size > (1 + limit) * old_size        || limit' is 3 bits fixed point
	 *    new_size > (1 + (limit' / 8)) * old_size || * 8
	 *    8 * new_size > (8 + limit') * old_size   || : 8
	 *    new_size > (8 + limit') * (old_size / 8)
	 *    new_size > limit'' * (old_size / 8)      || limit'' = 9 -> max 25% increase
	 *    arr_idx + 1 > limit'' * (old_size / 8)
	 *
	 *  This check doesn't work well for small values, so old_size is rounded
	 *  up for the check (and the '+ 1' of arr_idx can be ignored in practice):
	 *
	 *    arr_idx > limit'' * ((old_size + 7) / 8)
	 */

	return (arr_idx > DUK_HOBJECT_A_FAST_RESIZE_LIMIT * ((old_size + 7) >> 3));
}

/*
 *  Proxy helpers
 */

#if defined(DUK_USE_ES6_PROXY)
DUK_INTERNAL duk_bool_t duk_hobject_proxy_check(duk_hthread *thr, duk_hobject *obj, duk_hobject **out_target, duk_hobject **out_handler) {
	duk_tval *tv_target;
	duk_tval *tv_handler;
	duk_hobject *h_target;
	duk_hobject *h_handler;

	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(obj != NULL);
	DUK_ASSERT(out_target != NULL);
	DUK_ASSERT(out_handler != NULL);

	/* Caller doesn't need to check exotic proxy behavior (but does so for
	 * some fast paths).
	 */
	if (DUK_LIKELY(!DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(obj))) {
		return 0;
	}

	tv_handler = duk_hobject_find_existing_entry_tval_ptr(thr->heap, obj, DUK_HTHREAD_STRING_INT_HANDLER(thr));
	if (!tv_handler) {
		DUK_ERROR_TYPE(thr, DUK_STR_PROXY_REVOKED);
		return 0;
	}
	DUK_ASSERT(DUK_TVAL_IS_OBJECT(tv_handler));
	h_handler = DUK_TVAL_GET_OBJECT(tv_handler);
	DUK_ASSERT(h_handler != NULL);
	*out_handler = h_handler;
	tv_handler = NULL;  /* avoid issues with relocation */

	tv_target = duk_hobject_find_existing_entry_tval_ptr(thr->heap, obj, DUK_HTHREAD_STRING_INT_TARGET(thr));
	if (!tv_target) {
		DUK_ERROR_TYPE(thr, DUK_STR_PROXY_REVOKED);
		return 0;
	}
	DUK_ASSERT(DUK_TVAL_IS_OBJECT(tv_target));
	h_target = DUK_TVAL_GET_OBJECT(tv_target);
	DUK_ASSERT(h_target != NULL);
	*out_target = h_target;
	tv_target = NULL;  /* avoid issues with relocation */

	return 1;
}
#endif  /* DUK_USE_ES6_PROXY */

/* Get Proxy target object.  If the argument is not a Proxy, return it as is.
 * If a Proxy is revoked, an error is thrown.
 */
#if defined(DUK_USE_ES6_PROXY)
DUK_INTERNAL duk_hobject *duk_hobject_resolve_proxy_target(duk_hthread *thr, duk_hobject *obj) {
	duk_hobject *h_target;
	duk_hobject *h_handler;

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

	/* Resolve Proxy targets until Proxy chain ends.  No explicit check for
	 * a Proxy loop: user code cannot create such a loop without tweaking
	 * internal properties directly.
	 */

	while (DUK_UNLIKELY(DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(obj))) {
		if (duk_hobject_proxy_check(thr, obj, &h_target, &h_handler)) {
			DUK_ASSERT(h_target != NULL);
			obj = h_target;
		} else {
			break;
		}
	}

	DUK_ASSERT(obj != NULL);
	return obj;
}
#endif  /* DUK_USE_ES6_PROXY */

#if defined(DUK_USE_ES6_PROXY)
DUK_LOCAL duk_bool_t duk__proxy_check_prop(duk_hthread *thr, duk_hobject *obj, duk_small_uint_t stridx_trap, duk_tval *tv_key, duk_hobject **out_target) {
	duk_context *ctx = (duk_context *) thr;
	duk_hobject *h_handler;

	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(obj != NULL);
	DUK_ASSERT(tv_key != NULL);
	DUK_ASSERT(out_target != NULL);

	if (!duk_hobject_proxy_check(thr, obj, out_target, &h_handler)) {
		return 0;
	}
	DUK_ASSERT(*out_target != NULL);
	DUK_ASSERT(h_handler != NULL);

	/* XXX: At the moment Duktape accesses internal keys like _Finalizer using a
	 * normal property set/get which would allow a proxy handler to interfere with
	 * such behavior and to get access to internal key strings.  This is not a problem
	 * as such because internal key strings can be created in other ways too (e.g.
	 * through buffers).  The best fix is to change Duktape internal lookups to
	 * skip proxy behavior.  Until that, internal property accesses bypass the
	 * proxy and are applied to the target (as if the handler did not exist).
	 * This has some side effects, see test-bi-proxy-internal-keys.js.
	 */

	if (DUK_TVAL_IS_STRING(tv_key)) {
		duk_hstring *h_key = (duk_hstring *) DUK_TVAL_GET_STRING(tv_key);
		DUK_ASSERT(h_key != NULL);
		if (DUK_HSTRING_HAS_INTERNAL(h_key)) {
			DUK_DDD(DUK_DDDPRINT("internal key, skip proxy handler and apply to target"));
			return 0;
		}
	}

	/* The handler is looked up with a normal property lookup; it may be an
	 * accessor or the handler object itself may be a proxy object.  If the
	 * handler is a proxy, we need to extend the valstack as we make a
	 * recursive proxy check without a function call in between (in fact
	 * there is no limit to the potential recursion here).
	 *
	 * (For sanity, proxy creation rejects another proxy object as either
	 * the handler or the target at the moment so recursive proxy cases
	 * are not realized now.)
	 */

	/* XXX: C recursion limit if proxies are allowed as handler/target values */

	duk_require_stack(ctx, DUK__VALSTACK_PROXY_LOOKUP);
	duk_push_hobject(ctx, h_handler);
	if (duk_get_prop_stridx(ctx, -1, stridx_trap)) {
		/* -> [ ... handler trap ] */
		duk_insert(ctx, -2);  /* -> [ ... trap handler ] */

		/* stack prepped for func call: [ ... trap handler ] */
		return 1;
	} else {
		duk_pop_2(ctx);
		return 0;
	}
}
#endif  /* DUK_USE_ES6_PROXY */

/*
 *  Reallocate property allocation, moving properties to the new allocation.
 *
 *  Includes key compaction, rehashing, and can also optionally abandoning
 *  the array part, 'migrating' array entries into the beginning of the
 *  new entry part.  Arguments are not validated here, so e.g. new_h_size
 *  MUST be a valid prime.
 *
 *  There is no support for in-place reallocation or just compacting keys
 *  without resizing the property allocation.  This is intentional to keep
 *  code size minimal.
 *
 *  The implementation is relatively straightforward, except for the array
 *  abandonment process.  Array abandonment requires that new string keys
 *  are interned, which may trigger GC.  All keys interned so far must be
 *  reachable for GC at all times; valstack is used for that now.
 *
 *  Also, a GC triggered during this reallocation process must not interfere
 *  with the object being resized.  This is currently controlled by using
 *  heap->mark_and_sweep_base_flags to indicate that no finalizers will be
 *  executed (as they can affect ANY object) and no objects are compacted
 *  (it would suffice to protect this particular object only, though).
 *
 *  Note: a non-checked variant would be nice but is a bit tricky to
 *  implement for the array abandonment process.  It's easy for
 *  everything else.
 *
 *  Note: because we need to potentially resize the valstack (as part
 *  of abandoning the array part), any tval pointers to the valstack
 *  will become invalid after this call.
 */

DUK_LOCAL
void duk__realloc_props(duk_hthread *thr,
                        duk_hobject *obj,
                        duk_uint32_t new_e_size,
                        duk_uint32_t new_a_size,
                        duk_uint32_t new_h_size,
                        duk_bool_t abandon_array) {
	duk_context *ctx = (duk_context *) thr;
#ifdef DUK_USE_MARK_AND_SWEEP
	duk_small_uint_t prev_mark_and_sweep_base_flags;
#endif
	duk_uint32_t new_alloc_size;
	duk_uint32_t new_e_size_adjusted;
	duk_uint8_t *new_p;
	duk_hstring **new_e_k;
	duk_propvalue *new_e_pv;
	duk_uint8_t *new_e_f;
	duk_tval *new_a;
	duk_uint32_t *new_h;
	duk_uint32_t new_e_next;
	duk_uint_fast32_t i;

	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(ctx != NULL);
	DUK_ASSERT(obj != NULL);
	DUK_ASSERT(!abandon_array || new_a_size == 0);  /* if abandon_array, new_a_size must be 0 */
	DUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL || (DUK_HOBJECT_GET_ESIZE(obj) == 0 && DUK_HOBJECT_GET_ASIZE(obj) == 0));
	DUK_ASSERT(new_h_size == 0 || new_h_size >= new_e_size);  /* required to guarantee success of rehashing,
	                                                           * intentionally use unadjusted new_e_size
	                                                           */
	DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));
	DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);

	/*
	 *  Pre resize assertions.
	 */

#ifdef DUK_USE_ASSERTIONS
	/* XXX: pre-checks (such as no duplicate keys) */
#endif

	/*
	 *  For property layout 1, tweak e_size to ensure that the whole entry
	 *  part (key + val + flags) is a suitable multiple for alignment
	 *  (platform specific).
	 *
	 *  Property layout 2 does not require this tweaking and is preferred
	 *  on low RAM platforms requiring alignment.
	 */

#if defined(DUK_USE_HOBJECT_LAYOUT_2) || defined(DUK_USE_HOBJECT_LAYOUT_3)
	DUK_DDD(DUK_DDDPRINT("using layout 2 or 3, no need to pad e_size: %ld", (long) new_e_size));
	new_e_size_adjusted = new_e_size;
#elif defined(DUK_USE_HOBJECT_LAYOUT_1) && (DUK_HOBJECT_ALIGN_TARGET == 1)
	DUK_DDD(DUK_DDDPRINT("using layout 1, but no need to pad e_size: %ld", (long) new_e_size));
	new_e_size_adjusted = new_e_size;
#elif defined(DUK_USE_HOBJECT_LAYOUT_1) && ((DUK_HOBJECT_ALIGN_TARGET == 4) || (DUK_HOBJECT_ALIGN_TARGET == 8))
	new_e_size_adjusted = (new_e_size + DUK_HOBJECT_ALIGN_TARGET - 1) & (~(DUK_HOBJECT_ALIGN_TARGET - 1));
	DUK_DDD(DUK_DDDPRINT("using layout 1, and alignment target is %ld, adjusted e_size: %ld -> %ld",
	                     (long) DUK_HOBJECT_ALIGN_TARGET, (long) new_e_size, (long) new_e_size_adjusted));
	DUK_ASSERT(new_e_size_adjusted >= new_e_size);
#else
#error invalid hobject layout defines
#endif

	/*
	 *  Debug logging after adjustment.
	 */

	DUK_DDD(DUK_DDDPRINT("attempt to resize hobject %p props (%ld -> %ld bytes), from {p=%p,e_size=%ld,e_next=%ld,a_size=%ld,h_size=%ld} to "
	                     "{e_size=%ld,a_size=%ld,h_size=%ld}, abandon_array=%ld, unadjusted new_e_size=%ld",
	                     (void *) obj,
	                     (long) DUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE(obj),
	                                                       DUK_HOBJECT_GET_ASIZE(obj),
	                                                       DUK_HOBJECT_GET_HSIZE(obj)),
	                     (long) DUK_HOBJECT_P_COMPUTE_SIZE(new_e_size_adjusted, new_a_size, new_h_size),
	                     (void *) DUK_HOBJECT_GET_PROPS(thr->heap, obj),
	                     (long) DUK_HOBJECT_GET_ESIZE(obj),
	                     (long) DUK_HOBJECT_GET_ENEXT(obj),
	                     (long) DUK_HOBJECT_GET_ASIZE(obj),
	                     (long) DUK_HOBJECT_GET_HSIZE(obj),
	                     (long) new_e_size_adjusted,
	                     (long) new_a_size,
	                     (long) new_h_size,
	                     (long) abandon_array,
	                     (long) new_e_size));

	/*
	 *  Property count check.  This is the only point where we ensure that
	 *  we don't get more (allocated) property space that we can handle.
	 *  There aren't hard limits as such, but some algorithms fail (e.g.
	 *  finding next higher prime, selecting hash part size) if we get too
	 *  close to the 4G property limit.
	 *
	 *  Since this works based on allocation size (not actually used size),
	 *  the limit is a bit approximate but good enough in practice.
	 */

	if (new_e_size_adjusted + new_a_size > DUK_HOBJECT_MAX_PROPERTIES) {
		DUK_ERROR_ALLOC_DEFMSG(thr);
	}

	/*
	 *  Compute new alloc size and alloc new area.
	 *
	 *  The new area is allocated as a dynamic buffer and placed into the
	 *  valstack for reachability.  The actual buffer is then detached at
	 *  the end.
	 *
	 *  Note: heap_mark_and_sweep_base_flags are altered here to ensure
	 *  no-one touches this object while we're resizing and rehashing it.
	 *  The flags must be reset on every exit path after it.  Finalizers
	 *  and compaction is prevented currently for all objects while it
	 *  would be enough to restrict it only for the current object.
	 */

#ifdef DUK_USE_MARK_AND_SWEEP
	prev_mark_and_sweep_base_flags = thr->heap->mark_and_sweep_base_flags;
	thr->heap->mark_and_sweep_base_flags |=
	        DUK_MS_FLAG_NO_FINALIZERS |         /* avoid attempts to add/remove object keys */
	        DUK_MS_FLAG_NO_OBJECT_COMPACTION;   /* avoid attempt to compact the current object */
#endif

	new_alloc_size = DUK_HOBJECT_P_COMPUTE_SIZE(new_e_size_adjusted, new_a_size, new_h_size);
	DUK_DDD(DUK_DDDPRINT("new hobject allocation size is %ld", (long) new_alloc_size));
	if (new_alloc_size == 0) {
		/* for zero size, don't push anything on valstack */
		DUK_ASSERT(new_e_size_adjusted == 0);
		DUK_ASSERT(new_a_size == 0);
		DUK_ASSERT(new_h_size == 0);
		new_p = NULL;
	} else {
		/* This may trigger mark-and-sweep with arbitrary side effects,
		 * including an attempted resize of the object we're resizing,
		 * executing a finalizer which may add or remove properties of
		 * the object we're resizing etc.
		 */

		/* Note: buffer is dynamic so that we can 'steal' the actual
		 * allocation later.
		 */

		new_p = (duk_uint8_t *) duk_push_dynamic_buffer(ctx, new_alloc_size);  /* errors out if out of memory */
		DUK_ASSERT(new_p != NULL);  /* since new_alloc_size > 0 */
	}

	/* Set up pointers to the new property area: this is hidden behind a macro
	 * because it is memory layout specific.
	 */
	DUK_HOBJECT_P_SET_REALLOC_PTRS(new_p, new_e_k, new_e_pv, new_e_f, new_a, new_h,
	                               new_e_size_adjusted, new_a_size, new_h_size);
	DUK_UNREF(new_h);  /* happens when hash part dropped */
	new_e_next = 0;

	/* if new_p == NULL, all of these pointers are NULL */
	DUK_ASSERT((new_p != NULL) ||
	           (new_e_k == NULL && new_e_pv == NULL && new_e_f == NULL &&
	            new_a == NULL && new_h == NULL));

	DUK_DDD(DUK_DDDPRINT("new alloc size %ld, new_e_k=%p, new_e_pv=%p, new_e_f=%p, new_a=%p, new_h=%p",
	                     (long) new_alloc_size, (void *) new_e_k, (void *) new_e_pv, (void *) new_e_f,
	                     (void *) new_a, (void *) new_h));

	/*
	 *  Migrate array to start of entries if requested.
	 *
	 *  Note: from an enumeration perspective the order of entry keys matters.
	 *  Array keys should appear wherever they appeared before the array abandon
	 *  operation.
	 */

	if (abandon_array) {
		/*
		 *  Note: assuming new_a_size == 0, and that entry part contains
		 *  no conflicting keys, refcounts do not need to be adjusted for
		 *  the values, as they remain exactly the same.
		 *
		 *  The keys, however, need to be interned, incref'd, and be
		 *  reachable for GC.  Any intern attempt may trigger a GC and
		 *  claim any non-reachable strings, so every key must be reachable
		 *  at all times.
		 *
		 *  A longjmp must not occur here, as the new_p allocation would
		 *  be freed without these keys being decref'd, hence the messy
		 *  decref handling if intern fails.
		 */
		DUK_ASSERT(new_a_size == 0);

		for (i = 0; i < DUK_HOBJECT_GET_ASIZE(obj); i++) {
			duk_tval *tv1;
			duk_tval *tv2;
			duk_hstring *key;

			DUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL);

			tv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i);
			if (DUK_TVAL_IS_UNUSED(tv1)) {
				continue;
			}

			DUK_ASSERT(new_p != NULL && new_e_k != NULL &&
			           new_e_pv != NULL && new_e_f != NULL);

			/*
			 *  Intern key via the valstack to ensure reachability behaves
			 *  properly.  We must avoid longjmp's here so use non-checked
			 *  primitives.
			 *
			 *  Note: duk_check_stack() potentially reallocs the valstack,
			 *  invalidating any duk_tval pointers to valstack.  Callers
			 *  must be careful.
			 */

			/* never shrinks; auto-adds DUK_VALSTACK_INTERNAL_EXTRA, which is generous */
			if (!duk_check_stack(ctx, 1)) {
				goto abandon_error;
			}
			DUK_ASSERT_VALSTACK_SPACE(thr, 1);
			key = duk_heap_string_intern_u32(thr->heap, i);
			if (!key) {
				goto abandon_error;
			}
			duk_push_hstring(ctx, key);  /* keep key reachable for GC etc; guaranteed not to fail */

			/* key is now reachable in the valstack */

			DUK_HSTRING_INCREF(thr, key);   /* second incref for the entry reference */
			new_e_k[new_e_next] = key;
			tv2 = &new_e_pv[new_e_next].v;  /* array entries are all plain values */
			DUK_TVAL_SET_TVAL(tv2, tv1);
			new_e_f[new_e_next] = DUK_PROPDESC_FLAG_WRITABLE |
			                      DUK_PROPDESC_FLAG_ENUMERABLE |
			                      DUK_PROPDESC_FLAG_CONFIGURABLE;
			new_e_next++;

			/* Note: new_e_next matches pushed temp key count, and nothing can
			 * fail above between the push and this point.
			 */
		}

		DUK_DDD(DUK_DDDPRINT("abandon array: pop %ld key temps from valstack", (long) new_e_next));
		duk_pop_n(ctx, new_e_next);
	}

	/*
	 *  Copy keys and values in the entry part (compacting them at the same time).
	 */

	for (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {
		duk_hstring *key;

		DUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL);

		key = DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i);
		if (!key) {
			continue;
		}

		DUK_ASSERT(new_p != NULL && new_e_k != NULL &&
		           new_e_pv != NULL && new_e_f != NULL);

		new_e_k[new_e_next] = key;
		new_e_pv[new_e_next] = DUK_HOBJECT_E_GET_VALUE(thr->heap, obj, i);
		new_e_f[new_e_next] = DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, i);
		new_e_next++;
	}
	/* the entries [new_e_next, new_e_size_adjusted[ are left uninitialized on purpose (ok, not gc reachable) */

	/*
	 *  Copy array elements to new array part.
	 */

	if (new_a_size > DUK_HOBJECT_GET_ASIZE(obj)) {
		/* copy existing entries as is */
		DUK_ASSERT(new_p != NULL && new_a != NULL);
		if (DUK_HOBJECT_GET_ASIZE(obj) > 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(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL);
			DUK_ASSERT(DUK_HOBJECT_GET_ASIZE(obj) > 0);
			DUK_MEMCPY((void *) new_a, (void *) DUK_HOBJECT_A_GET_BASE(thr->heap, obj), sizeof(duk_tval) * DUK_HOBJECT_GET_ASIZE(obj));
		}

		/* fill new entries with -unused- (required, gc reachable) */
		for (i = DUK_HOBJECT_GET_ASIZE(obj); i < new_a_size; i++) {
			duk_tval *tv = &new_a[i];
			DUK_TVAL_SET_UNUSED(tv);
		}
	} else {
#ifdef DUK_USE_ASSERTIONS
		/* caller must have decref'd values above new_a_size (if that is necessary) */
		if (!abandon_array) {
			for (i = new_a_size; i < DUK_HOBJECT_GET_ASIZE(obj); i++) {
				duk_tval *tv;
				tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i);

				/* current assertion is quite strong: decref's and set to unused */
				DUK_ASSERT(DUK_TVAL_IS_UNUSED(tv));
			}
		}
#endif
		if (new_a_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(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL);
			DUK_ASSERT(new_a_size > 0);
			DUK_MEMCPY((void *) new_a, (void *) DUK_HOBJECT_A_GET_BASE(thr->heap, obj), sizeof(duk_tval) * new_a_size);
		}
	}

	/*
	 *  Rebuild the hash part always from scratch (guaranteed to finish).
	 *
	 *  Any resize of hash part requires rehashing.  In addition, by rehashing
	 *  get rid of any elements marked deleted (DUK__HASH_DELETED) which is critical
	 *  to ensuring the hash part never fills up.
	 */

#if defined(DUK_USE_HOBJECT_HASH_PART)
	if (DUK_UNLIKELY(new_h_size > 0)) {
		DUK_ASSERT(new_h != NULL);

		/* fill new_h with u32 0xff = UNUSED */
		DUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL);
		DUK_ASSERT(new_h_size > 0);
		DUK_MEMSET(new_h, 0xff, sizeof(duk_uint32_t) * new_h_size);

		DUK_ASSERT(new_e_next <= new_h_size);  /* equality not actually possible */
		for (i = 0; i < new_e_next; i++) {
			duk_hstring *key = new_e_k[i];
			duk_uint32_t j, step;

			DUK_ASSERT(key != NULL);
			j = DUK__HASH_INITIAL(DUK_HSTRING_GET_HASH(key), new_h_size);
			step = DUK__HASH_PROBE_STEP(DUK_HSTRING_GET_HASH(key));

			for (;;) {
				DUK_ASSERT(new_h[j] != DUK__HASH_DELETED);  /* should never happen */
				if (new_h[j] == DUK__HASH_UNUSED) {
					DUK_DDD(DUK_DDDPRINT("rebuild hit %ld -> %ld", (long) j, (long) i));
					new_h[j] = i;
					break;
				}
				DUK_DDD(DUK_DDDPRINT("rebuild miss %ld, step %ld", (long) j, (long) step));
				j = (j + step) % new_h_size;

				/* guaranteed to finish */
				DUK_ASSERT(j != (duk_uint32_t) DUK__HASH_INITIAL(DUK_HSTRING_GET_HASH(key), new_h_size));
			}
		}
	} else {
		DUK_DDD(DUK_DDDPRINT("no hash part, no rehash"));
	}
#endif  /* DUK_USE_HOBJECT_HASH_PART */

	/*
	 *  Nice debug log.
	 */

	DUK_DD(DUK_DDPRINT("resized hobject %p props (%ld -> %ld bytes), from {p=%p,e_size=%ld,e_next=%ld,a_size=%ld,h_size=%ld} to "
	                   "{p=%p,e_size=%ld,e_next=%ld,a_size=%ld,h_size=%ld}, abandon_array=%ld, unadjusted new_e_size=%ld",
	                   (void *) obj,
	                   (long) DUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE(obj),
	                                                     DUK_HOBJECT_GET_ASIZE(obj),
	                                                     DUK_HOBJECT_GET_HSIZE(obj)),
	                   (long) new_alloc_size,
	                   (void *) DUK_HOBJECT_GET_PROPS(thr->heap, obj),
	                   (long) DUK_HOBJECT_GET_ESIZE(obj),
	                   (long) DUK_HOBJECT_GET_ENEXT(obj),
	                   (long) DUK_HOBJECT_GET_ASIZE(obj),
	                   (long) DUK_HOBJECT_GET_HSIZE(obj),
	                   (void *) new_p,
	                   (long) new_e_size_adjusted,
	                   (long) new_e_next,
	                   (long) new_a_size,
	                   (long) new_h_size,
	                   (long) abandon_array,
	                   (long) new_e_size));

	/*
	 *  All done, switch properties ('p') allocation to new one.
	 */

	DUK_FREE(thr->heap, DUK_HOBJECT_GET_PROPS(thr->heap, obj));  /* NULL obj->p is OK */
	DUK_HOBJECT_SET_PROPS(thr->heap, obj, new_p);
	DUK_HOBJECT_SET_ESIZE(obj, new_e_size_adjusted);
	DUK_HOBJECT_SET_ENEXT(obj, new_e_next);
	DUK_HOBJECT_SET_ASIZE(obj, new_a_size);
	DUK_HOBJECT_SET_HSIZE(obj, new_h_size);

	if (new_p) {
		/*
		 *  Detach actual buffer from dynamic buffer in valstack, and
		 *  pop it from the stack.
		 *
		 *  XXX: the buffer object is certainly not reachable at this point,
		 *  so it would be nice to free it forcibly even with only
		 *  mark-and-sweep enabled.  Not a big issue though.
		 */
		(void) duk_steal_buffer(ctx, -1, NULL);
		duk_pop(ctx);
	} else {
		DUK_ASSERT(new_alloc_size == 0);
		/* no need to pop, nothing was pushed */
	}

	/* clear array part flag only after switching */
	if (abandon_array) {
		DUK_HOBJECT_CLEAR_ARRAY_PART(obj);
	}

	DUK_DDD(DUK_DDDPRINT("resize result: %!O", (duk_heaphdr *) obj));

#ifdef DUK_USE_MARK_AND_SWEEP
	thr->heap->mark_and_sweep_base_flags = prev_mark_and_sweep_base_flags;
#endif

	/*
	 *  Post resize assertions.
	 */

#ifdef DUK_USE_ASSERTIONS
	/* XXX: post-checks (such as no duplicate keys) */
#endif
	return;

	/*
	 *  Abandon array failed, need to decref keys already inserted
	 *  into the beginning of new_e_k before unwinding valstack.
	 */

 abandon_error:
	DUK_D(DUK_DPRINT("hobject resize failed during abandon array, decref keys"));
	i = new_e_next;
	while (i > 0) {
		i--;
		DUK_ASSERT(new_e_k != NULL);
		DUK_ASSERT(new_e_k[i] != NULL);
		DUK_HSTRING_DECREF(thr, new_e_k[i]);  /* side effects */
	}

#ifdef DUK_USE_MARK_AND_SWEEP
	thr->heap->mark_and_sweep_base_flags = prev_mark_and_sweep_base_flags;
#endif

	DUK_ERROR_ALLOC_DEFMSG(thr);
}

/*
 *  Helpers to resize properties allocation on specific needs.
 */

/* Grow entry part allocation for one additional entry. */
DUK_LOCAL void duk__grow_props_for_new_entry_item(duk_hthread *thr, duk_hobject *obj) {
	duk_uint32_t old_e_used;  /* actually used, non-NULL entries */
	duk_uint32_t new_e_size;
	duk_uint32_t new_a_size;
	duk_uint32_t new_h_size;

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

	/* Duktape 0.11.0 and prior tried to optimize the resize by not
	 * counting the number of actually used keys prior to the resize.
	 * This worked mostly well but also caused weird leak-like behavior
	 * as in: test-bug-object-prop-alloc-unbounded.js.  So, now we count
	 * the keys explicitly to compute the new entry part size.
	 */

	old_e_used = duk__count_used_e_keys(thr, obj);
	new_e_size = old_e_used + duk__get_min_grow_e(old_e_used);
#if defined(DUK_USE_HOBJECT_HASH_PART)
	new_h_size = duk__get_default_h_size(new_e_size);
#else
	new_h_size = 0;
#endif
	new_a_size = DUK_HOBJECT_GET_ASIZE(obj);
	DUK_ASSERT(new_e_size >= old_e_used + 1);  /* duk__get_min_grow_e() is always >= 1 */

	duk__realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 0);
}

/* Grow array part for a new highest array index. */
DUK_LOCAL void duk__grow_props_for_array_item(duk_hthread *thr, duk_hobject *obj, duk_uint32_t highest_arr_idx) {
	duk_uint32_t new_e_size;
	duk_uint32_t new_a_size;
	duk_uint32_t new_h_size;

	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(obj != NULL);
	DUK_ASSERT(highest_arr_idx >= DUK_HOBJECT_GET_ASIZE(obj));

	/* minimum new length is highest_arr_idx + 1 */

	new_e_size = DUK_HOBJECT_GET_ESIZE(obj);
	new_h_size = DUK_HOBJECT_GET_HSIZE(obj);
	new_a_size = highest_arr_idx + duk__get_min_grow_a(highest_arr_idx);
	DUK_ASSERT(new_a_size >= highest_arr_idx + 1);  /* duk__get_min_grow_a() is always >= 1 */

	duk__realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 0);
}

/* Abandon array part, moving array entries into entries part.
 * This requires a props resize, which is a heavy operation.
 * We also compact the entries part while we're at it, although
 * this is not strictly required.
 */
DUK_LOCAL void duk__abandon_array_checked(duk_hthread *thr, duk_hobject *obj) {
	duk_uint32_t new_e_size;
	duk_uint32_t new_a_size;
	duk_uint32_t new_h_size;
	duk_uint32_t e_used;  /* actually used, non-NULL keys */
	duk_uint32_t a_used;
	duk_uint32_t a_size;

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

	e_used = duk__count_used_e_keys(thr, obj);
	duk__compute_a_stats(thr, obj, &a_used, &a_size);

	/*
	 *  Must guarantee all actually used array entries will fit into
	 *  new entry part.  Add one growth step to ensure we don't run out
	 *  of space right away.
	 */

	new_e_size = e_used + a_used;
	new_e_size = new_e_size + duk__get_min_grow_e(new_e_size);
	new_a_size = 0;
#if defined(DUK_USE_HOBJECT_HASH_PART)
	new_h_size = duk__get_default_h_size(new_e_size);
#else
	new_h_size = 0;
#endif

	DUK_DD(DUK_DDPRINT("abandon array part for hobject %p, "
	                   "array stats before: e_used=%ld, a_used=%ld, a_size=%ld; "
	                   "resize to e_size=%ld, a_size=%ld, h_size=%ld",
	                   (void *) obj, (long) e_used, (long) a_used, (long) a_size,
	                   (long) new_e_size, (long) new_a_size, (long) new_h_size));

	duk__realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 1);
}

/*
 *  Compact an object.  Minimizes allocation size for objects which are
 *  not likely to be extended.  This is useful for internal and non-
 *  extensible objects, but can also be called for non-extensible objects.
 *  May abandon the array part if it is computed to be too sparse.
 *
 *  This call is relatively expensive, as it needs to scan both the
 *  entries and the array part.
 *
 *  The call may fail due to allocation error.
 */

DUK_INTERNAL void duk_hobject_compact_props(duk_hthread *thr, duk_hobject *obj) {
	duk_uint32_t e_size;       /* currently used -> new size */
	duk_uint32_t a_size;       /* currently required */
	duk_uint32_t a_used;       /* actually used */
	duk_uint32_t h_size;
	duk_bool_t abandon_array;

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

#if defined(DUK_USE_ROM_OBJECTS)
	if (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {
		DUK_DD(DUK_DDPRINT("ignore attempt to compact a rom object"));
		return;
	}
#endif

	e_size = duk__count_used_e_keys(thr, obj);
	duk__compute_a_stats(thr, obj, &a_used, &a_size);

	DUK_DD(DUK_DDPRINT("compacting hobject, used e keys %ld, used a keys %ld, min a size %ld, "
	                   "resized array density would be: %ld/%ld = %lf",
	                   (long) e_size, (long) a_used, (long) a_size,
	                   (long) a_used, (long) a_size,
	                   (double) a_used / (double) a_size));

	if (duk__abandon_array_density_check(a_used, a_size)) {
		DUK_DD(DUK_DDPRINT("decided to abandon array during compaction, a_used=%ld, a_size=%ld",
		                   (long) a_used, (long) a_size));
		abandon_array = 1;
		e_size += a_used;
		a_size = 0;
	} else {
		DUK_DD(DUK_DDPRINT("decided to keep array during compaction"));
		abandon_array = 0;
	}

#if defined(DUK_USE_HOBJECT_HASH_PART)
	if (e_size >= DUK_HOBJECT_E_USE_HASH_LIMIT) {
		h_size = duk__get_default_h_size(e_size);
	} else {
		h_size = 0;
	}
#else
	h_size = 0;
#endif

	DUK_DD(DUK_DDPRINT("compacting hobject -> new e_size %ld, new a_size=%ld, new h_size=%ld, abandon_array=%ld",
	                   (long) e_size, (long) a_size, (long) h_size, (long) abandon_array));

	duk__realloc_props(thr, obj, e_size, a_size, h_size, abandon_array);
}

/*
 *  Find an existing key from entry part either by linear scan or by
 *  using the hash index (if it exists).
 *
 *  Sets entry index (and possibly the hash index) to output variables,
 *  which allows the caller to update the entry and hash entries in-place.
 *  If entry is not found, both values are set to -1.  If entry is found
 *  but there is no hash part, h_idx is set to -1.
 */

DUK_INTERNAL void duk_hobject_find_existing_entry(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *e_idx, duk_int_t *h_idx) {
	DUK_ASSERT(obj != NULL);
	DUK_ASSERT(key != NULL);
	DUK_ASSERT(e_idx != NULL);
	DUK_ASSERT(h_idx != NULL);
	DUK_UNREF(heap);

	if (DUK_LIKELY(DUK_HOBJECT_GET_HSIZE(obj) == 0))
	{
		/* Linear scan: more likely because most objects are small.
		 * This is an important fast path.
		 *
		 * XXX: this might be worth inlining for property lookups.
		 */
		duk_uint_fast32_t i;
		duk_uint_fast32_t n;
		duk_hstring **h_keys_base;
		DUK_DDD(DUK_DDDPRINT("duk_hobject_find_existing_entry() using linear scan for lookup"));

		h_keys_base = DUK_HOBJECT_E_GET_KEY_BASE(heap, obj);
		n = DUK_HOBJECT_GET_ENEXT(obj);
		for (i = 0; i < n; i++) {
			if (h_keys_base[i] == key) {
				*e_idx = i;
				*h_idx = -1;
				return;
			}
		}
	}
#if defined(DUK_USE_HOBJECT_HASH_PART)
	else
	{
		/* hash lookup */
		duk_uint32_t n;
		duk_uint32_t i, step;
		duk_uint32_t *h_base;

		DUK_DDD(DUK_DDDPRINT("duk_hobject_find_existing_entry() using hash part for lookup"));

		h_base = DUK_HOBJECT_H_GET_BASE(heap, obj);
		n = DUK_HOBJECT_GET_HSIZE(obj);
		i = DUK__HASH_INITIAL(DUK_HSTRING_GET_HASH(key), n);
		step = DUK__HASH_PROBE_STEP(DUK_HSTRING_GET_HASH(key));

		for (;;) {
			duk_uint32_t t;

			DUK_ASSERT_DISABLE(i >= 0);  /* unsigned */
			DUK_ASSERT(i < DUK_HOBJECT_GET_HSIZE(obj));
			t = h_base[i];
			DUK_ASSERT(t == DUK__HASH_UNUSED || t == DUK__HASH_DELETED ||
			           (t < DUK_HOBJECT_GET_ESIZE(obj)));  /* t >= 0 always true, unsigned */

			if (t == DUK__HASH_UNUSED) {
				break;
			} else if (t == DUK__HASH_DELETED) {
				DUK_DDD(DUK_DDDPRINT("lookup miss (deleted) i=%ld, t=%ld",
				                     (long) i, (long) t));
			} else {
				DUK_ASSERT(t < DUK_HOBJECT_GET_ESIZE(obj));
				if (DUK_HOBJECT_E_GET_KEY(heap, obj, t) == key) {
					DUK_DDD(DUK_DDDPRINT("lookup hit i=%ld, t=%ld -> key %p",
					                     (long) i, (long) t, (void *) key));
					*e_idx = t;
					*h_idx = i;
					return;
				}
				DUK_DDD(DUK_DDDPRINT("lookup miss i=%ld, t=%ld",
				                     (long) i, (long) t));
			}
			i = (i + step) % n;

			/* guaranteed to finish, as hash is never full */
			DUK_ASSERT(i != (duk_uint32_t) DUK__HASH_INITIAL(DUK_HSTRING_GET_HASH(key), n));
		}
	}
#endif  /* DUK_USE_HOBJECT_HASH_PART */

	/* not found */
	*e_idx = -1;
	*h_idx = -1;
}

/* For internal use: get non-accessor entry value */
DUK_INTERNAL duk_tval *duk_hobject_find_existing_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_hstring *key) {
	duk_int_t e_idx;
	duk_int_t h_idx;

	DUK_ASSERT(obj != NULL);
	DUK_ASSERT(key != NULL);
	DUK_UNREF(heap);

	duk_hobject_find_existing_entry(heap, obj, key, &e_idx, &h_idx);
	if (e_idx >= 0 && !DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, obj, e_idx)) {
		return DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, obj, e_idx);
	} else {
		return NULL;
	}
}

/* For internal use: get non-accessor entry value and attributes */
DUK_INTERNAL duk_tval *duk_hobject_find_existing_entry_tval_ptr_and_attrs(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *out_attrs) {
	duk_int_t e_idx;
	duk_int_t h_idx;

	DUK_ASSERT(obj != NULL);
	DUK_ASSERT(key != NULL);
	DUK_ASSERT(out_attrs != NULL);
	DUK_UNREF(heap);

	duk_hobject_find_existing_entry(heap, obj, key, &e_idx, &h_idx);
	if (e_idx >= 0 && !DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, obj, e_idx)) {
		*out_attrs = DUK_HOBJECT_E_GET_FLAGS(heap, obj, e_idx);
		return DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, obj, e_idx);
	} else {
		*out_attrs = 0;
		return NULL;
	}
}

/* For internal use: get array part value */
DUK_INTERNAL duk_tval *duk_hobject_find_existing_array_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_uarridx_t i) {
	duk_tval *tv;

	DUK_ASSERT(obj != NULL);
	DUK_UNREF(heap);

	if (!DUK_HOBJECT_HAS_ARRAY_PART(obj)) {
		return NULL;
	}
	if (i >= DUK_HOBJECT_GET_ASIZE(obj)) {
		return NULL;
	}
	tv = DUK_HOBJECT_A_GET_VALUE_PTR(heap, obj, i);
	return tv;
}

/*
 *  Allocate and initialize a new entry, resizing the properties allocation
 *  if necessary.  Returns entry index (e_idx) or throws an error if alloc fails.
 *
 *  Sets the key of the entry (increasing the key's refcount), and updates
 *  the hash part if it exists.  Caller must set value and flags, and update
 *  the entry value refcount.  A decref for the previous value is not necessary.
 */

DUK_LOCAL duk_bool_t duk__alloc_entry_checked(duk_hthread *thr, duk_hobject *obj, duk_hstring *key) {
	duk_uint32_t idx;

	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(obj != NULL);
	DUK_ASSERT(key != NULL);
	DUK_ASSERT(DUK_HOBJECT_GET_ENEXT(obj) <= DUK_HOBJECT_GET_ESIZE(obj));

#ifdef DUK_USE_ASSERTIONS
	/* key must not already exist in entry part */
	{
		duk_uint_fast32_t i;
		for (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {
			DUK_ASSERT(DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i) != key);
		}
	}
#endif

	if (DUK_HOBJECT_GET_ENEXT(obj) >= DUK_HOBJECT_GET_ESIZE(obj)) {
		/* only need to guarantee 1 more slot, but allocation growth is in chunks */
		DUK_DDD(DUK_DDDPRINT("entry part full, allocate space for one more entry"));
		duk__grow_props_for_new_entry_item(thr, obj);
	}
	DUK_ASSERT(DUK_HOBJECT_GET_ENEXT(obj) < DUK_HOBJECT_GET_ESIZE(obj));
	idx = DUK_HOBJECT_POSTINC_ENEXT(obj);

	/* previous value is assumed to be garbage, so don't touch it */
	DUK_HOBJECT_E_SET_KEY(thr->heap, obj, idx, key);
	DUK_HSTRING_INCREF(thr, key);

#if defined(DUK_USE_HOBJECT_HASH_PART)
	if (DUK_UNLIKELY(DUK_HOBJECT_GET_HSIZE(obj) > 0)) {
		duk_uint32_t n;
		duk_uint32_t i, step;
		duk_uint32_t *h_base = DUK_HOBJECT_H_GET_BASE(thr->heap, obj);

		n = DUK_HOBJECT_GET_HSIZE(obj);
		i = DUK__HASH_INITIAL(DUK_HSTRING_GET_HASH(key), n);
		step = DUK__HASH_PROBE_STEP(DUK_HSTRING_GET_HASH(key));

		for (;;) {
			duk_uint32_t t = h_base[i];
			if (t == DUK__HASH_UNUSED || t == DUK__HASH_DELETED) {
				DUK_DDD(DUK_DDDPRINT("duk__alloc_entry_checked() inserted key into hash part, %ld -> %ld",
				                     (long) i, (long) idx));
				DUK_ASSERT_DISABLE(i >= 0);  /* unsigned */
				DUK_ASSERT(i < DUK_HOBJECT_GET_HSIZE(obj));
				DUK_ASSERT_DISABLE(idx >= 0);
				DUK_ASSERT(idx < DUK_HOBJECT_GET_ESIZE(obj));
				h_base[i] = idx;
				break;
			}
			DUK_DDD(DUK_DDDPRINT("duk__alloc_entry_checked() miss %ld", (long) i));
			i = (i + step) % n;

			/* guaranteed to find an empty slot */
			DUK_ASSERT(i != (duk_uint32_t) DUK__HASH_INITIAL(DUK_HSTRING_GET_HASH(key), DUK_HOBJECT_GET_HSIZE(obj)));
		}
	}
#endif  /* DUK_USE_HOBJECT_HASH_PART */

	/* Note: we could return the hash index here too, but it's not
	 * needed right now.
	 */

	DUK_ASSERT_DISABLE(idx >= 0);
	DUK_ASSERT(idx < DUK_HOBJECT_GET_ESIZE(obj));
	DUK_ASSERT(idx < DUK_HOBJECT_GET_ENEXT(obj));
	return idx;
}

/*
 *  Object internal value
 *
 *  Returned value is guaranteed to be reachable / incref'd, caller does not need
 *  to incref OR decref.  No proxies or accessors are invoked, no prototype walk.
 */

DUK_INTERNAL duk_bool_t duk_hobject_get_internal_value(duk_heap *heap, duk_hobject *obj, duk_tval *tv_out) {
	duk_int_t e_idx;
	duk_int_t h_idx;

	DUK_ASSERT(heap != NULL);
	DUK_ASSERT(obj != NULL);
	DUK_ASSERT(tv_out != NULL);

	/* always in entry part, no need to look up parents etc */
	duk_hobject_find_existing_entry(heap, obj, DUK_HEAP_STRING_INT_VALUE(heap), &e_idx, &h_idx);
	if (e_idx >= 0) {
		DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, obj, e_idx));
		DUK_TVAL_SET_TVAL(tv_out, DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, obj, e_idx));
		return 1;
	}
	DUK_TVAL_SET_UNDEFINED(tv_out);
	return 0;
}

DUK_INTERNAL duk_hstring *duk_hobject_get_internal_value_string(duk_heap *heap, duk_hobject *obj) {
	duk_tval tv;

	DUK_ASSERT(heap != NULL);
	DUK_ASSERT(obj != NULL);

	/* 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));

	if (duk_hobject_get_internal_value(heap, obj, &tv)) {
		duk_hstring *h;
		DUK_ASSERT(DUK_TVAL_IS_STRING(&tv));
		h = DUK_TVAL_GET_STRING(&tv);
		return h;
	}

	return NULL;
}

/*
 *  Arguments handling helpers (argument map mainly).
 *
 *  An arguments object has exotic behavior for some numeric indices.
 *  Accesses may translate to identifier operations which may have
 *  arbitrary side effects (potentially invalidating any duk_tval
 *  pointers).
 */

/* Lookup 'key' from arguments internal 'map', perform a variable lookup
 * if mapped, and leave the result on top of stack (and return non-zero).
 * Used in E5 Section 10.6 algorithms [[Get]] and [[GetOwnProperty]].
 */
DUK_LOCAL
duk_bool_t duk__lookup_arguments_map(duk_hthread *thr,
                                     duk_hobject *obj,
                                     duk_hstring *key,
                                     duk_propdesc *temp_desc,
                                     duk_hobject **out_map,
                                     duk_hobject **out_varenv) {
	duk_context *ctx = (duk_context *) thr;
	duk_hobject *map;
	duk_hobject *varenv;
	duk_bool_t rc;

	DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);

	DUK_DDD(DUK_DDDPRINT("arguments map lookup: thr=%p, obj=%p, key=%p, temp_desc=%p "
	                     "(obj -> %!O, key -> %!O)",
	                     (void *) thr, (void *) obj, (void *) key, (void *) temp_desc,
	                     (duk_heaphdr *) obj, (duk_heaphdr *) key));

	if (!duk_hobject_get_own_propdesc(thr, obj, DUK_HTHREAD_STRING_INT_MAP(thr), temp_desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {
		DUK_DDD(DUK_DDDPRINT("-> no 'map'"));
		return 0;
	}

	map = duk_require_hobject(ctx, -1);
	DUK_ASSERT(map != NULL);
	duk_pop(ctx);  /* map is reachable through obj */

	if (!duk_hobject_get_own_propdesc(thr, map, key, temp_desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {
		DUK_DDD(DUK_DDDPRINT("-> 'map' exists, but key not in map"));
		return 0;
	}

	/* [... varname] */
	DUK_DDD(DUK_DDDPRINT("-> 'map' exists, and contains key, key is mapped to argument/variable binding %!T",
	                     (duk_tval *) duk_get_tval(ctx, -1)));
	DUK_ASSERT(duk_is_string(ctx, -1));  /* guaranteed when building arguments */

	/* get varenv for varname (callee's declarative lexical environment) */
	rc = duk_hobject_get_own_propdesc(thr, obj, DUK_HTHREAD_STRING_INT_VARENV(thr), temp_desc, DUK_GETDESC_FLAG_PUSH_VALUE);
	DUK_UNREF(rc);
	DUK_ASSERT(rc != 0);  /* arguments MUST have an initialized lexical environment reference */
	varenv = duk_require_hobject(ctx, -1);
	DUK_ASSERT(varenv != NULL);
	duk_pop(ctx);  /* varenv remains reachable through 'obj' */

	DUK_DDD(DUK_DDDPRINT("arguments varenv is: %!dO", (duk_heaphdr *) varenv));

	/* success: leave varname in stack */
	*out_map = map;
	*out_varenv = varenv;
	return 1;  /* [... varname] */
}

/* Lookup 'key' from arguments internal 'map', and leave replacement value
 * on stack top if mapped (and return non-zero).
 * Used in E5 Section 10.6 algorithm for [[GetOwnProperty]] (used by [[Get]]).
 */
DUK_LOCAL duk_bool_t duk__check_arguments_map_for_get(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc) {
	duk_context *ctx = (duk_context *) thr;
	duk_hobject *map;
	duk_hobject *varenv;
	duk_hstring *varname;

	DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);

	if (!duk__lookup_arguments_map(thr, obj, key, temp_desc, &map, &varenv)) {
		DUK_DDD(DUK_DDDPRINT("arguments: key not mapped, no exotic get behavior"));
		return 0;
	}

	/* [... varname] */

	varname = duk_require_hstring(ctx, -1);
	DUK_ASSERT(varname != NULL);
	duk_pop(ctx);  /* varname is still reachable */

	DUK_DDD(DUK_DDDPRINT("arguments object automatic getvar for a bound variable; "
	                     "key=%!O, varname=%!O",
	                     (duk_heaphdr *) key,
	                     (duk_heaphdr *) varname));

	(void) duk_js_getvar_envrec(thr, varenv, varname, 1 /*throw*/);

	/* [... value this_binding] */

	duk_pop(ctx);

	/* leave result on stack top */
	return 1;
}

/* Lookup 'key' from arguments internal 'map', perform a variable write if mapped.
 * Used in E5 Section 10.6 algorithm for [[DefineOwnProperty]] (used by [[Put]]).
 * Assumes stack top contains 'put' value (which is NOT popped).
 */
DUK_LOCAL void duk__check_arguments_map_for_put(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc, duk_bool_t throw_flag) {
	duk_context *ctx = (duk_context *) thr;
	duk_hobject *map;
	duk_hobject *varenv;
	duk_hstring *varname;

	DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);

	if (!duk__lookup_arguments_map(thr, obj, key, temp_desc, &map, &varenv)) {
		DUK_DDD(DUK_DDDPRINT("arguments: key not mapped, no exotic put behavior"));
		return;
	}

	/* [... put_value varname] */

	varname = duk_require_hstring(ctx, -1);
	DUK_ASSERT(varname != NULL);
	duk_pop(ctx);  /* varname is still reachable */

	DUK_DDD(DUK_DDDPRINT("arguments object automatic putvar for a bound variable; "
	                     "key=%!O, varname=%!O, value=%!T",
	                     (duk_heaphdr *) key,
	                     (duk_heaphdr *) varname,
	                     (duk_tval *) duk_require_tval(ctx, -1)));

	/* [... put_value] */

	/*
	 *  Note: although arguments object variable mappings are only established
	 *  for non-strict functions (and a call to a non-strict function created
	 *  the arguments object in question), an inner strict function may be doing
	 *  the actual property write.  Hence the throw_flag applied here comes from
	 *  the property write call.
	 */

	duk_js_putvar_envrec(thr, varenv, varname, duk_require_tval(ctx, -1), throw_flag);

	/* [... put_value] */
}

/* Lookup 'key' from arguments internal 'map', delete mapping if found.
 * Used in E5 Section 10.6 algorithm for [[Delete]].  Note that the
 * variable/argument itself (where the map points) is not deleted.
 */
DUK_LOCAL void duk__check_arguments_map_for_delete(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc) {
	duk_context *ctx = (duk_context *) thr;
	duk_hobject *map;

	DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);

	if (!duk_hobject_get_own_propdesc(thr, obj, DUK_HTHREAD_STRING_INT_MAP(thr), temp_desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {
		DUK_DDD(DUK_DDDPRINT("arguments: key not mapped, no exotic delete behavior"));
		return;
	}

	map = duk_require_hobject(ctx, -1);
	DUK_ASSERT(map != NULL);
	duk_pop(ctx);  /* map is reachable through obj */

	DUK_DDD(DUK_DDDPRINT("-> have 'map', delete key %!O from map (if exists)); ignore result",
	                     (duk_heaphdr *) key));

	/* Note: no recursion issue, we can trust 'map' to behave */
	DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_BEHAVIOR(map));
	DUK_DDD(DUK_DDDPRINT("map before deletion: %!O", (duk_heaphdr *) map));
	(void) duk_hobject_delprop_raw(thr, map, key, 0);  /* ignore result */
	DUK_DDD(DUK_DDDPRINT("map after deletion: %!O", (duk_heaphdr *) map));
}

/*
 *  Ecmascript compliant [[GetOwnProperty]](P), for internal use only.
 *
 *  If property is found:
 *    - Fills descriptor fields to 'out_desc'
 *    - If DUK_GETDESC_FLAG_PUSH_VALUE is set, pushes a value related to the
 *      property onto the stack ('undefined' for accessor properties).
 *    - Returns non-zero
 *
 *  If property is not found:
 *    - 'out_desc' is left in untouched state (possibly garbage)
 *    - Nothing is pushed onto the stack (not even with DUK_GETDESC_FLAG_PUSH_VALUE
 *      set)
 *    - Returns zero
 *
 *  Notes:
 *
 *    - Getting a property descriptor may cause an allocation (and hence
 *      GC) to take place, hence reachability and refcount of all related
 *      values matter.  Reallocation of value stack, properties, etc may
 *      invalidate many duk_tval pointers (concretely, those which reside
 *      in memory areas subject to reallocation).  However, heap object
 *      pointers are never affected (heap objects have stable pointers).
 *
 *    - The value of a plain property is always reachable and has a non-zero
 *      reference count.
 *
 *    - The value of a virtual property is not necessarily reachable from
 *      elsewhere and may have a refcount of zero.  Hence we push it onto
 *      the valstack for the caller, which ensures it remains reachable
 *      while it is needed.
 *
 *    - There are no virtual accessor properties.  Hence, all getters and
 *      setters are always related to concretely stored properties, which
 *      ensures that the get/set functions in the resulting descriptor are
 *      reachable and have non-zero refcounts.  Should there be virtual
 *      accessor properties later, this would need to change.
 */

DUK_LOCAL duk_bool_t duk__get_own_propdesc_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_uint32_t arr_idx, duk_propdesc *out_desc, duk_small_uint_t flags) {
	duk_context *ctx = (duk_context *) thr;
	duk_tval *tv;

	DUK_DDD(DUK_DDDPRINT("duk_hobject_get_own_propdesc: thr=%p, obj=%p, key=%p, out_desc=%p, flags=%lx, "
	                     "arr_idx=%ld (obj -> %!O, key -> %!O)",
	                     (void *) thr, (void *) obj, (void *) key, (void *) out_desc,
	                     (long) flags, (long) arr_idx,
	                     (duk_heaphdr *) obj, (duk_heaphdr *) key));

	DUK_ASSERT(ctx != NULL);
	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(thr->heap != NULL);
	DUK_ASSERT(obj != NULL);
	DUK_ASSERT(key != NULL);
	DUK_ASSERT(out_desc != NULL);
	DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);

	/* XXX: optimize this filling behavior later */
	out_desc->flags = 0;
	out_desc->get = NULL;
	out_desc->set = NULL;
	out_desc->e_idx = -1;
	out_desc->h_idx = -1;
	out_desc->a_idx = -1;

	/*
	 *  Array part
	 */

	if (DUK_HOBJECT_HAS_ARRAY_PART(obj) && arr_idx != DUK__NO_ARRAY_INDEX) {
		if (arr_idx < DUK_HOBJECT_GET_ASIZE(obj)) {
			tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);
			if (!DUK_TVAL_IS_UNUSED(tv)) {
				DUK_DDD(DUK_DDDPRINT("-> found in array part"));
				if (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {
					duk_push_tval(ctx, tv);
				}
				/* implicit attributes */
				out_desc->flags = DUK_PROPDESC_FLAG_WRITABLE |
				                  DUK_PROPDESC_FLAG_CONFIGURABLE |
				                  DUK_PROPDESC_FLAG_ENUMERABLE;
				out_desc->a_idx = arr_idx;
				goto prop_found;
			}
		}
		/* assume array part is comprehensive (contains all array indexed elements
		 * or none of them); hence no need to check the entries part here.
		 */
		DUK_DDD(DUK_DDDPRINT("-> not found as a concrete property (has array part, "
		                     "should be there if present)"));
		goto prop_not_found_concrete;
	}

	/*
	 *  Entries part
	 */

	duk_hobject_find_existing_entry(thr->heap, obj, key, &out_desc->e_idx, &out_desc->h_idx);
	if (out_desc->e_idx >= 0) {
		duk_int_t e_idx = out_desc->e_idx;
		out_desc->flags = DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, e_idx);
		if (out_desc->flags & DUK_PROPDESC_FLAG_ACCESSOR) {
			DUK_DDD(DUK_DDDPRINT("-> found accessor property in entry part"));
			out_desc->get = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, e_idx);
			out_desc->set = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, e_idx);
			if (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {
				/* a dummy undefined value is pushed to make valstack
				 * behavior uniform for caller
				 */
				duk_push_undefined(ctx);
			}
		} else {
			DUK_DDD(DUK_DDDPRINT("-> found plain property in entry part"));
			tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, e_idx);
			if (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {
				duk_push_tval(ctx, tv);
			}
		}
		goto prop_found;
	}

	/*
	 *  Not found as a concrete property, check whether a String object
	 *  virtual property matches.
	 */

 prop_not_found_concrete:

	if (DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(obj)) {
		DUK_DDD(DUK_DDDPRINT("string object exotic property get for key: %!O, arr_idx: %ld",
		                     (duk_heaphdr *) key, (long) arr_idx));

		if (arr_idx != DUK__NO_ARRAY_INDEX) {
			duk_hstring *h_val;

			DUK_DDD(DUK_DDDPRINT("array index exists"));

			h_val = duk_hobject_get_internal_value_string(thr->heap, obj);
			DUK_ASSERT(h_val);
			if (arr_idx < DUK_HSTRING_GET_CHARLEN(h_val)) {
				DUK_DDD(DUK_DDDPRINT("-> found, array index inside string"));
				if (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {
					duk_push_hstring(ctx, h_val);
					duk_substring(ctx, -1, arr_idx, arr_idx + 1);  /* [str] -> [substr] */
				}
				out_desc->flags = DUK_PROPDESC_FLAG_ENUMERABLE |  /* E5 Section 15.5.5.2 */
				                  DUK_PROPDESC_FLAG_VIRTUAL;

				DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));
				return 1;  /* cannot be e.g. arguments exotic, since exotic 'traits' are mutually exclusive */
			} else {
				/* index is above internal string length -> property is fully normal */
				DUK_DDD(DUK_DDDPRINT("array index outside string -> normal property"));
			}
		} else if (key == DUK_HTHREAD_STRING_LENGTH(thr)) {
			duk_hstring *h_val;

			DUK_DDD(DUK_DDDPRINT("-> found, key is 'length', length exotic behavior"));

			h_val = duk_hobject_get_internal_value_string(thr->heap, obj);
			DUK_ASSERT(h_val != NULL);
			if (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {
				duk_push_uint(ctx, (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h_val));
			}
			out_desc->flags = DUK_PROPDESC_FLAG_VIRTUAL;  /* E5 Section 15.5.5.1 */

			DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));
			return 1;  /* cannot be arguments exotic */
		}
	} else if (DUK_HOBJECT_IS_BUFFEROBJECT(obj)) {
		duk_hbufferobject *h_bufobj;
		duk_uint_t byte_off;
		duk_small_uint_t elem_size;

		h_bufobj = (duk_hbufferobject *) obj;
		DUK_ASSERT_HBUFFEROBJECT_VALID(h_bufobj);
		DUK_DDD(DUK_DDDPRINT("bufferobject property get for key: %!O, arr_idx: %ld",
		                     (duk_heaphdr *) key, (long) arr_idx));

		if (arr_idx != DUK__NO_ARRAY_INDEX) {
			DUK_DDD(DUK_DDDPRINT("array index exists"));

			/* Careful with wrapping: arr_idx upshift may easily wrap, whereas
			 * length downshift won't.
			 */
			if (arr_idx < (h_bufobj->length >> h_bufobj->shift)) {
				byte_off = arr_idx << h_bufobj->shift;  /* no wrap assuming h_bufobj->length is valid */
				elem_size = 1 << h_bufobj->shift;
				if (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {
					duk_uint8_t *data;

					if (h_bufobj->buf != NULL && DUK_HBUFFEROBJECT_VALID_BYTEOFFSET_EXCL(h_bufobj, byte_off + elem_size)) {
						data = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf) + h_bufobj->offset + byte_off;
						duk_hbufferobject_push_validated_read(ctx, h_bufobj, data, elem_size);
					} else {
						DUK_D(DUK_DPRINT("bufferobject access out of underlying buffer, ignoring (read zero)"));
						duk_push_uint(ctx, 0);
					}
				}
				out_desc->flags = DUK_PROPDESC_FLAG_WRITABLE |
				                  DUK_PROPDESC_FLAG_ENUMERABLE |
				                  DUK_PROPDESC_FLAG_VIRTUAL;

				DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));
				return 1;  /* cannot be e.g. arguments exotic, since exotic 'traits' are mutually exclusive */
			} else {
				/* index is above internal buffer length -> property is fully normal */
				DUK_DDD(DUK_DDDPRINT("array index outside buffer -> normal property"));
			}
		} else if (key == DUK_HTHREAD_STRING_LENGTH(thr)) {
			DUK_DDD(DUK_DDDPRINT("-> found, key is 'length', length exotic behavior"));

			if (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {
				/* Length in elements: take into account shift, but
				 * intentionally don't check the underlying buffer here.
				 */
				duk_push_uint(ctx, h_bufobj->length >> h_bufobj->shift);
			}
			out_desc->flags = DUK_PROPDESC_FLAG_VIRTUAL;

			DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));
			return 1;  /* cannot be arguments exotic */
		} else if (key == DUK_HTHREAD_STRING_BYTE_LENGTH(thr)) {
			/* If neutered must return 0; length is zeroed during
			 * neutering.
			 */
			if (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {
				duk_push_uint(ctx, h_bufobj->length);
			}
			out_desc->flags = DUK_PROPDESC_FLAG_VIRTUAL;
			return 1;  /* cannot be arguments exotic */
		} else if (key == DUK_HTHREAD_STRING_BYTE_OFFSET(thr)) {
			/* If neutered must return 0; offset is zeroed during
			 * neutering.
			 */
			if (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {
				duk_push_uint(ctx, h_bufobj->offset);
			}
			out_desc->flags = DUK_PROPDESC_FLAG_VIRTUAL;
			return 1;  /* cannot be arguments exotic */
		} else if (key == DUK_HTHREAD_STRING_BYTES_PER_ELEMENT(thr)) {
			if (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {
				duk_push_uint(ctx, 1 << h_bufobj->shift);
			}
			out_desc->flags = DUK_PROPDESC_FLAG_VIRTUAL;
			return 1;  /* cannot be arguments exotic */
		}
	} else if (DUK_HOBJECT_HAS_EXOTIC_DUKFUNC(obj)) {
		DUK_DDD(DUK_DDDPRINT("duktape/c object exotic property get for key: %!O, arr_idx: %ld",
		                     (duk_heaphdr *) key, (long) arr_idx));

		if (key == DUK_HTHREAD_STRING_LENGTH(thr)) {
			DUK_DDD(DUK_DDDPRINT("-> found, key is 'length', length exotic behavior"));

			if (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {
				duk_int16_t func_nargs = ((duk_hnativefunction *) obj)->nargs;
				duk_push_int(ctx, func_nargs == DUK_HNATIVEFUNCTION_NARGS_VARARGS ? 0 : func_nargs);
			}
			out_desc->flags = DUK_PROPDESC_FLAG_VIRTUAL;  /* not enumerable */

			DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));
			return 1;  /* cannot be arguments exotic */
		}
	}

	/* Array properties have exotic behavior but they are concrete,
	 * so no special handling here.
	 *
	 * Arguments exotic behavior (E5 Section 10.6, [[GetOwnProperty]]
	 * is only relevant as a post-check implemented below; hence no
	 * check here.
	 */

	/*
	 *  Not found as concrete or virtual
	 */

	DUK_DDD(DUK_DDDPRINT("-> not found (virtual, entry part, or array part)"));
	return 0;

	/*
	 *  Found
	 *
	 *  Arguments object has exotic post-processing, see E5 Section 10.6,
	 *  description of [[GetOwnProperty]] variant for arguments.
	 */

 prop_found:
	DUK_DDD(DUK_DDDPRINT("-> property found, checking for arguments exotic post-behavior"));

	/* Notes:
	 *  - only numbered indices are relevant, so arr_idx fast reject is good
	 *    (this is valid unless there are more than 4**32-1 arguments).
	 *  - since variable lookup has no side effects, this can be skipped if
	 *    DUK_GETDESC_FLAG_PUSH_VALUE is not set.
	 */

	if (DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj) &&
	    arr_idx != DUK__NO_ARRAY_INDEX &&
	    (flags & DUK_GETDESC_FLAG_PUSH_VALUE)) {
		duk_propdesc temp_desc;

		/* Magically bound variable cannot be an accessor.  However,
		 * there may be an accessor property (or a plain property) in
		 * place with magic behavior removed.  This happens e.g. when
		 * a magic property is redefined with defineProperty().
		 * Cannot assert for "not accessor" here.
		 */

		/* replaces top of stack with new value if necessary */
		DUK_ASSERT((flags & DUK_GETDESC_FLAG_PUSH_VALUE) != 0);

		if (duk__check_arguments_map_for_get(thr, obj, key, &temp_desc)) {
			DUK_DDD(DUK_DDDPRINT("-> arguments exotic behavior overrides result: %!T -> %!T",
			                     (duk_tval *) duk_get_tval(ctx, -2),
			                     (duk_tval *) duk_get_tval(ctx, -1)));
			/* [... old_result result] -> [... result] */
			duk_remove(ctx, -2);
		}
	}

	return 1;
}

DUK_INTERNAL duk_bool_t duk_hobject_get_own_propdesc(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *out_desc, duk_small_uint_t flags) {
	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(obj != NULL);
	DUK_ASSERT(key != NULL);
	DUK_ASSERT(out_desc != NULL);
	DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);

	return duk__get_own_propdesc_raw(thr, obj, key, DUK_HSTRING_GET_ARRIDX_SLOW(key), out_desc, flags);
}

/*
 *  Ecmascript compliant [[GetProperty]](P), for internal use only.
 *
 *  If property is found:
 *    - Fills descriptor fields to 'out_desc'
 *    - If DUK_GETDESC_FLAG_PUSH_VALUE is set, pushes a value related to the
 *      property onto the stack ('undefined' for accessor properties).
 *    - Returns non-zero
 *
 *  If property is not found:
 *    - 'out_desc' is left in untouched state (possibly garbage)
 *    - Nothing is pushed onto the stack (not even with DUK_GETDESC_FLAG_PUSH_VALUE
 *      set)
 *    - Returns zero
 *
 *  May cause arbitrary side effects and invalidate (most) duk_tval
 *  pointers.
 */

DUK_LOCAL duk_bool_t duk__get_propdesc(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *out_desc, duk_small_uint_t flags) {
	duk_hobject *curr;
	duk_uint32_t arr_idx;
	duk_uint_t sanity;

	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(thr->heap != NULL);
	DUK_ASSERT(obj != NULL);
	DUK_ASSERT(key != NULL);
	DUK_ASSERT(out_desc != NULL);
	DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);

	arr_idx = DUK_HSTRING_GET_ARRIDX_FAST(key);

	DUK_DDD(DUK_DDDPRINT("duk__get_propdesc: thr=%p, obj=%p, key=%p, out_desc=%p, flags=%lx, "
	                     "arr_idx=%ld (obj -> %!O, key -> %!O)",
	                     (void *) thr, (void *) obj, (void *) key, (void *) out_desc,
	                     (long) flags, (long) arr_idx,
	                     (duk_heaphdr *) obj, (duk_heaphdr *) key));

	curr = obj;
	DUK_ASSERT(curr != NULL);
	sanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;
	do {
		if (duk__get_own_propdesc_raw(thr, curr, key, arr_idx, out_desc, flags)) {
			/* stack contains value (if requested), 'out_desc' is set */
			return 1;
		}

		/* not found in 'curr', next in prototype chain; impose max depth */
		if (sanity-- == 0) {
			if (flags & DUK_GETDESC_FLAG_IGNORE_PROTOLOOP) {
				/* treat like property not found */
				break;
			} else {
				DUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);
			}
		}
		curr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);
	} while (curr);

	/* out_desc is left untouched (possibly garbage), caller must use return
	 * value to determine whether out_desc can be looked up
	 */

	return 0;
}

/*
 *  Shallow fast path checks for accessing array elements with numeric
 *  indices.  The goal is to try to avoid coercing an array index to an
 *  (interned) string for the most common lookups, in particular, for
 *  standard Array objects.
 *
 *  Interning is avoided but only for a very narrow set of cases:
 *    - Object has array part, index is within array allocation, and
 *      value is not unused (= key exists)
 *    - Object has no interfering exotic behavior (e.g. arguments or
 *      string object exotic behaviors interfere, array exotic
 *      behavior does not).
 *
 *  Current shortcoming: if key does not exist (even if it is within
 *  the array allocation range) a slow path lookup with interning is
 *  always required.  This can probably be fixed so that there is a
 *  quick fast path for non-existent elements as well, at least for
 *  standard Array objects.
 */

DUK_LOCAL duk_tval *duk__getprop_shallow_fastpath_array_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *tv_key) {
	duk_tval *tv;
	duk_uint32_t idx;

	DUK_UNREF(thr);

	if (!(DUK_HOBJECT_HAS_ARRAY_PART(obj) &&
	     !DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj) &&
	     !DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(obj) &&
	     !DUK_HOBJECT_IS_BUFFEROBJECT(obj) &&
	     !DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(obj))) {
		/* Must have array part and no conflicting exotic behaviors.
		 * Doesn't need to have array special behavior, e.g. Arguments
		 * object has array part.
		 */
		return NULL;
	}

	/* Arrays never have other exotic behaviors. */

	DUK_DDD(DUK_DDDPRINT("fast path attempt (no exotic string/arguments/buffer "
	                     "behavior, object has array part)"));

#if defined(DUK_USE_FASTINT)
	if (DUK_TVAL_IS_FASTINT(tv_key)) {
		idx = duk__tval_fastint_to_arr_idx(tv_key);
	} else
#endif
	if (DUK_TVAL_IS_DOUBLE(tv_key)) {
		idx = duk__tval_number_to_arr_idx(tv_key);
	} else {
		DUK_DDD(DUK_DDDPRINT("key is not a number"));
		return NULL;
	}

	/* If index is not valid, idx will be DUK__NO_ARRAY_INDEX which
	 * is 0xffffffffUL.  We don't need to check for that explicitly
	 * because 0xffffffffUL will never be inside object 'a_size'.
	 */

	if (idx >= DUK_HOBJECT_GET_ASIZE(obj)) {
		DUK_DDD(DUK_DDDPRINT("key is not an array index or outside array part"));
		return NULL;
	}
	DUK_ASSERT(idx != 0xffffffffUL);
	DUK_ASSERT(idx != DUK__NO_ARRAY_INDEX);

	/* XXX: for array instances we could take a shortcut here and assume
	 * Array.prototype doesn't contain an array index property.
	 */

	DUK_DDD(DUK_DDDPRINT("key is a valid array index and inside array part"));
	tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, idx);
	if (!DUK_TVAL_IS_UNUSED(tv)) {
		DUK_DDD(DUK_DDDPRINT("-> fast path successful"));
		return tv;
	}

	DUK_DDD(DUK_DDDPRINT("fast path attempt failed, fall back to slow path"));
	return NULL;
}

DUK_LOCAL duk_bool_t duk__putprop_shallow_fastpath_array_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *tv_key, duk_tval *tv_val, duk_propdesc *temp_desc) {
	duk_tval *tv;
	duk_uint32_t idx;
	duk_uint32_t old_len, new_len;

	if (!(DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj) &&
	      DUK_HOBJECT_HAS_ARRAY_PART(obj) &&
	      DUK_HOBJECT_HAS_EXTENSIBLE(obj))) {
		return 0;
	}
	DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));  /* caller ensures */

#if defined(DUK_USE_FASTINT)
	if (DUK_TVAL_IS_FASTINT(tv_key)) {
		idx = duk__tval_fastint_to_arr_idx(tv_key);
	} else
#endif
	if (DUK_TVAL_IS_DOUBLE(tv_key)) {
		idx = duk__tval_number_to_arr_idx(tv_key);
	} else {
		DUK_DDD(DUK_DDDPRINT("key is not a number"));
		return 0;
	}

	/* If index is not valid, idx will be DUK__NO_ARRAY_INDEX which
	 * is 0xffffffffUL.  We don't need to check for that explicitly
	 * because 0xffffffffUL will never be inside object 'a_size'.
	 */

	if (idx >= DUK_HOBJECT_GET_ASIZE(obj)) {  /* for resizing of array part, use slow path */
		return 0;
	}
	DUK_ASSERT(idx != 0xffffffffUL);
	DUK_ASSERT(idx != DUK__NO_ARRAY_INDEX);

	old_len = duk__get_old_array_length(thr, obj, temp_desc);

	if (idx >= old_len) {
		DUK_DDD(DUK_DDDPRINT("write new array entry requires length update "
		                     "(arr_idx=%ld, old_len=%ld)",
		                     (long) idx, (long) old_len));
		if (!(temp_desc->flags & DUK_PROPDESC_FLAG_WRITABLE)) {
			DUK_ERROR_TYPE(thr, DUK_STR_NOT_WRITABLE);
			return 0;  /* not reachable */
		}
		new_len = idx + 1;

		/* No resize has occurred so temp_desc->e_idx is still OK */
		tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, temp_desc->e_idx);
		DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));
		DUK_TVAL_SET_FASTINT_U32(tv, new_len);  /* no need for decref/incref because value is a number */
	} else {
		;
	}

	tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, idx);
	DUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv_val);  /* side effects */

	DUK_DDD(DUK_DDDPRINT("array fast path success for index %ld", (long) idx));
	return 1;
}

/*
 *  Fast path for bufferobject getprop/putprop
 */

DUK_LOCAL duk_bool_t duk__getprop_fastpath_bufobj_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *tv_key) {
	duk_context *ctx;
	duk_uint32_t idx;
	duk_hbufferobject *h_bufobj;
	duk_uint_t byte_off;
	duk_small_uint_t elem_size;
	duk_uint8_t *data;

	ctx = (duk_context *) thr;

	if (!DUK_HOBJECT_IS_BUFFEROBJECT(obj)) {
		return 0;
	}
	h_bufobj = (duk_hbufferobject *) obj;

#if defined(DUK_USE_FASTINT)
	if (DUK_TVAL_IS_FASTINT(tv_key)) {
		idx = duk__tval_fastint_to_arr_idx(tv_key);
	} else
#endif
	if (DUK_TVAL_IS_DOUBLE(tv_key)) {
		idx = duk__tval_number_to_arr_idx(tv_key);
	} else {
		return 0;
	}

	/* If index is not valid, idx will be DUK__NO_ARRAY_INDEX which
	 * is 0xffffffffUL.  We don't need to check for that explicitly
	 * because 0xffffffffUL will never be inside bufferobject length.
	 */

	/* Careful with wrapping (left shifting idx would be unsafe). */
	if (idx >= (h_bufobj->length >> h_bufobj->shift)) {
		return 0;
	}
	DUK_ASSERT(idx != DUK__NO_ARRAY_INDEX);

	byte_off = idx << h_bufobj->shift;  /* no wrap assuming h_bufobj->length is valid */
	elem_size = 1 << h_bufobj->shift;

	if (h_bufobj->buf != NULL && DUK_HBUFFEROBJECT_VALID_BYTEOFFSET_EXCL(h_bufobj, byte_off + elem_size)) {
		data = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf) + h_bufobj->offset + byte_off;
		duk_hbufferobject_push_validated_read(ctx, h_bufobj, data, elem_size);
	} else {
		DUK_D(DUK_DPRINT("bufferobject access out of underlying buffer, ignoring (read zero)"));
		duk_push_uint(ctx, 0);
	}

	return 1;
}

DUK_LOCAL duk_bool_t duk__putprop_fastpath_bufobj_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *tv_key, duk_tval *tv_val) {
	duk_context *ctx;
	duk_uint32_t idx;
	duk_hbufferobject *h_bufobj;
	duk_uint_t byte_off;
	duk_small_uint_t elem_size;
	duk_uint8_t *data;

	ctx = (duk_context *) thr;

	if (!(DUK_HOBJECT_IS_BUFFEROBJECT(obj) &&
	      DUK_TVAL_IS_NUMBER(tv_val))) {
		return 0;
	}
	DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));  /* caller ensures; rom objects are never bufferobjects now */

	h_bufobj = (duk_hbufferobject *) obj;
#if defined(DUK_USE_FASTINT)
	if (DUK_TVAL_IS_FASTINT(tv_key)) {
		idx = duk__tval_fastint_to_arr_idx(tv_key);
	} else
#endif
	if (DUK_TVAL_IS_DOUBLE(tv_key)) {
		idx = duk__tval_number_to_arr_idx(tv_key);
	} else {
		return 0;
	}

	/* If index is not valid, idx will be DUK__NO_ARRAY_INDEX which
	 * is 0xffffffffUL.  We don't need to check for that explicitly
	 * because 0xffffffffUL will never be inside bufferobject length.
	 */

	/* Careful with wrapping (left shifting idx would be unsafe). */
	if (idx >= (h_bufobj->length >> h_bufobj->shift)) {
		return 0;
	}
	DUK_ASSERT(idx != DUK__NO_ARRAY_INDEX);

	byte_off = idx << h_bufobj->shift;  /* no wrap assuming h_bufobj->length is valid */
	elem_size = 1 << h_bufobj->shift;

	/* Value is required to be a number in the fast path so there
	 * are no side effects in write coercion.
	 */
	duk_push_tval(ctx, tv_val);
	DUK_ASSERT(duk_is_number(ctx, -1));

	if (h_bufobj->buf != NULL && DUK_HBUFFEROBJECT_VALID_BYTEOFFSET_EXCL(h_bufobj, byte_off + elem_size)) {
		data = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf) + h_bufobj->offset + byte_off;
		duk_hbufferobject_validated_write(ctx, h_bufobj, data, elem_size);
	} else {
		DUK_D(DUK_DPRINT("bufferobject access out of underlying buffer, ignoring (write skipped)"));
	}

	duk_pop(ctx);
	return 1;
}

/*
 *  GETPROP: Ecmascript property read.
 */

DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key) {
	duk_context *ctx = (duk_context *) thr;
	duk_tval tv_obj_copy;
	duk_tval tv_key_copy;
	duk_hobject *curr = NULL;
	duk_hstring *key = NULL;
	duk_uint32_t arr_idx = DUK__NO_ARRAY_INDEX;
	duk_propdesc desc;
	duk_uint_t sanity;

	DUK_DDD(DUK_DDDPRINT("getprop: thr=%p, obj=%p, key=%p (obj -> %!T, key -> %!T)",
	                     (void *) thr, (void *) tv_obj, (void *) tv_key,
	                     (duk_tval *) tv_obj, (duk_tval *) tv_key));

	DUK_ASSERT(ctx != NULL);
	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(thr->heap != NULL);
	DUK_ASSERT(tv_obj != NULL);
	DUK_ASSERT(tv_key != NULL);

	DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);

	/*
	 *  Make a copy of tv_obj, tv_key, and tv_val to avoid any issues of
	 *  them being invalidated by a valstack resize.
	 *
	 *  XXX: this is now an overkill for many fast paths.  Rework this
	 *  to be faster (although switching to a valstack discipline might
	 *  be a better solution overall).
	 */

	DUK_TVAL_SET_TVAL(&tv_obj_copy, tv_obj);
	DUK_TVAL_SET_TVAL(&tv_key_copy, tv_key);
	tv_obj = &tv_obj_copy;
	tv_key = &tv_key_copy;

	/*
	 *  Coercion and fast path processing
	 */

	switch (DUK_TVAL_GET_TAG(tv_obj)) {
	case DUK_TAG_UNDEFINED:
	case DUK_TAG_NULL: {
		/* Note: unconditional throw */
		DUK_DDD(DUK_DDDPRINT("base object is undefined or null -> reject"));
#if defined(DUK_USE_PARANOID_ERRORS)
		DUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE);
#else
		DUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, "cannot read property %s of %s",
		               duk_push_string_tval_readable(ctx, tv_key), duk_push_string_tval_readable(ctx, tv_obj));
#endif
		return 0;
	}

	case DUK_TAG_BOOLEAN: {
		DUK_DDD(DUK_DDDPRINT("base object is a boolean, start lookup from boolean prototype"));
		curr = thr->builtins[DUK_BIDX_BOOLEAN_PROTOTYPE];
		break;
	}

	case DUK_TAG_STRING: {
		duk_hstring *h = DUK_TVAL_GET_STRING(tv_obj);
		duk_int_t pop_count;

#if defined(DUK_USE_FASTINT)
		if (DUK_TVAL_IS_FASTINT(tv_key)) {
			arr_idx = duk__tval_fastint_to_arr_idx(tv_key);
			DUK_DDD(DUK_DDDPRINT("base object string, key is a fast-path fastint; arr_idx %ld", (long) arr_idx));
			pop_count = 0;
		} else
#endif
		if (DUK_TVAL_IS_NUMBER(tv_key)) {
			arr_idx = duk__tval_number_to_arr_idx(tv_key);
			DUK_DDD(DUK_DDDPRINT("base object string, key is a fast-path number; arr_idx %ld", (long) arr_idx));
			pop_count = 0;
		} else {
			arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
			DUK_ASSERT(key != NULL);
			DUK_DDD(DUK_DDDPRINT("base object string, key is a non-fast-path number; after "
			                     "coercion key is %!T, arr_idx %ld",
			                     (duk_tval *) duk_get_tval(ctx, -1), (long) arr_idx));
			pop_count = 1;
		}

		if (arr_idx != DUK__NO_ARRAY_INDEX &&
		    arr_idx < DUK_HSTRING_GET_CHARLEN(h)) {
			duk_pop_n(ctx, pop_count);
			duk_push_hstring(ctx, h);
			duk_substring(ctx, -1, arr_idx, arr_idx + 1);  /* [str] -> [substr] */

			DUK_DDD(DUK_DDDPRINT("-> %!T (base is string, key is an index inside string length "
			                     "after coercion -> return char)",
			                     (duk_tval *) duk_get_tval(ctx, -1)));
			return 1;
		}

		if (pop_count == 0) {
			/* This is a pretty awkward control flow, but we need to recheck the
			 * key coercion here.
			 */
			arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
			DUK_ASSERT(key != NULL);
			DUK_DDD(DUK_DDDPRINT("base object string, key is a non-fast-path number; after "
			                     "coercion key is %!T, arr_idx %ld",
			                     (duk_tval *) duk_get_tval(ctx, -1), (long) arr_idx));
		}

		if (key == DUK_HTHREAD_STRING_LENGTH(thr)) {
			duk_pop(ctx);  /* [key] -> [] */
			duk_push_uint(ctx, (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h));  /* [] -> [res] */

			DUK_DDD(DUK_DDDPRINT("-> %!T (base is string, key is 'length' after coercion -> "
			                     "return string length)",
			                     (duk_tval *) duk_get_tval(ctx, -1)));
			return 1;
		}
		DUK_DDD(DUK_DDDPRINT("base object is a string, start lookup from string prototype"));
		curr = thr->builtins[DUK_BIDX_STRING_PROTOTYPE];
		goto lookup;  /* avoid double coercion */
	}

	case DUK_TAG_OBJECT: {
		duk_tval *tmp;

		curr = DUK_TVAL_GET_OBJECT(tv_obj);
		DUK_ASSERT(curr != NULL);

		tmp = duk__getprop_shallow_fastpath_array_tval(thr, curr, tv_key);
		if (tmp) {
			duk_push_tval(ctx, tmp);

			DUK_DDD(DUK_DDDPRINT("-> %!T (base is object, key is a number, array part "
			                     "fast path)",
			                     (duk_tval *) duk_get_tval(ctx, -1)));
			return 1;
		}

		if (duk__getprop_fastpath_bufobj_tval(thr, curr, tv_key) != 0) {
			/* Read value pushed on stack. */
			DUK_DDD(DUK_DDDPRINT("-> %!T (base is bufobj, key is a number, bufferobject "
			                     "fast path)",
			                     (duk_tval *) duk_get_tval(ctx, -1)));
			return 1;
		}

#if defined(DUK_USE_ES6_PROXY)
		if (DUK_UNLIKELY(DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(curr))) {
			duk_hobject *h_target;

			if (duk__proxy_check_prop(thr, curr, DUK_STRIDX_GET, tv_key, &h_target)) {
				/* -> [ ... trap handler ] */
				DUK_DDD(DUK_DDDPRINT("-> proxy object 'get' for key %!T", (duk_tval *) tv_key));
				duk_push_hobject(ctx, h_target);  /* target */
				duk_push_tval(ctx, tv_key);       /* P */
				duk_push_tval(ctx, tv_obj);       /* Receiver: Proxy object */
				duk_call_method(ctx, 3 /*nargs*/);

				/* Target object must be checked for a conflicting
				 * non-configurable property.
				 */
				arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
				DUK_ASSERT(key != NULL);

				if (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {
					duk_tval *tv_hook = duk_require_tval(ctx, -3);  /* value from hook */
					duk_tval *tv_targ = duk_require_tval(ctx, -1);  /* value from target */
					duk_bool_t datadesc_reject;
					duk_bool_t accdesc_reject;

					DUK_DDD(DUK_DDDPRINT("proxy 'get': target has matching property %!O, check for "
					                     "conflicting property; tv_hook=%!T, tv_targ=%!T, desc.flags=0x%08lx, "
					                     "desc.get=%p, desc.set=%p",
					                     (duk_heaphdr *) key, (duk_tval *) tv_hook, (duk_tval *) tv_targ,
					                     (unsigned long) desc.flags,
					                     (void *) desc.get, (void *) desc.set));

					datadesc_reject = !(desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) &&
					                  !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) &&
					                  !(desc.flags & DUK_PROPDESC_FLAG_WRITABLE) &&
					                  !duk_js_samevalue(tv_hook, tv_targ);
					accdesc_reject = (desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) &&
					                 !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) &&
					                 (desc.get == NULL) &&
					                 !DUK_TVAL_IS_UNDEFINED(tv_hook);
					if (datadesc_reject || accdesc_reject) {
						DUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);
					}

					duk_pop_2(ctx);
				} else {
					duk_pop(ctx);
				}
				return 1;  /* return value */
			}

			curr = h_target;  /* resume lookup from target */
			DUK_TVAL_SET_OBJECT(tv_obj, curr);
		}
#endif  /* DUK_USE_ES6_PROXY */

		if (DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(curr)) {
			arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
			DUK_ASSERT(key != NULL);

			if (duk__check_arguments_map_for_get(thr, curr, key, &desc)) {
				DUK_DDD(DUK_DDDPRINT("-> %!T (base is object with arguments exotic behavior, "
				                     "key matches magically bound property -> skip standard "
				                     "Get with replacement value)",
				                     (duk_tval *) duk_get_tval(ctx, -1)));

				/* no need for 'caller' post-check, because 'key' must be an array index */

				duk_remove(ctx, -2);  /* [key result] -> [result] */
				return 1;
			}

			goto lookup;  /* avoid double coercion */
		}
		break;
	}

	/* Buffer has virtual properties similar to string, but indexed values
	 * are numbers, not 1-byte buffers/strings which would perform badly.
	 */
	case DUK_TAG_BUFFER: {
		duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv_obj);
		duk_int_t pop_count;

		/*
		 *  Because buffer values are often looped over, a number fast path
		 *  is important.
		 */

#if defined(DUK_USE_FASTINT)
		if (DUK_TVAL_IS_FASTINT(tv_key)) {
			arr_idx = duk__tval_fastint_to_arr_idx(tv_key);
			DUK_DDD(DUK_DDDPRINT("base object buffer, key is a fast-path fastint; arr_idx %ld", (long) arr_idx));
			pop_count = 0;
		}
		else
#endif
		if (DUK_TVAL_IS_NUMBER(tv_key)) {
			arr_idx = duk__tval_number_to_arr_idx(tv_key);
			DUK_DDD(DUK_DDDPRINT("base object buffer, key is a fast-path number; arr_idx %ld", (long) arr_idx));
			pop_count = 0;
		} else {
			arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
			DUK_ASSERT(key != NULL);
			DUK_DDD(DUK_DDDPRINT("base object buffer, key is a non-fast-path number; after "
			                     "coercion key is %!T, arr_idx %ld",
			                     (duk_tval *) duk_get_tval(ctx, -1), (long) arr_idx));
			pop_count = 1;
		}

		if (arr_idx != DUK__NO_ARRAY_INDEX &&
		    arr_idx < DUK_HBUFFER_GET_SIZE(h)) {
			duk_pop_n(ctx, pop_count);
			duk_push_uint(ctx, ((duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h))[arr_idx]);

			DUK_DDD(DUK_DDDPRINT("-> %!T (base is buffer, key is an index inside buffer length "
			                     "after coercion -> return byte as number)",
			                     (duk_tval *) duk_get_tval(ctx, -1)));
			return 1;
		}

		if (pop_count == 0) {
			/* This is a pretty awkward control flow, but we need to recheck the
			 * key coercion here.
			 */
			arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
			DUK_ASSERT(key != NULL);
			DUK_DDD(DUK_DDDPRINT("base object buffer, key is a non-fast-path number; after "
			                     "coercion key is %!T, arr_idx %ld",
			                     (duk_tval *) duk_get_tval(ctx, -1), (long) arr_idx));
		}

		if (key == DUK_HTHREAD_STRING_LENGTH(thr) ||
		    key == DUK_HTHREAD_STRING_BYTE_LENGTH(thr)) {
			duk_pop(ctx);  /* [key] -> [] */
			duk_push_uint(ctx, (duk_uint_t) DUK_HBUFFER_GET_SIZE(h));  /* [] -> [res] */

			DUK_DDD(DUK_DDDPRINT("-> %!T (base is buffer, key is 'length' or 'byteLength' "
			                     "after coercion -> return buffer length)",
			                     (duk_tval *) duk_get_tval(ctx, -1)));
			return 1;
		} else if (key == DUK_HTHREAD_STRING_BYTE_OFFSET(thr)) {
			duk_pop(ctx);  /* [key] -> [] */
			duk_push_uint(ctx, 0);  /* [] -> [res] */

			DUK_DDD(DUK_DDDPRINT("-> %!T (base is buffer, key is 'byteOffset' after coercion -> "
			                     "return 0 for consistency with Buffer objects)",
			                     (duk_tval *) duk_get_tval(ctx, -1)));
			return 1;
		} else if (key == DUK_HTHREAD_STRING_BYTES_PER_ELEMENT(thr)) {
			duk_pop(ctx);  /* [key] -> [] */
			duk_push_uint(ctx, 1);  /* [] -> [res] */

			DUK_DDD(DUK_DDDPRINT("-> %!T (base is buffer, key is 'BYTES_PER_ELEMENT' after coercion -> "
			                     "return 1 for consistency with Buffer objects)",
			                     (duk_tval *) duk_get_tval(ctx, -1)));
			return 1;
		}

		DUK_DDD(DUK_DDDPRINT("base object is a buffer, start lookup from buffer prototype"));
		curr = thr->builtins[DUK_BIDX_BUFFER_PROTOTYPE];
		goto lookup;  /* avoid double coercion */
	}

	case DUK_TAG_POINTER: {
		DUK_DDD(DUK_DDDPRINT("base object is a pointer, start lookup from pointer prototype"));
		curr = thr->builtins[DUK_BIDX_POINTER_PROTOTYPE];
		break;
	}

	case DUK_TAG_LIGHTFUNC: {
		duk_int_t lf_flags = DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv_obj);

		/* Must coerce key: if key is an object, it may coerce to e.g. 'length'. */
		arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);

		if (key == DUK_HTHREAD_STRING_LENGTH(thr)) {
			duk_int_t lf_len = DUK_LFUNC_FLAGS_GET_LENGTH(lf_flags);
			duk_pop(ctx);
			duk_push_int(ctx, lf_len);
			return 1;
		} else if (key == DUK_HTHREAD_STRING_NAME(thr)) {
			duk_pop(ctx);
			duk_push_lightfunc_name(ctx, tv_obj);
			return 1;
		}

		DUK_DDD(DUK_DDDPRINT("base object is a lightfunc, start lookup from function prototype"));
		curr = thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE];
		goto lookup;  /* avoid double coercion */
	}

#if defined(DUK_USE_FASTINT)
	case DUK_TAG_FASTINT:
#endif
	default: {
		/* number */
		DUK_DDD(DUK_DDDPRINT("base object is a number, start lookup from number prototype"));
		DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv_obj));
		DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_obj));
		curr = thr->builtins[DUK_BIDX_NUMBER_PROTOTYPE];
		break;
	}
	}

	/* key coercion (unless already coerced above) */
	DUK_ASSERT(key == NULL);
	arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
	DUK_ASSERT(key != NULL);

	/*
	 *  Property lookup
	 */

 lookup:
	/* [key] (coerced) */
	DUK_ASSERT(curr != NULL);
	DUK_ASSERT(key != NULL);

	sanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;
	do {
		if (!duk__get_own_propdesc_raw(thr, curr, key, arr_idx, &desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {
			goto next_in_chain;
		}

		if (desc.get != NULL) {
			/* accessor with defined getter */
			DUK_ASSERT((desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) != 0);

			duk_pop(ctx);                     /* [key undefined] -> [key] */
			duk_push_hobject(ctx, desc.get);
			duk_push_tval(ctx, tv_obj);       /* note: original, uncoerced base */
#ifdef DUK_USE_NONSTD_GETTER_KEY_ARGUMENT
			duk_dup(ctx, -3);
			duk_call_method(ctx, 1);          /* [key getter this key] -> [key retval] */
#else
			duk_call_method(ctx, 0);          /* [key getter this] -> [key retval] */
#endif
		} else {
			/* [key value] or [key undefined] */

			/* data property or accessor without getter */
			DUK_ASSERT(((desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) == 0) ||
			           (desc.get == NULL));

			/* if accessor without getter, return value is undefined */
			DUK_ASSERT(((desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) == 0) ||
			           duk_is_undefined(ctx, -1));

			/* Note: for an accessor without getter, falling through to
			 * check for "caller" exotic behavior is unnecessary as
			 * "undefined" will never activate the behavior.  But it does
			 * no harm, so we'll do it anyway.
			 */
		}

		goto found;  /* [key result] */

	 next_in_chain:
		/* XXX: option to pretend property doesn't exist if sanity limit is
		 * hit might be useful.
		 */
		if (sanity-- == 0) {
			DUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);
		}
		curr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);
	} while (curr);

	/*
	 *  Not found
	 */

	duk_to_undefined(ctx, -1);  /* [key] -> [undefined] (default value) */

	DUK_DDD(DUK_DDDPRINT("-> %!T (not found)", (duk_tval *) duk_get_tval(ctx, -1)));
	return 0;

	/*
	 *  Found; post-processing (Function and arguments objects)
	 */

 found:
	/* [key result] */

#if !defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)
	/* Special behavior for 'caller' property of (non-bound) function objects
	 * and non-strict Arguments objects: if 'caller' -value- (!) is a strict
	 * mode function, throw a TypeError (E5 Sections 15.3.5.4, 10.6).
	 * Quite interestingly, a non-strict function with no formal arguments
	 * will get an arguments object -without- special 'caller' behavior!
	 *
	 * The E5.1 spec is a bit ambiguous if this special behavior applies when
	 * a bound function is the base value (not the 'caller' value): Section
	 * 15.3.4.5 (describing bind()) states that [[Get]] for bound functions
	 * matches that of Section 15.3.5.4 ([[Get]] for Function instances).
	 * However, Section 13.3.5.4 has "NOTE: Function objects created using
	 * Function.prototype.bind use the default [[Get]] internal method."
	 * The current implementation assumes this means that bound functions
	 * should not have the special [[Get]] behavior.
	 *
	 * The E5.1 spec is also a bit unclear if the TypeError throwing is
	 * applied if the 'caller' value is a strict bound function.  The
	 * current implementation will throw even for both strict non-bound
	 * and strict bound functions.
	 *
	 * See test-dev-strict-func-as-caller-prop-value.js for quite extensive
	 * tests.
	 *
	 * This exotic behavior is disabled when the non-standard 'caller' property
	 * is enabled, as it conflicts with the free use of 'caller'.
	 */
	if (key == DUK_HTHREAD_STRING_CALLER(thr) &&
	    DUK_TVAL_IS_OBJECT(tv_obj)) {
		duk_hobject *orig = DUK_TVAL_GET_OBJECT(tv_obj);
		DUK_ASSERT(orig != NULL);

		if (DUK_HOBJECT_IS_NONBOUND_FUNCTION(orig) ||
		    DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(orig)) {
			duk_hobject *h;

			/* XXX: The TypeError is currently not applied to bound
			 * functions because the 'strict' flag is not copied by
			 * bind().  This may or may not be correct, the specification
			 * only refers to the value being a "strict mode Function
			 * object" which is ambiguous.
			 */
			DUK_ASSERT(!DUK_HOBJECT_HAS_BOUND(orig));

			h = duk_get_hobject(ctx, -1);  /* NULL if not an object */
			if (h &&
			    DUK_HOBJECT_IS_FUNCTION(h) &&
			    DUK_HOBJECT_HAS_STRICT(h)) {
				/* XXX: sufficient to check 'strict', assert for 'is function' */
				DUK_ERROR_TYPE(thr, DUK_STR_STRICT_CALLER_READ);
			}
		}
	}
#endif   /* !DUK_USE_NONSTD_FUNC_CALLER_PROPERTY */

	duk_remove(ctx, -2);  /* [key result] -> [result] */

	DUK_DDD(DUK_DDDPRINT("-> %!T (found)", (duk_tval *) duk_get_tval(ctx, -1)));
	return 1;
}

/*
 *  HASPROP: Ecmascript property existence check ("in" operator).
 *
 *  Interestingly, the 'in' operator does not do any coercion of
 *  the target object.
 */

DUK_INTERNAL duk_bool_t duk_hobject_hasprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key) {
	duk_context *ctx = (duk_context *) thr;
	duk_tval tv_key_copy;
	duk_hobject *obj;
	duk_hstring *key;
	duk_uint32_t arr_idx;
	duk_bool_t rc;
	duk_propdesc desc;

	DUK_DDD(DUK_DDDPRINT("hasprop: thr=%p, obj=%p, key=%p (obj -> %!T, key -> %!T)",
	                     (void *) thr, (void *) tv_obj, (void *) tv_key,
	                     (duk_tval *) tv_obj, (duk_tval *) tv_key));

	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(thr->heap != NULL);
	DUK_ASSERT(tv_obj != NULL);
	DUK_ASSERT(tv_key != NULL);
	DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);

	DUK_TVAL_SET_TVAL(&tv_key_copy, tv_key);
	tv_key = &tv_key_copy;

	/*
	 *  The 'in' operator requires an object as its right hand side,
	 *  throwing a TypeError unconditionally if this is not the case.
	 *
	 *  However, lightfuncs need to behave like fully fledged objects
	 *  here to be maximally transparent, so we need to handle them
	 *  here.
	 */

	/* XXX: Refactor key coercion so that it's only called once.  It can't
	 * be trivially lifted here because the object must be type checked
	 * first.
	 */

	if (DUK_TVAL_IS_OBJECT(tv_obj)) {
		obj = DUK_TVAL_GET_OBJECT(tv_obj);
		DUK_ASSERT(obj != NULL);

		arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
	} else if (DUK_TVAL_IS_LIGHTFUNC(tv_obj)) {
		arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
		if (duk__key_is_lightfunc_ownprop(thr, key)) {
			/* FOUND */
			rc = 1;
			goto pop_and_return;
		}

		/* If not found, resume existence check from Function.prototype.
		 * We can just substitute the value in this case; nothing will
		 * need the original base value (as would be the case with e.g.
		 * setters/getters.
		 */
		obj = thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE];
	} else {
		/* Note: unconditional throw */
		DUK_DDD(DUK_DDDPRINT("base object is not an object -> reject"));
		DUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE);
	}

	/* XXX: fast path for arrays? */

	DUK_ASSERT(key != NULL);
	DUK_ASSERT(obj != NULL);
	DUK_UNREF(arr_idx);

#if defined(DUK_USE_ES6_PROXY)
	if (DUK_UNLIKELY(DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(obj))) {
		duk_hobject *h_target;
		duk_bool_t tmp_bool;

		/* XXX: the key in 'key in obj' is string coerced before we're called
		 * (which is the required behavior in E5/E5.1/E6) so the key is a string
		 * here already.
		 */

		if (duk__proxy_check_prop(thr, obj, DUK_STRIDX_HAS, tv_key, &h_target)) {
			/* [ ... key trap handler ] */
			DUK_DDD(DUK_DDDPRINT("-> proxy object 'has' for key %!T", (duk_tval *) tv_key));
			duk_push_hobject(ctx, h_target);  /* target */
			duk_push_tval(ctx, tv_key);       /* P */
			duk_call_method(ctx, 2 /*nargs*/);
			tmp_bool = duk_to_boolean(ctx, -1);
			if (!tmp_bool) {
				/* Target object must be checked for a conflicting
				 * non-configurable property.
				 */

				if (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, 0 /*flags*/)) {  /* don't push value */
					DUK_DDD(DUK_DDDPRINT("proxy 'has': target has matching property %!O, check for "
					                     "conflicting property; desc.flags=0x%08lx, "
					                     "desc.get=%p, desc.set=%p",
					                     (duk_heaphdr *) key, (unsigned long) desc.flags,
					                     (void *) desc.get, (void *) desc.set));
					/* XXX: Extensibility check for target uses IsExtensible().  If we
					 * implemented the isExtensible trap and didn't reject proxies as
					 * proxy targets, it should be respected here.
					 */
					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_pop_2(ctx);  /* [ key trap_result ] -> [] */
			return tmp_bool;
		}

		obj = h_target;  /* resume check from proxy target */
	}
#endif  /* DUK_USE_ES6_PROXY */

	/* XXX: inline into a prototype walking loop? */

	rc = duk__get_propdesc(thr, obj, key, &desc, 0 /*flags*/);  /* don't push value */
	/* fall through */

 pop_and_return:
	duk_pop(ctx);  /* [ key ] -> [] */
	return rc;
}

/*
 *  HASPROP variant used internally.
 *
 *  This primitive must never throw an error, callers rely on this.
 *  In particular, don't throw an error for prototype loops; instead,
 *  pretend like the property doesn't exist if a prototype sanity limit
 *  is reached.
 *
 *  Does not implement proxy behavior: if applied to a proxy object,
 *  returns key existence on the proxy object itself.
 */

DUK_INTERNAL duk_bool_t duk_hobject_hasprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key) {
	duk_propdesc dummy;

	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(thr->heap != NULL);
	DUK_ASSERT(obj != NULL);
	DUK_ASSERT(key != NULL);

	DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);

	return duk__get_propdesc(thr, obj, key, &dummy, DUK_GETDESC_FLAG_IGNORE_PROTOLOOP);  /* don't push value */
}

/*
 *  Helper: handle Array object 'length' write which automatically
 *  deletes properties, see E5 Section 15.4.5.1, step 3.  This is
 *  quite tricky to get right.
 *
 *  Used by duk_hobject_putprop().
 */

DUK_LOCAL duk_uint32_t duk__get_old_array_length(duk_hthread *thr, duk_hobject *obj, duk_propdesc *temp_desc) {
	duk_bool_t rc;
	duk_tval *tv;
	duk_uint32_t res;

	DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);

	/* This function is only called for objects with array exotic behavior.
	 * The [[DefineOwnProperty]] algorithm for arrays requires that
	 * 'length' can never have a value outside the unsigned 32-bit range,
	 * attempt to write such a value is a RangeError.  Here we can thus
	 * assert for this.  When Duktape internals go around the official
	 * property write interface (doesn't happen often) this assumption is
	 * easy to accidentally break, so such code must be written carefully.
	 * See test-bi-array-push-maxlen.js.
	 */

	rc = duk__get_own_propdesc_raw(thr, obj, DUK_HTHREAD_STRING_LENGTH(thr), DUK__NO_ARRAY_INDEX, temp_desc, 0 /*flags*/);  /* don't push value */
	DUK_UNREF(rc);
	DUK_ASSERT(rc != 0);  /* arrays MUST have a 'length' property */
	DUK_ASSERT(temp_desc->e_idx >= 0);

	tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, temp_desc->e_idx);
	DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));  /* array 'length' is always a number, as we coerce it */
	DUK_ASSERT(DUK_TVAL_GET_NUMBER(tv) >= 0.0);
	DUK_ASSERT(DUK_TVAL_GET_NUMBER(tv) <= (double) 0xffffffffUL);
	DUK_ASSERT((duk_double_t) (duk_uint32_t) DUK_TVAL_GET_NUMBER(tv) == DUK_TVAL_GET_NUMBER(tv));
#if defined(DUK_USE_FASTINT)
	/* Downgrade checks are not made everywhere, so 'length' is not always
	 * a fastint (it is a number though).  This can be removed once length
	 * is always guaranteed to be a fastint.
	 */
	DUK_ASSERT(DUK_TVAL_IS_FASTINT(tv) || DUK_TVAL_IS_DOUBLE(tv));
	if (DUK_TVAL_IS_FASTINT(tv)) {
		res = (duk_uint32_t) DUK_TVAL_GET_FASTINT_U32(tv);
	} else {
		res = (duk_uint32_t) DUK_TVAL_GET_DOUBLE(tv);
	}
#else
	res = (duk_uint32_t) DUK_TVAL_GET_NUMBER(tv);
#endif  /* DUK_USE_FASTINT */

	return res;
}

DUK_LOCAL duk_uint32_t duk__to_new_array_length_checked(duk_hthread *thr) {
	duk_context *ctx = (duk_context *) thr;
	duk_uint32_t res;
	duk_double_t d;

	/* Input value should be on stack top and will be coerced and
	 * popped.  Refuse to update an Array's 'length' to a value
	 * outside the 32-bit range.  Negative zero is accepted as zero.
	 */

	/* XXX: fastint */

	d = duk_to_number(ctx, -1);
	res = (duk_uint32_t) d;
	if ((duk_double_t) res != d) {
		DUK_ERROR_RANGE(thr, DUK_STR_INVALID_ARRAY_LENGTH);
	}
	duk_pop(ctx);
	return res;
}

/* Delete elements required by a smaller length, taking into account
 * potentially non-configurable elements.  Returns non-zero if all
 * elements could be deleted, and zero if all or some elements could
 * not be deleted.  Also writes final "target length" to 'out_result_len'.
 * This is the length value that should go into the 'length' property
 * (must be set by the caller).  Never throws an error.
 */
DUK_LOCAL
duk_bool_t duk__handle_put_array_length_smaller(duk_hthread *thr,
                                                duk_hobject *obj,
                                                duk_uint32_t old_len,
                                                duk_uint32_t new_len,
                                                duk_bool_t force_flag,
                                                duk_uint32_t *out_result_len) {
	duk_uint32_t target_len;
	duk_uint_fast32_t i;
	duk_uint32_t arr_idx;
	duk_hstring *key;
	duk_tval *tv;
	duk_bool_t rc;

	DUK_DDD(DUK_DDDPRINT("new array length smaller than old (%ld -> %ld), "
	                     "probably need to remove elements",
	                     (long) old_len, (long) new_len));

	/*
	 *  New length is smaller than old length, need to delete properties above
	 *  the new length.
	 *
	 *  If array part exists, this is straightforward: array entries cannot
	 *  be non-configurable so this is guaranteed to work.
	 *
	 *  If array part does not exist, array-indexed values are scattered
	 *  in the entry part, and some may not be configurable (preventing length
	 *  from becoming lower than their index + 1).  To handle the algorithm
	 *  in E5 Section 15.4.5.1, step l correctly, we scan the entire property
	 *  set twice.
	 */

	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(obj != NULL);
	DUK_ASSERT(new_len < old_len);
	DUK_ASSERT(out_result_len != NULL);
	DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);

	if (DUK_HOBJECT_HAS_ARRAY_PART(obj)) {
		/*
		 *  All defined array-indexed properties are in the array part
		 *  (we assume the array part is comprehensive), and all array
		 *  entries are writable, configurable, and enumerable.  Thus,
		 *  nothing can prevent array entries from being deleted.
		 */

		DUK_DDD(DUK_DDDPRINT("have array part, easy case"));

		if (old_len < DUK_HOBJECT_GET_ASIZE(obj)) {
			/* XXX: assertion that entries >= old_len are already unused */
			i = old_len;
		} else {
			i = DUK_HOBJECT_GET_ASIZE(obj);
		}
		DUK_ASSERT(i <= DUK_HOBJECT_GET_ASIZE(obj));

		while (i > new_len) {
			i--;
			tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i);
			DUK_TVAL_SET_UNUSED_UPDREF(thr, tv);  /* side effects */
		}

		*out_result_len = new_len;
		return 1;
	} else {
		/*
		 *  Entries part is a bit more complex
		 */

		/* Stage 1: find highest preventing non-configurable entry (if any).
		 * When forcing, ignore non-configurability.
		 */

		DUK_DDD(DUK_DDDPRINT("no array part, slow case"));

		DUK_DDD(DUK_DDDPRINT("array length write, no array part, stage 1: find target_len "
		                     "(highest preventing non-configurable entry (if any))"));

		target_len = new_len;
		if (force_flag) {
			DUK_DDD(DUK_DDDPRINT("array length write, no array part; force flag -> skip stage 1"));
			goto skip_stage1;
		}
		for (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {
			key = DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i);
			if (!key) {
				DUK_DDD(DUK_DDDPRINT("skip entry index %ld: null key", (long) i));
				continue;
			}
			if (!DUK_HSTRING_HAS_ARRIDX(key)) {
				DUK_DDD(DUK_DDDPRINT("skip entry index %ld: key not an array index", (long) i));
				continue;
			}

			DUK_ASSERT(DUK_HSTRING_HAS_ARRIDX(key));  /* XXX: macro checks for array index flag, which is unnecessary here */
			arr_idx = DUK_HSTRING_GET_ARRIDX_SLOW(key);
			DUK_ASSERT(arr_idx != DUK__NO_ARRAY_INDEX);
			DUK_ASSERT(arr_idx < old_len);  /* consistency requires this */

			if (arr_idx < new_len) {
				DUK_DDD(DUK_DDDPRINT("skip entry index %ld: key is array index %ld, below new_len",
				                     (long) i, (long) arr_idx));
				continue;
			}
			if (DUK_HOBJECT_E_SLOT_IS_CONFIGURABLE(thr->heap, obj, i)) {
				DUK_DDD(DUK_DDDPRINT("skip entry index %ld: key is a relevant array index %ld, but configurable",
				                     (long) i, (long) arr_idx));
				continue;
			}

			/* relevant array index is non-configurable, blocks write */
			if (arr_idx >= target_len) {
				DUK_DDD(DUK_DDDPRINT("entry at index %ld has arr_idx %ld, is not configurable, "
				                     "update target_len %ld -> %ld",
				                     (long) i, (long) arr_idx, (long) target_len,
				                     (long) (arr_idx + 1)));
				target_len = arr_idx + 1;
			}
		}
	 skip_stage1:

		/* stage 2: delete configurable entries above target length */

		DUK_DDD(DUK_DDDPRINT("old_len=%ld, new_len=%ld, target_len=%ld",
		                     (long) old_len, (long) new_len, (long) target_len));

		DUK_DDD(DUK_DDDPRINT("array length write, no array part, stage 2: remove "
		                     "entries >= target_len"));

		for (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {
			key = DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i);
			if (!key) {
				DUK_DDD(DUK_DDDPRINT("skip entry index %ld: null key", (long) i));
				continue;
			}
			if (!DUK_HSTRING_HAS_ARRIDX(key)) {
				DUK_DDD(DUK_DDDPRINT("skip entry index %ld: key not an array index", (long) i));
				continue;
			}

			DUK_ASSERT(DUK_HSTRING_HAS_ARRIDX(key));  /* XXX: macro checks for array index flag, which is unnecessary here */
			arr_idx = DUK_HSTRING_GET_ARRIDX_SLOW(key);
			DUK_ASSERT(arr_idx != DUK__NO_ARRAY_INDEX);
			DUK_ASSERT(arr_idx < old_len);  /* consistency requires this */

			if (arr_idx < target_len) {
				DUK_DDD(DUK_DDDPRINT("skip entry index %ld: key is array index %ld, below target_len",
				                     (long) i, (long) arr_idx));
				continue;
			}
			DUK_ASSERT(force_flag || DUK_HOBJECT_E_SLOT_IS_CONFIGURABLE(thr->heap, obj, i));  /* stage 1 guarantees */

			DUK_DDD(DUK_DDDPRINT("delete entry index %ld: key is array index %ld",
			                     (long) i, (long) arr_idx));

			/*
			 *  Slow delete, but we don't care as we're already in a very slow path.
			 *  The delete always succeeds: key has no exotic behavior, property
			 *  is configurable, and no resize occurs.
			 */
			rc = duk_hobject_delprop_raw(thr, obj, key, force_flag ? DUK_DELPROP_FLAG_FORCE : 0);
			DUK_UNREF(rc);
			DUK_ASSERT(rc != 0);
		}

		/* stage 3: update length (done by caller), decide return code */

		DUK_DDD(DUK_DDDPRINT("array length write, no array part, stage 3: update length (done by caller)"));

		*out_result_len = target_len;

		if (target_len == new_len) {
			DUK_DDD(DUK_DDDPRINT("target_len matches new_len, return success"));
			return 1;
		}
		DUK_DDD(DUK_DDDPRINT("target_len does not match new_len (some entry prevented "
		                     "full length adjustment), return error"));
		return 0;
	}

	DUK_UNREACHABLE();
}

/* XXX: is valstack top best place for argument? */
DUK_LOCAL duk_bool_t duk__handle_put_array_length(duk_hthread *thr, duk_hobject *obj) {
	duk_context *ctx = (duk_context *) thr;
	duk_propdesc desc;
	duk_uint32_t old_len;
	duk_uint32_t new_len;
	duk_uint32_t result_len;
	duk_tval *tv;
	duk_bool_t rc;

	DUK_DDD(DUK_DDDPRINT("handling a put operation to array 'length' exotic property, "
	                     "new val: %!T",
	                     (duk_tval *) duk_get_tval(ctx, -1)));

	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(ctx != NULL);
	DUK_ASSERT(obj != NULL);

	DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);

	DUK_ASSERT(duk_is_valid_index(ctx, -1));

	/*
	 *  Get old and new length
	 */

	old_len = duk__get_old_array_length(thr, obj, &desc);
	duk_dup(ctx, -1);  /* [in_val in_val] */
	new_len = duk__to_new_array_length_checked(thr);  /* -> [in_val] */
	DUK_DDD(DUK_DDDPRINT("old_len=%ld, new_len=%ld", (long) old_len, (long) new_len));

	/*
	 *  Writability check
	 */

	if (!(desc.flags & DUK_PROPDESC_FLAG_WRITABLE)) {
		DUK_DDD(DUK_DDDPRINT("length is not writable, fail"));
		return 0;
	}

	/*
	 *  New length not lower than old length => no changes needed
	 *  (not even array allocation).
	 */

	if (new_len >= old_len) {
		DUK_DDD(DUK_DDDPRINT("new length is higher than old length, just update length, no deletions"));

		DUK_ASSERT(desc.e_idx >= 0);
		DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, desc.e_idx));
		tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, desc.e_idx);
		DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));
		/* no decref needed for a number */
		DUK_TVAL_SET_FASTINT_U32(tv, new_len);
		DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));
		return 1;
	}

	DUK_DDD(DUK_DDDPRINT("new length is lower than old length, probably must delete entries"));

	/*
	 *  New length lower than old length => delete elements, then
	 *  update length.
	 *
	 *  Note: even though a bunch of elements have been deleted, the 'desc' is
	 *  still valid as properties haven't been resized (and entries compacted).
	 */

	rc = duk__handle_put_array_length_smaller(thr, obj, old_len, new_len, 0 /*force_flag*/, &result_len);
	DUK_ASSERT(result_len >= new_len && result_len <= old_len);

	DUK_ASSERT(desc.e_idx >= 0);
	DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, desc.e_idx));
	tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, desc.e_idx);
	DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));
	/* no decref needed for a number */
	DUK_TVAL_SET_FASTINT_U32(tv, result_len);
	DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));

	/* XXX: shrink array allocation or entries compaction here? */

	return rc;
}

/*
 *  PUTPROP: Ecmascript property write.
 *
 *  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:
 *
 *    * Currently a decref may trigger a GC, which may compact an object's
 *      property allocation.  Consequently, any entry indices (e_idx) will
 *      be potentially invalidated by a decref.
 *
 *    * Exotic behaviors (strings, arrays, arguments object) require,
 *      among other things:
 *
 *      - Preprocessing before and postprocessing after an actual property
 *        write.  For example, array index write requires pre-checking the
 *        array 'length' property for access control, and may require an
 *        array 'length' update after the actual write has succeeded (but
 *        not if it fails).
 *
 *      - Deletion of multiple entries, as a result of array 'length' write.
 *
 *    * Input values are taken as pointers which may point to the valstack.
 *      If valstack is resized because of the put (this may happen at least
 *      when the array part is abandoned), the pointers can be invalidated.
 *      (We currently make a copy of all of the input values to avoid issues.)
 */

DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key, duk_tval *tv_val, duk_bool_t throw_flag) {
	duk_context *ctx = (duk_context *) thr;
	duk_tval tv_obj_copy;
	duk_tval tv_key_copy;
	duk_tval tv_val_copy;
	duk_hobject *orig = NULL;  /* NULL if tv_obj is primitive */
	duk_hobject *curr;
	duk_hstring *key = NULL;
	duk_propdesc desc;
	duk_tval *tv;
	duk_uint32_t arr_idx;
	duk_bool_t rc;
	duk_int_t e_idx;
	duk_uint_t sanity;
	duk_uint32_t new_array_length = 0;  /* 0 = no update */

	DUK_DDD(DUK_DDDPRINT("putprop: thr=%p, obj=%p, key=%p, val=%p, throw=%ld "
	                     "(obj -> %!T, key -> %!T, val -> %!T)",
	                     (void *) thr, (void *) tv_obj, (void *) tv_key, (void *) tv_val,
	                     (long) throw_flag, (duk_tval *) tv_obj, (duk_tval *) tv_key, (duk_tval *) tv_val));

	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(thr->heap != NULL);
	DUK_ASSERT(ctx != NULL);
	DUK_ASSERT(tv_obj != NULL);
	DUK_ASSERT(tv_key != NULL);
	DUK_ASSERT(tv_val != NULL);

	DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);

	/*
	 *  Make a copy of tv_obj, tv_key, and tv_val to avoid any issues of
	 *  them being invalidated by a valstack resize.
	 *
	 *  XXX: this is an overkill for some paths, so optimize this later
	 *  (or maybe switch to a stack arguments model entirely).
	 */

	DUK_TVAL_SET_TVAL(&tv_obj_copy, tv_obj);
	DUK_TVAL_SET_TVAL(&tv_key_copy, tv_key);
	DUK_TVAL_SET_TVAL(&tv_val_copy, tv_val);
	tv_obj = &tv_obj_copy;
	tv_key = &tv_key_copy;
	tv_val = &tv_val_copy;

	/*
	 *  Coercion and fast path processing.
	 */

	switch (DUK_TVAL_GET_TAG(tv_obj)) {
	case DUK_TAG_UNDEFINED:
	case DUK_TAG_NULL: {
		/* Note: unconditional throw */
		DUK_DDD(DUK_DDDPRINT("base object is undefined or null -> reject (object=%!iT)",
		                     (duk_tval *) tv_obj));
#if defined(DUK_USE_PARANOID_ERRORS)
		DUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE);
#else
		DUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, "cannot write property %s of %s",
		               duk_push_string_tval_readable(ctx, tv_key), duk_push_string_tval_readable(ctx, tv_obj));
#endif
		return 0;
	}

	case DUK_TAG_BOOLEAN: {
		DUK_DDD(DUK_DDDPRINT("base object is a boolean, start lookup from boolean prototype"));
		curr = thr->builtins[DUK_BIDX_BOOLEAN_PROTOTYPE];
		break;
	}

	case DUK_TAG_STRING: {
		duk_hstring *h = DUK_TVAL_GET_STRING(tv_obj);

		/*
		 *  Note: currently no fast path for array index writes.
		 *  They won't be possible anyway as strings are immutable.
		 */

		DUK_ASSERT(key == NULL);
		arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
		DUK_ASSERT(key != NULL);

		if (key == DUK_HTHREAD_STRING_LENGTH(thr)) {
			goto fail_not_writable;
		}

		if (arr_idx != DUK__NO_ARRAY_INDEX &&
		    arr_idx < DUK_HSTRING_GET_CHARLEN(h)) {
			goto fail_not_writable;
		}

		DUK_DDD(DUK_DDDPRINT("base object is a string, start lookup from string prototype"));
		curr = thr->builtins[DUK_BIDX_STRING_PROTOTYPE];
		goto lookup;  /* avoid double coercion */
	}

	case DUK_TAG_OBJECT: {
		orig = DUK_TVAL_GET_OBJECT(tv_obj);
		DUK_ASSERT(orig != NULL);

#if defined(DUK_USE_ROM_OBJECTS)
		/* With this check in place fast paths won't need read-only
		 * object checks.  This is technically incorrect if there are
		 * setters that cause no writes to ROM objects, but current
		 * built-ins don't have such setters.
		 */
		if (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) orig)) {
			DUK_DD(DUK_DDPRINT("attempt to putprop on read-only target object"));
			goto fail_not_writable_no_pop;  /* Must avoid duk_pop() in exit path */
		}
#endif

		/* The fast path for array property put is not fully compliant:
		 * If one places conflicting number-indexed properties into
		 * Array.prototype (for example, a non-writable Array.prototype[7])
		 * the fast path will incorrectly ignore them.
		 *
		 * This fast path could be made compliant by falling through
		 * to the slow path if the previous value was UNUSED.  This would
		 * also remove the need to check for extensibility.  Right now a
		 * non-extensible array is slower than an extensible one as far
		 * as writes are concerned.
		 *
		 * The fast path behavior is documented in more detail here:
		 * tests/ecmascript/test-misc-array-fast-write.js
		 */

		if (duk__putprop_shallow_fastpath_array_tval(thr, orig, tv_key, tv_val, &desc) != 0) {
			DUK_DDD(DUK_DDDPRINT("array fast path success"));
			return 1;
		}

		if (duk__putprop_fastpath_bufobj_tval(thr, orig, tv_key, tv_val) != 0) {
			DUK_DDD(DUK_DDDPRINT("base is bufobj, key is a number, bufferobject fast path"));
			return 1;
		}

#if defined(DUK_USE_ES6_PROXY)
		if (DUK_UNLIKELY(DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(orig))) {
			duk_hobject *h_target;
			duk_bool_t tmp_bool;

			if (duk__proxy_check_prop(thr, orig, DUK_STRIDX_SET, tv_key, &h_target)) {
				/* -> [ ... trap handler ] */
				DUK_DDD(DUK_DDDPRINT("-> proxy object 'set' for key %!T", (duk_tval *) tv_key));
				duk_push_hobject(ctx, h_target);  /* target */
				duk_push_tval(ctx, tv_key);       /* P */
				duk_push_tval(ctx, tv_val);       /* V */
				duk_push_tval(ctx, tv_obj);       /* Receiver: Proxy object */
				duk_call_method(ctx, 4 /*nargs*/);
				tmp_bool = duk_to_boolean(ctx, -1);
				duk_pop(ctx);
				if (!tmp_bool) {
					goto fail_proxy_rejected;
				}

				/* Target object must be checked for a conflicting
				 * non-configurable property.
				 */
				arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
				DUK_ASSERT(key != NULL);

				if (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {
					duk_tval *tv_targ = duk_require_tval(ctx, -1);
					duk_bool_t datadesc_reject;
					duk_bool_t accdesc_reject;

					DUK_DDD(DUK_DDDPRINT("proxy 'set': target has matching property %!O, check for "
					                     "conflicting property; tv_val=%!T, tv_targ=%!T, desc.flags=0x%08lx, "
					                     "desc.get=%p, desc.set=%p",
					                     (duk_heaphdr *) key, (duk_tval *) tv_val, (duk_tval *) tv_targ,
					                     (unsigned long) desc.flags,
					                     (void *) desc.get, (void *) desc.set));

					datadesc_reject = !(desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) &&
					                  !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) &&
					                  !(desc.flags & DUK_PROPDESC_FLAG_WRITABLE) &&
					                  !duk_js_samevalue(tv_val, tv_targ);
					accdesc_reject = (desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) &&
					                 !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) &&
					                 (desc.set == NULL);
					if (datadesc_reject || accdesc_reject) {
						DUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);
					}

					duk_pop_2(ctx);
				} else {
					duk_pop(ctx);
				}
				return 1;  /* success */
			}

			orig = h_target;  /* resume write to target */
			DUK_TVAL_SET_OBJECT(tv_obj, orig);
		}
#endif  /* DUK_USE_ES6_PROXY */

		curr = orig;
		break;
	}

	case DUK_TAG_BUFFER: {
		duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv_obj);
		duk_int_t pop_count = 0;

		/*
		 *  Because buffer values may be looped over and read/written
		 *  from, an array index fast path is important.
		 */

#if defined(DUK_USE_FASTINT)
		if (DUK_TVAL_IS_FASTINT(tv_key)) {
			arr_idx = duk__tval_fastint_to_arr_idx(tv_key);
			DUK_DDD(DUK_DDDPRINT("base object buffer, key is a fast-path fastint; arr_idx %ld", (long) arr_idx));
			pop_count = 0;
		} else
#endif
		if (DUK_TVAL_IS_NUMBER(tv_key)) {
			arr_idx = duk__tval_number_to_arr_idx(tv_key);
			DUK_DDD(DUK_DDDPRINT("base object buffer, key is a fast-path number; arr_idx %ld", (long) arr_idx));
			pop_count = 0;
		} else {
			arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
			DUK_ASSERT(key != NULL);
			DUK_DDD(DUK_DDDPRINT("base object buffer, key is a non-fast-path number; after "
			                     "coercion key is %!T, arr_idx %ld",
			                     (duk_tval *) duk_get_tval(ctx, -1), (long) arr_idx));
			pop_count = 1;
		}

		if (arr_idx != DUK__NO_ARRAY_INDEX &&
		    arr_idx < DUK_HBUFFER_GET_SIZE(h)) {
			duk_uint8_t *data;
			DUK_DDD(DUK_DDDPRINT("writing to buffer data at index %ld", (long) arr_idx));
			data = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h);

			/* XXX: duk_to_int() ensures we'll get 8 lowest bits as
			 * as input is within duk_int_t range (capped outside it).
			 */
#if defined(DUK_USE_FASTINT)
			/* Buffer writes are often integers. */
			if (DUK_TVAL_IS_FASTINT(tv_val)) {
				data[arr_idx] = (duk_uint8_t) DUK_TVAL_GET_FASTINT_U32(tv_val);
			}
			else
#endif
			{
				duk_push_tval(ctx, tv_val);
				data[arr_idx] = (duk_uint8_t) duk_to_uint32(ctx, -1);
				pop_count++;
			}

			duk_pop_n(ctx, pop_count);
			DUK_DDD(DUK_DDDPRINT("result: success (buffer data write)"));
			return 1;
		}

		if (pop_count == 0) {
			/* This is a pretty awkward control flow, but we need to recheck the
			 * key coercion here.
			 */
			arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
			DUK_ASSERT(key != NULL);
			DUK_DDD(DUK_DDDPRINT("base object buffer, key is a non-fast-path number; after "
			                     "coercion key is %!T, arr_idx %ld",
			                     (duk_tval *) duk_get_tval(ctx, -1), (long) arr_idx));
		}

		if (key == DUK_HTHREAD_STRING_LENGTH(thr) ||
		    key == DUK_HTHREAD_STRING_BYTE_LENGTH(thr) ||
		    key == DUK_HTHREAD_STRING_BYTE_OFFSET(thr) ||
		    key == DUK_HTHREAD_STRING_BYTES_PER_ELEMENT(thr)) {
			goto fail_not_writable;
		}

		DUK_DDD(DUK_DDDPRINT("base object is a buffer, start lookup from buffer prototype"));
		curr = thr->builtins[DUK_BIDX_BUFFER_PROTOTYPE];
		goto lookup;  /* avoid double coercion */
	}

	case DUK_TAG_POINTER: {
		DUK_DDD(DUK_DDDPRINT("base object is a pointer, start lookup from pointer prototype"));
		curr = thr->builtins[DUK_BIDX_POINTER_PROTOTYPE];
		break;
	}

	case DUK_TAG_LIGHTFUNC: {
		/* All lightfunc own properties are non-writable and the lightfunc
		 * is considered non-extensible.  However, the write may be captured
		 * by an inherited setter which means we can't stop the lookup here.
		 */

		arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);

		if (duk__key_is_lightfunc_ownprop(thr, key)) {
			goto fail_not_writable;
		}

		DUK_DDD(DUK_DDDPRINT("base object is a lightfunc, start lookup from function prototype"));
		curr = thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE];
		goto lookup;  /* avoid double coercion */
	}

#if defined(DUK_USE_FASTINT)
	case DUK_TAG_FASTINT:
#endif
	default: {
		/* number */
		DUK_DDD(DUK_DDDPRINT("base object is a number, start lookup from number prototype"));
		DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_obj));
		curr = thr->builtins[DUK_BIDX_NUMBER_PROTOTYPE];
		break;
	}
	}

	DUK_ASSERT(key == NULL);
	arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
	DUK_ASSERT(key != NULL);

 lookup:

	/*
	 *  Check whether the property already exists in the prototype chain.
	 *  Note that the actual write goes into the original base object
	 *  (except if an accessor property captures the write).
	 */

	/* [key] */

	DUK_ASSERT(curr != NULL);
	sanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;
	do {
		if (!duk__get_own_propdesc_raw(thr, curr, key, arr_idx, &desc, 0 /*flags*/)) {  /* don't push value */
			goto next_in_chain;
		}

		if (desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) {
			/*
			 *  Found existing accessor property (own or inherited).
			 *  Call setter with 'this' set to orig, and value as the only argument.
			 *  Setter calls are OK even for ROM objects.
			 *
			 *  Note: no exotic arguments object behavior, because [[Put]] never
			 *  calls [[DefineOwnProperty]] (E5 Section 8.12.5, step 5.b).
			 */

			duk_hobject *setter;

			DUK_DD(DUK_DDPRINT("put to an own or inherited accessor, calling setter"));

			setter = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, curr, desc.e_idx);
			if (!setter) {
				goto fail_no_setter;
			}
			duk_push_hobject(ctx, setter);
			duk_push_tval(ctx, tv_obj);  /* note: original, uncoerced base */
			duk_push_tval(ctx, tv_val);  /* [key setter this val] */
#ifdef DUK_USE_NONSTD_SETTER_KEY_ARGUMENT
			duk_dup(ctx, -4);
			duk_call_method(ctx, 2);     /* [key setter this val key] -> [key retval] */
#else
			duk_call_method(ctx, 1);     /* [key setter this val] -> [key retval] */
#endif
			duk_pop(ctx);                /* ignore retval -> [key] */
			goto success_no_arguments_exotic;
		}

		if (orig == NULL) {
			/*
			 *  Found existing own or inherited plain property, but original
			 *  base is a primitive value.
			 */
			DUK_DD(DUK_DDPRINT("attempt to create a new property in a primitive base object"));
			goto fail_base_primitive;
		}

		if (curr != orig) {
			/*
			 *  Found existing inherited plain property.
			 *  Do an access control check, and if OK, write
			 *  new property to 'orig'.
			 */
			if (!DUK_HOBJECT_HAS_EXTENSIBLE(orig)) {
				DUK_DD(DUK_DDPRINT("found existing inherited plain property, but original object is not extensible"));
				goto fail_not_extensible;
			}
			if (!(desc.flags & DUK_PROPDESC_FLAG_WRITABLE)) {
				DUK_DD(DUK_DDPRINT("found existing inherited plain property, original object is extensible, but inherited property is not writable"));
				goto fail_not_writable;
			}
			DUK_DD(DUK_DDPRINT("put to new property, object extensible, inherited property found and is writable"));
			goto create_new;
		} else {
			/*
			 *  Found existing own (non-inherited) plain property.
			 *  Do an access control check and update in place.
			 */

			if (!(desc.flags & DUK_PROPDESC_FLAG_WRITABLE)) {
				DUK_DD(DUK_DDPRINT("found existing own (non-inherited) plain property, but property is not writable"));
				goto fail_not_writable;
			}
			if (desc.flags & DUK_PROPDESC_FLAG_VIRTUAL) {
				DUK_DD(DUK_DDPRINT("found existing own (non-inherited) virtual property, property is writable"));
				if (DUK_HOBJECT_IS_BUFFEROBJECT(curr)) {
					duk_hbufferobject *h_bufobj;
					duk_uint_t byte_off;
					duk_small_uint_t elem_size;

					h_bufobj = (duk_hbufferobject *) curr;
					DUK_ASSERT_HBUFFEROBJECT_VALID(h_bufobj);

					DUK_DD(DUK_DDPRINT("writable virtual property is in buffer object"));

					/* Careful with wrapping: arr_idx upshift may easily wrap, whereas
					 * length downshift won't.
					 */
					if (arr_idx < (h_bufobj->length >> h_bufobj->shift)) {
						duk_uint8_t *data;
						DUK_DDD(DUK_DDDPRINT("writing to buffer data at index %ld", (long) arr_idx));

						DUK_ASSERT(arr_idx != DUK__NO_ARRAY_INDEX);  /* index/length check guarantees */
						byte_off = arr_idx << h_bufobj->shift;       /* no wrap assuming h_bufobj->length is valid */
						elem_size = 1 << h_bufobj->shift;

						/* Coerce to number before validating pointers etc so that the
						 * number coercions in duk_hbufferobject_validated_write() are
						 * guaranteed to be side effect free and not invalidate the
						 * pointer checks we do here.
						 */
						duk_push_tval(ctx, tv_val);
						duk_to_number(ctx, -1);

						if (h_bufobj->buf != NULL && DUK_HBUFFEROBJECT_VALID_BYTEOFFSET_EXCL(h_bufobj, byte_off + elem_size)) {
							data = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf) + h_bufobj->offset + byte_off;
							duk_hbufferobject_validated_write(ctx, h_bufobj, data, elem_size);
						} else {
							DUK_D(DUK_DPRINT("bufferobject access out of underlying buffer, ignoring (write skipped)"));
						}
						duk_pop(ctx);
						goto success_no_arguments_exotic;
					}
				}

				goto fail_internal;  /* should not happen */
			}
			DUK_DD(DUK_DDPRINT("put to existing own plain property, property is writable"));
			goto update_old;
		}
		DUK_UNREACHABLE();

	 next_in_chain:
		/* XXX: option to pretend property doesn't exist if sanity limit is
		 * hit might be useful.
		 */
		if (sanity-- == 0) {
			DUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);
		}
		curr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);
	} while (curr);

	/*
	 *  Property not found in prototype chain.
	 */

	DUK_DDD(DUK_DDDPRINT("property not found in prototype chain"));

	if (orig == NULL) {
		DUK_DD(DUK_DDPRINT("attempt to create a new property in a primitive base object"));
		goto fail_base_primitive;
	}

	if (!DUK_HOBJECT_HAS_EXTENSIBLE(orig)) {
		DUK_DD(DUK_DDPRINT("put to a new property (not found in prototype chain), but original object not extensible"));
		goto fail_not_extensible;
	}

	goto create_new;

 update_old:

	/*
	 *  Update an existing property of the base object.
	 */

	/* [key] */

	DUK_DDD(DUK_DDDPRINT("update an existing property of the original object"));

	DUK_ASSERT(orig != NULL);
#if defined(DUK_USE_ROM_OBJECTS)
	/* This should not happen because DUK_TAG_OBJECT case checks
	 * for this already, but check just in case.
	 */
	if (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) orig)) {
		goto fail_not_writable;
	}
#endif

	/* Although there are writable virtual properties (e.g. plain buffer
	 * and buffer object number indices), they are handled before we come
	 * here.
	 */
	DUK_ASSERT((desc.flags & DUK_PROPDESC_FLAG_VIRTUAL) == 0);
	DUK_ASSERT(desc.a_idx >= 0 || desc.e_idx >= 0);

	if (DUK_HOBJECT_HAS_EXOTIC_ARRAY(orig) &&
	    key == DUK_HTHREAD_STRING_LENGTH(thr)) {
		/*
		 *  Write to 'length' of an array is a very complex case
		 *  handled in a helper which updates both the array elements
		 *  and writes the new 'length'.  The write may result in an
		 *  unconditional RangeError or a partial write (indicated
		 *  by a return code).
		 *
		 *  Note: the helper has an unnecessary writability check
		 *  for 'length', we already know it is writable.
		 */

		DUK_DDD(DUK_DDDPRINT("writing existing 'length' property to array exotic, invoke complex helper"));

		/* XXX: the helper currently assumes stack top contains new
		 * 'length' value and the whole calling convention is not very
		 * compatible with what we need.
		 */

		duk_push_tval(ctx, tv_val);  /* [key val] */
		rc = duk__handle_put_array_length(thr, orig);
		duk_pop(ctx);  /* [key val] -> [key] */
		if (!rc) {
			goto fail_array_length_partial;
		}

		/* key is 'length', cannot match argument exotic behavior */
		goto success_no_arguments_exotic;
	}

	if (desc.e_idx >= 0) {
		tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, orig, desc.e_idx);
		DUK_DDD(DUK_DDDPRINT("previous entry value: %!iT", (duk_tval *) tv));
		DUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv_val);  /* side effects */
		/* don't touch property attributes or hash part */
		DUK_DD(DUK_DDPRINT("put to an existing entry at index %ld -> new value %!iT",
		                   (long) desc.e_idx, (duk_tval *) tv));
	} else {
		/* Note: array entries are always writable, so the writability check
		 * above is pointless for them.  The check could be avoided with some
		 * refactoring but is probably not worth it.
		 */

		DUK_ASSERT(desc.a_idx >= 0);
		tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, orig, desc.a_idx);
		DUK_DDD(DUK_DDDPRINT("previous array value: %!iT", (duk_tval *) tv));
		DUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv_val);  /* side effects */
		DUK_DD(DUK_DDPRINT("put to an existing array entry at index %ld -> new value %!iT",
		                   (long) desc.a_idx, (duk_tval *) tv));
	}

	/* Regardless of whether property is found in entry or array part,
	 * it may have arguments exotic behavior (array indices may reside
	 * in entry part for abandoned / non-existent array parts).
	 */
	goto success_with_arguments_exotic;

 create_new:

	/*
	 *  Create a new property in the original object.
	 *
	 *  Exotic properties need to be reconsidered here from a write
	 *  perspective (not just property attributes perspective).
	 *  However, the property does not exist in the object already,
	 *  so this limits the kind of exotic properties that apply.
	 */

	/* [key] */

	DUK_DDD(DUK_DDDPRINT("create new property to original object"));

	DUK_ASSERT(orig != NULL);

#if defined(DUK_USE_ROM_OBJECTS)
	/* This should not happen because DUK_TAG_OBJECT case checks
	 * for this already, but check just in case.
	 */
	if (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) orig)) {
		goto fail_not_writable;
	}
#endif

	/* Not possible because array object 'length' is present
	 * from its creation and cannot be deleted, and is thus
	 * caught as an existing property above.
	 */
	DUK_ASSERT(!(DUK_HOBJECT_HAS_EXOTIC_ARRAY(orig) &&
	             key == DUK_HTHREAD_STRING_LENGTH(thr)));

	if (DUK_HOBJECT_HAS_EXOTIC_ARRAY(orig) &&
	    arr_idx != DUK__NO_ARRAY_INDEX) {
		/* automatic length update */
		duk_uint32_t old_len;

		old_len = duk__get_old_array_length(thr, orig, &desc);

		if (arr_idx >= old_len) {
			DUK_DDD(DUK_DDDPRINT("write new array entry requires length update "
			                     "(arr_idx=%ld, old_len=%ld)",
			                     (long) arr_idx, (long) old_len));

			if (!(desc.flags & DUK_PROPDESC_FLAG_WRITABLE)) {
				DUK_DD(DUK_DDPRINT("attempt to extend array, but array 'length' is not writable"));
				goto fail_not_writable;
			}

			/* Note: actual update happens once write has been completed
			 * without error below.  The write should always succeed
			 * from a specification viewpoint, but we may e.g. run out
			 * of memory.  It's safer in this order.
			 */

			DUK_ASSERT(arr_idx != 0xffffffffUL);
			new_array_length = arr_idx + 1;  /* flag for later write */
		} else {
			DUK_DDD(DUK_DDDPRINT("write new array entry does not require length update "
			                     "(arr_idx=%ld, old_len=%ld)",
			                     (long) arr_idx, (long) old_len));
		}
	}

 /* write_to_array_part: */

	/*
	 *  Write to array part?
	 *
	 *  Note: array abandonding requires a property resize which uses
	 *  'rechecks' valstack for temporaries and may cause any existing
	 *  valstack pointers to be invalidated.  To protect against this,
	 *  tv_obj, tv_key, and tv_val are copies of the original inputs.
	 */

	if (arr_idx != DUK__NO_ARRAY_INDEX &&
	    DUK_HOBJECT_HAS_ARRAY_PART(orig)) {
		if (arr_idx < DUK_HOBJECT_GET_ASIZE(orig)) {
			goto no_array_growth;
		}

		/*
		 *  Array needs to grow, but we don't want it becoming too sparse.
		 *  If it were to become sparse, abandon array part, moving all
		 *  array entries into the entries part (for good).
		 *
		 *  Since we don't keep track of actual density (used vs. size) of
		 *  the array part, we need to estimate somehow.  The check is made
		 *  in two parts:
		 *
		 *    - Check whether the resize need is small compared to the
		 *      current size (relatively); if so, resize without further
		 *      checking (essentially we assume that the original part is
		 *      "dense" so that the result would be dense enough).
		 *
		 *    - Otherwise, compute the resize using an actual density
		 *      measurement based on counting the used array entries.
		 */

		DUK_DDD(DUK_DDDPRINT("write to new array requires array resize, decide whether to do a "
		                     "fast resize without abandon check (arr_idx=%ld, old_size=%ld)",
		                     (long) arr_idx, (long) DUK_HOBJECT_GET_ASIZE(orig)));

		if (duk__abandon_array_slow_check_required(arr_idx, DUK_HOBJECT_GET_ASIZE(orig))) {
			duk_uint32_t old_used;
			duk_uint32_t old_size;

			DUK_DDD(DUK_DDDPRINT("=> fast check is NOT OK, do slow check for array abandon"));

			duk__compute_a_stats(thr, orig, &old_used, &old_size);

			DUK_DDD(DUK_DDDPRINT("abandon check, array stats: old_used=%ld, old_size=%ld, arr_idx=%ld",
			                     (long) old_used, (long) old_size, (long) arr_idx));

			/* Note: intentionally use approximations to shave a few instructions:
			 *   a_used = old_used  (accurate: old_used + 1)
			 *   a_size = arr_idx   (accurate: arr_idx + 1)
			 */
			if (duk__abandon_array_density_check(old_used, arr_idx)) {
				DUK_DD(DUK_DDPRINT("write to new array entry beyond current length, "
				                   "decided to abandon array part (would become too sparse)"));

				/* abandoning requires a props allocation resize and
				 * 'rechecks' the valstack, invalidating any existing
				 * valstack value pointers!
				 */
				duk__abandon_array_checked(thr, orig);
				DUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(orig));

				goto write_to_entry_part;
			}

			DUK_DDD(DUK_DDDPRINT("=> decided to keep array part"));
		} else {
			DUK_DDD(DUK_DDDPRINT("=> fast resize is OK"));
		}

		DUK_DD(DUK_DDPRINT("write to new array entry beyond current length, "
		                   "decided to extend current allocation"));

		duk__grow_props_for_array_item(thr, orig, arr_idx);

	 no_array_growth:

		/* Note: assume array part is comprehensive, so that either
		 * the write goes to the array part, or we've abandoned the
		 * array above (and will not come here).
		 */

		DUK_ASSERT(DUK_HOBJECT_HAS_ARRAY_PART(orig));
		DUK_ASSERT(arr_idx < DUK_HOBJECT_GET_ASIZE(orig));

		tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, orig, arr_idx);
		/* prev value must be unused, no decref */
		DUK_ASSERT(DUK_TVAL_IS_UNUSED(tv));
		DUK_TVAL_SET_TVAL(tv, tv_val);
		DUK_TVAL_INCREF(thr, tv);
		DUK_DD(DUK_DDPRINT("put to new array entry: %ld -> %!T",
		                   (long) arr_idx, (duk_tval *) tv));

		/* Note: array part values are [[Writable]], [[Enumerable]],
		 * and [[Configurable]] which matches the required attributes
		 * here.
		 */
		goto entry_updated;
	}

 write_to_entry_part:

	/*
	 *  Write to entry part
	 */

	/* entry allocation updates hash part and increases the key
	 * refcount; may need a props allocation resize but doesn't
	 * 'recheck' the valstack.
	 */
	e_idx = duk__alloc_entry_checked(thr, orig, key);
	DUK_ASSERT(e_idx >= 0);

	tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, orig, e_idx);
	/* prev value can be garbage, no decref */
	DUK_TVAL_SET_TVAL(tv, tv_val);
	DUK_TVAL_INCREF(thr, tv);
	DUK_HOBJECT_E_SET_FLAGS(thr->heap, orig, e_idx, DUK_PROPDESC_FLAGS_WEC);
	goto entry_updated;

 entry_updated:

	/*
	 *  Possible pending array length update, which must only be done
	 *  if the actual entry write succeeded.
	 */

	if (new_array_length > 0) {
		/*
		 *  Note: zero works as a "no update" marker because the new length
		 *  can never be zero after a new property is written.
		 *
		 *  Note: must re-lookup because calls above (e.g. duk__alloc_entry_checked())
		 *  may realloc and compact properties and hence change e_idx.
		 */

		DUK_DDD(DUK_DDDPRINT("write successful, pending array length update to: %ld",
		                     (long) new_array_length));

		rc = duk__get_own_propdesc_raw(thr, orig, DUK_HTHREAD_STRING_LENGTH(thr), DUK__NO_ARRAY_INDEX, &desc, 0 /*flags*/);  /* don't push value */
		DUK_UNREF(rc);
		DUK_ASSERT(rc != 0);
		DUK_ASSERT(desc.e_idx >= 0);

		tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, orig, desc.e_idx);
		DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));
		/* no need for decref/incref because value is a number */
		DUK_TVAL_SET_FASTINT_U32(tv, new_array_length);
	}

	/*
	 *  Arguments exotic behavior not possible for new properties: all
	 *  magically bound properties are initially present in the arguments
	 *  object, and if they are deleted, the binding is also removed from
	 *  parameter map.
	 */

	goto success_no_arguments_exotic;

 success_with_arguments_exotic:

	/*
	 *  Arguments objects have exotic [[DefineOwnProperty]] which updates
	 *  the internal 'map' of arguments for writes to currently mapped
	 *  arguments.  More conretely, writes to mapped arguments generate
	 *  a write to a bound variable.
	 *
	 *  The [[Put]] algorithm invokes [[DefineOwnProperty]] for existing
	 *  data properties and new properties, but not for existing accessors.
	 *  Hence, in E5 Section 10.6 ([[DefinedOwnProperty]] algorithm), we
	 *  have a Desc with 'Value' (and possibly other properties too), and
	 *  we end up in step 5.b.i.
	 */

	if (arr_idx != DUK__NO_ARRAY_INDEX &&
	    DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(orig)) {
		/* Note: only numbered indices are relevant, so arr_idx fast reject
		 * is good (this is valid unless there are more than 4**32-1 arguments).
		 */

		DUK_DDD(DUK_DDDPRINT("putprop successful, arguments exotic behavior needed"));

		/* Note: we can reuse 'desc' here */

		/* XXX: top of stack must contain value, which helper doesn't touch,
		 * rework to use tv_val directly?
		 */

		duk_push_tval(ctx, tv_val);
		(void) duk__check_arguments_map_for_put(thr, orig, key, &desc, throw_flag);
		duk_pop(ctx);
	}
	/* fall thru */

 success_no_arguments_exotic:
	/* shared exit path now */
	DUK_DDD(DUK_DDDPRINT("result: success"));
	duk_pop(ctx);  /* remove key */
	return 1;

#if defined(DUK_USE_ES6_PROXY)
 fail_proxy_rejected:
	DUK_DDD(DUK_DDDPRINT("result: error, proxy rejects"));
	if (throw_flag) {
		DUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);
	}
	/* Note: no key on stack */
	return 0;
#endif

 fail_base_primitive:
	DUK_DDD(DUK_DDDPRINT("result: error, base primitive"));
	if (throw_flag) {
#if defined(DUK_USE_PARANOID_ERRORS)
		DUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE);
#else
		DUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, "cannot write property %s of %s",
		               duk_push_string_tval_readable(ctx, tv_key), duk_push_string_tval_readable(ctx, tv_obj));
#endif
	}
	duk_pop(ctx);  /* remove key */
	return 0;

 fail_not_extensible:
	DUK_DDD(DUK_DDDPRINT("result: error, not extensible"));
	if (throw_flag) {
		DUK_ERROR_TYPE(thr, DUK_STR_NOT_EXTENSIBLE);
	}
	duk_pop(ctx);  /* remove key */
	return 0;

 fail_not_writable:
	DUK_DDD(DUK_DDDPRINT("result: error, not writable"));
	if (throw_flag) {
		DUK_ERROR_TYPE(thr, DUK_STR_NOT_WRITABLE);
	}
	duk_pop(ctx);  /* remove key */
	return 0;

#if defined(DUK_USE_ROM_OBJECTS)
 fail_not_writable_no_pop:
	DUK_DDD(DUK_DDDPRINT("result: error, not writable"));
	if (throw_flag) {
		DUK_ERROR_TYPE(thr, DUK_STR_NOT_WRITABLE);
	}
	return 0;
#endif

 fail_array_length_partial:
	DUK_DDD(DUK_DDDPRINT("result: error, array length write only partially successful"));
	if (throw_flag) {
		DUK_ERROR_TYPE(thr, DUK_STR_ARRAY_LENGTH_WRITE_FAILED);
	}
	duk_pop(ctx);  /* remove key */
	return 0;

 fail_no_setter:
	DUK_DDD(DUK_DDDPRINT("result: error, accessor property without setter"));
	if (throw_flag) {
		DUK_ERROR_TYPE(thr, DUK_STR_SETTER_UNDEFINED);
	}
	duk_pop(ctx);  /* remove key */
	return 0;

 fail_internal:
	DUK_DDD(DUK_DDDPRINT("result: error, internal"));
	if (throw_flag) {
		DUK_ERROR_INTERNAL_DEFMSG(thr);
	}
	duk_pop(ctx);  /* remove key */
	return 0;
}

/*
 *  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) {
	duk_propdesc desc;
	duk_tval *tv;
	duk_uint32_t arr_idx;
	duk_bool_t throw_flag;
	duk_bool_t force_flag;

	throw_flag = (flags & DUK_DELPROP_FLAG_THROW);
	force_flag = (flags & DUK_DELPROP_FLAG_FORCE);

	DUK_DDD(DUK_DDDPRINT("delprop_raw: thr=%p, obj=%p, key=%p, throw=%ld, force=%ld (obj -> %!O, key -> %!O)",
	                     (void *) thr, (void *) obj, (void *) key, (long) throw_flag, (long) force_flag,
	                     (duk_heaphdr *) obj, (duk_heaphdr *) key));

	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(thr->heap != NULL);
	DUK_ASSERT(obj != NULL);
	DUK_ASSERT(key != NULL);

	DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);

	arr_idx = DUK_HSTRING_GET_ARRIDX_FAST(key);

	/* 0 = don't push current value */
	if (!duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &desc, 0 /*flags*/)) {  /* don't push value */
		DUK_DDD(DUK_DDDPRINT("property not found, succeed always"));
		goto success;
	}

#if defined(DUK_USE_ROM_OBJECTS)
	if (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {
		DUK_DD(DUK_DDPRINT("attempt to delprop on read-only target object"));
		goto fail_not_configurable;
	}
#endif

	if ((desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) == 0 && !force_flag) {
		goto fail_not_configurable;
	}
	if (desc.a_idx < 0 && desc.e_idx < 0) {
		/* Currently there are no deletable virtual properties, but
		 * with force_flag we might attempt to delete one.
		 */
		goto fail_virtual;
	}

	if (desc.a_idx >= 0) {
		DUK_ASSERT(desc.e_idx < 0);

		tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, desc.a_idx);
		DUK_TVAL_SET_UNUSED_UPDREF(thr, tv);  /* side effects */
		goto success;
	} else {
		duk_hobject *h_get = NULL;
		duk_hobject *h_set = NULL;
		duk_tval tv_tmp;

		DUK_ASSERT(desc.a_idx < 0);

		/* Set property slot to an empty state.  Careful not to invoke
		 * any side effects while using desc.e_idx so that it doesn't
		 * get invalidated by a finalizer mutating our object.
		 */

		/* remove hash entry (no decref) */
#if defined(DUK_USE_HOBJECT_HASH_PART)
		if (desc.h_idx >= 0) {
			duk_uint32_t *h_base = DUK_HOBJECT_H_GET_BASE(thr->heap, obj);

			DUK_DDD(DUK_DDDPRINT("removing hash entry at h_idx %ld", (long) desc.h_idx));
			DUK_ASSERT(DUK_HOBJECT_GET_HSIZE(obj) > 0);
			DUK_ASSERT((duk_uint32_t) desc.h_idx < DUK_HOBJECT_GET_HSIZE(obj));
			h_base[desc.h_idx] = DUK__HASH_DELETED;
		} else {
			DUK_ASSERT(DUK_HOBJECT_GET_HSIZE(obj) == 0);
		}
#else
		DUK_ASSERT(DUK_HOBJECT_GET_HSIZE(obj) == 0);
#endif

		/* remove value */
		DUK_DDD(DUK_DDDPRINT("before removing value, e_idx %ld, key %p, key at slot %p",
		                     (long) desc.e_idx, (void *) key, (void *) DUK_HOBJECT_E_GET_KEY(thr->heap, obj, desc.e_idx)));
		DUK_DDD(DUK_DDDPRINT("removing value at e_idx %ld", (long) desc.e_idx));
		DUK_MEMSET((void *) &tv_tmp, 0, sizeof(tv_tmp));
		DUK_TVAL_SET_UNDEFINED(&tv_tmp);
		if (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, desc.e_idx)) {
			h_get = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, desc.e_idx);
			h_set = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, desc.e_idx);
			DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, desc.e_idx, NULL);
			DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, desc.e_idx, NULL);
		} else {
			tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, desc.e_idx);
			DUK_TVAL_SET_TVAL(&tv_tmp, tv);
			DUK_TVAL_SET_UNDEFINED(tv);
		}
#if 0
		/* Not strictly necessary because if key == NULL, flag MUST be ignored. */
		DUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, desc.e_idx, 0);
#endif

		/* remove key */
		DUK_DDD(DUK_DDDPRINT("before removing key, e_idx %ld, key %p, key at slot %p",
		                     (long) desc.e_idx, (void *) key, (void *) DUK_HOBJECT_E_GET_KEY(thr->heap, obj, desc.e_idx)));
		DUK_DDD(DUK_DDDPRINT("removing key at e_idx %ld", (long) desc.e_idx));
		DUK_ASSERT(key == DUK_HOBJECT_E_GET_KEY(thr->heap, obj, desc.e_idx));
		DUK_HOBJECT_E_SET_KEY(thr->heap, obj, desc.e_idx, NULL);

		/* Do decrefs only with safe pointers to avoid side effects
		 * disturbing e_idx.
		 */
		DUK_TVAL_DECREF(thr, &tv_tmp);
		DUK_HOBJECT_DECREF_ALLOWNULL(thr, h_get);
		DUK_HOBJECT_DECREF_ALLOWNULL(thr, h_set);
		DUK_HSTRING_DECREF(thr, key);
		goto success;
	}

	DUK_UNREACHABLE();

 success:
	/*
	 *  Argument exotic [[Delete]] behavior (E5 Section 10.6) is
	 *  a post-check, keeping arguments internal 'map' in sync with
	 *  any successful deletes (note that property does not need to
	 *  exist for delete to 'succeed').
	 *
	 *  Delete key from 'map'.  Since 'map' only contains array index
	 *  keys, we can use arr_idx for a fast skip.
	 */

	DUK_DDD(DUK_DDDPRINT("delete successful, check for arguments exotic behavior"));

	if (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj)) {
		/* Note: only numbered indices are relevant, so arr_idx fast reject
		 * is good (this is valid unless there are more than 4**32-1 arguments).
		 */

		DUK_DDD(DUK_DDDPRINT("delete successful, arguments exotic behavior needed"));

		/* Note: we can reuse 'desc' here */
		(void) duk__check_arguments_map_for_delete(thr, obj, key, &desc);
	}

	DUK_DDD(DUK_DDDPRINT("delete successful"));
	return 1;

 fail_virtual:
	DUK_DDD(DUK_DDDPRINT("delete failed: property found, force flag, but virtual"));

	if (throw_flag) {
		DUK_ERROR_TYPE(thr, DUK_STR_PROPERTY_IS_VIRTUAL);
	}
	return 0;

 fail_not_configurable:
	DUK_DDD(DUK_DDDPRINT("delete failed: property found, not configurable"));

	if (throw_flag) {
		DUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);
	}
	return 0;
}

/*
 *  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) {
	duk_context *ctx = (duk_context *) thr;
	duk_hstring *key = NULL;
#if defined(DUK_USE_ES6_PROXY)
	duk_propdesc desc;
#endif
	duk_int_t entry_top;
	duk_uint32_t arr_idx = DUK__NO_ARRAY_INDEX;
	duk_bool_t rc;

	DUK_DDD(DUK_DDDPRINT("delprop: thr=%p, obj=%p, key=%p (obj -> %!T, key -> %!T)",
	                     (void *) thr, (void *) tv_obj, (void *) tv_key,
	                     (duk_tval *) tv_obj, (duk_tval *) tv_key));

	DUK_ASSERT(ctx != NULL);
	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(thr->heap != NULL);
	DUK_ASSERT(tv_obj != NULL);
	DUK_ASSERT(tv_key != NULL);

	DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);

	/* Storing the entry top is cheaper here to ensure stack is correct at exit,
	 * as there are several paths out.
	 */
	entry_top = duk_get_top(ctx);

	if (DUK_TVAL_IS_UNDEFINED(tv_obj) ||
	    DUK_TVAL_IS_NULL(tv_obj)) {
		DUK_DDD(DUK_DDDPRINT("base object is undefined or null -> reject"));
		goto fail_invalid_base_uncond;
	}

	duk_push_tval(ctx, tv_obj);
	duk_push_tval(ctx, tv_key);

	tv_obj = DUK_GET_TVAL_NEGIDX(ctx, -2);
	if (DUK_TVAL_IS_OBJECT(tv_obj)) {
		duk_hobject *obj = DUK_TVAL_GET_OBJECT(tv_obj);
		DUK_ASSERT(obj != NULL);

#if defined(DUK_USE_ES6_PROXY)
		if (DUK_UNLIKELY(DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(obj))) {
			duk_hobject *h_target;
			duk_bool_t tmp_bool;

			/* Note: proxy handling must happen before key is string coerced. */

			if (duk__proxy_check_prop(thr, obj, DUK_STRIDX_DELETE_PROPERTY, tv_key, &h_target)) {
				/* -> [ ... trap handler ] */
				DUK_DDD(DUK_DDDPRINT("-> proxy object 'deleteProperty' for key %!T", (duk_tval *) tv_key));
				duk_push_hobject(ctx, h_target);  /* target */
				duk_push_tval(ctx, tv_key);       /* P */
				duk_call_method(ctx, 2 /*nargs*/);
				tmp_bool = duk_to_boolean(ctx, -1);
				duk_pop(ctx);
				if (!tmp_bool) {
					goto fail_proxy_rejected;  /* retval indicates delete failed */
				}

				/* Target object must be checked for a conflicting
				 * non-configurable property.
				 */
				arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
				DUK_ASSERT(key != NULL);

				if (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, 0 /*flags*/)) {  /* don't push value */
					int desc_reject;

					DUK_DDD(DUK_DDDPRINT("proxy 'deleteProperty': target has matching property %!O, check for "
					                     "conflicting property; desc.flags=0x%08lx, "
					                     "desc.get=%p, desc.set=%p",
					                     (duk_heaphdr *) key, (unsigned long) desc.flags,
					                     (void *) desc.get, (void *) desc.set));

					desc_reject = !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE);
					if (desc_reject) {
						/* unconditional */
						DUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);
					}
				}
				rc = 1;  /* success */
				goto done_rc;
			}

			obj = h_target;  /* resume delete to target */
		}
#endif  /* DUK_USE_ES6_PROXY */

		duk_to_string(ctx, -1);
		key = duk_get_hstring(ctx, -1);
		DUK_ASSERT(key != NULL);

		rc = duk_hobject_delprop_raw(thr, obj, key, throw_flag ? DUK_DELPROP_FLAG_THROW : 0);
		goto done_rc;
	} else if (DUK_TVAL_IS_STRING(tv_obj)) {
		/* XXX: unnecessary string coercion for array indices,
		 * intentional to keep small.
		 */
		duk_hstring *h = DUK_TVAL_GET_STRING(tv_obj);
		DUK_ASSERT(h != NULL);

		duk_to_string(ctx, -1);
		key = duk_get_hstring(ctx, -1);
		DUK_ASSERT(key != NULL);

		if (key == DUK_HTHREAD_STRING_LENGTH(thr)) {
			goto fail_not_configurable;
		}

		arr_idx = DUK_HSTRING_GET_ARRIDX_FAST(key);

		if (arr_idx != DUK__NO_ARRAY_INDEX &&
		    arr_idx < DUK_HSTRING_GET_CHARLEN(h)) {
			goto fail_not_configurable;
		}
	} else if (DUK_TVAL_IS_BUFFER(tv_obj)) {
		/* XXX: unnecessary string coercion for array indices,
		 * intentional to keep small; some overlap with string
		 * handling.
		 */
		duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv_obj);
		DUK_ASSERT(h != NULL);

		duk_to_string(ctx, -1);
		key = duk_get_hstring(ctx, -1);
		DUK_ASSERT(key != NULL);

		if (key == DUK_HTHREAD_STRING_LENGTH(thr)) {
			goto fail_not_configurable;
		}

		arr_idx = DUK_HSTRING_GET_ARRIDX_FAST(key);

		if (arr_idx != DUK__NO_ARRAY_INDEX &&
		    arr_idx < DUK_HBUFFER_GET_SIZE(h)) {
			goto fail_not_configurable;
		}
	} else if (DUK_TVAL_IS_LIGHTFUNC(tv_obj)) {
		/* Lightfunc virtual properties are non-configurable, so
		 * reject if match any of them.
		 */

		duk_to_string(ctx, -1);
		key = duk_get_hstring(ctx, -1);
		DUK_ASSERT(key != NULL);

		if (duk__key_is_lightfunc_ownprop(thr, key)) {
			goto fail_not_configurable;
		}
	}

	/* non-object base, no offending virtual property */
	rc = 1;
	goto done_rc;

 done_rc:
	duk_set_top(ctx, entry_top);
	return rc;

 fail_invalid_base_uncond:
	/* Note: unconditional throw */
	DUK_ASSERT(duk_get_top(ctx) == entry_top);
#if defined(DUK_USE_PARANOID_ERRORS)
	DUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE);
#else
	DUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, "cannot delete property %s of %s",
	               duk_push_string_tval_readable(ctx, tv_key), duk_push_string_tval_readable(ctx, tv_obj));
#endif
	return 0;

#if defined(DUK_USE_ES6_PROXY)
 fail_proxy_rejected:
	if (throw_flag) {
		DUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);
	}
	duk_set_top(ctx, entry_top);
	return 0;
#endif

 fail_not_configurable:
	if (throw_flag) {
		DUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);
	}
	duk_set_top(ctx, entry_top);
	return 0;
}

/*
 *  Internal helper to define a property with specific flags, ignoring
 *  normal semantics such as extensibility, write protection etc.
 *  Overwrites any existing value and attributes unless caller requests
 *  that value only be updated if it doesn't already exists.
 *
 *  Does not support:
 *    - virtual properties (error if write attempted)
 *    - getter/setter properties (error if write attempted)
 *    - non-default (!= WEC) attributes for array entries (error if attempted)
 *    - array abandoning: if array part exists, it is always extended
 *    - array 'length' updating
 *
 *  Stack: [... in_val] -> []
 *
 *  Used for e.g. built-in initialization and environment record
 *  operations.
 */

DUK_INTERNAL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags) {
	duk_context *ctx = (duk_context *) thr;
	duk_propdesc desc;
	duk_uint32_t arr_idx;
	duk_int_t e_idx;
	duk_tval *tv1 = NULL;
	duk_tval *tv2 = NULL;
	duk_small_uint_t propflags = flags & DUK_PROPDESC_FLAGS_MASK;  /* mask out flags not actually stored */

	DUK_DDD(DUK_DDDPRINT("define new property (internal): thr=%p, obj=%!O, key=%!O, flags=0x%02lx, val=%!T",
	                     (void *) thr, (duk_heaphdr *) obj, (duk_heaphdr *) key,
	                     (unsigned long) flags, (duk_tval *) duk_get_tval(ctx, -1)));

	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(thr->heap != NULL);
	DUK_ASSERT(obj != NULL);
	DUK_ASSERT(key != NULL);
	DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));
	DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);
	DUK_ASSERT(duk_is_valid_index(ctx, -1));  /* contains value */

	arr_idx = DUK_HSTRING_GET_ARRIDX_SLOW(key);

	if (duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &desc, 0 /*flags*/)) {  /* don't push value */
		if (desc.e_idx >= 0) {
			if (flags & DUK_PROPDESC_FLAG_NO_OVERWRITE) {
				DUK_DDD(DUK_DDDPRINT("property already exists in the entry part -> skip as requested"));
				goto pop_exit;
			}
			DUK_DDD(DUK_DDDPRINT("property already exists in the entry part -> update value and attributes"));
			if (DUK_UNLIKELY(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, desc.e_idx))) {
				DUK_D(DUK_DPRINT("existing property is an accessor, not supported"));
				goto error_internal;
			}

			DUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, desc.e_idx, propflags);
			tv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, desc.e_idx);
		} else if (desc.a_idx >= 0) {
			if (flags & DUK_PROPDESC_FLAG_NO_OVERWRITE) {
				DUK_DDD(DUK_DDDPRINT("property already exists in the array part -> skip as requested"));
				goto pop_exit;
			}
			DUK_DDD(DUK_DDDPRINT("property already exists in the array part -> update value (assert attributes)"));
			if (propflags != DUK_PROPDESC_FLAGS_WEC) {
				DUK_D(DUK_DPRINT("existing property in array part, but propflags not WEC (0x%02lx)",
				                 (unsigned long) propflags));
				goto error_internal;
			}

			tv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, desc.a_idx);
		} else {
			if (flags & DUK_PROPDESC_FLAG_NO_OVERWRITE) {
				DUK_DDD(DUK_DDDPRINT("property already exists but is virtual -> skip as requested"));
				goto pop_exit;
			}
			DUK_DDD(DUK_DDDPRINT("property already exists but is virtual -> failure"));
			goto error_virtual;
		}

		goto write_value;
	}

	if (DUK_HOBJECT_HAS_ARRAY_PART(obj)) {
		if (arr_idx != DUK__NO_ARRAY_INDEX) {
			DUK_DDD(DUK_DDDPRINT("property does not exist, object has array part -> possibly extend array part and write value (assert attributes)"));
			DUK_ASSERT(propflags == DUK_PROPDESC_FLAGS_WEC);

			/* always grow the array, no sparse / abandon support here */
			if (arr_idx >= DUK_HOBJECT_GET_ASIZE(obj)) {
				duk__grow_props_for_array_item(thr, obj, arr_idx);
			}

			DUK_ASSERT(arr_idx < DUK_HOBJECT_GET_ASIZE(obj));
			tv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);
			goto write_value;
		}
	}

	DUK_DDD(DUK_DDDPRINT("property does not exist, object belongs in entry part -> allocate new entry and write value and attributes"));
	e_idx = duk__alloc_entry_checked(thr, obj, key);  /* increases key refcount */
	DUK_ASSERT(e_idx >= 0);
	DUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, e_idx, propflags);
	tv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, e_idx);
	/* new entry: previous value is garbage; set to undefined to share write_value */
	DUK_TVAL_SET_UNDEFINED(tv1);
	goto write_value;

 write_value:
	/* tv1 points to value storage */

	tv2 = duk_require_tval(ctx, -1);  /* late lookup, avoid side effects */
	DUK_DDD(DUK_DDDPRINT("writing/updating value: %!T -> %!T",
	                     (duk_tval *) tv1, (duk_tval *) tv2));

	DUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2);  /* side effects */
	goto pop_exit;

 pop_exit:
	duk_pop(ctx);  /* remove in_val */
	return;

 error_internal:
	DUK_ERROR_INTERNAL_DEFMSG(thr);
	return;

 error_virtual:
	DUK_ERROR_TYPE(thr, DUK_STR_REDEFINE_VIRT_PROP);
	return;
}

/*
 *  Fast path for defining array indexed values without interning the key.
 *  This is used by e.g. code for Array prototype and traceback creation so
 *  must avoid interning.
 */

DUK_INTERNAL void duk_hobject_define_property_internal_arridx(duk_hthread *thr, duk_hobject *obj, duk_uarridx_t arr_idx, duk_small_uint_t flags) {
	duk_context *ctx = (duk_context *) thr;
	duk_hstring *key;
	duk_tval *tv1, *tv2;

	DUK_DDD(DUK_DDDPRINT("define new property (internal) arr_idx fast path: thr=%p, obj=%!O, "
	                     "arr_idx=%ld, flags=0x%02lx, val=%!T",
	                     (void *) thr, obj, (long) arr_idx, (unsigned long) flags,
	                     (duk_tval *) duk_get_tval(ctx, -1)));

	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(thr->heap != NULL);
	DUK_ASSERT(obj != NULL);
	DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));

	if (DUK_HOBJECT_HAS_ARRAY_PART(obj) &&
	    arr_idx != DUK__NO_ARRAY_INDEX &&
	    flags == DUK_PROPDESC_FLAGS_WEC) {
		DUK_ASSERT((flags & DUK_PROPDESC_FLAG_NO_OVERWRITE) == 0);  /* covered by comparison */

		DUK_DDD(DUK_DDDPRINT("define property to array part (property may or may not exist yet)"));

		/* always grow the array, no sparse / abandon support here */
		if (arr_idx >= DUK_HOBJECT_GET_ASIZE(obj)) {
			duk__grow_props_for_array_item(thr, obj, arr_idx);
		}

		DUK_ASSERT(arr_idx < DUK_HOBJECT_GET_ASIZE(obj));
		tv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);
		tv2 = duk_require_tval(ctx, -1);

		DUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2);  /* side effects */

		duk_pop(ctx);  /* [ ...val ] -> [ ... ] */
		return;
	}

	DUK_DDD(DUK_DDDPRINT("define property fast path didn't work, use slow path"));

	duk_push_uint(ctx, (duk_uint_t) arr_idx);
	key = duk_to_hstring(ctx, -1);
	DUK_ASSERT(key != NULL);
	duk_insert(ctx, -2);  /* [ ... val key ] -> [ ... key val ] */

	duk_hobject_define_property_internal(thr, obj, key, flags);

	duk_pop(ctx);  /* [ ... key ] -> [ ... ] */
}

/*
 *  Internal helper for defining an accessor property, ignoring
 *  normal semantics such as extensibility, write protection etc.
 *  Overwrites any existing value and attributes.  This is called
 *  very rarely, so the implementation first sets a value to undefined
 *  and then changes the entry to an accessor (this is to save code space).
 */

DUK_INTERNAL void duk_hobject_define_accessor_internal(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_hobject *getter, duk_hobject *setter, duk_small_uint_t propflags) {
	duk_context *ctx = (duk_context *) thr;
	duk_int_t e_idx;
	duk_int_t h_idx;

	DUK_DDD(DUK_DDDPRINT("define new accessor (internal): thr=%p, obj=%!O, key=%!O, "
	                     "getter=%!O, setter=%!O, flags=0x%02lx",
	                     (void *) thr, (duk_heaphdr *) obj, (duk_heaphdr *) key,
	                     (duk_heaphdr *) getter, (duk_heaphdr *) setter,
	                     (unsigned long) propflags));

	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(thr->heap != NULL);
	DUK_ASSERT(obj != NULL);
	DUK_ASSERT(key != NULL);
	DUK_ASSERT((propflags & ~DUK_PROPDESC_FLAGS_MASK) == 0);
	/* setter and/or getter may be NULL */
	DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));

	DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);

	/* force the property to 'undefined' to create a slot for it */
	duk_push_undefined(ctx);
	duk_hobject_define_property_internal(thr, obj, key, propflags);
	duk_hobject_find_existing_entry(thr->heap, obj, key, &e_idx, &h_idx);
	DUK_DDD(DUK_DDDPRINT("accessor slot: e_idx=%ld, h_idx=%ld", (long) e_idx, (long) h_idx));
	DUK_ASSERT(e_idx >= 0);
	DUK_ASSERT((duk_uint32_t) e_idx < DUK_HOBJECT_GET_ENEXT(obj));

	/* no need to decref, as previous value is 'undefined' */
	DUK_HOBJECT_E_SLOT_SET_ACCESSOR(thr->heap, obj, e_idx);
	DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, e_idx, getter);
	DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, e_idx, setter);
	DUK_HOBJECT_INCREF_ALLOWNULL(thr, getter);
	DUK_HOBJECT_INCREF_ALLOWNULL(thr, setter);
}

/*
 *  Internal helpers for managing object 'length'
 */

/* XXX: awkward helpers */

DUK_INTERNAL void duk_hobject_set_length(duk_hthread *thr, duk_hobject *obj, duk_uint32_t length) {
	duk_context *ctx = (duk_context *) thr;
	duk_push_hobject(ctx, obj);
	duk_push_hstring_stridx(ctx, DUK_STRIDX_LENGTH);
	duk_push_u32(ctx, length);
	(void) duk_hobject_putprop(thr,
	                           DUK_GET_TVAL_NEGIDX(ctx, -3),
	                           DUK_GET_TVAL_NEGIDX(ctx, -2),
	                           DUK_GET_TVAL_NEGIDX(ctx, -1),
	                           0);
	duk_pop_n(ctx, 3);
}

DUK_INTERNAL void duk_hobject_set_length_zero(duk_hthread *thr, duk_hobject *obj) {
	duk_hobject_set_length(thr, obj, 0);
}

DUK_INTERNAL duk_uint32_t duk_hobject_get_length(duk_hthread *thr, duk_hobject *obj) {
	duk_context *ctx = (duk_context *) thr;
	duk_double_t val;
	duk_push_hobject(ctx, obj);
	duk_push_hstring_stridx(ctx, DUK_STRIDX_LENGTH);
	(void) duk_hobject_getprop(thr,
	                           DUK_GET_TVAL_NEGIDX(ctx, -2),
	                           DUK_GET_TVAL_NEGIDX(ctx, -1));
	val = duk_to_number(ctx, -1);
	duk_pop_n(ctx, 3);
	if (val >= 0.0 && val < DUK_DOUBLE_2TO32) {
		return (duk_uint32_t) val;
	}
	return 0;
}

/*
 *  Object.getOwnPropertyDescriptor()  (E5 Sections 15.2.3.3, 8.10.4)
 *
 *  This is an actual function call.
 */

DUK_INTERNAL duk_ret_t duk_hobject_object_get_own_property_descriptor(duk_context *ctx) {
	duk_hthread *thr = (duk_hthread *) ctx;
	duk_hobject *obj;
	duk_hstring *key;
	duk_propdesc pd;
	duk_bool_t rc;

	DUK_ASSERT(ctx != NULL);
	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(thr->heap != NULL);

	obj = duk_require_hobject_or_lfunc_coerce(ctx, 0);
	(void) duk_to_string(ctx, 1);
	key = duk_require_hstring(ctx, 1);

	DUK_ASSERT(obj != NULL);
	DUK_ASSERT(key != NULL);

	DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);

	rc = duk_hobject_get_own_propdesc(thr, obj, key, &pd, DUK_GETDESC_FLAG_PUSH_VALUE);
	if (!rc) {
		duk_push_undefined(ctx);

		/* [obj key undefined] */
		return 1;
	}

	duk_push_object(ctx);

	/* [obj key value desc] */

	if (DUK_PROPDESC_IS_ACCESSOR(&pd)) {
		/* If a setter/getter is missing (undefined), the descriptor must
		 * still have the property present with the value 'undefined'.
		 */
		if (pd.get) {
			duk_push_hobject(ctx, pd.get);
		} else {
			duk_push_undefined(ctx);
		}
		duk_put_prop_stridx(ctx, -2, DUK_STRIDX_GET);
		if (pd.set) {
			duk_push_hobject(ctx, pd.set);
		} else {
			duk_push_undefined(ctx);
		}
		duk_put_prop_stridx(ctx, -2, DUK_STRIDX_SET);
	} else {
		duk_dup(ctx, -2);  /* [obj key value desc value] */
		duk_put_prop_stridx(ctx, -2, DUK_STRIDX_VALUE);
		duk_push_boolean(ctx, DUK_PROPDESC_IS_WRITABLE(&pd));
		duk_put_prop_stridx(ctx, -2, DUK_STRIDX_WRITABLE);

		/* [obj key value desc] */
	}
	duk_push_boolean(ctx, DUK_PROPDESC_IS_ENUMERABLE(&pd));
	duk_put_prop_stridx(ctx, -2, DUK_STRIDX_ENUMERABLE);
	duk_push_boolean(ctx, DUK_PROPDESC_IS_CONFIGURABLE(&pd));
	duk_put_prop_stridx(ctx, -2, DUK_STRIDX_CONFIGURABLE);

	/* [obj key value desc] */
	return 1;
}

/*
 *  NormalizePropertyDescriptor() related helper.
 *
 *  Internal helper which validates and normalizes a property descriptor
 *  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; some subset of: property value,
 *  getter, setter.  Caller must manage stack top carefully because the
 *  number of values pushed depends on the input property descriptor.
 *
 *  The original descriptor object must not be altered in the process.
 */

/* XXX: very basic optimization -> duk_get_prop_stridx_top */

DUK_INTERNAL
void duk_hobject_prepare_property_descriptor(duk_context *ctx,
                                             duk_idx_t idx_in,
                                             duk_uint_t *out_defprop_flags,
                                             duk_idx_t *out_idx_value,
                                             duk_hobject **out_getter,
                                             duk_hobject **out_setter) {
	duk_hthread *thr = (duk_hthread *) ctx;
	duk_idx_t idx_value = -1;
	duk_hobject *getter = NULL;
	duk_hobject *setter = NULL;
	duk_bool_t is_data_desc = 0;
	duk_bool_t is_acc_desc = 0;
	duk_uint_t defprop_flags = 0;

	DUK_ASSERT(ctx != NULL);
	DUK_ASSERT(out_defprop_flags != NULL);
	DUK_ASSERT(out_idx_value != NULL);
	DUK_ASSERT(out_getter != NULL);
	DUK_ASSERT(out_setter != NULL);

	/* Must be an object, otherwise TypeError (E5.1 Section 8.10.5, step 1). */
	idx_in = duk_require_normalize_index(ctx, idx_in);
	(void) duk_require_hobject(ctx, idx_in);

	/* The coercion order must match the ToPropertyDescriptor() algorithm
	 * so that side effects in coercion happen in the correct order.
	 * (This order also happens to be compatible with duk_def_prop(),
	 * although it doesn't matter in practice.)
	 */

	if (duk_get_prop_stridx(ctx, idx_in, DUK_STRIDX_VALUE)) {
		is_data_desc = 1;
		defprop_flags |= DUK_DEFPROP_HAVE_VALUE;
		idx_value = duk_get_top_index(ctx);
		/* Leave 'value' on stack */
	} else {
		duk_pop(ctx);
	}

	if (duk_get_prop_stridx(ctx, idx_in, DUK_STRIDX_WRITABLE)) {
		is_data_desc = 1;
		if (duk_to_boolean(ctx, -1)) {
			defprop_flags |= DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_WRITABLE;
		} else {
			defprop_flags |= DUK_DEFPROP_HAVE_WRITABLE;
		}
	}
	duk_pop(ctx);

	if (duk_get_prop_stridx(ctx, idx_in, DUK_STRIDX_GET)) {
		duk_tval *tv = duk_require_tval(ctx, -1);
		duk_hobject *h_get;

		if (DUK_TVAL_IS_UNDEFINED(tv)) {
			/* undefined is accepted */
			DUK_ASSERT(getter == NULL);
		} else {
			/* NOTE: lightfuncs are coerced to full functions because
			 * lightfuncs don't fit into a property value slot.  This
			 * has some side effects, see test-dev-lightfunc-accessor.js.
			 */
			h_get = duk_get_hobject_or_lfunc_coerce(ctx, -1);
			if (h_get == NULL || !DUK_HOBJECT_IS_CALLABLE(h_get)) {
				goto type_error;
			}
			getter = h_get;
		}
		is_acc_desc = 1;
		defprop_flags |= DUK_DEFPROP_HAVE_GETTER;
		/* Leave 'getter' on stack */
	} else {
		duk_pop(ctx);
	}

	if (duk_get_prop_stridx(ctx, idx_in, DUK_STRIDX_SET)) {
		duk_tval *tv = duk_require_tval(ctx, -1);
		duk_hobject *h_set;

		if (DUK_TVAL_IS_UNDEFINED(tv)) {
			/* undefined is accepted */
			DUK_ASSERT(setter == NULL);
		}  else {
			/* NOTE: lightfuncs are coerced to full functions because
			 * lightfuncs don't fit into a property value slot.  This
			 * has some side effects, see test-dev-lightfunc-accessor.js.
			 */
			h_set = duk_get_hobject_or_lfunc_coerce(ctx, -1);
			if (h_set == NULL || !DUK_HOBJECT_IS_CALLABLE(h_set)) {
				goto type_error;
			}
			setter = h_set;
		}
		is_acc_desc = 1;
		defprop_flags |= DUK_DEFPROP_HAVE_SETTER;
		/* Leave 'setter' on stack */
	} else {
		duk_pop(ctx);
	}

	if (duk_get_prop_stridx(ctx, idx_in, DUK_STRIDX_ENUMERABLE)) {
		if (duk_to_boolean(ctx, -1)) {
			defprop_flags |= DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE;
		} else {
			defprop_flags |= DUK_DEFPROP_HAVE_ENUMERABLE;
		}
	}
	duk_pop(ctx);

	if (duk_get_prop_stridx(ctx, idx_in, DUK_STRIDX_CONFIGURABLE)) {
		if (duk_to_boolean(ctx, -1)) {
			defprop_flags |= DUK_DEFPROP_HAVE_CONFIGURABLE | DUK_DEFPROP_CONFIGURABLE;
		} else {
			defprop_flags |= DUK_DEFPROP_HAVE_CONFIGURABLE;
		}
	}
	duk_pop(ctx);

	if (is_data_desc && is_acc_desc) {
		goto type_error;
	}

	*out_defprop_flags = defprop_flags;
	*out_idx_value = idx_value;
	*out_getter = getter;
	*out_setter = setter;

	/* [ ... value? getter? setter? ] */
	return;

 type_error:
	DUK_ERROR_TYPE(thr, DUK_STR_INVALID_DESCRIPTOR);
}

/*
 *  Object.defineProperty() related helper  (E5 Section 15.2.3.6)
 *
 *  Inlines all [[DefineOwnProperty]] exotic behaviors.
 *
 *  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
 *  entirely.
 *
 *  Note: this is only called for actual objects, not primitive values.
 *  This must support virtual properties for full objects (e.g. Strings)
 *  but not for plain values (e.g. strings).  Lightfuncs, even though
 *  primitive in a sense, are treated like objects and accepted as target
 *  values.
 */

/* XXX: this is a major target for size optimization */
DUK_INTERNAL
void duk_hobject_define_property_helper(duk_context *ctx,
                                        duk_uint_t defprop_flags,
                                        duk_hobject *obj,
                                        duk_hstring *key,
                                        duk_idx_t idx_value,
                                        duk_hobject *get,
                                        duk_hobject *set) {
	duk_hthread *thr = (duk_hthread *) ctx;
	duk_uint32_t arr_idx;
	duk_tval tv;
	duk_bool_t has_enumerable;
	duk_bool_t has_configurable;
	duk_bool_t has_writable;
	duk_bool_t has_value;
	duk_bool_t has_get;
	duk_bool_t has_set;
	duk_bool_t is_enumerable;
	duk_bool_t is_configurable;
	duk_bool_t is_writable;
	duk_bool_t throw_flag;
	duk_bool_t force_flag;
	duk_small_uint_t new_flags;
	duk_propdesc curr;
	duk_uint32_t arridx_new_array_length;  /* != 0 => post-update for array 'length' (used when key is an array index) */
	duk_uint32_t arrlen_old_len;
	duk_uint32_t arrlen_new_len;
	duk_bool_t pending_write_protect;

	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(thr->heap != NULL);
	DUK_ASSERT(ctx != NULL);
	DUK_ASSERT(obj != NULL);
	DUK_ASSERT(key != NULL);
	/* idx_value may be < 0 (no value), set and get may be NULL */

	DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);

	/* All the flags fit in 16 bits, so will fit into duk_bool_t. */

	has_writable = (defprop_flags & DUK_DEFPROP_HAVE_WRITABLE);
	has_enumerable = (defprop_flags & DUK_DEFPROP_HAVE_ENUMERABLE);
	has_configurable = (defprop_flags & DUK_DEFPROP_HAVE_CONFIGURABLE);
	has_value = (defprop_flags & DUK_DEFPROP_HAVE_VALUE);
	has_get = (defprop_flags & DUK_DEFPROP_HAVE_GETTER);
	has_set = (defprop_flags & DUK_DEFPROP_HAVE_SETTER);
	is_writable = (defprop_flags & DUK_DEFPROP_WRITABLE);
	is_enumerable = (defprop_flags & DUK_DEFPROP_ENUMERABLE);
	is_configurable = (defprop_flags & DUK_DEFPROP_CONFIGURABLE);
	throw_flag = 1;   /* Object.defineProperty() calls [[DefineOwnProperty]] with Throw=true */
	force_flag = (defprop_flags & DUK_DEFPROP_FORCE);

	arr_idx = DUK_HSTRING_GET_ARRIDX_SLOW(key);

	arridx_new_array_length = 0;
	pending_write_protect = 0;
	arrlen_old_len = 0;
	arrlen_new_len = 0;

	DUK_DDD(DUK_DDDPRINT("has_enumerable=%ld is_enumerable=%ld "
	                     "has_configurable=%ld is_configurable=%ld "
	                     "has_writable=%ld is_writable=%ld "
	                     "has_value=%ld value=%!T "
	                     "has_get=%ld get=%p=%!O "
	                     "has_set=%ld set=%p=%!O "
	                     "arr_idx=%ld",
	                     (long) has_enumerable, (long) is_enumerable,
	                     (long) has_configurable, (long) is_configurable,
	                     (long) has_writable, (long) is_writable,
	                     (long) has_value, (duk_tval *) (idx_value >= 0 ? duk_get_tval(ctx, idx_value) : NULL),
	                     (long) has_get, (void *) get, (duk_heaphdr *) get,
	                     (long) has_set, (void *) set, (duk_heaphdr *) set,
	                     (long) arr_idx));

	/*
	 *  Array exotic behaviors can be implemented at this point.  The local variables
	 *  are essentially a 'value copy' of the input descriptor (Desc), which is modified
	 *  by the Array [[DefineOwnProperty]] (E5 Section 15.4.5.1).
	 */

	if (!DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {
		goto skip_array_exotic;
	}

	if (key == DUK_HTHREAD_STRING_LENGTH(thr)) {
		/* E5 Section 15.4.5.1, step 3, steps a - i are implemented here, j - n at the end */
		if (!has_value) {
			DUK_DDD(DUK_DDDPRINT("exotic array behavior for 'length', but no value in descriptor -> normal behavior"));
			goto skip_array_exotic;
		}

		DUK_DDD(DUK_DDDPRINT("exotic array behavior for 'length', value present in descriptor -> exotic behavior"));

		/*
		 *  Get old and new length
		 */

		/* Note: reuse 'curr' as a temp propdesc */
		arrlen_old_len = duk__get_old_array_length(thr, obj, &curr);

		duk_dup(ctx, idx_value);
		arrlen_new_len = duk__to_new_array_length_checked(thr);
		duk_push_u32(ctx, arrlen_new_len);
		duk_replace(ctx, idx_value);  /* step 3.e: replace 'Desc.[[Value]]' */

		DUK_DDD(DUK_DDDPRINT("old_len=%ld, new_len=%ld", (long) arrlen_old_len, (long) arrlen_new_len));

		if (arrlen_new_len >= arrlen_old_len) {
			/* standard behavior, step 3.f.i */
			DUK_DDD(DUK_DDDPRINT("new length is same or higher as previous => standard behavior"));
			goto skip_array_exotic;
		}
		DUK_DDD(DUK_DDDPRINT("new length is smaller than previous => exotic post behavior"));

		/* XXX: consolidated algorithm step 15.f -> redundant? */
		if (!(curr.flags & DUK_PROPDESC_FLAG_WRITABLE) && !force_flag) {
			/* Note: 'curr' refers to 'length' propdesc */
			goto fail_not_writable_array_length;
		}

		/* steps 3.h and 3.i */
		if (has_writable && !is_writable) {
			DUK_DDD(DUK_DDDPRINT("desc writable is false, force it back to true, and flag pending write protect"));
			is_writable = 1;
			pending_write_protect = 1;
		}

		/* remaining actual steps are carried out if standard DefineOwnProperty succeeds */
	} else if (arr_idx != DUK__NO_ARRAY_INDEX) {
		/* XXX: any chance of unifying this with the 'length' key handling? */

		/* E5 Section 15.4.5.1, step 4 */
		duk_uint32_t old_len;

		/* Note: use 'curr' as a temp propdesc */
		old_len = duk__get_old_array_length(thr, obj, &curr);

		if (arr_idx >= old_len) {
			DUK_DDD(DUK_DDDPRINT("defineProperty requires array length update "
			                     "(arr_idx=%ld, old_len=%ld)",
			                     (long) arr_idx, (long) old_len));

			if (!(curr.flags & DUK_PROPDESC_FLAG_WRITABLE)) {
				/* Note: 'curr' refers to 'length' propdesc */
				goto fail_not_writable_array_length;
			}

			/* actual update happens once write has been completed without
			 * error below.
			 */
			DUK_ASSERT(arr_idx != 0xffffffffUL);
			arridx_new_array_length = arr_idx + 1;
		} else {
			DUK_DDD(DUK_DDDPRINT("defineProperty does not require length update "
			                     "(arr_idx=%ld, old_len=%ld) -> standard behavior",
			                     (long) arr_idx, (long) old_len));
		}
	}
 skip_array_exotic:

	/* XXX: There is currently no support for writing buffer object
	 * indexed elements here.  Attempt to do so will succeed and
	 * write a concrete property into the buffer object.  This should
	 * be fixed at some point but because buffers are a custom feature
	 * anyway, this is relatively unimportant.
	 */

	/*
	 *  Actual Object.defineProperty() default algorithm.
	 */

	/*
	 *  First check whether property exists; if not, simple case.  This covers
	 *  steps 1-4.
	 */

	if (!duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &curr, DUK_GETDESC_FLAG_PUSH_VALUE)) {
		DUK_DDD(DUK_DDDPRINT("property does not exist"));

		if (!DUK_HOBJECT_HAS_EXTENSIBLE(obj) && !force_flag) {
			goto fail_not_extensible;
		}

		/* XXX: share final setting code for value and flags?  difficult because
		 * refcount code is different.  Share entry allocation?  But can't allocate
		 * until array index checked.
		 */

		/* steps 4.a and 4.b are tricky */
		if (has_set || has_get) {
			duk_int_t e_idx;

			DUK_DDD(DUK_DDDPRINT("create new accessor property"));

			DUK_ASSERT(has_set || set == NULL);
			DUK_ASSERT(has_get || get == NULL);
			DUK_ASSERT(!has_value);
			DUK_ASSERT(!has_writable);

			new_flags = DUK_PROPDESC_FLAG_ACCESSOR;  /* defaults, E5 Section 8.6.1, Table 7 */
			if (has_enumerable && is_enumerable) {
				new_flags |= DUK_PROPDESC_FLAG_ENUMERABLE;
			}
			if (has_configurable && is_configurable) {
				new_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE;
			}

			if (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_ARRAY_PART(obj)) {
				DUK_DDD(DUK_DDDPRINT("accessor cannot go to array part, abandon array"));
				duk__abandon_array_checked(thr, obj);
			}

			/* write to entry part */
			e_idx = duk__alloc_entry_checked(thr, obj, key);
			DUK_ASSERT(e_idx >= 0);

			DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, e_idx, get);
			DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, e_idx, set);
			DUK_HOBJECT_INCREF_ALLOWNULL(thr, get);
			DUK_HOBJECT_INCREF_ALLOWNULL(thr, set);

			DUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, e_idx, new_flags);
			goto success_exotics;
		} else {
			duk_int_t e_idx;
			duk_tval *tv2;

			DUK_DDD(DUK_DDDPRINT("create new data property"));

			DUK_ASSERT(!has_set);
			DUK_ASSERT(!has_get);

			new_flags = 0;  /* defaults, E5 Section 8.6.1, Table 7 */
			if (has_writable && is_writable) {
				new_flags |= DUK_PROPDESC_FLAG_WRITABLE;
			}
			if (has_enumerable && is_enumerable) {
				new_flags |= DUK_PROPDESC_FLAG_ENUMERABLE;
			}
			if (has_configurable && is_configurable) {
				new_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE;
			}
			if (has_value) {
				duk_tval *tv_tmp = duk_require_tval(ctx, idx_value);
				DUK_TVAL_SET_TVAL(&tv, tv_tmp);
			} else {
				DUK_TVAL_SET_UNDEFINED(&tv);  /* default value */
			}

			if (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_ARRAY_PART(obj)) {
				if (new_flags == DUK_PROPDESC_FLAGS_WEC) {
#if 0
					DUK_DDD(DUK_DDDPRINT("new data property attributes match array defaults, attempt to write to array part"));
					/* may become sparse...*/
#endif
					/* XXX: handling for array part missing now; this doesn't affect
					 * compliance but causes array entry writes using defineProperty()
					 * to always abandon array part.
					 */
				}
				DUK_DDD(DUK_DDDPRINT("new data property cannot go to array part, abandon array"));
				duk__abandon_array_checked(thr, obj);
				/* fall through */
			}

			/* write to entry part */
			e_idx = duk__alloc_entry_checked(thr, obj, key);
			DUK_ASSERT(e_idx >= 0);
			tv2 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, e_idx);
			DUK_TVAL_SET_TVAL(tv2, &tv);
			DUK_TVAL_INCREF(thr, tv2);

			DUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, e_idx, new_flags);
			goto success_exotics;
		}
		DUK_UNREACHABLE();
	}

	/* we currently assume virtual properties are not configurable (as none of them are) */
	DUK_ASSERT((curr.e_idx >= 0 || curr.a_idx >= 0) || !(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE));

	/* [obj key desc value get set curr_value] */

	/*
	 *  Property already exists.  Steps 5-6 detect whether any changes need
	 *  to be made.
	 */

	if (has_enumerable) {
		if (is_enumerable) {
			if (!(curr.flags & DUK_PROPDESC_FLAG_ENUMERABLE)) {
				goto need_check;
			}
		} else {
			if (curr.flags & DUK_PROPDESC_FLAG_ENUMERABLE) {
				goto need_check;
			}
		}
	}
	if (has_configurable) {
		if (is_configurable) {
			if (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE)) {
				goto need_check;
			}
		} else {
			if (curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) {
				goto need_check;
			}
		}
	}
	if (has_value) {
		duk_tval *tmp1;
		duk_tval *tmp2;

		/* attempt to change from accessor to data property */
		if (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {
			goto need_check;
		}

		tmp1 = duk_require_tval(ctx, -1);         /* curr value */
		tmp2 = duk_require_tval(ctx, idx_value);  /* new value */
		if (!duk_js_samevalue(tmp1, tmp2)) {
			goto need_check;
		}
	}
	if (has_writable) {
		/* attempt to change from accessor to data property */
		if (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {
			goto need_check;
		}

		if (is_writable) {
			if (!(curr.flags & DUK_PROPDESC_FLAG_WRITABLE)) {
				goto need_check;
			}
		} else {
			if (curr.flags & DUK_PROPDESC_FLAG_WRITABLE) {
				goto need_check;
			}
		}
	}
	if (has_set) {
		if (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {
			if (set != curr.set) {
				goto need_check;
			}
		} else {
			goto need_check;
		}
	}
	if (has_get) {
		if (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {
			if (get != curr.get) {
				goto need_check;
			}
		} else {
			goto need_check;
		}
	}

	/* property exists, either 'desc' is empty, or all values
	 * match (SameValue)
	 */
	goto success_no_exotics;

 need_check:

	/*
	 *  Some change(s) need to be made.  Steps 7-11.
	 */

	/* shared checks for all descriptor types */
	if (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {
		if (has_configurable && is_configurable) {
			goto fail_not_configurable;
		}
		if (has_enumerable) {
			if (curr.flags & DUK_PROPDESC_FLAG_ENUMERABLE) {
				if (!is_enumerable) {
					goto fail_not_configurable;
				}
			} else {
				if (is_enumerable) {
					goto fail_not_configurable;
				}
			}
		}
	}

	/* Reject attempt to change virtual properties: not part of the
	 * standard algorithm, applies currently to e.g. virtual index
	 * properties of buffer objects (which are virtual but writable).
	 * (Cannot "force" modification of a virtual property.)
	 */
	if (curr.flags & DUK_PROPDESC_FLAG_VIRTUAL) {
		goto fail_virtual;
	}

	/* Reject attempt to change a read-only object. */
#if defined(DUK_USE_ROM_OBJECTS)
	if (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {
		DUK_DD(DUK_DDPRINT("attempt to define property on read-only target object"));
		goto fail_not_configurable;
	}
#endif

	/* descriptor type specific checks */
	if (has_set || has_get) {
		/* IsAccessorDescriptor(desc) == true */
		DUK_ASSERT(!has_writable);
		DUK_ASSERT(!has_value);

		if (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {
			/* curr and desc are accessors */
			if (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {
				if (has_set && set != curr.set) {
					goto fail_not_configurable;
				}
				if (has_get && get != curr.get) {
					goto fail_not_configurable;
				}
			}
		} else {
			duk_bool_t rc;
			duk_tval *tv1;
			duk_tval tv_tmp;

			/* curr is data, desc is accessor */
			if (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {
				goto fail_not_configurable;
			}

			DUK_DDD(DUK_DDDPRINT("convert property to accessor property"));
			if (curr.a_idx >= 0) {
				DUK_DDD(DUK_DDDPRINT("property to convert is stored in an array entry, abandon array and re-lookup"));
				duk__abandon_array_checked(thr, obj);
				duk_pop(ctx);  /* remove old value */
				rc = duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &curr, DUK_GETDESC_FLAG_PUSH_VALUE);
				DUK_UNREF(rc);
				DUK_ASSERT(rc != 0);
				DUK_ASSERT(curr.e_idx >= 0 && curr.a_idx < 0);
			}

			DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));

			/* Avoid side effects that might disturb curr.e_idx until
			 * we're done editing the slot.
			 */
			tv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx);
			DUK_TVAL_SET_TVAL(&tv_tmp, tv1);
			DUK_TVAL_SET_UNDEFINED(tv1);

			DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, curr.e_idx, NULL);
			DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, curr.e_idx, NULL);
			DUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(thr->heap, obj, curr.e_idx);
			DUK_HOBJECT_E_SLOT_SET_ACCESSOR(thr->heap, obj, curr.e_idx);

			DUK_DDD(DUK_DDDPRINT("flags after data->accessor conversion: 0x%02lx",
			                     (unsigned long) DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, curr.e_idx)));

			DUK_TVAL_DECREF(thr, &tv_tmp);  /* side effects */

			/* re-lookup to update curr.flags
			 * XXX: would be faster to update directly
			 */
			duk_pop(ctx);  /* remove old value */
			rc = duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &curr, DUK_GETDESC_FLAG_PUSH_VALUE);
			DUK_UNREF(rc);
			DUK_ASSERT(rc != 0);
		}
	} else if (has_value || has_writable) {
		/* IsDataDescriptor(desc) == true */
		DUK_ASSERT(!has_set);
		DUK_ASSERT(!has_get);

		if (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {
			duk_bool_t rc;
			duk_hobject *h_get;
			duk_hobject *h_set;

			/* curr is accessor, desc is data */
			if (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {
				goto fail_not_configurable;
			}

			/* curr is accessor -> cannot be in array part */
			DUK_ASSERT(curr.e_idx >= 0 && curr.a_idx < 0);

			DUK_DDD(DUK_DDDPRINT("convert property to data property"));

			/* Avoid side effects that might disturb curr.e_idx until
			 * we're done editing the slot.
			 */
			DUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));
			h_get = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, curr.e_idx);
			DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, curr.e_idx, NULL);
			h_set = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, curr.e_idx);
			DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, curr.e_idx, NULL);

			DUK_TVAL_SET_UNDEFINED(DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx));
			DUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(thr->heap, obj, curr.e_idx);
			DUK_HOBJECT_E_SLOT_CLEAR_ACCESSOR(thr->heap, obj, curr.e_idx);

			DUK_DDD(DUK_DDDPRINT("flags after accessor->data conversion: 0x%02lx",
			                     (unsigned long) DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, curr.e_idx)));

			DUK_HOBJECT_DECREF_ALLOWNULL(thr, h_get);  /* side effects */
			DUK_HOBJECT_DECREF_ALLOWNULL(thr, h_set);  /* side effects */

			/* re-lookup to update curr.flags
			 * XXX: would be faster to update directly
			 */
			duk_pop(ctx);  /* remove old value */
			rc = duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &curr, DUK_GETDESC_FLAG_PUSH_VALUE);
			DUK_UNREF(rc);
			DUK_ASSERT(rc != 0);
		} else {
			/* curr and desc are data */
			if (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {
				if (!(curr.flags & DUK_PROPDESC_FLAG_WRITABLE) && has_writable && is_writable) {
					goto fail_not_configurable;
				}
				/* Note: changing from writable to non-writable is OK */
				if (!(curr.flags & DUK_PROPDESC_FLAG_WRITABLE) && has_value) {
					duk_tval *tmp1 = duk_require_tval(ctx, -1);         /* curr value */
					duk_tval *tmp2 = duk_require_tval(ctx, idx_value);  /* new value */
					if (!duk_js_samevalue(tmp1, tmp2)) {
						goto fail_not_configurable;
					}
				}
			}
		}
	} else {
		/* IsGenericDescriptor(desc) == true; this means in practice that 'desc'
		 * only has [[Enumerable]] or [[Configurable]] flag updates, which are
		 * allowed at this point.
		 */

		DUK_ASSERT(!has_value && !has_writable && !has_get && !has_set);
	}

	/*
	 *  Start doing property attributes updates.  Steps 12-13.
	 *
	 *  Start by computing new attribute flags without writing yet.
	 *  Property type conversion is done above if necessary.
	 */

	new_flags = curr.flags;

	if (has_enumerable) {
		if (is_enumerable) {
			new_flags |= DUK_PROPDESC_FLAG_ENUMERABLE;
		} else {
			new_flags &= ~DUK_PROPDESC_FLAG_ENUMERABLE;
		}
	}
	if (has_configurable) {
		if (is_configurable) {
			new_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE;
		} else {
			new_flags &= ~DUK_PROPDESC_FLAG_CONFIGURABLE;
		}
	}
	if (has_writable) {
		if (is_writable) {
			new_flags |= DUK_PROPDESC_FLAG_WRITABLE;
		} else {
			new_flags &= ~DUK_PROPDESC_FLAG_WRITABLE;
		}
	}

	/* XXX: write protect after flag? -> any chance of handling it here? */

	DUK_DDD(DUK_DDDPRINT("new flags that we want to write: 0x%02lx",
	                     (unsigned long) new_flags));

	/*
	 *  Check whether we need to abandon an array part (if it exists)
	 */

	if (curr.a_idx >= 0) {
		duk_bool_t rc;

		DUK_ASSERT(curr.e_idx < 0);

		if (new_flags == DUK_PROPDESC_FLAGS_WEC) {
			duk_tval *tv1, *tv2;

			DUK_DDD(DUK_DDDPRINT("array index, new property attributes match array defaults, update in-place"));

			DUK_ASSERT(curr.flags == DUK_PROPDESC_FLAGS_WEC);  /* must have been, since in array part */
			DUK_ASSERT(!has_set);
			DUK_ASSERT(!has_get);

			tv2 = duk_require_tval(ctx, idx_value);
			tv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, curr.a_idx);
			DUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2);  /* side effects */
			goto success_exotics;
		}

		DUK_DDD(DUK_DDDPRINT("array index, new property attributes do not match array defaults, abandon array and re-lookup"));
		duk__abandon_array_checked(thr, obj);
		duk_pop(ctx);  /* remove old value */
		rc = duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &curr, DUK_GETDESC_FLAG_PUSH_VALUE);
		DUK_UNREF(rc);
		DUK_ASSERT(rc != 0);
		DUK_ASSERT(curr.e_idx >= 0 && curr.a_idx < 0);
	}

	DUK_DDD(DUK_DDDPRINT("updating existing property in entry part"));

	/* array case is handled comprehensively above */
	DUK_ASSERT(curr.e_idx >= 0 && curr.a_idx < 0);

	DUK_DDD(DUK_DDDPRINT("update existing property attributes"));
	DUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, curr.e_idx, new_flags);

	if (has_set) {
		duk_hobject *tmp;

		DUK_DDD(DUK_DDDPRINT("update existing property setter"));
		DUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));

		tmp = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, curr.e_idx);
		DUK_UNREF(tmp);
		DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, curr.e_idx, set);
		DUK_HOBJECT_INCREF_ALLOWNULL(thr, set);
		DUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp);  /* side effects */
	}
	if (has_get) {
		duk_hobject *tmp;

		DUK_DDD(DUK_DDDPRINT("update existing property getter"));
		DUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));

		tmp = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, curr.e_idx);
		DUK_UNREF(tmp);
		DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, curr.e_idx, get);
		DUK_HOBJECT_INCREF_ALLOWNULL(thr, get);
		DUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp);  /* side effects */
	}
	if (has_value) {
		duk_tval *tv1, *tv2;

		DUK_DDD(DUK_DDDPRINT("update existing property value"));
		DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));

		tv2 = duk_require_tval(ctx, idx_value);
		tv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx);
		DUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2);  /* side effects */
	}

	/*
	 *  Standard algorithm succeeded without errors, check for exotic post-behaviors.
	 *
	 *  Arguments exotic behavior in E5 Section 10.6 occurs after the standard
	 *  [[DefineOwnProperty]] has completed successfully.
	 *
	 *  Array exotic behavior in E5 Section 15.4.5.1 is implemented partly
	 *  prior to the default [[DefineOwnProperty]], but:
	 *    - for an array index key (e.g. "10") the final 'length' update occurs here
	 *    - for 'length' key the element deletion and 'length' update occurs here
	 */

 success_exotics:

	/* [obj key desc value get set curr_value] */

	if (DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {
		if (arridx_new_array_length > 0) {
			duk_tval *tmp;
			duk_bool_t rc;

			/*
			 *  Note: zero works as a "no update" marker because the new length
			 *  can never be zero after a new property is written.
			 */

			/* E5 Section 15.4.5.1, steps 4.e.i - 4.e.ii */

			DUK_DDD(DUK_DDDPRINT("defineProperty successful, pending array length update to: %ld",
			                     (long) arridx_new_array_length));

			/* Note: reuse 'curr' */
			rc = duk__get_own_propdesc_raw(thr, obj, DUK_HTHREAD_STRING_LENGTH(thr), DUK__NO_ARRAY_INDEX, &curr, 0 /*flags*/);  /* don't push value */
			DUK_UNREF(rc);
			DUK_ASSERT(rc != 0);
			DUK_ASSERT(curr.e_idx >= 0);

			tmp = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx);
			DUK_ASSERT(DUK_TVAL_IS_NUMBER(tmp));
			/* no need for decref/incref because value is a number */
			DUK_TVAL_SET_FASTINT_U32(tmp, arridx_new_array_length);
		}
		if (key == DUK_HTHREAD_STRING_LENGTH(thr) && arrlen_new_len < arrlen_old_len) {
			/*
			 *  E5 Section 15.4.5.1, steps 3.k - 3.n.  The order at the end combines
			 *  the error case 3.l.iii and the success case 3.m-3.n.
			 *
			 *  Note: 'length' is always in entries part, so no array abandon issues for
			 *  'writable' update.
			 */

			/* XXX: investigate whether write protect can be handled above, if we
			 * just update length here while ignoring its protected status
			 */

			duk_tval *tmp;
			duk_uint32_t result_len;
			duk_bool_t rc;

			DUK_DDD(DUK_DDDPRINT("defineProperty successful, key is 'length', exotic array behavior, "
			                     "doing array element deletion and length update"));

			rc = duk__handle_put_array_length_smaller(thr, obj, arrlen_old_len, arrlen_new_len, force_flag, &result_len);

			/* update length (curr points to length, and we assume it's still valid) */
			DUK_ASSERT(result_len >= arrlen_new_len && result_len <= arrlen_old_len);

			DUK_ASSERT(curr.e_idx >= 0);
			DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));
			tmp = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx);
			DUK_ASSERT(DUK_TVAL_IS_NUMBER(tmp));
			/* no decref needed for a number */
			DUK_TVAL_SET_FASTINT_U32(tmp, result_len);
			DUK_ASSERT(DUK_TVAL_IS_NUMBER(tmp));

			if (pending_write_protect) {
				DUK_DDD(DUK_DDDPRINT("setting array length non-writable (pending writability update)"));
				DUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(thr->heap, obj, curr.e_idx);
			}

			/*
			 *  XXX: shrink array allocation or entries compaction here?
			 */

			if (!rc) {
				goto fail_array_length_partial;
			}
		}
	} else if (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj)) {
		duk_hobject *map;
		duk_hobject *varenv;

		DUK_ASSERT(arridx_new_array_length == 0);
		DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj));  /* traits are separate; in particular, arguments not an array */

		map = NULL;
		varenv = NULL;
		if (!duk__lookup_arguments_map(thr, obj, key, &curr, &map, &varenv)) {
			goto success_no_exotics;
		}
		DUK_ASSERT(map != NULL);
		DUK_ASSERT(varenv != NULL);

		/* [obj key desc value get set curr_value varname] */

		if (has_set || has_get) {
			/* = IsAccessorDescriptor(Desc) */
			DUK_DDD(DUK_DDDPRINT("defineProperty successful, key mapped to arguments 'map' "
			                     "changed to an accessor, delete arguments binding"));

			(void) duk_hobject_delprop_raw(thr, map, key, 0);  /* ignore result */
		} else {
			/* Note: this order matters (final value before deleting map entry must be done) */
			DUK_DDD(DUK_DDDPRINT("defineProperty successful, key mapped to arguments 'map', "
			                     "check for value update / binding deletion"));

			if (has_value) {
				duk_hstring *varname;

				DUK_DDD(DUK_DDDPRINT("defineProperty successful, key mapped to arguments 'map', "
				                     "update bound value (variable/argument)"));

				varname = duk_require_hstring(ctx, -1);
				DUK_ASSERT(varname != NULL);

				DUK_DDD(DUK_DDDPRINT("arguments object automatic putvar for a bound variable; "
				                     "key=%!O, varname=%!O, value=%!T",
				                     (duk_heaphdr *) key,
				                     (duk_heaphdr *) varname,
				                     (duk_tval *) duk_require_tval(ctx, idx_value)));

				/* strict flag for putvar comes from our caller (currently: fixed) */
				duk_js_putvar_envrec(thr, varenv, varname, duk_require_tval(ctx, idx_value), throw_flag);
			}
			if (has_writable && !is_writable) {
				DUK_DDD(DUK_DDDPRINT("defineProperty successful, key mapped to arguments 'map', "
				                     "changed to non-writable, delete arguments binding"));

				(void) duk_hobject_delprop_raw(thr, map, key, 0);  /* ignore result */
			}
		}

		/* 'varname' is in stack in this else branch, leaving an unbalanced stack below,
		 * but this doesn't matter now.
		 */
	}

 success_no_exotics:
	return;

 fail_virtual:
	DUK_ERROR_TYPE(thr, DUK_STR_PROPERTY_IS_VIRTUAL);
	return;

 fail_not_writable_array_length:
	DUK_ERROR_TYPE(thr, DUK_STR_ARRAY_LENGTH_NOT_WRITABLE);
	return;

 fail_not_extensible:
	DUK_ERROR_TYPE(thr, DUK_STR_NOT_EXTENSIBLE);
	return;

 fail_not_configurable:
	DUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);
	return;

 fail_array_length_partial:
	DUK_ERROR_TYPE(thr, DUK_STR_ARRAY_LENGTH_WRITE_FAILED);
	return;
}

/*
 *  Object.prototype.hasOwnProperty() and Object.prototype.propertyIsEnumerable().
 */

DUK_INTERNAL duk_bool_t duk_hobject_object_ownprop_helper(duk_context *ctx, duk_small_uint_t required_desc_flags) {
	duk_hthread *thr = (duk_hthread *) ctx;
	duk_hstring *h_v;
	duk_hobject *h_obj;
	duk_propdesc desc;
	duk_bool_t ret;

	/* coercion order matters */
	h_v = duk_to_hstring(ctx, 0);
	DUK_ASSERT(h_v != NULL);

	h_obj = duk_push_this_coercible_to_object(ctx);
	DUK_ASSERT(h_obj != NULL);

	ret = duk_hobject_get_own_propdesc(thr, h_obj, h_v, &desc, 0 /*flags*/);  /* don't push value */

	duk_push_boolean(ctx, ret && ((desc.flags & required_desc_flags) == required_desc_flags));
	return 1;
}

/*
 *  Object.seal() and Object.freeze()  (E5 Sections 15.2.3.8 and 15.2.3.9)
 *
 *  Since the algorithms are similar, a helper provides both functions.
 *  Freezing is essentially sealing + making plain properties non-writable.
 *
 *  Note: virtual (non-concrete) properties which are non-configurable but
 *  writable would pose some problems, but such properties do not currently
 *  exist (all virtual properties are non-configurable and non-writable).
 *  If they did exist, the non-configurability does NOT prevent them from
 *  becoming non-writable.  However, this change should be recorded somehow
 *  so that it would turn up (e.g. when getting the property descriptor),
 *  requiring some additional flags in the object.
 */

DUK_INTERNAL void duk_hobject_object_seal_freeze_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_freeze) {
	duk_uint_fast32_t i;

	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(thr->heap != NULL);
	DUK_ASSERT(obj != NULL);

	DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);

#if defined(DUK_USE_ROM_OBJECTS)
	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);
	}
#endif

	/*
	 *  Abandon array part because all properties must become non-configurable.
	 *  Note that this is now done regardless of whether this is always the case
	 *  (skips check, but performance problem if caller would do this many times
	 *  for the same object; not likely).
	 */

	duk__abandon_array_checked(thr, obj);
	DUK_ASSERT(DUK_HOBJECT_GET_ASIZE(obj) == 0);

	for (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {
		duk_uint8_t *fp;

		/* since duk__abandon_array_checked() causes a resize, there should be no gaps in keys */
		DUK_ASSERT(DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i) != NULL);

		/* avoid multiple computations of flags address; bypasses macros */
		fp = DUK_HOBJECT_E_GET_FLAGS_PTR(thr->heap, obj, i);
		if (is_freeze && !((*fp) & DUK_PROPDESC_FLAG_ACCESSOR)) {
			*fp &= ~(DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_CONFIGURABLE);
		} else {
			*fp &= ~DUK_PROPDESC_FLAG_CONFIGURABLE;
		}
	}

	DUK_HOBJECT_CLEAR_EXTENSIBLE(obj);

	/* no need to compact since we already did that in duk__abandon_array_checked()
	 * (regardless of whether an array part existed or not.
	 */

	return;
}

/*
 *  Object.isSealed() and Object.isFrozen()  (E5 Sections 15.2.3.11, 15.2.3.13)
 *
 *  Since the algorithms are similar, a helper provides both functions.
 *  Freezing is essentially sealing + making plain properties non-writable.
 *
 *  Note: all virtual (non-concrete) properties are currently non-configurable
 *  and non-writable (and there are no accessor virtual properties), so they don't
 *  need to be considered here now.
 */

DUK_INTERNAL duk_bool_t duk_hobject_object_is_sealed_frozen_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_frozen) {
	duk_uint_fast32_t i;

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

	/* Note: no allocation pressure, no need to check refcounts etc */

	/* must not be extensible */
	if (DUK_HOBJECT_HAS_EXTENSIBLE(obj)) {
		return 0;
	}

	/* all virtual properties are non-configurable and non-writable */

	/* entry part must not contain any configurable properties, or
	 * writable properties (if is_frozen).
	 */
	for (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {
		duk_small_uint_t flags;

		if (!DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i)) {
			continue;
		}

		/* avoid multiple computations of flags address; bypasses macros */
		flags = (duk_small_uint_t) DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, i);

		if (flags & DUK_PROPDESC_FLAG_CONFIGURABLE) {
			return 0;
		}
		if (is_frozen &&
		    !(flags & DUK_PROPDESC_FLAG_ACCESSOR) &&
		    (flags & DUK_PROPDESC_FLAG_WRITABLE)) {
			return 0;
		}
	}

	/* array part must not contain any non-unused properties, as they would
	 * be configurable and writable.
	 */
	for (i = 0; i < DUK_HOBJECT_GET_ASIZE(obj); i++) {
		duk_tval *tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i);
		if (!DUK_TVAL_IS_UNUSED(tv)) {
			return 0;
		}
	}

	return 1;
}

/*
 *  Object.preventExtensions() and Object.isExtensible()  (E5 Sections 15.2.3.10, 15.2.3.13)
 *
 *  Not needed, implemented by macros DUK_HOBJECT_{HAS,CLEAR,SET}_EXTENSIBLE
 *  and the Object built-in bindings.
 */

/* Undefine local defines */

#undef DUK__NO_ARRAY_INDEX
#undef DUK__HASH_INITIAL
#undef DUK__HASH_PROBE_STEP
#undef DUK__HASH_UNUSED
#undef DUK__HASH_DELETED
#undef DUK__VALSTACK_SPACE
