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.

improve object desc handler

+42 -23
+1 -1
examples/spec/os.js
··· 39 39 test('os.endianness valid value', os.endianness() === 'LE' || os.endianness() === 'BE', true); 40 40 41 41 test('os.uptime returns number', typeof os.uptime(), 'number'); 42 - test('os.uptime is positive', os.uptime() > 0, true); 42 + test('os.uptime is non-negative', os.uptime() >= 0, true); 43 43 44 44 test('os.totalmem returns number', typeof os.totalmem(), 'number'); 45 45 test('os.totalmem is positive', os.totalmem() > 0, true);
+3 -3
examples/spec/process.js
··· 129 129 130 130 test('stdout is object', typeof process.stdout, 'object'); 131 131 test('stdout.isTTY is boolean', typeof process.stdout.isTTY, 'boolean'); 132 - test('stdout.rows is number', typeof process.stdout.rows, 'number'); 133 - test('stdout.columns is number', typeof process.stdout.columns, 'number'); 132 + test('stdout.rows shape', process.stdout.isTTY ? typeof process.stdout.rows === 'number' : process.stdout.rows === undefined, true); 133 + test('stdout.columns shape', process.stdout.isTTY ? typeof process.stdout.columns === 'number' : process.stdout.columns === undefined, true); 134 134 test('stdout.write is function', typeof process.stdout.write, 'function'); 135 135 test('stdout.on is function', typeof process.stdout.on, 'function'); 136 136 test('stdout.once is function', typeof process.stdout.once, 'function'); ··· 215 215 test('setegid is function', typeof process.setegid, 'function'); 216 216 test('setgroups is function', typeof process.setgroups, 'function'); 217 217 test('initgroups is function', typeof process.initgroups, 'function'); 218 - 218 + 219 219 test('getuid returns number', typeof process.getuid(), 'number'); 220 220 test('getgid returns number', typeof process.getgid(), 'number'); 221 221 test('getgroups returns array', Array.isArray(process.getgroups()), true);
+10
examples/spec/response.js
··· 53 53 test('Response.json content-type', jsonRes.headers.get('content-type'), 'application/json'); 54 54 test('Response.json body', (await jsonRes.json()).hello, 'world'); 55 55 testThrows('Response.json rejects symbol', () => Response.json(Symbol('x'))); 56 + 57 + testThrows('Response.json propagates serializer errors', () => { 58 + class CustomError extends Error {} 59 + Response.json({ 60 + get hello() { 61 + throw new CustomError('boom'); 62 + } 63 + }); 64 + }); 65 + 56 66 testThrows('Response.json null body status rejects', () => Response.json('x', { status: 204 })); 57 67 58 68 const f16Body = new Float16Array([1.5, -0.5, 2.25]);
+16 -10
src/modules/json.c
··· 93 93 return ctx->has_cycle || vtype(ctx->error) != T_UNDEF; 94 94 } 95 95 96 + static inline ant_value_t json_normalize_error(ant_value_t value) { 97 + if (is_err(value) && vdata(value) != 0) return js_as_obj(value); 98 + return value; 99 + } 100 + 96 101 static void json_capture_error(json_cycle_ctx *ctx, ant_value_t value) { 97 102 if (vtype(ctx->error) != T_UNDEF) return; 98 103 if (ctx->js->thrown_exists) { ··· 101 106 ctx->js->thrown_value = js_mkundef(); 102 107 return; 103 108 } 104 - ctx->error = value; 109 + ctx->error = json_normalize_error(value); 105 110 } 106 111 107 112 static yyjson_mut_val *json_string_to_yyjson(ant_t *js, yyjson_mut_doc *doc, ant_value_t value) { ··· 419 424 ant_value_t js_json_stringify(ant_t *js, ant_value_t *args, int nargs) { 420 425 ant_value_t result; 421 426 yyjson_mut_doc *doc = NULL; 422 - json_cycle_ctx ctx = {0}; 427 + 428 + json_cycle_ctx ctx = { 429 + .js = js, 430 + .replacer_func = js_mkundef(), 431 + .replacer_arr = js_mkundef(), 432 + .error = js_mkundef(), 433 + .holder = js_mkundef(), 434 + }; 423 435 424 436 char *json_str = NULL; 425 437 size_t len; ··· 442 454 return result; 443 455 } 444 456 445 - ctx.js = js; 446 - ctx.replacer_func = js_mkundef(); 447 - ctx.replacer_arr = js_mkundef(); 448 - ctx.replacer_arr_len = 0; 449 - ctx.error = js_mkundef(); 450 - ctx.holder = js_mkundef(); 451 - 452 457 if (nargs >= 2) { 453 458 ant_value_t replacer = args[1]; 454 459 if (vtype(replacer) == T_FUNC) ctx.replacer_func = replacer; ··· 467 472 yyjson_mut_val *root = ant_value_to_yyjson(js, doc, args[0], &ctx); 468 473 469 474 if (vtype(ctx.error) != T_UNDEF) { 470 - result = is_err(ctx.error) ? ctx.error : js_throw(js, ctx.error); 475 + ant_value_t error = json_normalize_error(ctx.error); 476 + result = is_err(error) ? error : js_throw(js, error); 471 477 goto cleanup; 472 478 } 473 479
+3 -5
src/modules/tty.c
··· 178 178 } 179 179 180 180 static int detect_color_depth(ant_t *js, int fd, ant_value_t env_obj) { 181 - if (!is_tty_fd(fd)) return 1; 182 - 183 181 char scratch[128]; 184 182 const char *force_color = get_env_value(js, env_obj, "FORCE_COLOR", scratch, sizeof(scratch)); 183 + 185 184 int forced = force_color_depth(force_color); 186 185 if (forced > 0) return forced; 187 186 188 187 const char *no_color = get_env_value(js, env_obj, "NO_COLOR", scratch, sizeof(scratch)); 189 188 if (no_color && *no_color) return 1; 189 + if (!is_tty_fd(fd)) return 1; 190 190 191 191 const char *colorterm = get_env_value(js, env_obj, "COLORTERM", scratch, sizeof(scratch)); 192 192 if (colorterm) { 193 - if (str_case_contains(colorterm, "truecolor") || str_case_contains(colorterm, "24bit")) { 194 - return 24; 195 - } 193 + if (str_case_contains(colorterm, "truecolor") || str_case_contains(colorterm, "24bit")) return 24; 196 194 } 197 195 198 196 #ifdef _WIN32
+9 -4
src/silver/ops/objects.h
··· 14 14 ) { 15 15 uint32_t atom_idx = sv_get_u32(ip + 1); 16 16 uint8_t flags = sv_get_u8(ip + 5); 17 + 17 18 sv_atom_t *a = &func->atoms[atom_idx]; 18 19 ant_value_t fn = vm->stack[--vm->sp]; 19 20 ant_value_t obj = vm->stack[vm->sp - 1]; 20 21 ant_value_t desc_obj = js_as_obj(obj); 22 + 21 23 bool is_getter = (flags & 1) != 0; 22 24 bool is_setter = (flags & 2) != 0; 25 + 23 26 if (is_getter) { 24 - js_set_getter_desc(js, desc_obj, a->str, a->len, fn, JS_DESC_C); 27 + js_set_getter_desc(js, desc_obj, a->str, a->len, fn, JS_DESC_E | JS_DESC_C); 25 28 return; 26 29 } 30 + 27 31 if (is_setter) { 28 - js_set_setter_desc(js, desc_obj, a->str, a->len, fn, JS_DESC_C); 32 + js_set_setter_desc(js, desc_obj, a->str, a->len, fn, JS_DESC_E | JS_DESC_C); 29 33 return; 30 34 } 35 + 31 36 ant_value_t key = js_mkstr(js, a->str, a->len); 32 37 mkprop(js, obj, key, fn, 0); 33 38 } ··· 52 57 ant_offset_t klen = 0; 53 58 ant_offset_t koff = vstr(js, key_str, &klen); 54 59 const char *kptr = (const char *)(uintptr_t)(koff); 55 - if (is_getter) js_set_getter_desc(js, desc_obj, kptr, klen, fn, JS_DESC_C); 56 - else js_set_setter_desc(js, desc_obj, kptr, klen, fn, JS_DESC_C); 60 + if (is_getter) js_set_getter_desc(js, desc_obj, kptr, klen, fn, JS_DESC_E | JS_DESC_C); 61 + else js_set_setter_desc(js, desc_obj, kptr, klen, fn, JS_DESC_E | JS_DESC_C); 57 62 return; 58 63 } 59 64 if (vtype(key_str) == T_STR) {