/*
 *  Hobject enumeration support.
 *
 *  Creates an internal enumeration state object to be used e.g. with for-in
 *  enumeration.  The state object contains a snapshot of target object keys
 *  and internal control state for enumeration.  Enumerator flags allow caller
 *  to e.g. request internal/non-enumerable properties, and to enumerate only
 *  "own" properties.
 *
 *  Also creates the result value for e.g. Object.keys() based on the same
 *  internal structure.
 *
 *  This snapshot-based enumeration approach is used to simplify enumeration:
 *  non-snapshot-based approaches are difficult to reconcile with mutating
 *  the enumeration target, running multiple long-lived enumerators at the
 *  same time, garbage collection details, etc.  The downside is that the
 *  enumerator object is memory inefficient especially for iterating arrays.
 */

#include "duk_internal.h"

/* XXX: identify enumeration target with an object index (not top of stack) */

/* must match exactly the number of internal properties inserted to enumerator */
#define DUK__ENUM_START_INDEX  2

DUK_LOCAL const duk_uint16_t duk__bufferobject_virtual_props[] = {
	DUK_STRIDX_LENGTH,
	DUK_STRIDX_BYTE_LENGTH,
	DUK_STRIDX_BYTE_OFFSET,
	DUK_STRIDX_BYTES_PER_ELEMENT
};

/*
 *  Helper to sort array index keys.  The keys are in the enumeration object
 *  entry part, starting from DUK__ENUM_START_INDEX, and the entry part is dense.
 *
 *  We use insertion sort because it is simple (leading to compact code,)
 *  works nicely in-place, and minimizes operations if data is already sorted
 *  or nearly sorted (which is a very common case here).  It also minimizes
 *  the use of element comparisons in general.  This is nice because element
 *  comparisons here involve re-parsing the string keys into numbers each
 *  time, which is naturally very expensive.
 *
 *  Note that the entry part values are all "true", e.g.
 *
 *    "1" -> true, "3" -> true, "2" -> true
 *
 *  so it suffices to only work in the key part without exchanging any keys,
 *  simplifying the sort.
 *
 *  http://en.wikipedia.org/wiki/Insertion_sort
 *
 *  (Compiles to about 160 bytes now as a stand-alone function.)
 */

DUK_LOCAL void duk__sort_array_indices(duk_hthread *thr, duk_hobject *h_obj) {
	duk_hstring **keys;
	duk_hstring **p_curr, **p_insert, **p_end;
	duk_hstring *h_curr;
	duk_uarridx_t val_highest, val_curr, val_insert;

	DUK_ASSERT(h_obj != NULL);
	DUK_ASSERT(DUK_HOBJECT_GET_ENEXT(h_obj) >= 2);  /* control props */
	DUK_UNREF(thr);

	if (DUK_HOBJECT_GET_ENEXT(h_obj) <= 1 + DUK__ENUM_START_INDEX) {
		return;
	}

	keys = DUK_HOBJECT_E_GET_KEY_BASE(thr->heap, h_obj);
	p_end = keys + DUK_HOBJECT_GET_ENEXT(h_obj);
	keys += DUK__ENUM_START_INDEX;

	DUK_DDD(DUK_DDDPRINT("keys=%p, p_end=%p (after skipping enum props)",
	                     (void *) keys, (void *) p_end));

#ifdef DUK_USE_DDDPRINT
	{
		duk_uint_fast32_t i;
		for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(h_obj); i++) {
			DUK_DDD(DUK_DDDPRINT("initial: %ld %p -> %!O",
			                     (long) i,
			                     (void *) DUK_HOBJECT_E_GET_KEY_PTR(thr->heap, h_obj, i),
			                     (duk_heaphdr *) DUK_HOBJECT_E_GET_KEY(thr->heap, h_obj, i)));
		}
	}
