MIRROR: javascript for ๐Ÿœ's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

DOMException/AbortController

+549 -2
+3
.gitignore
··· 22 22 /javascript-zoo 23 23 /game-of-life 24 24 25 + /wpt 26 + /tools 27 + 25 28 /vendor/*/ 26 29 /vendor/.wraplock 27 30 !/vendor/packagefiles
+2
include/gc/modules.h
··· 19 19 void gc_mark_symbols(ant_t *js, gc_mark_fn mark); 20 20 void gc_mark_esm(ant_t *js, gc_mark_fn mark); 21 21 void gc_mark_worker_threads(ant_t *js, gc_mark_fn mark); 22 + void gc_mark_abort(ant_t *js, gc_mark_fn mark); 23 + void gc_mark_domexception(ant_t *js, gc_mark_fn mark); 22 24 23 25 #endif
+16
include/modules/abort.h
··· 1 + #ifndef ANT_ABORT_MODULE_H 2 + #define ANT_ABORT_MODULE_H 3 + 4 + #include "types.h" 5 + #include "gc/modules.h" 6 + 7 + void init_abort_module(void); 8 + 9 + void gc_mark_abort(ant_t *js, gc_mark_fn mark); 10 + void signal_do_abort(ant_t *js, ant_value_t signal, ant_value_t reason); 11 + void abort_signal_add_listener(ant_t *js, ant_value_t signal, ant_value_t callback); 12 + 13 + bool abort_signal_is_aborted(ant_value_t signal); 14 + ant_value_t abort_signal_get_reason(ant_value_t signal); 15 + 16 + #endif
+11
include/modules/domexception.h
··· 1 + #ifndef ANT_DOMEXCEPTION_MODULE_H 2 + #define ANT_DOMEXCEPTION_MODULE_H 3 + 4 + #include "types.h" 5 + #include "gc/modules.h" 6 + 7 + void init_domexception_module(void); 8 + void gc_mark_domexception(ant_t *js, gc_mark_fn mark); 9 + ant_value_t make_dom_exception(ant_t *js, const char *message, const char *name); 10 + 11 + #endif
+2
src/gc/objects.c
··· 452 452 gc_mark_symbols(js, gc_mark_value); 453 453 gc_mark_esm(js, gc_mark_value); 454 454 gc_mark_worker_threads(js, gc_mark_value); 455 + gc_mark_abort(js, gc_mark_value); 456 + gc_mark_domexception(js, gc_mark_value); 455 457 456 458 for ( 457 459 ant_object_t *obj = g_pending_promises;
+6 -2
src/main.c
··· 69 69 #include "modules/net.h" 70 70 #include "modules/dns.h" 71 71 #include "modules/assert.h" 72 + #include "modules/domexception.h" 73 + #include "modules/abort.h" 72 74 #include "modules/v8.h" 73 75 #include "modules/worker_threads.h" 74 76 ··· 572 574 proc_argv = build_process_argv(argc, argv, module_file, script_tail); 573 575 ant_runtime_init(js, proc_argv.argc, proc_argv.argv, localstorage_file); 574 576 577 + init_symbol_module(); 578 + init_timer_module(); 579 + init_domexception_module(); 580 + init_abort_module(); 575 581 init_math_module(); 576 582 init_bigint_module(); 577 - init_symbol_module(); 578 583 init_date_module(); 579 584 init_regex_module(); 580 585 init_collections_module(); ··· 587 592 init_console_module(); 588 593 init_json_module(); 589 594 init_server_module(); 590 - init_timer_module(); 591 595 init_process_module(); 592 596 init_tty_module(); 593 597 init_events_module();
+400
src/modules/abort.c
··· 1 + #include <stdlib.h> 2 + #include <string.h> 3 + #include <utarray.h> 4 + #include <uv.h> 5 + 6 + #include "ant.h" 7 + #include "errors.h" 8 + #include "internal.h" 9 + #include "runtime.h" 10 + #include "descriptors.h" 11 + 12 + #include "gc/modules.h" 13 + #include "modules/symbol.h" 14 + #include "modules/timer.h" 15 + #include "modules/abort.h" 16 + #include "modules/domexception.h" 17 + #include "silver/engine.h" 18 + 19 + typedef struct { 20 + ant_value_t callback; 21 + bool once; 22 + } abort_listener_t; 23 + 24 + typedef struct { 25 + bool aborted; 26 + bool fired; 27 + ant_value_t reason; 28 + UT_array *listeners; 29 + UT_array *followers; 30 + } abort_signal_data_t; 31 + 32 + typedef struct abort_timeout_entry { 33 + uv_timer_t handle; 34 + ant_t *js; 35 + ant_value_t signal; 36 + int closed; 37 + struct abort_timeout_entry *next; 38 + } abort_timeout_entry_t; 39 + 40 + static const UT_icd abort_listener_icd = { sizeof(abort_listener_t), NULL, NULL, NULL }; 41 + static const UT_icd abort_value_icd = { sizeof(ant_value_t), NULL, NULL, NULL }; 42 + 43 + static abort_timeout_entry_t *timeout_entries = NULL; 44 + static ant_value_t g_signal_proto = 0; 45 + static bool g_initialized = false; 46 + 47 + static abort_signal_data_t *get_signal_data(ant_value_t obj) { 48 + ant_value_t slot = js_get_slot(obj, SLOT_DATA); 49 + if (vtype(slot) != T_NUM) return NULL; 50 + return (abort_signal_data_t *)(uintptr_t)js_getnum(slot); 51 + } 52 + 53 + static ant_value_t make_abort_error(ant_t *js) { 54 + return make_dom_exception(js, "signal is aborted without reason", "AbortError"); 55 + } 56 + 57 + static ant_value_t make_timeout_error(ant_t *js) { 58 + return make_dom_exception(js, "signal timed out", "TimeoutError"); 59 + } 60 + 61 + void signal_do_abort(ant_t *js, ant_value_t signal_obj, ant_value_t reason) { 62 + abort_signal_data_t *data = get_signal_data(signal_obj); 63 + if (!data || data->aborted) return; 64 + 65 + data->aborted = true; 66 + data->fired = true; 67 + data->reason = reason; 68 + 69 + js_set(js, signal_obj, "aborted", js_true); 70 + js_set(js, signal_obj, "reason", reason); 71 + 72 + ant_value_t event_obj = js_mkobj(js); 73 + js_set(js, event_obj, "type", js_mkstr(js, "abort", 5)); 74 + js_set(js, event_obj, "target", signal_obj); 75 + ant_value_t call_args[1] = { event_obj }; 76 + 77 + ant_value_t onabort = js_get(js, signal_obj, "onabort"); 78 + if (vtype(onabort) == T_FUNC) { 79 + sv_vm_call(js->vm, js, onabort, signal_obj, call_args, 1, NULL, false); 80 + process_microtasks(js); 81 + } 82 + 83 + unsigned int n = utarray_len(data->listeners); 84 + for (unsigned int i = 0; i < n;) { 85 + abort_listener_t *entry = (abort_listener_t *)utarray_eltptr(data->listeners, i); 86 + ant_value_t cb = entry->callback; 87 + bool once = entry->once; 88 + 89 + if (once) { 90 + utarray_erase(data->listeners, i, 1); 91 + n--; 92 + } else i++; 93 + 94 + if (vtype(cb) != T_FUNC) continue; 95 + sv_vm_call(js->vm, js, cb, signal_obj, call_args, 1, NULL, false); 96 + process_microtasks(js); 97 + } 98 + 99 + unsigned int nf = utarray_len(data->followers); 100 + for (unsigned int i = 0; i < nf; i++) { 101 + ant_value_t *sig = (ant_value_t *)utarray_eltptr(data->followers, i); 102 + signal_do_abort(js, *sig, reason); 103 + } 104 + } 105 + 106 + static ant_value_t make_new_signal(ant_t *js) { 107 + abort_signal_data_t *data = ant_calloc(sizeof(abort_signal_data_t)); 108 + if (!data) return js_mkerr(js, "AbortSignal: out of memory"); 109 + 110 + data->aborted = false; 111 + data->fired = false; 112 + data->reason = js_mkundef(); 113 + utarray_new(data->listeners, &abort_listener_icd); 114 + utarray_new(data->followers, &abort_value_icd); 115 + 116 + ant_value_t obj = js_mkobj(js); 117 + js_set_slot(obj, SLOT_DATA, ANT_PTR(data)); 118 + if (g_initialized) js_set_slot_wb(js, obj, SLOT_PROTO, g_signal_proto); 119 + 120 + js_set(js, obj, "aborted", js_false); 121 + js_set(js, obj, "reason", js_mkundef()); 122 + js_set(js, obj, "onabort", js_mkundef()); 123 + js_set_sym(js, obj, get_toStringTag_sym(), js_mkstr(js, "AbortSignal", 11)); 124 + 125 + return obj; 126 + } 127 + 128 + // signal.addEventListener(type, listener, options?) 129 + static ant_value_t abort_signal_add_event_listener(ant_t *js, ant_value_t *args, int nargs) { 130 + if (nargs < 2) return js_mkundef(); 131 + 132 + const char *type = js_getstr(js, args[0], NULL); 133 + if (!type || strcmp(type, "abort") != 0) return js_mkundef(); 134 + if (vtype(args[1]) != T_FUNC) return js_mkundef(); 135 + 136 + abort_signal_data_t *data = get_signal_data(js_getthis(js)); 137 + if (!data) return js_mkundef(); 138 + 139 + if (data->aborted) { 140 + ant_value_t event_obj = js_mkobj(js); 141 + js_set(js, event_obj, "type", js_mkstr(js, "abort", 5)); 142 + js_set(js, event_obj, "target", js_getthis(js)); 143 + ant_value_t call_args[1] = { event_obj }; 144 + sv_vm_call(js->vm, js, args[1], js_getthis(js), call_args, 1, NULL, false); 145 + return js_mkundef(); 146 + } 147 + 148 + bool once = false; 149 + if (nargs >= 3 && vtype(args[2]) == T_OBJ) { 150 + ant_value_t once_val = js_get(js, args[2], "once"); 151 + if (vtype(once_val) != T_UNDEF) once = js_truthy(js, once_val); 152 + } else if (nargs >= 3 && vtype(args[2]) == T_BOOL) once = js_truthy(js, args[2]); 153 + 154 + unsigned int n = utarray_len(data->listeners); 155 + for (unsigned int i = 0; i < n; i++) { 156 + abort_listener_t *e = (abort_listener_t *)utarray_eltptr(data->listeners, i); 157 + if (e->callback == args[1] && e->once == once) return js_mkundef(); 158 + } 159 + 160 + abort_listener_t entry = { args[1], once }; 161 + utarray_push_back(data->listeners, &entry); 162 + 163 + return js_mkundef(); 164 + } 165 + 166 + // signal.removeEventListener(type, listener) 167 + static ant_value_t abort_signal_remove_event_listener(ant_t *js, ant_value_t *args, int nargs) { 168 + if (nargs < 2) return js_mkundef(); 169 + 170 + const char *type = js_getstr(js, args[0], NULL); 171 + if (!type || strcmp(type, "abort") != 0) return js_mkundef(); 172 + 173 + abort_signal_data_t *data = get_signal_data(js_getthis(js)); 174 + if (!data) return js_mkundef(); 175 + 176 + unsigned int n = utarray_len(data->listeners); 177 + for (unsigned int i = 0; i < n; i++) { 178 + abort_listener_t *e = (abort_listener_t *)utarray_eltptr(data->listeners, i); 179 + if (e->callback != args[1]) continue; 180 + utarray_erase(data->listeners, i, 1); 181 + return js_mkundef(); 182 + } 183 + 184 + return js_mkundef(); 185 + } 186 + 187 + // signal.dispatchEvent(event) 188 + static ant_value_t abort_signal_dispatch_event(ant_t *js, ant_value_t *args, int nargs) { 189 + if (nargs < 1) return js_false; 190 + 191 + const char *type = NULL; 192 + if (vtype(args[0]) == T_OBJ) type = js_getstr(js, js_get(js, args[0], "type"), NULL); 193 + else type = js_getstr(js, args[0], NULL); 194 + 195 + if (!type || strcmp(type, "abort") != 0) return js_true; 196 + 197 + abort_signal_data_t *data = get_signal_data(js_getthis(js)); 198 + if (!data || data->fired) return js_true; 199 + 200 + signal_do_abort(js, js_getthis(js), data->reason); 201 + return js_true; 202 + } 203 + 204 + // signal.throwIfAborted() 205 + static ant_value_t abort_signal_throw_if_aborted(ant_t *js, ant_value_t *args, int nargs) { 206 + abort_signal_data_t *data = get_signal_data(js_getthis(js)); 207 + if (!data || !data->aborted) return js_mkundef(); 208 + return js_throw(js, data->reason); 209 + } 210 + 211 + // AbortSignal.abort(reason?) 212 + static ant_value_t abort_signal_static_abort(ant_t *js, ant_value_t *args, int nargs) { 213 + ant_value_t reason = (nargs >= 1 && vtype(args[0]) != T_UNDEF) 214 + ? args[0] 215 + : make_abort_error(js); 216 + 217 + ant_value_t signal = make_new_signal(js); 218 + if (is_err(signal)) return signal; 219 + 220 + signal_do_abort(js, signal, reason); 221 + return signal; 222 + } 223 + 224 + // AbortSignal.any(signals) 225 + static ant_value_t abort_signal_static_any(ant_t *js, ant_value_t *args, int nargs) { 226 + if (nargs < 1 || vtype(args[0]) != T_ARR) 227 + return js_mkerr(js, "AbortSignal.any: argument must be an array of AbortSignal objects"); 228 + 229 + ant_value_t composite = make_new_signal(js); 230 + if (is_err(composite)) return composite; 231 + ant_offset_t len = js_arr_len(js, args[0]); 232 + 233 + for (ant_offset_t i = 0; i < len; i++) { 234 + ant_value_t sig = js_arr_get(js, args[0], i); 235 + abort_signal_data_t *d = get_signal_data(sig); 236 + if (d && d->aborted) { 237 + signal_do_abort(js, composite, d->reason); 238 + return composite; 239 + }} 240 + 241 + for (ant_offset_t i = 0; i < len; i++) { 242 + ant_value_t sig = js_arr_get(js, args[0], i); 243 + abort_signal_data_t *d = get_signal_data(sig); 244 + if (!d) continue; 245 + utarray_push_back(d->followers, &composite); 246 + } 247 + 248 + return composite; 249 + } 250 + 251 + static void abort_timeout_close_cb(uv_handle_t *h) { 252 + abort_timeout_entry_t *entry = (abort_timeout_entry_t *)h->data; 253 + if (entry) entry->closed = 1; 254 + } 255 + 256 + static void abort_timeout_fire_cb(uv_timer_t *handle) { 257 + abort_timeout_entry_t *entry = (abort_timeout_entry_t *)handle->data; 258 + if (!entry || entry->closed) return; 259 + 260 + ant_t *js = entry->js; 261 + signal_do_abort(js, entry->signal, make_timeout_error(js)); 262 + process_microtasks(js); 263 + 264 + if (!uv_is_closing((uv_handle_t *)handle)) 265 + uv_close((uv_handle_t *)handle, abort_timeout_close_cb); 266 + } 267 + 268 + // AbortSignal.timeout(milliseconds) 269 + static ant_value_t abort_signal_static_timeout(ant_t *js, ant_value_t *args, int nargs) { 270 + if (nargs < 1) return js_mkerr(js, "AbortSignal.timeout: milliseconds argument required"); 271 + 272 + double ms = js_getnum(args[0]); 273 + if (ms < 0) return js_mkerr(js, "AbortSignal.timeout: milliseconds must be non-negative"); 274 + 275 + ant_value_t signal = make_new_signal(js); 276 + if (is_err(signal)) return signal; 277 + 278 + abort_timeout_entry_t *entry = ant_calloc(sizeof(abort_timeout_entry_t)); 279 + if (!entry) return js_mkerr(js, "AbortSignal.timeout: out of memory"); 280 + 281 + entry->js = js; 282 + entry->signal = signal; 283 + entry->closed = 0; 284 + entry->next = timeout_entries; 285 + timeout_entries = entry; 286 + 287 + uv_timer_init(uv_default_loop(), &entry->handle); 288 + entry->handle.data = entry; 289 + uv_timer_start(&entry->handle, abort_timeout_fire_cb, (uint64_t)(ms > 0 ? ms : 0), 0); 290 + 291 + return signal; 292 + } 293 + 294 + // new AbortController() 295 + static ant_value_t abort_controller_ctor(ant_t *js, ant_value_t *args, int nargs) { 296 + ant_value_t this_obj = js_getthis(js); 297 + 298 + ant_value_t signal = make_new_signal(js); 299 + if (is_err(signal)) return signal; 300 + 301 + js_mkprop_fast(js, this_obj, "signal", 6, signal); 302 + js_set_descriptor(js, this_obj, "signal", 6, 0); 303 + js_set_sym(js, this_obj, get_toStringTag_sym(), js_mkstr(js, "AbortController", 15)); 304 + 305 + return js_mkundef(); 306 + } 307 + 308 + // controller.abort(reason?) 309 + static ant_value_t abort_controller_abort(ant_t *js, ant_value_t *args, int nargs) { 310 + ant_value_t signal = js_get(js, js_getthis(js), "signal"); 311 + 312 + abort_signal_data_t *data = get_signal_data(signal); 313 + if (!data || data->aborted) return js_mkundef(); 314 + 315 + ant_value_t reason = (nargs >= 1 && vtype(args[0]) != T_UNDEF) 316 + ? args[0] 317 + : make_abort_error(js); 318 + 319 + signal_do_abort(js, signal, reason); 320 + return js_mkundef(); 321 + } 322 + 323 + void init_abort_module(void) { 324 + ant_t *js = rt->js; 325 + ant_value_t global = js_glob(js); 326 + 327 + ant_value_t signal_proto = js_mkobj(js); 328 + g_signal_proto = signal_proto; 329 + g_initialized = true; 330 + 331 + js_set(js, signal_proto, "addEventListener", js_mkfun(abort_signal_add_event_listener)); 332 + js_set(js, signal_proto, "removeEventListener", js_mkfun(abort_signal_remove_event_listener)); 333 + js_set(js, signal_proto, "dispatchEvent", js_mkfun(abort_signal_dispatch_event)); 334 + js_set(js, signal_proto, "throwIfAborted", js_mkfun(abort_signal_throw_if_aborted)); 335 + js_set_sym(js, signal_proto, get_toStringTag_sym(), js_mkstr(js, "AbortSignal", 11)); 336 + 337 + ant_value_t signal_ctor = js_mkobj(js); 338 + js_mkprop_fast(js, signal_ctor, "prototype", 9, signal_proto); 339 + js_mkprop_fast(js, signal_ctor, "name", 4, ANT_STRING("AbortSignal")); 340 + js_set_descriptor(js, signal_ctor, "name", 4, 0); 341 + 342 + ant_value_t signal_fn = js_obj_to_func_ex(signal_ctor, SV_CALL_IS_DEFAULT_CTOR); 343 + js_set(js, signal_fn, "abort", js_mkfun(abort_signal_static_abort)); 344 + js_set(js, signal_fn, "timeout", js_mkfun(abort_signal_static_timeout)); 345 + js_set(js, signal_fn, "any", js_mkfun(abort_signal_static_any)); 346 + 347 + js_set(js, signal_proto, "constructor", signal_fn); 348 + js_set_descriptor(js, signal_proto, "constructor", 11, JS_DESC_W | JS_DESC_C); 349 + 350 + ant_value_t ctrl_proto = js_mkobj(js); 351 + js_set(js, ctrl_proto, "abort", js_mkfun(abort_controller_abort)); 352 + js_set_sym(js, ctrl_proto, get_toStringTag_sym(), js_mkstr(js, "AbortController", 15)); 353 + 354 + ant_value_t ctrl_ctor = js_mkobj(js); 355 + js_set_slot(ctrl_ctor, SLOT_CFUNC, js_mkfun(abort_controller_ctor)); 356 + js_mkprop_fast(js, ctrl_ctor, "prototype", 9, ctrl_proto); 357 + js_mkprop_fast(js, ctrl_ctor, "name", 4, ANT_STRING("AbortController")); 358 + js_set_descriptor(js, ctrl_ctor, "name", 4, 0); 359 + 360 + ant_value_t ctrl_fn = js_obj_to_func(ctrl_ctor); 361 + js_set(js, ctrl_proto, "constructor", ctrl_fn); 362 + js_set_descriptor(js, ctrl_proto, "constructor", 11, JS_DESC_W | JS_DESC_C); 363 + 364 + js_set(js, global, "AbortController", ctrl_fn); 365 + js_set(js, global, "AbortSignal", signal_fn); 366 + } 367 + 368 + void gc_mark_abort(ant_t *js, gc_mark_fn mark) { 369 + if (g_initialized) mark(js, g_signal_proto); 370 + for (abort_timeout_entry_t *e = timeout_entries; e; e = e->next) 371 + if (!e->closed) mark(js, e->signal); 372 + } 373 + 374 + bool abort_signal_is_aborted(ant_value_t signal) { 375 + abort_signal_data_t *data = get_signal_data(signal); 376 + return data && data->aborted; 377 + } 378 + 379 + ant_value_t abort_signal_get_reason(ant_value_t signal) { 380 + abort_signal_data_t *data = get_signal_data(signal); 381 + return data ? data->reason : js_mkundef(); 382 + } 383 + 384 + void abort_signal_add_listener(ant_t *js, ant_value_t signal, ant_value_t callback) { 385 + abort_signal_data_t *data = get_signal_data(signal); 386 + if (!data) return; 387 + 388 + if (data->aborted) { 389 + ant_value_t event_obj = js_mkobj(js); 390 + js_set(js, event_obj, "type", js_mkstr(js, "abort", 5)); 391 + js_set(js, event_obj, "target", signal); 392 + ant_value_t call_args[1] = { event_obj }; 393 + sv_vm_call(js->vm, js, callback, signal, call_args, 1, NULL, false); 394 + return; 395 + } 396 + 397 + abort_listener_t entry = { callback, false }; 398 + utarray_push_back(data->listeners, &entry); 399 + } 400 +
+109
src/modules/domexception.c
··· 1 + #include <string.h> 2 + 3 + #include "ant.h" 4 + #include "internal.h" 5 + #include "runtime.h" 6 + #include "descriptors.h" 7 + 8 + #include "gc/modules.h" 9 + #include "modules/symbol.h" 10 + #include "modules/domexception.h" 11 + 12 + static ant_value_t g_domexception_proto = 0; 13 + static bool g_initialized = false; 14 + 15 + static const struct { const char *name; int code; } domex_codes[] = { 16 + { "IndexSizeError", 1 }, 17 + { "HierarchyRequestError", 3 }, 18 + { "WrongDocumentError", 4 }, 19 + { "InvalidCharacterError", 5 }, 20 + { "NoModificationAllowedError", 7 }, 21 + { "NotFoundError", 8 }, 22 + { "NotSupportedError", 9 }, 23 + { "InUseAttributeError", 10 }, 24 + { "InvalidStateError", 11 }, 25 + { "SyntaxError", 12 }, 26 + { "InvalidModificationError", 13 }, 27 + { "NamespaceError", 14 }, 28 + { "InvalidAccessError", 15 }, 29 + { "SecurityError", 18 }, 30 + { "NetworkError", 19 }, 31 + { "AbortError", 20 }, 32 + { "URLMismatchError", 21 }, 33 + { "QuotaExceededError", 22 }, 34 + { "TimeoutError", 23 }, 35 + { "InvalidNodeTypeError", 24 }, 36 + { "DataCloneError", 25 }, 37 + }; 38 + 39 + static int name_to_code(const char *name) { 40 + if (!name) return 0; 41 + for (size_t i = 0; i < sizeof(domex_codes) / sizeof(domex_codes[0]); i++) { 42 + if (strcmp(name, domex_codes[i].name) == 0) return domex_codes[i].code; 43 + } 44 + return 0; 45 + } 46 + 47 + // new DOMException(message?, name?) 48 + static ant_value_t domexception_ctor(ant_t *js, ant_value_t *args, int nargs) { 49 + ant_value_t self = js_getthis(js); 50 + 51 + const char *msg = (nargs >= 1 && vtype(args[0]) == T_STR) ? js_getstr(js, args[0], NULL) : ""; 52 + const char *name = (nargs >= 2 && vtype(args[1]) == T_STR) ? js_getstr(js, args[1], NULL) : "Error"; 53 + 54 + int code = name_to_code(name); 55 + size_t msg_len = strlen(msg); 56 + size_t name_len = strlen(name); 57 + 58 + js_set(js, self, "message", js_mkstr(js, msg, msg_len)); 59 + js_set(js, self, "name", js_mkstr(js, name, name_len)); 60 + js_set(js, self, "code", js_mknum(code)); 61 + 62 + return js_mkundef(); 63 + } 64 + 65 + ant_value_t make_dom_exception(ant_t *js, const char *message, const char *name) { 66 + size_t msg_len = strlen(message); 67 + size_t name_len = strlen(name); 68 + int code = name_to_code(name); 69 + 70 + ant_value_t obj = js_mkobj(js); 71 + if (g_initialized) js_set_slot_wb(js, obj, SLOT_PROTO, g_domexception_proto); 72 + 73 + js_set(js, obj, "message", js_mkstr(js, message, msg_len)); 74 + js_set(js, obj, "name", js_mkstr(js, name, name_len)); 75 + js_set(js, obj, "code", js_mknum(code)); 76 + js_set_sym(js, obj, get_toStringTag_sym(), js_mkstr(js, "DOMException", 12)); 77 + 78 + return obj; 79 + } 80 + 81 + void init_domexception_module(void) { 82 + ant_t *js = rt->js; 83 + ant_value_t global = js_glob(js); 84 + 85 + ant_value_t proto = js_mkobj(js); 86 + g_domexception_proto = proto; 87 + g_initialized = true; 88 + 89 + js_set(js, proto, "name", js_mkstr(js, "Error", 5)); 90 + js_set(js, proto, "message", js_mkstr(js, "", 0)); 91 + js_set(js, proto, "code", js_mknum(0)); 92 + js_set_sym(js, proto, get_toStringTag_sym(), js_mkstr(js, "DOMException", 12)); 93 + 94 + ant_value_t ctor = js_mkobj(js); 95 + js_set_slot(ctor, SLOT_CFUNC, js_mkfun(domexception_ctor)); 96 + js_mkprop_fast(js, ctor, "prototype", 9, proto); 97 + js_mkprop_fast(js, ctor, "name", 4, ANT_STRING("DOMException")); 98 + js_set_descriptor(js, ctor, "name", 4, 0); 99 + 100 + ant_value_t fn = js_obj_to_func(ctor); 101 + js_set(js, proto, "constructor", fn); 102 + js_set_descriptor(js, proto, "constructor", 11, JS_DESC_W | JS_DESC_C); 103 + 104 + js_set(js, global, "DOMException", fn); 105 + } 106 + 107 + void gc_mark_domexception(ant_t *js, gc_mark_fn mark) { 108 + if (g_initialized) mark(js, g_domexception_proto); 109 + }