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.

refactor: simplify error constructor logic and standardize new target handling

+87 -162
+1
include/internal.h
··· 29 29 jsval_t tval; // holds last parsed numeric or string literal value 30 30 jsval_t scope; // current scope 31 31 jsval_t this_val; // 'this' value for currently executing function 32 + jsval_t new_target; // constructor called with 'new', undefined otherwise 32 33 jsval_t module_ns; // current ESM module namespace 33 34 uint8_t *mem; // available JS memory 34 35 jsoff_t size; // memory size
+82 -160
src/ant.c
··· 814 814 static jsval_t setprop(struct js *js, jsval_t obj, jsval_t k, jsval_t v); 815 815 static descriptor_entry_t *lookup_descriptor(jsoff_t obj_off, const char *key, size_t klen); 816 816 817 + typedef struct { jsval_t handle; bool is_new; } ctor_t; 818 + 819 + static ctor_t get_constructor(struct js *js, const char *name, size_t len) { 820 + ctor_t ctor; 821 + 822 + ctor.handle = get_ctor_proto(js, name, len); 823 + ctor.is_new = (vtype(js->new_target) != T_UNDEF); 824 + 825 + return ctor; 826 + } 827 + 817 828 static jsval_t unwrap_primitive(struct js *js, jsval_t val) { 818 829 if (vtype(val) != T_OBJ) return val; 819 830 jsval_t prim = get_slot(js, val, SLOT_PRIMITIVE); ··· 4754 4765 return resolveprop(js, mkval(T_PROP, proto_off)); 4755 4766 } 4756 4767 4757 - static jsval_t get_ctor_proto(struct js *js, const char *name, size_t len) { 4768 + static inline jsval_t get_ctor_proto(struct js *js, const char *name, size_t len) { 4758 4769 return js_get_ctor_proto(js, name, len); 4759 4770 } 4760 4771 ··· 6273 6284 6274 6285 jsval_t target_this = peek_this(); 6275 6286 jsval_t target_proto = (vtype(target_this) == T_OBJ) ? get_slot(js, target_this, SLOT_PROTO) : js_mkundef(); 6276 - bool is_constructor_call = (vtype(target_this) == T_OBJ && vtype(target_proto) == T_UNDEF); 6277 6287 6278 6288 if (vtype(func) == T_FUNC && vtype(target_this) == T_OBJ) { 6279 6289 if (vtype(target_proto) == T_UNDEF) { ··· 6371 6381 6372 6382 jsval_t this_slot = get_slot(js, func_obj, SLOT_THIS); 6373 6383 if (vtype(this_slot) != T_UNDEF) { 6374 - captured_this = this_slot; 6375 - is_arrow = true; 6384 + captured_this = this_slot; is_arrow = true; 6376 6385 } 6377 6386 6378 6387 jsval_t bound_this_slot = get_slot(js, func_obj, SLOT_BOUND_THIS); 6379 - if (vtype(bound_this_slot) != T_UNDEF && !is_constructor_call) { 6380 - captured_this = bound_this_slot; 6381 - is_bound = true; 6388 + if (vtype(bound_this_slot) != T_UNDEF && vtype(js->new_target) == T_UNDEF) { 6389 + captured_this = bound_this_slot; is_bound = true; 6382 6390 } 6383 6391 6384 6392 int bound_argc; ··· 6386 6394 6387 6395 jsval_t nfe_name_val = js_mkundef(); 6388 6396 jsval_t slot_name = get_slot(js, func_obj, SLOT_NAME); 6389 - if (vtype(slot_name) == T_STR) { 6390 - nfe_name_val = slot_name; 6391 - } else { 6397 + 6398 + if (vtype(slot_name) == T_STR) nfe_name_val = slot_name; else { 6392 6399 jsoff_t nfe_name_off = lkp(js, func_obj, "name", 4); 6393 - if (nfe_name_off != 0) { 6394 - nfe_name_val = resolveprop(js, mkval(T_PROP, nfe_name_off)); 6395 - } 6400 + if (nfe_name_off != 0) nfe_name_val = resolveprop(js, mkval(T_PROP, nfe_name_off)); 6396 6401 } 6397 6402 6398 6403 static char full_func_name[256]; ··· 8425 8430 js->consumed = 1; 8426 8431 jsval_t obj = mkobj(js, 0); 8427 8432 jsval_t saved_this = js->this_val; 8433 + jsval_t saved_new_target = js->new_target; 8428 8434 js->this_val = obj; 8429 8435 8430 8436 jsval_t ctor = js_group(js); ··· 8456 8462 if (is_err(ctor)) { js->this_val = saved_this; return ctor; } 8457 8463 if (vtype(ctor) == T_PROP || vtype(ctor) == T_PROPREF) ctor = resolveprop(js, ctor); 8458 8464 8465 + js->new_target = ctor; 8466 + 8459 8467 jsval_t result; 8460 8468 push_this(obj); 8461 8469 if (next(js) == TOK_LPAREN) { 8462 8470 jsval_t params = js_call_params(js); 8463 - if (is_err(params)) { pop_this(); js->this_val = saved_this; return params; } 8471 + if (is_err(params)) { 8472 + pop_this(); js->this_val = saved_this; 8473 + js->new_target = saved_new_target; return params; 8474 + } 8464 8475 result = do_op(js, TOK_CALL, ctor, params); 8465 8476 } else { 8466 8477 result = do_op(js, TOK_CALL, ctor, mkcoderef(0, 0)); ··· 8470 8481 8471 8482 jsval_t constructed_obj = js->this_val; 8472 8483 js->this_val = saved_this; 8484 + js->new_target = saved_new_target; 8473 8485 8474 8486 uint8_t rtype = vtype(result); 8475 8487 jsval_t new_result = ( ··· 12169 12181 } 12170 12182 12171 12183 static jsval_t builtin_Error(struct js *js, jsval_t *args, int nargs) { 12172 - jsval_t err_obj = js->this_val; 12173 - jsval_t error_proto = get_ctor_proto(js, "Error", 5); 12174 - bool is_constructor_call = (vtype(err_obj) == T_OBJ); 12184 + bool is_new = (vtype(js->new_target) != T_UNDEF); 12185 + jsval_t this_val = js->this_val; 12186 + 12187 + jsval_t target = is_new ? js->new_target : js->current_func; 12188 + jsval_t name = ANT_STRING("Error"); 12175 12189 12176 - if (!is_constructor_call) { 12177 - err_obj = mkobj(js, 0); 12178 - set_proto(js, err_obj, error_proto); 12190 + if (vtype(target) == T_FUNC) { 12191 + jsoff_t off = lkp(js, mkval(T_OBJ, vdata(target)), "name", 4); 12192 + if (off) name = resolveprop(js, mkval(T_PROP, off)); 12193 + } 12194 + 12195 + if (!is_new) { 12196 + this_val = js_mkobj(js); 12197 + jsoff_t proto_off = lkp_interned(js, mkval(T_OBJ, vdata(js->current_func)), INTERN_PROTOTYPE, 9); 12198 + if (proto_off) set_proto(js, this_val, resolveprop(js, mkval(T_PROP, proto_off))); 12199 + else set_proto(js, this_val, get_ctor_proto(js, "Error", 5)); 12179 12200 } 12180 12201 12181 - jsval_t message = js_mkstr(js, "", 0); 12182 12202 if (nargs > 0) { 12183 - if (vtype(args[0]) == T_STR) { 12184 - message = args[0]; 12185 - } else { 12186 - const char *str = js_str(js, args[0]); 12187 - message = js_mkstr(js, str, strlen(str)); 12203 + jsval_t msg = args[0]; 12204 + if (vtype(msg) != T_STR) { 12205 + const char *str = js_str(js, msg); 12206 + msg = js_mkstr(js, str, strlen(str)); 12188 12207 } 12208 + setprop_fast(js, this_val, "message", 7, msg); 12189 12209 } 12190 12210 12191 - jsval_t message_key = js_mkstr(js, "message", 7); 12192 - setprop(js, err_obj, message_key, message); 12193 - 12194 - jsval_t name_key = js_mkstr(js, "name", 4); 12195 - jsval_t name_val = js_mkstr(js, "Error", 5); 12196 - setprop(js, err_obj, name_key, name_val); 12197 - 12198 - return err_obj; 12199 - } 12200 - 12201 - #define DEFINE_ERROR_BUILTIN(name, name_str, name_len) \ 12202 - static jsval_t builtin_##name(struct js *js, jsval_t *args, int nargs) { \ 12203 - jsval_t err_obj = js->this_val; \ 12204 - jsval_t error_proto = get_ctor_proto(js, name_str, name_len); \ 12205 - bool is_constructor_call = (vtype(err_obj) == T_OBJ); \ 12206 - if (!is_constructor_call) { \ 12207 - err_obj = mkobj(js, 0); \ 12208 - set_proto(js, err_obj, error_proto); \ 12209 - } \ 12210 - jsval_t message = js_mkstr(js, "", 0); \ 12211 - if (nargs > 0) { \ 12212 - if (vtype(args[0]) == T_STR) { \ 12213 - message = args[0]; \ 12214 - } else { \ 12215 - const char *str = js_str(js, args[0]); \ 12216 - message = js_mkstr(js, str, strlen(str)); \ 12217 - } \ 12218 - } \ 12219 - setprop(js, err_obj, js_mkstr(js, "message", 7), message); \ 12220 - setprop(js, err_obj, js_mkstr(js, "name", 4), js_mkstr(js, name_str, name_len)); \ 12221 - return err_obj; \ 12211 + setprop_fast(js, this_val, "name", 4, name); 12212 + return this_val; 12222 12213 } 12223 - 12224 - DEFINE_ERROR_BUILTIN(EvalError, "EvalError", 9) 12225 - DEFINE_ERROR_BUILTIN(RangeError, "RangeError", 10) 12226 - DEFINE_ERROR_BUILTIN(ReferenceError, "ReferenceError", 14) 12227 - DEFINE_ERROR_BUILTIN(SyntaxError, "SyntaxError", 11) 12228 - DEFINE_ERROR_BUILTIN(TypeError, "TypeError", 9) 12229 - DEFINE_ERROR_BUILTIN(URIError, "URIError", 8) 12230 - DEFINE_ERROR_BUILTIN(InternalError, "InternalError", 13) 12231 - 12232 - #undef DEFINE_ERROR_BUILTIN 12233 12214 12234 12215 static jsval_t builtin_RegExp(struct js *js, jsval_t *args, int nargs) { 12235 12216 jsval_t regexp_obj = js->this_val; ··· 12561 12542 12562 12543 static jsval_t builtin_Date(struct js *js, jsval_t *args, int nargs) { 12563 12544 jsval_t date_obj = js->this_val; 12564 - jsval_t date_proto = get_ctor_proto(js, "Date", 4); 12565 - jsval_t this_proto = get_proto(js, date_obj); 12566 12545 12567 - bool is_constructor_call = ( 12568 - vtype(date_obj) == T_OBJ && 12569 - vtype(this_proto) == T_OBJ && 12570 - vdata(this_proto) == vdata(date_proto) 12571 - ); 12572 - 12573 - if (!is_constructor_call) { 12546 + if (vtype(js->new_target) == T_UNDEF) { 12574 12547 struct timeval tv; 12575 12548 gettimeofday(&tv, NULL); 12576 12549 ··· 20661 20634 js->size = js->size / 8U * 8U; 20662 20635 js->lwm = js->size; 20663 20636 js->this_val = js->scope; 20637 + js->new_target = js_mkundef(); 20664 20638 js->errmsg_size = 4096; 20665 20639 js->errmsg = (char *)malloc(js->errmsg_size); 20666 20640 if (js->errmsg) js->errmsg[0] = '\0'; ··· 20796 20770 20797 20771 jsval_t error_proto = js_mkobj(js); 20798 20772 set_proto(js, error_proto, object_proto); 20799 - setprop(js, error_proto, js_mkstr(js, "name", 4), js_mkstr(js, "Error", 5)); 20800 - setprop(js, error_proto, js_mkstr(js, "message", 7), js_mkstr(js, "", 0)); 20773 + setprop(js, error_proto, ANT_STRING("name"), ANT_STRING("Error")); 20774 + setprop(js, error_proto, ANT_STRING("message"), js_mkstr(js, "", 0)); 20801 20775 20802 - jsval_t evalerror_proto = js_mkobj(js); 20803 - set_proto(js, evalerror_proto, error_proto); 20804 - setprop(js, evalerror_proto, js_mkstr(js, "name", 4), js_mkstr(js, "EvalError", 9)); 20776 + jsval_t err_ctor_obj = mkobj(js, 0); 20777 + set_proto(js, err_ctor_obj, function_proto); 20778 + set_slot(js, err_ctor_obj, SLOT_CFUNC, js_mkfun(builtin_Error)); 20779 + js_setprop_nonconfigurable(js, err_ctor_obj, "prototype", 9, error_proto); 20780 + setprop(js, err_ctor_obj, ANT_STRING("name"), ANT_STRING("Error")); 20781 + setprop(js, glob, ANT_STRING("Error"), mkval(T_FUNC, vdata(err_ctor_obj))); 20782 + setprop(js, error_proto, js_mkstr(js, "constructor", 11), mkval(T_FUNC, vdata(err_ctor_obj))); 20783 + js_set_descriptor(js, error_proto, "constructor", 11, JS_DESC_W | JS_DESC_C); 20805 20784 20806 - jsval_t rangeerror_proto = js_mkobj(js); 20807 - set_proto(js, rangeerror_proto, error_proto); 20808 - setprop(js, rangeerror_proto, js_mkstr(js, "name", 4), js_mkstr(js, "RangeError", 10)); 20809 - 20810 - jsval_t referenceerror_proto = js_mkobj(js); 20811 - set_proto(js, referenceerror_proto, error_proto); 20812 - setprop(js, referenceerror_proto, js_mkstr(js, "name", 4), js_mkstr(js, "ReferenceError", 14)); 20813 - 20814 - jsval_t syntaxerror_proto = js_mkobj(js); 20815 - set_proto(js, syntaxerror_proto, error_proto); 20816 - setprop(js, syntaxerror_proto, js_mkstr(js, "name", 4), js_mkstr(js, "SyntaxError", 11)); 20817 - 20818 - jsval_t typeerror_proto = js_mkobj(js); 20819 - set_proto(js, typeerror_proto, error_proto); 20820 - setprop(js, typeerror_proto, js_mkstr(js, "name", 4), js_mkstr(js, "TypeError", 9)); 20785 + #define REGISTER_ERROR_SUBTYPE(name_str) do { \ 20786 + jsval_t proto = js_mkobj(js); \ 20787 + set_proto(js, proto, error_proto); \ 20788 + setprop(js, proto, ANT_STRING("name"), ANT_STRING(name_str)); \ 20789 + jsval_t ctor = mkobj(js, 0); \ 20790 + set_proto(js, ctor, function_proto); \ 20791 + set_slot(js, ctor, SLOT_CFUNC, js_mkfun(builtin_Error)); \ 20792 + js_setprop_nonconfigurable(js, ctor, "prototype", 9, proto); \ 20793 + setprop(js, ctor, ANT_STRING("name"), ANT_STRING(name_str)); \ 20794 + setprop(js, proto, ANT_STRING("constructor"), mkval(T_FUNC, vdata(ctor))); \ 20795 + js_set_descriptor(js, proto, "constructor", 11, JS_DESC_W | JS_DESC_C); \ 20796 + setprop(js, glob, ANT_STRING(name_str), mkval(T_FUNC, vdata(ctor))); \ 20797 + } while(0) 20821 20798 20822 - jsval_t urierror_proto = js_mkobj(js); 20823 - set_proto(js, urierror_proto, error_proto); 20824 - setprop(js, urierror_proto, js_mkstr(js, "name", 4), js_mkstr(js, "URIError", 8)); 20799 + REGISTER_ERROR_SUBTYPE("EvalError"); 20800 + REGISTER_ERROR_SUBTYPE("RangeError"); 20801 + REGISTER_ERROR_SUBTYPE("ReferenceError"); 20802 + REGISTER_ERROR_SUBTYPE("SyntaxError"); 20803 + REGISTER_ERROR_SUBTYPE("TypeError"); 20804 + REGISTER_ERROR_SUBTYPE("URIError"); 20805 + REGISTER_ERROR_SUBTYPE("InternalError"); 20825 20806 20826 - jsval_t internalerror_proto = js_mkobj(js); 20827 - set_proto(js, internalerror_proto, error_proto); 20828 - setprop(js, internalerror_proto, js_mkstr(js, "name", 4), js_mkstr(js, "InternalError", 13)); 20807 + #undef REGISTER_ERROR_SUBTYPE 20829 20808 20830 20809 jsval_t date_proto = js_mkobj(js); 20831 20810 set_proto(js, date_proto, object_proto); ··· 21039 21018 setprop(js, proxy_ctor_obj, ANT_STRING("name"), ANT_STRING("Proxy")); 21040 21019 setprop(js, glob, js_mkstr(js, "Proxy", 5), mkval(T_FUNC, vdata(proxy_ctor_obj))); 21041 21020 21042 - jsval_t err_ctor_obj = mkobj(js, 0); 21043 - set_proto(js, err_ctor_obj, function_proto); 21044 - set_slot(js, err_ctor_obj, SLOT_CFUNC, js_mkfun(builtin_Error)); 21045 - js_setprop_nonconfigurable(js, err_ctor_obj, "prototype", 9, error_proto); 21046 - setprop(js, err_ctor_obj, ANT_STRING("name"), ANT_STRING("Error")); 21047 - setprop(js, glob, js_mkstr(js, "Error", 5), mkval(T_FUNC, vdata(err_ctor_obj))); 21048 - 21049 - jsval_t evalerr_ctor_obj = mkobj(js, 0); 21050 - set_proto(js, evalerr_ctor_obj, function_proto); 21051 - set_slot(js, evalerr_ctor_obj, SLOT_CFUNC, js_mkfun(builtin_EvalError)); 21052 - js_setprop_nonconfigurable(js, evalerr_ctor_obj, "prototype", 9, evalerror_proto); 21053 - setprop(js, evalerr_ctor_obj, ANT_STRING("name"), ANT_STRING("EvalError")); 21054 - setprop(js, glob, js_mkstr(js, "EvalError", 9), mkval(T_FUNC, vdata(evalerr_ctor_obj))); 21055 - 21056 - jsval_t rangeerr_ctor_obj = mkobj(js, 0); 21057 - set_proto(js, rangeerr_ctor_obj, function_proto); 21058 - set_slot(js, rangeerr_ctor_obj, SLOT_CFUNC, js_mkfun(builtin_RangeError)); 21059 - js_setprop_nonconfigurable(js, rangeerr_ctor_obj, "prototype", 9, rangeerror_proto); 21060 - setprop(js, rangeerr_ctor_obj, ANT_STRING("name"), ANT_STRING("RangeError")); 21061 - setprop(js, glob, js_mkstr(js, "RangeError", 10), mkval(T_FUNC, vdata(rangeerr_ctor_obj))); 21062 - 21063 - jsval_t referr_ctor_obj = mkobj(js, 0); 21064 - set_proto(js, referr_ctor_obj, function_proto); 21065 - set_slot(js, referr_ctor_obj, SLOT_CFUNC, js_mkfun(builtin_ReferenceError)); 21066 - js_setprop_nonconfigurable(js, referr_ctor_obj, "prototype", 9, referenceerror_proto); 21067 - setprop(js, referr_ctor_obj, ANT_STRING("name"), ANT_STRING("ReferenceError")); 21068 - setprop(js, glob, js_mkstr(js, "ReferenceError", 14), mkval(T_FUNC, vdata(referr_ctor_obj))); 21069 - 21070 - jsval_t syntaxerr_ctor_obj = mkobj(js, 0); 21071 - set_proto(js, syntaxerr_ctor_obj, function_proto); 21072 - set_slot(js, syntaxerr_ctor_obj, SLOT_CFUNC, js_mkfun(builtin_SyntaxError)); 21073 - js_setprop_nonconfigurable(js, syntaxerr_ctor_obj, "prototype", 9, syntaxerror_proto); 21074 - setprop(js, syntaxerr_ctor_obj, ANT_STRING("name"), ANT_STRING("SyntaxError")); 21075 - setprop(js, glob, js_mkstr(js, "SyntaxError", 11), mkval(T_FUNC, vdata(syntaxerr_ctor_obj))); 21076 - 21077 - jsval_t typeerr_ctor_obj = mkobj(js, 0); 21078 - set_proto(js, typeerr_ctor_obj, function_proto); 21079 - set_slot(js, typeerr_ctor_obj, SLOT_CFUNC, js_mkfun(builtin_TypeError)); 21080 - js_setprop_nonconfigurable(js, typeerr_ctor_obj, "prototype", 9, typeerror_proto); 21081 - setprop(js, typeerr_ctor_obj, ANT_STRING("name"), ANT_STRING("TypeError")); 21082 - setprop(js, glob, js_mkstr(js, "TypeError", 9), mkval(T_FUNC, vdata(typeerr_ctor_obj))); 21083 - 21084 - jsval_t urierr_ctor_obj = mkobj(js, 0); 21085 - set_proto(js, urierr_ctor_obj, function_proto); 21086 - set_slot(js, urierr_ctor_obj, SLOT_CFUNC, js_mkfun(builtin_URIError)); 21087 - js_setprop_nonconfigurable(js, urierr_ctor_obj, "prototype", 9, urierror_proto); 21088 - setprop(js, urierr_ctor_obj, ANT_STRING("name"), ANT_STRING("URIError")); 21089 - setprop(js, glob, js_mkstr(js, "URIError", 8), mkval(T_FUNC, vdata(urierr_ctor_obj))); 21090 - 21091 - jsval_t internerr_ctor_obj = mkobj(js, 0); 21092 - set_proto(js, internerr_ctor_obj, function_proto); 21093 - set_slot(js, internerr_ctor_obj, SLOT_CFUNC, js_mkfun(builtin_InternalError)); 21094 - js_setprop_nonconfigurable(js, internerr_ctor_obj, "prototype", 9, internalerror_proto); 21095 - setprop(js, internerr_ctor_obj, ANT_STRING("name"), ANT_STRING("InternalError")); 21096 - setprop(js, glob, js_mkstr(js, "InternalError", 13), mkval(T_FUNC, vdata(internerr_ctor_obj))); 21021 + 21097 21022 21098 21023 jsval_t regex_ctor_obj = mkobj(js, 0); 21099 21024 set_proto(js, regex_ctor_obj, function_proto); ··· 21221 21146 21222 21147 setprop(js, regexp_proto, js_mkstr(js, "constructor", 11), mkval(T_FUNC, vdata(regex_ctor_obj))); 21223 21148 js_set_descriptor(js, regexp_proto, "constructor", 11, JS_DESC_W | JS_DESC_C); 21224 - 21225 - setprop(js, error_proto, js_mkstr(js, "constructor", 11), mkval(T_FUNC, vdata(err_ctor_obj))); 21226 - js_set_descriptor(js, error_proto, "constructor", 11, JS_DESC_W | JS_DESC_C); 21227 21149 21228 21150 set_proto(js, glob, object_proto); 21229 21151
+2 -1
src/core/ant.ts
··· 25 25 T_BIGINT: 'bigint', 26 26 T_PROPREF: 'propref', 27 27 T_SYMBOL: 'symbol', 28 - T_GENERATOR: 'generator' 28 + T_GENERATOR: 'generator', 29 + T_FFI: 'ffi' 29 30 } as const; 30 31 31 32 const names = Object.values(types);
+2 -1
src/types/ant.d.ts
··· 16 16 | 'bigint' 17 17 | 'propref' 18 18 | 'symbol' 19 - | 'generator'; 19 + | 'generator' 20 + | 'ffi'; 20 21 21 22 type AntHost = 22 23 | 'cygwin'