DUK_EXTERNAL void duk_enum(duk_context *ctx, duk_idx_t obj_index, duk_uint_t enum_flags) { DUK_ASSERT_CTX_VALID(ctx); duk_dup(ctx, obj_index); duk_require_hobject_or_lfunc_coerce(ctx, -1); duk_hobject_enumerator_create(ctx, enum_flags); /* [target] -> [enum] */ }
duk_ret_t duk_hobject_get_enumerated_keys(duk_context *ctx, duk_small_uint_t enum_flags) { 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); /* 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) e->e_next; i++) { duk_hstring *k; k = DUK_HOBJECT_E_GET_KEY(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 */ }