#endif

	val_highest = DUK_HSTRING_GET_ARRIDX_SLOW(keys[0]);
	for (p_curr = keys + 1; p_curr < p_end; p_curr++) {
		DUK_ASSERT(*p_curr != NULL);
		val_curr = DUK_HSTRING_GET_ARRIDX_SLOW(*p_curr);

		if (val_curr >= val_highest) {
			DUK_DDD(DUK_DDDPRINT("p_curr=%p, p_end=%p, val_highest=%ld, val_curr=%ld -> "
			                     "already in correct order, next",
			                     (void *) p_curr, (void *) p_end, (long) val_highest, (long) val_curr));
			val_highest = val_curr;
			continue;
		}

		DUK_DDD(DUK_DDDPRINT("p_curr=%p, p_end=%p, val_highest=%ld, val_curr=%ld -> "
		                     "needs to be inserted",
		                     (void *) p_curr, (void *) p_end, (long) val_highest, (long) val_curr));

		/* Needs to be inserted; scan backwards, since we optimize
		 * for the case where elements are nearly in order.
		 */

		p_insert = p_curr - 1;
		for (;;) {
			val_insert = DUK_HSTRING_GET_ARRIDX_SLOW(*p_insert);
			if (val_insert < val_curr) {
				DUK_DDD(DUK_DDDPRINT("p_insert=%p, val_insert=%ld, val_curr=%ld -> insert after this",
				                     (void *) p_insert, (long) val_insert, (long) val_curr));
				p_insert++;
				break;
			}
			if (p_insert == keys) {
				DUK_DDD(DUK_DDDPRINT("p_insert=%p -> out of keys, insert to beginning", (void *) p_insert));
				break;
			}
			DUK_DDD(DUK_DDDPRINT("p_insert=%p, val_insert=%ld, val_curr=%ld -> search backwards",
			                     (void *) p_insert, (long) val_insert, (long) val_curr));
			p_insert--;
		}

		DUK_DDD(DUK_DDDPRINT("final p_insert=%p", (void *) p_insert));

		/*        .-- p_insert   .-- p_curr
		 *        v              v
		 *  | ... | insert | ... | curr
		 */

		h_curr = *p_curr;
		DUK_DDD(DUK_DDDPRINT("memmove: dest=%p, src=%p, size=%ld, h_curr=%p",
		                     (void *) (p_insert + 1), (void *) p_insert,
		                     (long) (p_curr - p_insert), (void *) h_curr));

		DUK_MEMMOVE((void *) (p_insert + 1),
		            (const void *) p_insert,
		            (size_t) ((p_curr - p_insert) * sizeof(duk_hstring *)));
		*p_insert = h_curr;
		/* keep val_highest */
	}

#ifdef DUK_USE_DDDPRINT
	{
		duk_uint_fast32_t i;
		for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(h_obj); i++) {
			DUK_DDD(DUK_DDDPRINT("final: %ld %p -> %!O",
			                     (long) i,
			                     (void *) DUK_HOBJECT_E_GET_KEY_PTR(thr->heap, h_obj, i),
			                     (duk_heaphdr *) DUK_HOBJECT_E_GET_KEY(thr->heap, h_obj, i)));
		}
	}
#endif
}

/*
 *  Create an internal enumerator object E, which has its keys ordered
 *  to match desired enumeration ordering.  Also initialize internal control
 *  properties for enumeration.
 *
 *  Note: if an array was used to hold enumeration keys instead, an array
 *  scan would be needed to eliminate duplicates found in the prototype chain.
 */

