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.

add array class name support and super call prototype fixing

+93 -20
+93 -20
src/ant.c
··· 739 739 (js)->consumed = (state).consumed; \ 740 740 } while(0) 741 741 742 + static jsoff_t vstr(struct js *js, jsval_t value, jsoff_t *len); 743 + static size_t strstring(struct js *js, jsval_t value, char *buf, size_t len); 744 + static size_t strkey(struct js *js, jsval_t value, char *buf, size_t len); 745 + 742 746 static inline jsoff_t loadoff(struct js *js, jsoff_t off) { 743 747 assert(js->brk <= js->size); 744 748 return *(jsoff_t *)(&js->mem[off]); ··· 1362 1366 return count <= 4 && !has_nested; 1363 1367 } 1364 1368 1369 + static bool is_array_index(const char *key, jsoff_t klen) { 1370 + if (klen == 0) return false; 1371 + for (jsoff_t i = 0; i < klen; i++) { 1372 + if (key[i] < '0' || key[i] > '9') return false; 1373 + } 1374 + return true; 1375 + } 1376 + 1365 1377 static size_t strarr(struct js *js, jsval_t obj, char *buf, size_t len) { 1366 1378 int ref = get_circular_ref(obj); 1367 1379 if (ref) return ref > 0 ? (size_t) snprintf(buf, len, "[Circular *%d]", ref) : cpy(buf, len, "[Circular]", 10); ··· 1383 1395 } 1384 1396 scan = loadoff(js, scan) & ~(3U | FLAGMASK); 1385 1397 } 1398 + 1399 + const char *class_name = NULL; 1400 + jsoff_t class_name_len = 0; 1401 + do { 1402 + jsval_t ctor_val = get_slot(js, obj, SLOT_CTOR); 1403 + if (vtype(ctor_val) != T_FUNC) { 1404 + jsval_t proto_val = get_slot(js, obj, SLOT_PROTO); 1405 + if (vtype(proto_val) == T_OBJ) { 1406 + jsoff_t ctor_off = lkp(js, proto_val, "constructor", 11); 1407 + if (ctor_off != 0) ctor_val = resolveprop(js, mkval(T_PROP, ctor_off)); 1408 + } 1409 + } 1410 + if (vtype(ctor_val) != T_FUNC) break; 1411 + 1412 + jsoff_t name_off = lkp(js, mkval(T_OBJ, vdata(ctor_val)), "name", 4); 1413 + if (name_off == 0) break; 1414 + 1415 + jsval_t name_val = resolveprop(js, mkval(T_PROP, name_off)); 1416 + if (vtype(name_val) != T_STR) break; 1417 + 1418 + jsoff_t name_str_off = vstr(js, name_val, &class_name_len); 1419 + class_name = (const char *) &js->mem[name_str_off]; 1420 + 1421 + if (class_name_len == 5 && memcmp(class_name, "Array", 5) == 0) { 1422 + class_name = NULL; 1423 + class_name_len = 0; 1424 + } 1425 + } while (0); 1386 1426 1387 1427 int elem_count = 0; 1388 1428 bool inline_mode = is_small_array(js, obj, &elem_count); 1389 1429 1430 + size_t n = 0; 1431 + 1432 + if (class_name && class_name_len > 0) { 1433 + n += cpy(buf + n, len - n, class_name, class_name_len); 1434 + n += (size_t) snprintf(buf + n, len - n, "(%u) ", (unsigned) length); 1435 + } 1436 + 1390 1437 if (length == 0) { 1438 + n += cpy(buf + n, len - n, "[]", 2); 1391 1439 pop_stringify(); 1392 - return cpy(buf, len, "[]", 2); 1440 + return n; 1393 1441 } 1394 1442 1395 - size_t n = cpy(buf, len, inline_mode ? "[ " : "[\n", 2); 1443 + n += cpy(buf + n, len - n, inline_mode ? "[ " : "[\n", 2); 1396 1444 if (!inline_mode) stringify_indent++; 1397 1445 1398 1446 for (jsoff_t i = 0; i < length; i++) { ··· 1423 1471 if (found) { 1424 1472 n += tostr(js, val, buf + n, len - n); 1425 1473 } else n += cpy(buf + n, len - n, "undefined", 9); 1474 + } 1475 + 1476 + scan = next; 1477 + while (scan < js->brk && scan != 0) { 1478 + jsoff_t header = loadoff(js, scan); 1479 + if (!is_slot_prop(header)) { 1480 + jsoff_t koff = loadoff(js, scan + (jsoff_t) sizeof(scan)); 1481 + jsoff_t klen = offtolen(loadoff(js, koff)); 1482 + const char *key = (char *) &js->mem[koff + sizeof(koff)]; 1483 + 1484 + if (!streq(key, klen, "length", 6) && !is_array_index(key, klen)) { 1485 + n += cpy(buf + n, len - n, inline_mode ? ", " : ",\n", 2); 1486 + if (!inline_mode) n += add_indent(buf + n, len - n, stringify_indent); 1487 + n += cpy(buf + n, len - n, key, klen); 1488 + n += cpy(buf + n, len - n, ": ", 2); 1489 + jsval_t val = loadval(js, scan + (jsoff_t) (sizeof(scan) + sizeof(koff))); 1490 + n += tostr(js, val, buf + n, len - n); 1491 + } 1492 + } 1493 + scan = header & ~(3U | FLAGMASK); 1426 1494 } 1427 1495 1428 1496 if (!inline_mode) { ··· 1523 1591 1524 1592 return (size_t) snprintf(buf, len, "%s GMT%+03d%02d (%s)", date_part, offset_hours, offset_mins, tz_name); 1525 1593 } 1526 - 1527 - static jsoff_t vstr(struct js *js, jsval_t value, jsoff_t *len); 1528 - static size_t strstring(struct js *js, jsval_t value, char *buf, size_t len); 1529 - static size_t strkey(struct js *js, jsval_t value, char *buf, size_t len); 1530 1594 1531 1595 static bool is_valid_identifier(const char *str, jsoff_t slen) { 1532 1596 if (slen == 0) return false; ··· 8436 8500 res = do_op(js, TOK_BRACKET, res, idx); 8437 8501 } else { 8438 8502 jsval_t func_this = obj; 8503 + bool is_super_call = (vtype(js->super_val) != T_UNDEF && res == js->super_val); 8439 8504 if (vtype(obj) == T_UNDEF) { 8440 8505 if (vtype(res) == T_PROPREF) { 8441 8506 jsoff_t obj_off = propref_obj(res); ··· 8450 8515 } 8451 8516 res = do_op(js, TOK_CALL, res, params); 8452 8517 pop_this(); 8518 + // to be cleaned up 8519 + if (is_super_call && !is_err(res)) { 8520 + uint8_t rt = vtype(res); 8521 + if (rt == T_OBJ || rt == T_ARR || rt == T_FUNC || rt == T_PROMISE) { 8522 + jsoff_t proto_off = lkp_interned(js, mkval(T_OBJ, vdata(js->current_func)), INTERN_PROTOTYPE, 9); 8523 + if (proto_off != 0) { 8524 + jsval_t subclass_proto = resolveprop(js, mkval(T_PROP, proto_off)); 8525 + set_proto(js, res, subclass_proto); 8526 + } 8527 + js->this_val = res; 8528 + if (global_this_stack.depth > 0) global_this_stack.stack[global_this_stack.depth - 1] = res; 8529 + } 8530 + } 8453 8531 obj = js_mkundef(); 8454 8532 } 8455 8533 } ··· 8569 8647 result = do_op(js, TOK_CALL, ctor, mkcoderef(0, 0)); 8570 8648 js->consumed = 0; 8571 8649 } 8650 + 8651 + jsval_t constructed_obj = peek_this(); 8572 8652 pop_this(); 8573 - 8574 - jsval_t constructed_obj = js->this_val; 8653 + 8575 8654 js->this_val = saved_this; 8576 8655 js->new_target = saved_new_target; 8577 - 8656 + 8578 8657 uint8_t rtype = vtype(result); 8579 8658 jsval_t new_result = ( 8580 8659 rtype == T_OBJ || rtype == T_ARR || ··· 12240 12319 if (nargs == 1 && vtype(args[0]) == T_NUM) { 12241 12320 jsval_t err = validate_array_length(js, args[0]); 12242 12321 if (is_err(err)) return err; 12243 - jsoff_t len = (jsoff_t) tod(args[0]); 12244 - jsval_t len_key = js_mkstr(js, "length", 6); 12245 - jsval_t len_val = tov((double) len); 12246 - setprop(js, arr, len_key, len_val); 12247 - } else { 12322 + setprop(js, arr, ANT_STRING("length"), tov(tod(args[0]))); 12323 + } else if (nargs > 0) { 12248 12324 for (int i = 0; i < nargs; i++) { 12249 12325 char idxstr[16]; 12250 12326 size_t idxlen = uint_to_str(idxstr, sizeof(idxstr), (unsigned)i); 12251 - jsval_t key = js_mkstr(js, idxstr, idxlen); 12252 - setprop(js, arr, key, args[i]); 12327 + setprop(js, arr, js_mkstr(js, idxstr, idxlen), args[i]); 12253 12328 } 12254 - jsval_t len_key = js_mkstr(js, "length", 6); 12255 - jsval_t len_val = tov((double) nargs); 12256 - setprop(js, arr, len_key, len_val); 12329 + setprop(js, arr, ANT_STRING("length"), tov((double)nargs)); 12257 12330 } 12258 12331 12259 - return mkval(T_ARR, vdata(arr)); 12332 + return arr; 12260 12333 } 12261 12334 12262 12335 static jsval_t builtin_Error(struct js *js, jsval_t *args, int nargs) {