Something went wrong. Try again.
javascript for 🐜's, a tiny runtime with big ambitions antjs.org
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577#ifndef ANT_INTERNAL_H#define ANT_INTERNAL_H
#include "ant.h"#include "value.h"#include "object.h"#include "errors.h"#include "isolate.h"
#include "gc/strings.h"#include "gc/roots.h"#include "silver/ast.h"#include "descriptors.h"#include "esm/loader.h"
#include <assert.h>#include <string.h>
typedef enum { ANT_STRING_INTRINSIC_INDEX_OF = 0, ANT_STRING_INTRINSIC_SUBSTRING,} ant_string_intrinsic_kind_t;
static inline bool ant_value_stack_push_with_spill( ant_value_t **stack, size_t *sp, size_t *cap, ant_value_t *local, ant_value_t value) { if (*sp == *cap) { size_t next_cap = *cap * 2u;
ant_value_t *next = *stack == local ? (ant_value_t *)malloc(next_cap * sizeof(*next)) : (ant_value_t *)realloc(*stack, next_cap * sizeof(*next));
if (!next) return false; if (*stack == local) memcpy(next, local, *sp * sizeof(*next));
*stack = next; *cap = next_cap; }
(*stack)[(*sp)++] = value; return true;}
#define T_FLAG_FIND(t) (1u << (t))#define T_MASK_HOLD ()#define T_MASK_EXPAND(...) T_MASK_E1(T_MASK_E1(T_MASK_E1(T_MASK_E1(__VA_ARGS__))))#define T_MASK_E1(...) T_MASK_E2(T_MASK_E2(T_MASK_E2(T_MASK_E2(__VA_ARGS__))))#define T_MASK_E2(...) __VA_ARGS__#define T_MASK_STEP(a, ...) \ T_FLAG_FIND(a) __VA_OPT__(| T_MASK_AGAIN T_MASK_HOLD (__VA_ARGS__))#define T_MASK_AGAIN() T_MASK_STEP#define T_MASK(...) (T_MASK_EXPAND(T_MASK_STEP(__VA_ARGS__)))
static_assert(T_MASK(kTypeObject) == T_FLAG_FIND(kTypeObject));
#define is_non_numeric(v) ((1u << vtype(v)) & T_NON_NUMERIC_MASK)#define is_object_type(v) ((1u << vtype(v)) & T_OBJECT_MASK)#define is_special_object(v) ((1u << vtype(v)) & T_SPECIAL_OBJECT_MASK)
static constexpr uint32_t T_SPECIAL_OBJECT_MASK = T_MASK(kTypeObject, kTypeArray);
static constexpr uint32_t T_BOXABLE_PRIMITIVE_MASK = T_MASK(kTypeString, kTypeNumber, kTypeBool, kTypeBigInt, kTypeSymbol);
static constexpr uint32_t T_NEEDS_PROTO_FALLBACK = T_MASK(kTypeFunction, kTypeArray, kTypePromise, kTypeGenerator);
static constexpr uint32_t T_OBJECT_MASK = T_MASK(kTypeObject, kTypeArray, kTypeFunction, kTypePromise, kTypeGenerator);
static constexpr uint32_t T_NON_NUMERIC_MASK = T_MASK(kTypeString, kTypeArray, kTypeFunction, kTypeBuiltin, kTypeObject, kTypeGenerator);
static_assert( T_NON_NUMERIC_MASK == ( T_FLAG_FIND(kTypeString) | T_FLAG_FIND(kTypeArray) | T_FLAG_FIND(kTypeFunction) | T_FLAG_FIND(kTypeBuiltin) | T_FLAG_FIND(kTypeObject) | T_FLAG_FIND(kTypeGenerator)), "T_MASK variadic expansion");
enum: ant_value_t { T_EMPTY = ANT_SENTINEL_TAG | 0xDEADULL, SV_JIT_BAILOUT = ANT_SENTINEL_TAG | 0xBA110ULL, SV_JIT_AWAIT_PARKED = ANT_SENTINEL_TAG | 0xBA111ULL, SV_AITER_ARRAY_TAG = ANT_SENTINEL_TAG | 0xFA1ULL, SV_AITER_AWAIT_MARK = ANT_SENTINEL_TAG | 0xFA2ULL, SV_AITER_STEP_MARK = ANT_SENTINEL_TAG | 0xFA3ULL, SV_AITER_CLOSE_SKIP = ANT_SENTINEL_TAG | 0xFA4ULL, PROMISE_ALL_ELEMENT = ANT_SENTINEL_TAG | 0xA11ULL, PROMISE_AWAIT_DEFER = ANT_SENTINEL_TAG | 0xA12ULL,};
static inline void ant_object_invalidate_guarded_absence(ant_t *js, ant_object_t *obj) { if (!obj || !obj->flags.guards_absence) return; obj->flags.guards_absence = 0; ant_ic_epoch_bump(js);}
typedef struct { bool has_getter; bool has_setter; bool writable; bool enumerable; bool configurable; ant_value_t getter; ant_value_t setter;} prop_meta_t;
typedef enum { PROP_META_STRING = 0, PROP_META_SYMBOL = 1,} prop_meta_key_t;
static inline bool is_err(ant_value_t v) { return vtype(v) == kTypeError;}
static inline bool is_null(ant_value_t v) { return vtype(v) == kTypeNull;}
static inline bool is_undefined(ant_value_t v) { return vtype(v) == kTypeUndefined;}
static inline bool is_nullish(ant_value_t v) { return vtype(v) == kTypeUndefined || vtype(v) == kTypeNull;}
static inline bool is_empty_slot(ant_value_t v) { return v == T_EMPTY;}
static inline void js_cstk_refresh_floor(ant_t *js) { uintptr_t base = (uintptr_t)js->cstk.base; js->cstk.floor = (js->cstk.base != NULL && js->cstk.limit != 0 && base > js->cstk.limit) ? (void *)(base - js->cstk.limit) : NULL;}
static inline bool is_callable(ant_value_t v) { uint8_t t = vtype(v); if (t == kTypeFunction || t == kTypeBuiltin) return true; if (t != kTypeObject) return false; ant_object_t *obj = js_obj_ptr(v); return obj && obj->flags.is_callable;}
static inline const ant_cfunc_meta_t *js_as_cfunc_meta(ant_value_t fn_val) { return (const ant_cfunc_meta_t *)ant_cage_decode(vdata(fn_val));}
static inline ant_cfunc_t js_as_cfunc(ant_value_t fn_val) { const ant_cfunc_meta_t *meta = js_as_cfunc_meta(fn_val); return meta ? meta->fn : NULL;}
static inline uint32_t js_cfunc_length(ant_value_t fn_val) { const ant_cfunc_meta_t *meta = js_as_cfunc_meta(fn_val); return meta ? meta->length : 0;}
static inline bool js_cfunc_same_entrypoint(ant_value_t fn_val, ant_cfunc_t fn) { const ant_cfunc_meta_t *meta = js_as_cfunc_meta(fn_val); return meta && meta->fn == fn;}
static constexpr int ANT_ARG_LIST_INLINE = 16;
typedef struct { gc_temp_root_scope_t roots; ant_value_t *args; int argc; bool rooted; ant_value_t inline_args[ANT_ARG_LIST_INLINE];} ant_arg_list_t;
typedef ant_value_t (*js_group_add_fn)( ant_t *js, void *ctx, ant_value_t key, ant_value_t value);
void Ant_ArgList_Release(ant_arg_list_t *list);const ant_value_t *Ant_Array_DenseView(ant_value_t arr, int *len_out);
ant_value_t Ant_String_CoerceThis(ant_t *js, const char *name);ant_value_t Ant_ArgList_FromArrayLike(ant_t *js, ant_value_t array_like, ant_arg_list_t *list);
size_t uint_to_str(char *buf, size_t bufsize, uint64_t val);size_t tostr(ant_t *js, ant_value_t value, char *buf, size_t len);size_t strstring(ant_t *js, ant_value_t value, char *buf, size_t len);size_t js_number_to_chars(ant_value_t value, char *buf, size_t len);
double js_to_number(ant_t *js, ant_value_t arg);double js_parse_int_value(ant_t *js, ant_value_t arg);double js_parse_float_value(ant_t *js, ant_value_t arg);
bool js_obj_ensure_prop_capacity(ant_t *js, ant_object_t *obj, uint32_t needed);bool js_obj_ensure_unique_shape(ant_object_t *obj);bool js_get_plain_index(ant_t *js, ant_value_t obj, uint32_t idx, ant_value_t *out);bool js_string_past_end_is_undefined(ant_t *js, ant_value_t str);
ant_value_t js_string_from_utf16_code_unit(ant_t *js, uint32_t code_unit);ant_value_t js_get_index_fast(ant_t *js, ant_value_t obj, ant_value_t key);
ant_value_t js_group_by(ant_t *js, ant_value_t items, ant_value_t callback, js_group_add_fn add, void *ctx);ant_value_t js_define_property(ant_t *js, ant_value_t obj, ant_value_t prop, ant_value_t descriptor, bool reflect_mode);ant_value_t js_proxy_has(ant_t *js, ant_value_t proxy, const char *key, size_t key_len);ant_value_t js_proxy_prevent_extensions(ant_t *js, ant_value_t proxy);ant_value_t js_mkproxy(ant_t *js, ant_value_t target, ant_value_t handler);ant_value_t js_get_own_property_descriptor(ant_t *js, ant_value_t obj, ant_value_t key);
ant_value_t js_vm_script_compile(ant_t *js, const char *buf, size_t len);ant_value_t js_vm_script_run(ant_t *js, ant_value_t compiled);ant_value_t js_function_from_source(ant_t *js, ant_value_t *params_and_body, int nargs);
ant_value_t js_proxy_set(ant_t *js, ant_value_t proxy, const char *key, size_t key_len, ant_value_t value);ant_value_t js_proxy_set_sym(ant_t *js, ant_value_t proxy, ant_value_t sym, ant_value_t value);ant_value_t js_set_reporting(ant_t *js, ant_value_t target, ant_value_t key, ant_value_t value);ant_value_t js_set_with_receiver(ant_t *js, ant_value_t target, ant_value_t key, ant_value_t value, ant_value_t receiver);
ant_value_t mkprop(ant_t *js, ant_value_t obj, ant_value_t k, ant_value_t v, uint8_t attrs);ant_value_t mkprop_exact_attrs(ant_t *js, ant_value_t obj, ant_value_t k, ant_value_t v, uint8_t attrs);ant_value_t mkprop_interned(ant_t *js, ant_value_t obj, const char *interned_key, ant_value_t v, uint8_t attrs);ant_value_t mkprop_interned_exact(ant_t *js, ant_value_t obj, const char *interned_key, ant_value_t v, uint8_t attrs);ant_value_t mkprop_append_fast(ant_t *js, ant_value_t obj, const char *key, size_t len, ant_value_t v);
ant_value_t setprop_cstr(ant_t *js, ant_value_t obj, const char *key, size_t len, ant_value_t v);ant_value_t setprop_interned(ant_t *js, ant_value_t obj, const char *key, size_t len, ant_value_t v);
ant_value_t js_codegen_refused(ant_t *js);ant_value_t js_template_to_string(ant_t *js, ant_value_t v);ant_value_t js_to_numeric(ant_t *js, ant_value_t arg);ant_value_t js_define_own_prop(ant_t *js, ant_value_t obj, const char *key, size_t klen, ant_value_t v);ant_value_t js_instance_proto_from_new_target(ant_t *js, ant_value_t fallback_proto, ant_value_t new_target);ant_value_t js_construct_native(ant_t *js, ant_cfunc_t ctor, ant_value_t *args, int nargs);
ant_value_t js_get_module_import_binding(ant_t *js);ant_value_t js_builtin_import(ant_params_t);ant_value_t js_create_import_meta(ant_t *js, const char *filename, bool is_main);ant_value_t js_create_module_context(ant_t *js, const char *filename, bool is_main);ant_value_t js_create_arguments_object(ant_t *js, sv_vm_t *vm, ant_value_t callee, sv_frame_t *frame, int argc, int mapped_count, bool is_strict);
void js_arguments_detach(ant_t *js, ant_value_t obj);void js_arguments_sync_slot(ant_t *js, ant_value_t obj, uint32_t idx, ant_value_t value);void js_arguments_rebind_frame(ant_t *js, ant_value_t obj, int frame_index);void js_arguments_bind_direct(ant_t *js, ant_value_t obj, struct sv_frame *frame);
ant_value_t coerce_to_str(ant_t *js, ant_value_t v);ant_value_t coerce_to_str_concat(ant_t *js, ant_value_t v);ant_value_t get_ctor_species_value(ant_t *js, ant_value_t ctor);
bool proto_chain_contains(ant_t *js, ant_value_t obj, ant_value_t proto_target);bool same_ctor_identity(ant_t *js, ant_value_t a, ant_value_t b);bool js_array_iteration_default(ant_t *js, ant_value_t arr);
ant_value_t lkp_interned_val(ant_t *js, ant_value_t obj, const char *search_intern);ant_prop_loc_t lkp_interned(ant_value_t obj, const char *search_intern);
ant_prop_loc_t lkp(ant_t *js, ant_value_t obj, const char *buf, size_t len);ant_prop_loc_t lkp_proto(ant_t *js, ant_value_t obj, const char *buf, size_t len);
ant_prop_loc_t lkp_sym(ant_value_t obj, ant_offset_t sym_off);ant_prop_loc_t lkp_sym_proto(ant_t *js, ant_value_t obj, ant_offset_t sym_off);
ant_value_t mkobj(ant_t *js, ant_offset_t parent);ant_value_t js_mkarr_dense_literal(ant_t *js, const ant_value_t *elements, uint32_t count);ant_value_t js_mkarr_dense_uninit(ant_t *js, uint32_t count, ant_value_t **out_data);ant_value_t js_arr_spread_into(ant_t *js, ant_value_t dst, ant_value_t src);
void js_arr_set_index(ant_t *js, ant_value_t arr, ant_offset_t idx, ant_value_t val);void js_arr_set_dense_length(ant_t *js, ant_value_t arr, ant_offset_t len);ant_object_t *js_dense_array_obj(ant_value_t value);
typedef enum { ITER_CONTINUE, ITER_BREAK, ITER_ERROR } iter_action_t;typedef iter_action_t (*iter_callback_t)(ant_t *js, ant_value_t value, void *ctx, ant_value_t *out);ant_value_t js_iter_foreach(ant_t *js, ant_value_t iterable, iter_callback_t cb, void *ctx);
ant_value_t js_make_data_cfunc(ant_t *js, ant_value_t data, ant_cfunc_t fn);bool js_obj_extra_reserve(ant_object_t *obj, uint8_t capacity);ant_value_t js_mkobj_from_template(ant_t *js, ant_value_t template);
ant_value_t js_for_in_keys(ant_t *js, ant_value_t obj);ant_value_t js_own_property_keys(ant_t *js, ant_value_t obj, bool include_symbols, bool enumerable_only);ant_value_t Ant_Object_ToStringTag(ant_t *js, ant_value_t obj);ant_value_t Ant_Object_PropertyIsEnumerable(ant_t *js, ant_value_t obj, ant_value_t key);ant_value_t Ant_Object_HasOwn(ant_t *js, ant_value_t obj, ant_value_t key);ant_value_t js_delete_prop(ant_t *js, ant_value_t obj, const char *key, size_t len);ant_value_t js_delete_prop_ordinary(ant_t *js, ant_value_t obj, const char *key, size_t len);ant_value_t js_delete_sym_prop(ant_t *js, ant_value_t obj, ant_value_t sym);
ant_value_t js_cfunc_promote(ant_t *js, ant_value_t cfunc);ant_value_t js_cfunc_expose_named(ant_t *js, ant_value_t cfunc, const char *name, size_t name_len);
typedef enum { JS_CFUNC_VALUE, JS_CFUNC_GETTER, JS_CFUNC_SETTER } js_cfunc_role_t;ant_value_t js_cfunc_expose_property(ant_t *js, ant_value_t fn, js_cfunc_role_t role, const char *key, size_t key_len, bool symbol);ant_value_t js_set_function_name(ant_t *js, ant_value_t fn, const char *name, size_t name_len);ant_value_t js_define_function_length(ant_t *js, ant_value_t fn, int length);
typedef enum { JS_FUNC_SOURCE_COPY, JS_FUNC_SOURCE_PINNED, JS_FUNC_SOURCE_UNIT,} js_func_source_t;
void js_set_func_source(ant_t *js, ant_value_t fn, const char *code, size_t len, js_func_source_t source);ant_value_t js_setprop_index(ant_t *js, ant_value_t obj, uint32_t idx, ant_value_t value);
ant_value_t js_set_function_name_prefixed( ant_t *js, ant_value_t fn, const char *prefix, size_t prefix_len, const char *name, size_t name_len);
ant_value_t js_set_function_name_from_key( ant_t *js, ant_value_t fn, ant_value_t key, const char *prefix, size_t prefix_len);
ant_value_t js_maybe_set_function_name_from_key( ant_t *js, ant_value_t fn, ant_value_t key, const char *prefix, size_t prefix_len);
sv_func_t *js_compile_parsed_bytecode( ant_t *js, struct sv_ast *program, const char *buf, size_t len, int mode, ant_value_t eval_env);
bool js_try_char_code_at( ant_t *js, ant_value_t func, ant_value_t receiver, ant_value_t *args, int argc, ant_value_t *result);
ant_value_t js_eval_bytecode_eval_in_env_with_strict( ant_t *js, const char *buf, size_t len, bool inherit_strict, ant_value_t this_val, ant_value_t eval_env, ant_value_t new_target, bool allows_new_target);
bool is_proxy(ant_value_t obj);bool js_proxy_is_host(ant_value_t obj);bool js_try_host_proxy_get(ant_t *js, ant_value_t obj, const char *key, size_t key_len, ant_value_t *out);bool is_array_value(ant_value_t value);bool js_is_array_includes_builtin(ant_value_t func);bool js_is_function_apply_builtin(ant_value_t func);bool strict_eq_values(ant_t *js, ant_value_t l, ant_value_t r);bool same_value_values(ant_t *js, ant_value_t l, ant_value_t r);bool js_string_intrinsic_builtin_matches(ant_value_t func, ant_string_intrinsic_kind_t kind);bool js_deep_equal(ant_t *js, ant_value_t a, ant_value_t b, bool strict);bool js_is_prototype_of(ant_t *js, ant_value_t proto_obj, ant_value_t obj);bool js_chain_may_override_has_instance(ant_t *js, ant_value_t obj, bool guard_absence);bool js_instance_of_proto(ant_t *js, ant_value_t obj, ant_value_t ctor_proto);void js_set_exotic_ops(ant_value_t obj, const ant_exotic_ops_t *ops);
ant_value_t js_call_getter(ant_t *js, ant_value_t receiver, ant_value_t getter);ant_value_t js_mkproxy_host(ant_t *js, ant_value_t target, const ant_host_proxy_ops_t *ops);ant_value_t js_copy_data_props(ant_t *js, ant_value_t dst, ant_value_t src, const ant_value_t *excluded, int excluded_count);ant_value_t js_primitive_prototype(ant_t *js, uint8_t type);ant_value_t js_normalize_sloppy_this(ant_t *js, ant_value_t value);ant_value_t js_resolve_bound_target(ant_value_t value);ant_value_t js_resolve_bound_target_known_bound(ant_value_t value);ant_value_t js_execute_compiled_bytecode(ant_t *js, sv_func_t *func, coroutine_t **async_coro_out);ant_value_t js_execute_compiled_module(ant_t *js, sv_func_t *func);ant_value_t js_proxy_apply(ant_t *js, ant_value_t proxy, ant_value_t this_arg, ant_value_t *args, int argc);ant_value_t js_proxy_construct(ant_t *js, ant_value_t proxy, ant_value_t *args, int argc, ant_value_t new_target);ant_value_t sv_call_native(ant_t *js, ant_value_t func, ant_value_t this_val, ant_value_t *args, int nargs, ant_value_t new_target);ant_value_t js_array_includes_call(ant_t *js, ant_value_t this_val, ant_value_t *args, int nargs);
const char *typestr(ant_value_type_t t);ant_value_t unwrap_primitive(ant_t *js, ant_value_t val);ant_value_t do_string_op(ant_t *js, uint8_t op, ant_value_t l, ant_value_t r);ant_value_t do_string_num_concat(ant_t *js, ant_value_t str, ant_value_t num, bool num_first);ant_value_t js_to_primitive(ant_t *js, ant_value_t value, int hint);ant_value_t js_is_array_value_checked(ant_t *js, ant_value_t value, bool *out);
ant_value_t do_instanceof(ant_t *js, ant_value_t l, ant_value_t r);ant_value_t do_in(ant_t *js, ant_value_t l, ant_value_t r);ant_value_t js_in_str(ant_t *js, ant_value_t r, const char *key, size_t key_len);const char *intern_find_flat(ant_t *js, const char *bytes, size_t len);
ant_value_t builtin_function_apply(ant_params_t);ant_value_t builtin_object_isPrototypeOf(ant_params_t);ant_value_t builtin_object_freeze(ant_params_t);ant_value_t builtin_string_charCodeAt(ant_params_t);ant_value_t builtin_object_getOwnPropertyDescriptor(ant_params_t);ant_value_t builtin_array_includes(ant_params_t);ant_value_t js_builtin_eval(ant_t *js);
void js_module_eval_ctx_push(ant_t *js, ant_module_t *ctx);void js_module_eval_ctx_pop(ant_t *js, ant_module_t *ctx);
ant_value_t js_string_intrinsic_call( ant_t *js, ant_string_intrinsic_kind_t kind, ant_value_t this_val, ant_value_t *args, int nargs);
bool js_try_get_own_data_prop( ant_t *js, ant_value_t obj, const char *key, size_t key_len, ant_value_t *out);
bool lookup_prop_meta( ant_t *js, ant_value_t cur_obj, prop_meta_key_t key_kind, const char *key, size_t klen, ant_offset_t sym_off, prop_meta_t *out);
const char *get_class_name( ant_t *js, ant_value_t obj, ant_offset_t *out_len, const char *skip);
static inline bool streq(const char *buf, size_t len, const char *s, size_t n) { return len == n && !memcmp(buf, s, n);}
static inline bool is_boxable_primitive_type(uint8_t type) { return (T_FLAG_FIND(type) & T_BOXABLE_PRIMITIVE_MASK) != 0;}
static inline size_t cpy(char *dst, size_t dstlen, const char *src, size_t srclen) { if (dstlen == 0) return srclen; size_t len = srclen < dstlen - 1 ? srclen : dstlen - 1; memcpy(dst, src, len); dst[len] = '\0'; return srclen;}
static inline ant_module_t *js_active_tla_module_ctx(ant_t *js) { if (!js) return NULL; for (coroutine_t *coro = js->active_async_coro; coro; coro = coro->active_parent) if (coro->module_eval_ctx) return coro->module_eval_ctx; return NULL;}
static inline void js_module_ctx_link_namespace(ant_t *js, ant_value_t module_ctx, ant_value_t ns) { if (!is_object_type(module_ctx) || !is_object_type(ns)) return; js_set_slot_wb(js, ns, SLOT_MODULE_CTX, module_ctx); js_set_slot_wb(js, module_ctx, SLOT_DATA, ns);}
static inline ant_value_t js_module_ctx_namespace(ant_value_t module_ctx) { if (!is_object_type(module_ctx)) return js_mkundef(); ant_value_t ns = js_get_slot(module_ctx, SLOT_DATA); return is_object_type(ns) ? ns : js_mkundef();}
static inline ant_value_t js_current_func_module_ns(ant_t *js) { if (!js || !is_object_type(js->current_func)) return js_mkundef(); return js_module_ctx_namespace(js_get_slot(js->current_func, SLOT_MODULE_CTX));}
static inline ant_value_t js_module_eval_active_ns(ant_t *js) { ant_module_t *ctx = js->modules.module_stack; if (ctx) return ctx->module_ns; ctx = js->active_async_coro ? js_active_tla_module_ctx(js) : NULL; if (ctx) return ctx->module_ns; return js_current_func_module_ns(js);}
static inline ant_value_t js_module_eval_active_ctx(ant_t *js) { ant_module_t *ctx = js->modules.module_stack; if (ctx) return ctx->module_ctx; ctx = js->active_async_coro ? js_active_tla_module_ctx(js) : NULL; return ctx ? ctx->module_ctx : js_mkundef();}
static inline const char *js_module_eval_active_filename(ant_t *js) { ant_value_t module_ctx = js_module_eval_active_ctx(js); if (is_object_type(module_ctx)) { ant_value_t filename = js_get(js, module_ctx, "filename"); if (vtype(filename) == kTypeString) return js_getstr(js, filename, NULL); } return js->filename;}
static constexpr size_t ANT_CANONICAL_NUMERIC_KEY_MAX = 32;
static inline bool ant_key_may_be_numeric(const char *key, size_t len) { if (!key || len == 0 || len > ANT_CANONICAL_NUMERIC_KEY_MAX) return false; switch (key[0]) { case 'I': return len == 8 && memcmp(key, "Infinity", 8) == 0; case 'N': return len == 3 && memcmp(key, "NaN", 3) == 0; case '-': return true; default: return key[0] >= '0' && key[0] <= '9'; }}
static inline bool is_length_key(const char *key, size_t len) { return len == 6 && !memcmp(key, "length", 6);}
static inline ant_value_t js_string_wrapper_value(ant_value_t obj) { if (vtype(obj) != kTypeObject) return js_mkundef(); ant_extra_slot_t *entry = ant_object_extra_slot((ant_object_t *)vptr(obj), SLOT_PRIMITIVE); return entry && vtype(entry->value) == kTypeString ? entry->value : js_mkundef();}
static inline int js_brand_id(ant_value_t obj) { if (!is_object_type(obj)) return BRAND_NONE; ant_value_t brand = js_get_slot(obj, SLOT_BRAND); return vtype(brand) == kTypeNumber ? (int)js_getnum(brand) : BRAND_NONE;}
static inline bool js_check_brand(ant_value_t obj, int brand) { return js_brand_id(obj) == brand;}
static inline bool lookup_symbol_prop_meta(ant_t *js, ant_value_t cur_obj, ant_offset_t sym_off, prop_meta_t *out) { return lookup_prop_meta(js, cur_obj, PROP_META_SYMBOL, NULL, 0, sym_off, out);}
static inline bool lookup_string_prop_meta(ant_t *js, ant_value_t cur_obj, const char *key, size_t klen, prop_meta_t *out) { return lookup_prop_meta(js, cur_obj, PROP_META_STRING, key, klen, 0, out);}
static inline ant_value_t defmethod(ant_t *js, ant_value_t obj, const char *name, size_t len, ant_value_t fn) { const char *interned = intern_string(js, name, len); if (!interned) return js_mkerr(js, "oom"); return mkprop_interned(js, obj, interned, fn, ANT_PROP_ATTR_METHOD);}
static inline ant_value_t defmethod_sym(ant_t *js, ant_value_t obj, ant_value_t sym, ant_value_t fn) { const char *desc = js_sym_desc(sym); fn = js_cfunc_expose_property(js, fn, JS_CFUNC_VALUE, desc, desc ? strlen(desc) : 0, true); return is_err(fn) ? fn : mkprop(js, obj, sym, fn, ANT_PROP_ATTR_METHOD);}
static inline ant_value_t defhidden(ant_t *js, ant_value_t obj, const char *name, size_t len, ant_value_t value) { const char *interned = intern_string(js, name, len); if (!interned) return js_mkerr(js, "oom"); return mkprop_interned_exact(js, obj, interned, value, ANT_PROP_ATTR_WRITABLE | ANT_PROP_ATTR_CONFIGURABLE);}
static inline ant_value_t defalias(ant_t *js, ant_value_t obj, const char *name, size_t len, ant_value_t fn) { const char *interned = intern_string(js, name, len); if (!interned) return js_mkerr(js, "oom"); return mkprop_interned_exact(js, obj, interned, fn, ANT_PROP_ATTR_WRITABLE | ANT_PROP_ATTR_CONFIGURABLE);}
static inline ant_value_t defalias_of(ant_t *js, ant_value_t obj, const char *alias, const char *target) { return defalias(js, obj, alias, strlen(alias), js_get(js, obj, target));}
static inline ant_value_t defalias_sym_of(ant_t *js, ant_value_t obj, ant_value_t sym, const char *target) { return mkprop(js, obj, sym, js_get(js, obj, target), ANT_PROP_ATTR_METHOD);}
static inline void js_set_global_builtin(ant_t *js, const char *name, ant_value_t value) { ant_value_t global = js->global; size_t name_len = strlen(name); js_set(js, global, name, value); js_set_descriptor(js, global, name, name_len, JS_DESC_W | JS_DESC_C);}
static inline void js_set_module_default(ant_t *js, ant_value_t lib, ant_value_t ctor_fn, const char *name) { js_set(js, ctor_fn, name, ctor_fn); js_set(js, lib, name, ctor_fn); js_set(js, lib, "default", ctor_fn); js_set(js, ctor_fn, "default", ctor_fn); js_set_slot_wb(js, lib, SLOT_DEFAULT, ctor_fn);}
#endif