DUK_INTERNAL void duk_hobject_enumerator_create(duk_context *ctx, duk_small_uint_t enum_flags) {
	duk_hthread *thr = (duk_hthread *) ctx;
	duk_hobject *enum_target;
	duk_hobject *curr;
	duk_hobject *res;
#if defined(DUK_USE_ES6_PROXY)
	duk_hobject *h_proxy_target;
	duk_hobject *h_proxy_handler;
	duk_hobject *h_trap_result;
#endif
	duk_uint_fast32_t i, len;  /* used for array, stack, and entry indices */

	DUK_ASSERT(ctx != NULL);

	DUK_DDD(DUK_DDDPRINT("create enumerator, stack top: %ld", (long) duk_get_top(ctx)));

	enum_target = duk_require_hobject(ctx, -1);
	DUK_ASSERT(enum_target != NULL);

	duk_push_object_internal(ctx);
	res = duk_require_hobject(ctx, -1);

	DUK_DDD(DUK_DDDPRINT("created internal object"));

	/* [enum_target res] */

	/* Target must be stored so that we can recheck whether or not
	 * keys still exist when we enumerate.  This is not done if the
	 * enumeration result comes from a proxy trap as there is no
	 * real object to check against.
	 */
	duk_push_hobject(ctx, enum_target);
	duk_put_prop_stridx(ctx, -2, DUK_STRIDX_INT_TARGET);

	/* Initialize index so that we skip internal control keys. */
	duk_push_int(ctx, DUK__ENUM_START_INDEX);
	duk_put_prop_stridx(ctx, -2, DUK_STRIDX_INT_NEXT);

	/*
	 *  Proxy object handling
	 */

#if defined(DUK_USE_ES6_PROXY)
	if (DUK_LIKELY((enum_flags & DUK_ENUM_NO_PROXY_BEHAVIOR) != 0)) {
		goto skip_proxy;
	}
	if (DUK_LIKELY(!duk_hobject_proxy_check(thr,
	                                        enum_target,
	                                        &h_proxy_target,
	                                        &h_proxy_handler))) {
		goto skip_proxy;
	}

	DUK_DDD(DUK_DDDPRINT("proxy enumeration"));
	duk_push_hobject(ctx, h_proxy_handler);
	if (!duk_get_prop_stridx(ctx, -1, DUK_STRIDX_ENUMERATE)) {
		/* No need to replace the 'enum_target' value in stack, only the
		 * enum_target reference.  This also ensures that the original
		 * enum target is reachable, which keeps the proxy and the proxy
		 * target reachable.  We do need to replace the internal _Target.
		 */
		DUK_DDD(DUK_DDDPRINT("no enumerate trap, enumerate proxy target instead"));
		DUK_DDD(DUK_DDDPRINT("h_proxy_target=%!O", (duk_heaphdr *) h_proxy_target));
		enum_target = h_proxy_target;

		duk_push_hobject(ctx, enum_target);  /* -> [ ... enum_target res handler undefined target ] */
		duk_put_prop_stridx(ctx, -4, DUK_STRIDX_INT_TARGET);

		duk_pop_2(ctx);  /* -> [ ... enum_target res ] */
		goto skip_proxy;
	}

	/* [ ... enum_target res handler trap ] */
	duk_insert(ctx, -2);
	duk_push_hobject(ctx, h_proxy_target);    /* -> [ ... enum_target res trap handler target ] */
	duk_call_method(ctx, 1 /*nargs*/);        /* -> [ ... enum_target res trap_result ] */
	h_trap_result = duk_require_hobject(ctx, -1);
	DUK_UNREF(h_trap_result);

	/* Copy trap result keys into the enumerator object. */
	len = (duk_uint_fast32_t) duk_get_length(ctx, -1);
	for (i = 0; i < len; i++) {
		/* XXX: not sure what the correct semantic details are here,
		 * e.g. handling of missing values (gaps), handling of non-array
		 * trap results, etc.
		 *
		 * For keys, we simply skip non-string keys which seems to be
		 * consistent with how e.g. Object.keys() will process proxy trap
		 * results (ES6, Section 19.1.2.14).
		 */
		if (duk_get_prop_index(ctx, -1, i) && duk_is_string(ctx, -1)) {
			/* [ ... enum_target res trap_result val ] */
			duk_push_true(ctx);
			/* [ ... enum_target res trap_result val true ] */
			duk_put_prop(ctx, -4);
		} else {
			duk_pop(ctx);
		}
	}
	/* [ ... enum_target res trap_result ] */
	duk_pop(ctx);
	duk_remove(ctx, -2);

	/* [ ... res ] */

	/* The internal _Target property is kept pointing to the original
	 * enumeration target (the proxy object), so that the enumerator
	 * 'next' operation can read property values if so requested.  The
	 * fact that the _Target is a proxy disables key existence check
	 * during enumeration.
	 */
	DUK_DDD(DUK_DDDPRINT("proxy enumeration, final res: %!O", (duk_heaphdr *) res));
	goto compact_and_return;

 skip_proxy:
#endif  /* DUK_USE_ES6_PROXY */

	curr = enum_target;
	while (curr) {
		/*
		 *  Virtual properties.
		 *
		 *  String and buffer indices are virtual and always enumerable,
		 *  'length' is virtual and non-enumerable.  Array and arguments
		 *  object props have special behavior but are concrete.
		 */

		if (DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(curr) ||
		    DUK_HOBJECT_IS_BUFFEROBJECT(curr)) {
			/* String and buffer enumeration behavior is identical now,
			 * so use shared handler.
			 */
			if (DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(curr)) {
				duk_hstring *h_val;
				h_val = duk_hobject_get_internal_value_string(thr->heap, curr);
				DUK_ASSERT(h_val != NULL);  /* string objects must not created without internal value */
				len = (duk_uint_fast32_t) DUK_HSTRING_GET_CHARLEN(h_val);
			} else {
				duk_hbufferobject *h_bufobj;
				DUK_ASSERT(DUK_HOBJECT_IS_BUFFEROBJECT(curr));
				h_bufobj = (duk_hbufferobject *) curr;
				if (h_bufobj == NULL) {
					/* Neutered buffer, zero length seems
					 * like good behavior here.
					 */
					len = 0;
				} else {
					/* There's intentionally no check for
					 * current underlying buffer length.
					 */
					len = (duk_uint_fast32_t) (h_bufobj->length >> h_bufobj->shift);
				}
			}

			for (i = 0; i < len; i++) {
				duk_hstring *k;

				k = duk_heap_string_intern_u32_checked(thr, i);
				DUK_ASSERT(k);
				duk_push_hstring(ctx, k);
				duk_push_true(ctx);

				/* [enum_target res key true] */
				duk_put_prop(ctx, -3);

				/* [enum_target res] */
			}

			/* 'length' and other virtual properties are not
			 * enumerable, but are included if non-enumerable
			 * properties are requested.
			 */

			if (enum_flags & DUK_ENUM_INCLUDE_NONENUMERABLE) {
				duk_uint_fast32_t n;

				if (DUK_HOBJECT_IS_BUFFEROBJECT(curr)) {
					n = sizeof(duk__bufferobject_virtual_props) / sizeof(duk_uint16_t);
				} else {
					DUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(curr));
					DUK_ASSERT(duk__bufferobject_virtual_props[0] == DUK_STRIDX_LENGTH);
					n = 1;  /* only 'length' */
				}

				for (i = 0; i < n; i++) {
					duk_push_hstring_stridx(ctx, duk__bufferobject_virtual_props[i]);
					duk_push_true(ctx);
					duk_put_prop(ctx, -3);
				}

			}
		} else if (DUK_HOBJECT_HAS_EXOTIC_DUKFUNC(curr)) {
			if (enum_flags & DUK_ENUM_INCLUDE_NONENUMERABLE) {
				duk_push_hstring_stridx(ctx, DUK_STRIDX_LENGTH);
				duk_push_true(ctx);
				duk_put_prop(ctx, -3);
			}
		}

		/*
		 *  Array part
		 *
		 *  Note: ordering between array and entry part must match 'abandon array'
		 *  behavior in duk_hobject_props.c: key order after an array is abandoned
		 *  must be the same.
		 */

		for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(curr); i++) {
			duk_hstring *k;
			duk_tval *tv;

			tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, curr, i);
			if (DUK_TVAL_IS_UNUSED(tv)) {
				continue;
			}
			k = duk_heap_string_intern_u32_checked(thr, i);
			DUK_ASSERT(k);

			duk_push_hstring(ctx, k);
			duk_push_true(ctx);

			/* [enum_target res key true] */
			duk_put_prop(ctx, -3);

			/* [enum_target res] */
		}

		/*
		 *  Entries part
		 */

		for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(curr); i++) {
			duk_hstring *k;

			k = DUK_HOBJECT_E_GET_KEY(thr->heap, curr, i);
			if (!k) {
				continue;
			}
			if (!DUK_HOBJECT_E_SLOT_IS_ENUMERABLE(thr->heap, curr, i) &&
			    !(enum_flags & DUK_ENUM_INCLUDE_NONENUMERABLE)) {
				continue;
			}
			if (DUK_HSTRING_HAS_INTERNAL(k) &&
			    !(enum_flags & DUK_ENUM_INCLUDE_INTERNAL)) {
				continue;
			}
			if ((enum_flags & DUK_ENUM_ARRAY_INDICES_ONLY) &&
			    (DUK_HSTRING_GET_ARRIDX_SLOW(k) == DUK_HSTRING_NO_ARRAY_INDEX)) {
				continue;
			}

			DUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, curr, i) ||
			           !DUK_TVAL_IS_UNUSED(&DUK_HOBJECT_E_GET_VALUE_PTR(thr->heap, curr, i)->v));

			duk_push_hstring(ctx, k);
			duk_push_true(ctx);

			/* [enum_target res key true] */
			duk_put_prop(ctx, -3);

			/* [enum_target res] */
		}

		if (enum_flags & DUK_ENUM_OWN_PROPERTIES_ONLY) {
			break;
		}

		curr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);
	}

	/* [enum_target res] */

	duk_remove(ctx, -2);

	/* [res] */

	if ((enum_flags & (DUK_ENUM_ARRAY_INDICES_ONLY | DUK_ENUM_SORT_ARRAY_INDICES)) ==
	                  (DUK_ENUM_ARRAY_INDICES_ONLY | DUK_ENUM_SORT_ARRAY_INDICES)) {
		/*
		 *  Some E5/E5.1 algorithms require that array indices are iterated
		 *  in a strictly ascending order.  This is the case for e.g.
		 *  Array.prototype.forEach() and JSON.stringify() PropertyList
		 *  handling.
		 *
		 *  To ensure this property for arrays with an array part (and
		 *  arbitrary objects too, since e.g. forEach() can be applied
		 *  to an array), the caller can request that we sort the keys
		 *  here.
		 */

		/* XXX: avoid this at least when enum_target is an Array, it has an
		 * array part, and no ancestor properties were included?  Not worth
		 * it for JSON, but maybe worth it for forEach().
		 */

		/* XXX: may need a 'length' filter for forEach()
		 */
		DUK_DDD(DUK_DDDPRINT("sort array indices by caller request"));
		duk__sort_array_indices(thr, res);
	}

