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.

at mir/inline-method 485 lines 19 kB view raw
1#include <compat.h> // IWYU pragma: keep 2 3#include <stdlib.h> 4#include <stdio.h> 5#include <signal.h> 6#include <string.h> 7#include <time.h> 8#include <errno.h> 9#include <crprintf.h> 10 11#ifdef __APPLE__ 12#include <mach/mach.h> 13#elif defined(__linux__) 14#include <sys/resource.h> 15#endif 16 17#include "ant.h" 18#include "gc.h" 19#include "crash.h" 20#include "errors.h" 21#include "runtime.h" 22#include "internal.h" 23#include "highlight.h" 24#include "descriptors.h" 25 26#include "silver/engine.h" 27#include "modules/builtin.h" 28#include "modules/buffer.h" 29#include "modules/symbol.h" 30 31static struct { 32 ant_t *js; 33 ant_value_t handler; 34} signal_handlers[NSIG] = {0}; 35 36static void general_signal_handler(int signum) { 37 if (signum < 0 || signum >= NSIG) return; 38 ant_t *js = signal_handlers[signum].js; 39 ant_value_t handler = signal_handlers[signum].handler; 40 41 if (js && vtype(handler) != T_UNDEF) { 42 ant_value_t args[] = {js_mknum(signum)}; 43 sv_vm_call(js->vm, js, handler, js_mkundef(), args, 1, NULL, false); 44 } 45 46 exit(0); 47} 48 49// Ant.signal(signal, handler) 50static ant_value_t js_signal(ant_t *js, ant_value_t *args, int nargs) { 51 if (nargs < 2) return js_mkerr(js, "Ant.signal() requires 2 arguments"); 52 53 int signum = (int)js_getnum(args[0]); 54 if (signum <= 0 || signum >= NSIG) { 55 return js_mkerr_typed(js, JS_ERR_RANGE, "Invalid signal number: %d", signum); 56 } 57 58 signal_handlers[signum].js = js; 59 signal_handlers[signum].handler = args[1]; 60 signal(signum, general_signal_handler); 61 62 return js_mkundef(); 63} 64 65// Ant.raw.stack() 66static ant_value_t js_raw_stack(ant_t *js, ant_value_t *args, int nargs) { 67 return js_capture_raw_stack(js); 68} 69 70// Ant.raw.typeof(ant_value_t) 71static ant_value_t js_raw_typeof(ant_t *js, ant_value_t *args, int nargs) { 72 if (nargs < 1) return js_mkerr(js, "Ant.raw.typeof() requires 1 argument"); 73 const uint8_t type = vtype(args[0]); 74 return js_mknum((double)type); 75} 76 77// Ant.raw.ctorPropFeedback(constructorFn) 78static ant_value_t js_raw_ctor_prop_feedback(ant_t *js, ant_value_t *args, int nargs) { 79 if (nargs < 1) return js_mkerr(js, "Ant.raw.ctorPropFeedback() requires 1 argument"); 80 if (vtype(args[0]) != T_FUNC) return js_mkerr(js, "constructor must be a function"); 81 82#ifndef ANT_JIT 83 return js_mkerr(js, "constructor property feedback requires ANT_JIT"); 84#else 85 ant_value_t ctor = args[0]; 86 ant_value_t ctor_obj = js_func_obj(ctor); 87 ant_value_t target_func = js_get_slot(ctor_obj, SLOT_TARGET_FUNC); 88 if (vtype(target_func) == T_FUNC) ctor = target_func; 89 90 sv_closure_t *closure = js_func_closure(ctor); 91 if (!closure || !closure->func) return js_mkundef(); 92 sv_func_t *fn = closure->func; 93 94 ant_value_t out = js_newobj(js); 95 js_set(js, out, "samples", js_mknum((double)fn->ctor_prop_samples)); 96 js_set(js, out, "overflowFrom", js_mknum((double)SV_TFB_CTOR_PROP_OVERFLOW_FROM)); 97 js_set(js, out, "inobjLimit", js_mknum((double)sv_tfb_ctor_inobj_limit(ctor))); 98 js_set(js, out, "inobjLimitFrozen", js_bool(sv_tfb_ctor_inobj_limit_frozen(ctor))); 99 js_set(js, out, "slackRemaining", js_mknum((double)sv_tfb_ctor_inobj_slack_remaining(ctor))); 100 101 ant_value_t bins = js_mkarr(js); 102 for (uint32_t i = 0; i < SV_TFB_CTOR_PROP_BINS; i++) { 103 js_arr_push(js, bins, js_mknum((double)fn->ctor_prop_hist[i])); 104 } 105 js_set(js, out, "bins", bins); 106 107 if (fn->name) js_set(js, out, "name", js_mkstr(js, fn->name, strlen(fn->name))); 108 if (fn->filename) js_set(js, out, "filename", js_mkstr(js, fn->filename, strlen(fn->filename))); 109 110 return out; 111#endif 112} 113 114static ant_value_t js_raw_gc_mark_profile(ant_t *js, ant_value_t *args, int nargs) { 115 gc_func_mark_profile_t p = gc_func_mark_profile_get(); 116 ant_value_t out = js_newobj(js); 117 118 js_set(js, out, "enabled", js_bool(p.enabled)); 119 js_set(js, out, "collections", js_mknum((double)p.collections)); 120 js_set(js, out, "funcVisits", js_mknum((double)p.func_visits)); 121 js_set(js, out, "childEdges", js_mknum((double)p.child_edges)); 122 js_set(js, out, "constSlots", js_mknum((double)p.const_slots)); 123 js_set(js, out, "timeNs", js_mknum((double)p.time_ns)); 124 js_set(js, out, "timeMs", js_mknum((double)p.time_ns / 1000000.0)); 125 126 return out; 127} 128 129static ant_value_t js_raw_gc_mark_profile_enable(ant_t *js, ant_value_t *args, int nargs) { 130 bool enabled = true; 131 if (nargs > 0) enabled = js_truthy(js, args[0]); 132 gc_func_mark_profile_enable(enabled); 133 return js_bool(enabled); 134} 135 136static ant_value_t js_raw_gc_mark_profile_reset(ant_t *js, ant_value_t *args, int nargs) { 137 gc_func_mark_profile_reset(); 138 return js_mkundef(); 139} 140 141// Ant.sleep(seconds) 142static ant_value_t js_sleep(ant_t *js, ant_value_t *args, int nargs) { 143 if (nargs < 1) return js_mkerr(js, "Ant.sleep() requires 1 argument"); 144 unsigned int seconds = (unsigned int)js_getnum(args[0]); 145 sleep(seconds); 146 return js_mkundef(); 147} 148 149// Ant.msleep(milliseconds) 150static ant_value_t js_msleep(ant_t *js, ant_value_t *args, int nargs) { 151 if (nargs < 1) return js_mkerr(js, "Ant.msleep() requires 1 argument"); 152 long ms = (long)js_getnum(args[0]); 153 struct timespec ts = { .tv_sec = ms / 1000, .tv_nsec = (ms % 1000) * 1000000 }; 154 struct timespec rem; 155 while (nanosleep(&ts, &rem) == -1 && errno == EINTR) ts = rem; 156 return js_mkundef(); 157} 158 159// Ant.usleep(microseconds) 160static ant_value_t js_usleep(ant_t *js, ant_value_t *args, int nargs) { 161 if (nargs < 1) return js_mkerr(js, "Ant.usleep() requires 1 argument"); 162 useconds_t us = (useconds_t)js_getnum(args[0]); 163 usleep(us); 164 return js_mkundef(); 165} 166 167// Ant.suppressReporting() 168static ant_value_t js_suppress_reporting(ant_t *js, ant_value_t *args, int nargs) { 169 ant_crash_suppress_reporting(); 170 return js_mkundef(); 171} 172 173// Ant.stats() 174static ant_value_t js_stats_fn(ant_t *js, ant_value_t *args, int nargs) { 175 ant_value_t result = js_newobj(js); 176 177 ant_pool_stats_t rope_s = js_pool_stats(&js->pool.rope); 178 ant_pool_stats_t sym_s = js_pool_stats(&js->pool.symbol); 179 ant_pool_stats_t bigint_s = js_class_pool_stats(&js->pool.bigint); 180 ant_string_pool_stats_t string_s = js_string_pool_stats(&js->pool.string); 181 182 ant_value_t pools = js_newobj(js); 183 ant_value_t rope_obj = js_newobj(js); 184 js_set(js, rope_obj, "used", js_mknum((double)rope_s.used)); 185 js_set(js, rope_obj, "capacity", js_mknum((double)rope_s.capacity)); 186 js_set(js, rope_obj, "blocks", js_mknum((double)rope_s.blocks)); 187 js_set(js, pools, "rope", rope_obj); 188 189 ant_value_t sym_obj = js_newobj(js); 190 js_set(js, sym_obj, "used", js_mknum((double)sym_s.used)); 191 js_set(js, sym_obj, "capacity", js_mknum((double)sym_s.capacity)); 192 js_set(js, sym_obj, "blocks", js_mknum((double)sym_s.blocks)); 193 js_set(js, pools, "symbol", sym_obj); 194 195 ant_value_t bigint_obj = js_newobj(js); 196 js_set(js, bigint_obj, "used", js_mknum((double)bigint_s.used)); 197 js_set(js, bigint_obj, "capacity", js_mknum((double)bigint_s.capacity)); 198 js_set(js, bigint_obj, "blocks", js_mknum((double)bigint_s.blocks)); 199 js_set(js, pools, "bigint", bigint_obj); 200 201 ant_value_t string_obj = js_newobj(js); 202 js_set(js, string_obj, "used", js_mknum((double)string_s.total.used)); 203 js_set(js, string_obj, "capacity", js_mknum((double)string_s.total.capacity)); 204 js_set(js, string_obj, "blocks", js_mknum((double)string_s.total.blocks)); 205 206 ant_value_t string_pooled_obj = js_newobj(js); 207 js_set(js, string_pooled_obj, "used", js_mknum((double)string_s.pooled.used)); 208 js_set(js, string_pooled_obj, "capacity", js_mknum((double)string_s.pooled.capacity)); 209 js_set(js, string_pooled_obj, "blocks", js_mknum((double)string_s.pooled.blocks)); 210 js_set(js, string_obj, "pooled", string_pooled_obj); 211 212 ant_value_t string_large_live_obj = js_newobj(js); 213 js_set(js, string_large_live_obj, "used", js_mknum((double)string_s.large_live.used)); 214 js_set(js, string_large_live_obj, "capacity", js_mknum((double)string_s.large_live.capacity)); 215 js_set(js, string_large_live_obj, "blocks", js_mknum((double)string_s.large_live.blocks)); 216 js_set(js, string_obj, "largeLive", string_large_live_obj); 217 218 ant_value_t string_large_reusable_obj = js_newobj(js); 219 js_set(js, string_large_reusable_obj, "used", js_mknum((double)string_s.large_reusable.used)); 220 js_set(js, string_large_reusable_obj, "capacity", js_mknum((double)string_s.large_reusable.capacity)); 221 js_set(js, string_large_reusable_obj, "blocks", js_mknum((double)string_s.large_reusable.blocks)); 222 js_set(js, string_obj, "largeReusable", string_large_reusable_obj); 223 224 ant_value_t string_large_quarantine_obj = js_newobj(js); 225 js_set(js, string_large_quarantine_obj, "used", js_mknum((double)string_s.large_quarantine.used)); 226 js_set(js, string_large_quarantine_obj, "capacity", js_mknum((double)string_s.large_quarantine.capacity)); 227 js_set(js, string_large_quarantine_obj, "blocks", js_mknum((double)string_s.large_quarantine.blocks)); 228 js_set(js, string_obj, "largeQuarantine", string_large_quarantine_obj); 229 230 size_t pool_used = rope_s.used + sym_s.used + bigint_s.used + string_s.total.used; 231 size_t pool_cap = rope_s.capacity + sym_s.capacity + bigint_s.capacity + string_s.total.capacity; 232 233 js_set(js, pools, "totalUsed", js_mknum((double)pool_used)); 234 js_set(js, pools, "totalCapacity", js_mknum((double)pool_cap)); 235 js_set(js, result, "pools", pools); 236 js_set(js, pools, "string", string_obj); 237 238 size_t obj_count = 0; 239 size_t obj_bytes = 0; 240 size_t overflow_bytes = 0; 241 size_t extra_bytes = 0; 242 size_t promise_bytes = 0; 243 size_t proxy_bytes = 0; 244 size_t exotic_bytes = 0; 245 size_t array_bytes = 0; 246 247 for (int pass = 0; pass < 3; pass++) { 248 ant_object_t *head = pass == 0 ? js->objects : pass == 1 ? js->objects_old : js->permanent_objects; 249 for (ant_object_t *obj = head; obj; obj = obj->next) { 250 obj_count++; 251 obj_bytes += sizeof(ant_object_t); 252 253 uint32_t inobj_limit = ant_object_inobj_limit(obj); 254 if (obj->overflow_prop && obj->prop_count > inobj_limit) 255 overflow_bytes += (obj->prop_count - inobj_limit) * sizeof(ant_value_t); 256 if (obj->extra_slots) extra_bytes += obj->extra_count * sizeof(ant_extra_slot_t); 257 if (obj->promise_state) promise_bytes += sizeof(ant_promise_state_t); 258 if (obj->proxy_state) proxy_bytes += sizeof(ant_proxy_state_t); 259 if (obj->exotic_ops) exotic_bytes += sizeof(ant_exotic_ops_t); 260 if (obj->type_tag == T_ARR && obj->u.array.data) 261 array_bytes += obj->u.array.cap * sizeof(ant_value_t); 262 } 263 } 264 265 ant_value_t alloc = js_newobj(js); 266 js_set(js, alloc, "objectCount", js_mknum((double)obj_count)); 267 js_set(js, alloc, "objects", js_mknum((double)obj_bytes)); 268 js_set(js, alloc, "overflow", js_mknum((double)overflow_bytes)); 269 js_set(js, alloc, "extraSlots", js_mknum((double)extra_bytes)); 270 js_set(js, alloc, "promises", js_mknum((double)promise_bytes)); 271 js_set(js, alloc, "proxies", js_mknum((double)proxy_bytes)); 272 js_set(js, alloc, "exotic", js_mknum((double)exotic_bytes)); 273 js_set(js, alloc, "arrays", js_mknum((double)array_bytes)); 274 275 size_t shape_bytes = ant_shape_total_bytes(); 276 js_set(js, alloc, "shapes", js_mknum((double)shape_bytes)); 277 js_set(js, alloc, "closures", js_mknum((double)js->alloc_bytes.closures)); 278 js_set(js, alloc, "upvalues", js_mknum((double)js->alloc_bytes.upvalues)); 279 js_set(js, alloc, "propRefs", js_mknum((double)(js->prop_refs_cap * sizeof(ant_prop_ref_t)))); 280 281 size_t alloc_total = obj_bytes + overflow_bytes + extra_bytes 282 + promise_bytes + proxy_bytes + exotic_bytes + array_bytes 283 + shape_bytes + js->alloc_bytes.closures + js->alloc_bytes.upvalues 284 + js->prop_refs_cap * sizeof(ant_prop_ref_t); 285 286 js_set(js, alloc, "total", js_mknum((double)alloc_total)); 287 js_set(js, result, "alloc", alloc); 288 289 size_t buffer_mem = buffer_get_external_memory(); 290 size_t code_mem = code_arena_get_memory(); 291 size_t external_total = buffer_mem + code_mem; 292 293 ant_value_t ext = js_newobj(js); 294 js_set(js, ext, "buffers", js_mknum((double)buffer_mem)); 295 js_set(js, ext, "code", js_mknum((double)code_mem)); 296 js_set(js, ext, "total", js_mknum((double)external_total)); 297 js_set(js, result, "external", ext); 298 299 js_intern_stats_t intern_stats = js_intern_stats(); 300 ant_value_t intern = js_newobj(js); 301 302 js_set(js, intern, "count", js_mknum((double)intern_stats.count)); 303 js_set(js, intern, "bytes", js_mknum((double)intern_stats.bytes)); 304 js_set(js, result, "intern", intern); 305 306 sv_vm_t *vm = sv_vm_get_active(js); 307 if (vm) { 308 ant_value_t vmobj = js_newobj(js); 309 js_set(js, vmobj, "stackSize", js_mknum((double)vm->stack_size)); 310 js_set(js, vmobj, "stackUsed", js_mknum((double)vm->sp)); 311 js_set(js, vmobj, "maxFrames", js_mknum((double)vm->max_frames)); 312 js_set(js, vmobj, "framesUsed", js_mknum((double)(vm->fp + 1))); 313 js_set(js, result, "vm", vmobj); 314 } 315 316 if (js->cstk.base != NULL) { 317 volatile char marker; 318 uintptr_t base = (uintptr_t)js->cstk.base; 319 uintptr_t curr = (uintptr_t)&marker; 320 size_t used = (base > curr) ? (base - curr) : (curr - base); 321 ant_value_t cstk = js_newobj(js); 322 js_set(js, cstk, "used", js_mknum((double)used)); 323 js_set(js, cstk, "limit", js_mknum((double)js->cstk.limit)); 324 js_set(js, result, "cstack", cstk); 325 } else js_set(js, result, "cstack", js_mknum(0)); 326 327#ifdef __APPLE__ 328 struct mach_task_basic_info info; 329 mach_msg_type_number_t count = MACH_TASK_BASIC_INFO_COUNT; 330 if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info, &count) == KERN_SUCCESS) { 331 js_set(js, result, "residentSize", js_mknum((double)info.resident_size)); 332 js_set(js, result, "virtualSize", js_mknum((double)info.virtual_size)); 333 } 334 335 task_vm_info_data_t vm_info; 336 mach_msg_type_number_t vm_count = TASK_VM_INFO_COUNT; 337 if (task_info(mach_task_self(), TASK_VM_INFO, (task_info_t)&vm_info, &vm_count) == KERN_SUCCESS) { 338 js_set(js, result, "rss", js_mknum((double)vm_info.phys_footprint)); 339 js_set(js, result, "physFootprint", js_mknum((double)vm_info.phys_footprint)); 340 } else if (vtype(js_get(js, result, "rss")) == T_UNDEF) { 341 ant_value_t resident = js_get(js, result, "residentSize"); 342 if (vtype(resident) != T_UNDEF) js_set(js, result, "rss", resident); 343 } 344#elif defined(__linux__) 345 struct rusage usage; 346 if (getrusage(RUSAGE_SELF, &usage) == 0) { 347 js_set(js, result, "rss", js_mknum((double)usage.ru_maxrss * 1024)); 348 } 349#endif 350 351 return result; 352} 353 354static inline ant_value_t match_resolve_arm(ant_t *js, ant_value_t arm, ant_value_t value) { 355 if (!is_callable(arm)) return arm; 356 return sv_vm_call(js->vm, js, arm, js_mkundef(), &value, 1, NULL, false); 357} 358 359static ant_value_t js_match(ant_t *js, ant_value_t *args, int nargs) { 360 if (nargs < 2) return js_mkerr(js, "Ant.match() requires 2 arguments"); 361 362 ant_value_t value = args[0]; 363 ant_value_t arms = args[1]; 364 365 if (is_callable(arms)) { 366 arms = sv_vm_call(js->vm, js, arms, js_mkundef(), &value, 1, NULL, false); 367 if (is_err(arms)) return arms; 368 } 369 370 if (!is_object_type(arms)) return js_mkundef(); 371 ant_value_t value_str = js_tostring_val(js, value); 372 const char *vs = js_getstr(js, value_str, NULL); 373 374 ant_iter_t iter = js_prop_iter_begin(js, arms); 375 ant_value_t guard_arm = js_mkundef(); 376 377 ant_value_t key = js_mkundef(); 378 ant_value_t arm = js_mkundef(); 379 380 while (js_prop_iter_next_val(&iter, &key, &arm)) { 381 if (vtype(key) == T_SYMBOL) continue; 382 383 const char *ks = js_getstr(js, key, NULL); 384 if (!ks) continue; 385 386 if (strcmp(ks, vs) == 0) { 387 js_prop_iter_end(&iter); 388 return match_resolve_arm(js, arm, value); 389 } 390 391 if ( 392 strcmp(ks, "true") == 0 393 && vtype(guard_arm) == T_UNDEF 394 ) guard_arm = arm; 395 } 396 397 js_prop_iter_end(&iter); 398 if (vtype(guard_arm) != T_UNDEF) return match_resolve_arm(js, guard_arm, value); 399 400 ant_value_t fallback = js_get_sym(js, arms, get_default_sym()); 401 if (vtype(fallback) != T_UNDEF) return match_resolve_arm(js, fallback, value); 402 403 return js_mkundef(); 404} 405 406static ant_value_t hl_get_tagged(ant_t *js, ant_value_t *args, int nargs) { 407 size_t input_len; 408 char *input = js_getstr(js, args[0], &input_len); 409 410 size_t out_size = input_len * 8 + 1; 411 char *out = malloc(out_size); 412 if (!out) return js_mkerr(js, "out of memory"); 413 414 int len = ant_highlight(input, input_len, out, out_size); 415 ant_value_t result = js_mkstr(js, out, (size_t)len); 416 free(out); 417 418 return result; 419} 420 421static ant_value_t hl_render_tagged(ant_t *js, ant_value_t tagged) { 422 size_t tagged_len; 423 char *tagged_str = js_getstr(js, tagged, &tagged_len); 424 425 size_t ansi_size = tagged_len * 2 + 1; 426 char *ansi = malloc(ansi_size); 427 if (!ansi) return js_mkerr(js, "out of memory"); 428 429 int len = crsprintf_stateful(ansi, ansi_size, NULL, tagged_str); 430 ant_value_t result = js_mkstr(js, ansi, len < 0 ? 0 : (size_t)len); 431 free(ansi); 432 433 return result; 434} 435 436static ant_value_t js_highlight(ant_t *js, ant_value_t *args, int nargs) { 437 if (nargs < 1) return js_mkerr(js, "Ant.highlight() requires 1 argument"); 438 if (vtype(args[0]) != T_STR) return js_mkerr(js, "Ant.highlight() argument must be a string"); 439 440 ant_value_t tagged = hl_get_tagged(js, args, nargs); 441 if (is_err(tagged)) return tagged; 442 return hl_render_tagged(js, tagged); 443} 444 445static ant_value_t js_highlight_render(ant_t *js, ant_value_t *args, int nargs) { 446 if (nargs < 1) return js_mkerr(js, "Ant.highlight.render() requires 1 argument"); 447 if (vtype(args[0]) != T_STR) return js_mkerr(js, "Ant.highlight.render() argument must be a string"); 448 return hl_render_tagged(js, args[0]); 449} 450 451static ant_value_t js_highlight_tags(ant_t *js, ant_value_t *args, int nargs) { 452 if (nargs < 1) return js_mkerr(js, "Ant.highlight.tags() requires 1 argument"); 453 if (vtype(args[0]) != T_STR) return js_mkerr(js, "Ant.highlight.tags() argument must be a string"); 454 return hl_get_tagged(js, args, nargs); 455} 456 457void init_builtin_module() { 458 ant_t *js = rt->js; 459 ant_value_t ant_obj = rt->ant_obj; 460 461 js_set(js, ant_obj, "match", js_mkfun(js_match)); 462 js_set(js, ant_obj, "stats", js_mkfun(js_stats_fn)); 463 js_set(js, ant_obj, "signal", js_mkfun(js_signal)); 464 js_set(js, ant_obj, "sleep", js_mkfun(js_sleep)); 465 js_set(js, ant_obj, "msleep", js_mkfun(js_msleep)); 466 js_set(js, ant_obj, "usleep", js_mkfun(js_usleep)); 467 js_set(js, ant_obj, "suppressReporting", js_mkfun(js_suppress_reporting)); 468 469 ant_value_t hl_obj = js_newobj(js); 470 ant_value_t hl_fn = js_obj_to_func(hl_obj); 471 472 js_set_slot(hl_obj, SLOT_CFUNC, js_mkfun(js_highlight)); 473 js_set(js, hl_fn, "render", js_mkfun(js_highlight_render)); 474 js_set(js, hl_fn, "tags", js_mkfun(js_highlight_tags)); 475 js_set(js, ant_obj, "highlight", hl_fn); 476 477 ant_value_t raw_obj = js_newobj(js); 478 js_set_getter_desc(js, js_as_obj(raw_obj), "stack", 5, js_mkfun(js_raw_stack), JS_DESC_C); 479 js_set(js, raw_obj, "typeof", js_mkfun(js_raw_typeof)); 480 js_set(js, raw_obj, "ctorPropFeedback", js_mkfun(js_raw_ctor_prop_feedback)); 481 js_set(js, raw_obj, "gcMarkProfile", js_mkfun(js_raw_gc_mark_profile)); 482 js_set(js, raw_obj, "gcMarkProfileEnable", js_mkfun(js_raw_gc_mark_profile_enable)); 483 js_set(js, raw_obj, "gcMarkProfileReset", js_mkfun(js_raw_gc_mark_profile_reset)); 484 js_set(js, ant_obj, "raw", raw_obj); 485}