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.

wasm prevent throwing stack

+48 -4
+1
include/errors.h
··· 31 31 void js_print_stack_trace_vm(ant_t *js, FILE *stream); 32 32 void js_set_error_site_from_vm_top(ant_t *js); 33 33 void js_capture_stack(ant_t *js, ant_value_t err_obj); 34 + bool js_mark_errorlike_no_stack(ant_t *js, ant_value_t value); 34 35 35 36 void js_get_call_location( 36 37 ant_t *js, const char **out_filename,
+24 -4
src/errors.c
··· 23 23 24 24 static void print_error_value(ant_t *js, ant_value_t value, ant_value_t fallback_stack, const char *prefix) { 25 25 ant_value_t obj = is_err(value) ? js_as_obj(value) : value; 26 - const char *stack = NULL; 26 + const char *stack = NULL; bool no_stack = false; 27 27 28 - if (vtype(obj) == T_OBJ) 29 - stack = get_str_prop(js, obj, "stack", 5, NULL); 28 + if (vtype(obj) == T_OBJ) { 29 + ant_value_t err_type = js_get_slot(obj, SLOT_ERR_TYPE); 30 + no_stack = vtype(err_type) == T_NUM && ((int)js_getnum(err_type) & JS_ERR_NO_STACK); 31 + if (!no_stack) stack = get_str_prop(js, obj, "stack", 5, NULL); 32 + } 30 33 31 - if (!stack && vtype(fallback_stack) == T_STR) { 34 + if (!no_stack && !stack && vtype(fallback_stack) == T_STR) { 32 35 ant_offset_t slen; 33 36 ant_offset_t soff = vstr(js, fallback_stack, &slen); 34 37 stack = (const char *)(uintptr_t)(soff); ··· 65 68 66 69 bool print_unhandled_promise_rejection(ant_t *js, ant_value_t value) { 67 70 print_error_value(js, value, js_mkundef(), "Uncaught (in promise) "); 71 + return true; 72 + } 73 + 74 + bool js_mark_errorlike_no_stack(ant_t *js, ant_value_t value) { 75 + if (vtype(value) != T_OBJ) return false; 76 + if (js_get_slot(value, SLOT_ERROR_BRAND) == js_true) return false; 77 + 78 + const char *name = get_str_prop(js, value, "name", 4, NULL); 79 + const char *message = get_str_prop(js, value, "message", 7, NULL); 80 + if ((!name || !*name) && (!message || !*message)) return false; 81 + 82 + ant_value_t err_type = js_get_slot(value, SLOT_ERR_TYPE); 83 + int base_type = vtype(err_type) == T_NUM ? (int)js_getnum(err_type) : JS_ERR_GENERIC; 84 + 85 + js_set(js, value, "stack", js_mkundef()); 86 + js_set_slot(value, SLOT_ERR_TYPE, js_mknum((double)(base_type | JS_ERR_NO_STACK))); 87 + 68 88 return true; 69 89 } 70 90
+2
src/modules/wasm.c
··· 517 517 if (trap) { 518 518 if (g_wasm_pending_import_throw_exists) { 519 519 result = wasm_consume_pending_import_throw(); 520 + js_mark_errorlike_no_stack(js, result); 520 521 wasm_val_vec_delete(&wasm_args); 521 522 wasm_val_vec_delete(&wasm_results); 522 523 wasm_functype_delete(type); ··· 950 951 if (trap) { 951 952 if (g_wasm_pending_import_throw_exists) { 952 953 ant_value_t thrown = wasm_consume_pending_import_throw(); 954 + js_mark_errorlike_no_stack(js, thrown); 953 955 wasm_trap_delete(trap); 954 956 return js_throw(js, thrown); 955 957 }
+21
tests/test_wasm_webassembly_api.mjs
··· 86 86 } 87 87 assert(sawErrorThrow, 'Error import throws should escape the wasm call'); 88 88 89 + const thrownStatus = { 90 + name: 'ExitStatus', 91 + message: 'Program terminated with exit(1)', 92 + status: 1 93 + }; 94 + let sawErrorlikeThrow = false; 95 + try { 96 + new WebAssembly.Instance(throwingModule, { 97 + env: { 98 + fail() { 99 + throw thrownStatus; 100 + } 101 + } 102 + }).exports.run(); 103 + } catch (error) { 104 + sawErrorlikeThrow = true; 105 + assert(error === thrownStatus, 'import throws should preserve original error-like objects'); 106 + assert(error.stack === undefined, 'error-like import throws should not grow a synthetic stack'); 107 + } 108 + assert(sawErrorlikeThrow, 'error-like import throws should escape the wasm call'); 109 + 89 110 const compiled = await WebAssembly.compile(incrementer); 90 111 assert(compiled instanceof WebAssembly.Module, 'WebAssembly.compile() should resolve a module'); 91 112