#if defined(DUK_USE_ES6_PROXY)
 compact_and_return:
#endif
	/* compact; no need to seal because object is internal */
	duk_hobject_compact_props(thr, res);

	DUK_DDD(DUK_DDDPRINT("created enumerator object: %!iT", (duk_tval *) duk_get_tval(ctx, -1)));
}

/*
 *  Returns non-zero if a key and/or value was enumerated, and:
 *
 *   [enum] -> [key]        (get_value == 0)
 *   [enum] -> [key value]  (get_value == 1)
 *
 *  Returns zero without pushing anything on the stack otherwise.
 */
DUK_INTERNAL duk_bool_t duk_hobject_enumerator_next(duk_context *ctx, duk_bool_t get_value) {
	duk_hthread *thr = (duk_hthread *) ctx;
	duk_hobject *e;
	duk_hobject *enum_target;
	duk_hstring *res = NULL;
	duk_uint_fast32_t idx;
	duk_bool_t check_existence;

	DUK_ASSERT(ctx != NULL);

	/* [... enum] */

	e = duk_require_hobject(ctx, -1);

	/* XXX use get tval ptr, more efficient */
	duk_get_prop_stridx(ctx, -1, DUK_STRIDX_INT_NEXT);
	idx = (duk_uint_fast32_t) duk_require_uint(ctx, -1);
	duk_pop(ctx);
	DUK_DDD(DUK_DDDPRINT("enumeration: index is: %ld", (long) idx));

	/* Enumeration keys are checked against the enumeration target (to see
	 * that they still exist).  In the proxy enumeration case _Target will
	 * be the proxy, and checking key existence against the proxy is not
	 * required (or sensible, as the keys may be fully virtual).
	 */
	duk_get_prop_stridx(ctx, -1, DUK_STRIDX_INT_TARGET);
	enum_target = duk_require_hobject(ctx, -1);
	DUK_ASSERT(enum_target != NULL);
#if defined(DUK_USE_ES6_PROXY)
	check_existence = (!DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(enum_target));
#else
	check_existence = 1;
#endif
	duk_pop(ctx);  /* still reachable */

	DUK_DDD(DUK_DDDPRINT("getting next enum value, enum_target=%!iO, enumerator=%!iT",
	                     (duk_heaphdr *) enum_target, (duk_tval *) duk_get_tval(ctx, -1)));

	/* no array part */
	for (;;) {
		duk_hstring *k;

		if (idx >= DUK_HOBJECT_GET_ENEXT(e)) {
			DUK_DDD(DUK_DDDPRINT("enumeration: ran out of elements"));
			break;
		}

		/* we know these because enum objects are internally created */
		k = DUK_HOBJECT_E_GET_KEY(thr->heap, e, idx);
		DUK_ASSERT(k != NULL);
		DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, e, idx));
		DUK_ASSERT(!DUK_TVAL_IS_UNUSED(&DUK_HOBJECT_E_GET_VALUE(thr->heap, e, idx).v));

		idx++;

		/* recheck that the property still exists */
		if (check_existence && !duk_hobject_hasprop_raw(thr, enum_target, k)) {
			DUK_DDD(DUK_DDDPRINT("property deleted during enumeration, skip"));
			continue;
		}

		DUK_DDD(DUK_DDDPRINT("enumeration: found element, key: %!O", (duk_heaphdr *) k));
		res = k;
		break;
	}

	DUK_DDD(DUK_DDDPRINT("enumeration: updating next index to %ld", (long) idx));

	duk_push_u32(ctx, (duk_uint32_t) idx);
	duk_put_prop_stridx(ctx, -2, DUK_STRIDX_INT_NEXT);

	/* [... enum] */

	if (res) {
		duk_push_hstring(ctx, res);
		if (get_value) {
			duk_push_hobject(ctx, enum_target);
			duk_dup(ctx, -2);      /* -> [... enum key enum_target key] */
			duk_get_prop(ctx, -2); /* -> [... enum key enum_target val] */
			duk_remove(ctx, -2);   /* -> [... enum key val] */
			duk_remove(ctx, -3);   /* -> [... key val] */
		} else {
			duk_remove(ctx, -2);   /* -> [... key] */
		}
		return 1;
	} else {
		duk_pop(ctx);  /* -> [...] */
		return 0;
	}
}

/*
 *  Get enumerated keys in an Ecmascript array.  Matches Object.keys() behavior
 *  described in E5 Section 15.2.3.14.
 */

DUK_INTERNAL duk_ret_t duk_hobject_get_enumerated_keys(duk_context *ctx, duk_small_uint_t enum_flags) {
	duk_hthread *thr = (duk_hthread *) ctx;
	duk_hobject *e;
	duk_uint_fast32_t i;
	duk_uint_fast32_t idx;

	DUK_ASSERT(ctx != NULL);
	DUK_ASSERT(duk_get_hobject(ctx, -1) != NULL);
	DUK_UNREF(thr);

	/* Create a temporary enumerator to get the (non-duplicated) key list;
	 * the enumerator state is initialized without being needed, but that
	 * has little impact.
	 */

	duk_hobject_enumerator_create(ctx, enum_flags);
	duk_push_array(ctx);

	/* [enum_target enum res] */

	e = duk_require_hobject(ctx, -2);
	DUK_ASSERT(e != NULL);

	idx = 0;
	for (i = DUK__ENUM_START_INDEX; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(e); i++) {
		duk_hstring *k;

		k = DUK_HOBJECT_E_GET_KEY(thr->heap, e, i);
		DUK_ASSERT(k);  /* enumerator must have no keys deleted */

		/* [enum_target enum res] */
		duk_push_hstring(ctx, k);
		duk_put_prop_index(ctx, -2, idx);
		idx++;
	}

	/* [enum_target enum res] */
	duk_remove(ctx, -2);

	/* [enum_target res] */

	return 1;  /* return 1 to allow callers to tail call */
}
