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 REMAIN macro for buffer length management

+166 -146
+166 -146
src/ant.c
··· 1282 1282 static jsval_t reject_coroutine_wrapper(struct js *js, jsval_t *args, int nargs); 1283 1283 1284 1284 static size_t cpy(char *dst, size_t dstlen, const char *src, size_t srclen) { 1285 - if (dstlen == 0) return 0; 1285 + if (dstlen == 0) return srclen; 1286 1286 size_t len = srclen < dstlen - 1 ? srclen : dstlen - 1; 1287 1287 memcpy(dst, src, len); dst[len] = '\0'; 1288 - return len; 1288 + return srclen; 1289 1289 } 1290 + 1291 + #define REMAIN(n, len) ((n) >= (len) ? 0 : (len) - (n)) 1290 1292 1291 1293 static inline size_t uint_to_str(char *buf, size_t bufsize, uint64_t val) { 1292 1294 if (bufsize == 0) return 0; ··· 1461 1463 } 1462 1464 1463 1465 static size_t add_indent(char *buf, size_t len, int level) { 1466 + size_t wanted = (size_t)(level * 2); 1464 1467 size_t n = 0; 1465 1468 for (int i = 0; i < level * 2 && n < len; i++) { 1466 1469 buf[n++] = ' '; 1467 1470 } 1468 - return n; 1471 + return wanted; 1469 1472 } 1470 1473 1471 1474 static inline jsoff_t get_prop_koff(struct js *js, jsoff_t prop) { ··· 1588 1591 size_t n = 0; 1589 1592 1590 1593 if (class_name) { 1591 - n += cpy(buf + n, len - n, class_name, class_len); 1592 - n += (size_t) snprintf(buf + n, len - n, "(%u) ", (unsigned) length); 1594 + n += cpy(buf + n, REMAIN(n, len), class_name, class_len); 1595 + n += (size_t) snprintf(buf + n, REMAIN(n, len), "(%u) ", (unsigned) length); 1593 1596 } 1594 1597 1595 1598 if (length == 0) { 1596 - n += cpy(buf + n, len - n, "[]", 2); 1599 + n += cpy(buf + n, REMAIN(n, len), "[]", 2); 1597 1600 pop_stringify(); 1598 1601 return n; 1599 1602 } 1600 1603 1601 - n += cpy(buf + n, len - n, inline_mode ? "[ " : "[\n", 2); 1604 + n += cpy(buf + n, REMAIN(n, len), inline_mode ? "[ " : "[\n", 2); 1602 1605 if (!inline_mode) stringify_indent++; 1603 1606 1604 1607 for (jsoff_t i = 0; i < length; i++) { 1605 - if (i > 0) n += cpy(buf + n, len - n, inline_mode ? ", " : ",\n", 2); 1606 - if (!inline_mode) n += add_indent(buf + n, len - n, stringify_indent); 1608 + if (i > 0) n += cpy(buf + n, REMAIN(n, len), inline_mode ? ", " : ",\n", 2); 1609 + if (!inline_mode) n += add_indent(buf + n, REMAIN(n, len), stringify_indent); 1607 1610 1608 1611 char idx[16]; 1609 1612 snprintf(idx, sizeof(idx), "%u", (unsigned) i); ··· 1619 1622 found = true; break; 1620 1623 } 1621 1624 } 1622 - n += found ? tostr(js, val, buf + n, len - n) : cpy(buf + n, len - n, "undefined", 9); 1625 + n += found ? tostr(js, val, buf + n, REMAIN(n, len)) : cpy(buf + n, REMAIN(n, len), "undefined", 9); 1623 1626 } 1624 1627 1625 1628 for (jsoff_t p = first; p < js->brk && p != 0; p = next_prop(loadoff(js, p))) { ··· 1630 1633 get_prop_key(js, p, &key, &klen); 1631 1634 if (streq(key, klen, "length", 6) || is_array_index(key, klen)) continue; 1632 1635 1633 - n += cpy(buf + n, len - n, inline_mode ? ", " : ",\n", 2); 1634 - if (!inline_mode) n += add_indent(buf + n, len - n, stringify_indent); 1635 - n += cpy(buf + n, len - n, key, klen); 1636 - n += cpy(buf + n, len - n, ": ", 2); 1637 - n += tostr(js, get_prop_val(js, p), buf + n, len - n); 1636 + n += cpy(buf + n, REMAIN(n, len), inline_mode ? ", " : ",\n", 2); 1637 + if (!inline_mode) n += add_indent(buf + n, REMAIN(n, len), stringify_indent); 1638 + n += cpy(buf + n, REMAIN(n, len), key, klen); 1639 + n += cpy(buf + n, REMAIN(n, len), ": ", 2); 1640 + n += tostr(js, get_prop_val(js, p), buf + n, REMAIN(n, len)); 1638 1641 } 1639 1642 1640 1643 if (!inline_mode) { 1641 1644 stringify_indent--; 1642 - n += cpy(buf + n, len - n, "\n", 1); 1643 - n += add_indent(buf + n, len - n, stringify_indent); 1645 + n += cpy(buf + n, REMAIN(n, len), "\n", 1); 1646 + n += add_indent(buf + n, REMAIN(n, len), stringify_indent); 1644 1647 } 1645 1648 1646 - n += cpy(buf + n, len - n, inline_mode ? " ]" : "]", inline_mode ? 2 : 1); 1649 + n += cpy(buf + n, REMAIN(n, len), inline_mode ? " ]" : "]", inline_mode ? 2 : 1); 1647 1650 pop_stringify(); 1648 1651 return n; 1649 1652 } ··· 1669 1672 } 1670 1673 1671 1674 for (jsoff_t i = 0; i < length; i++) { 1672 - if (i > 0) n += cpy(buf + n, len - n, ",", 1); 1675 + if (i > 0) n += cpy(buf + n, REMAIN(n, len), ",", 1); 1673 1676 char idx[16]; 1674 1677 snprintf(idx, sizeof(idx), "%u", (unsigned) i); 1675 1678 jsoff_t idxlen = (jsoff_t) strlen(idx); ··· 1692 1695 uint8_t vt = vtype(val); 1693 1696 if (vt == T_STR) { 1694 1697 jsoff_t slen, soff = vstr(js, val, &slen); 1695 - n += cpy(buf + n, len - n, (const char *)&js->mem[soff], slen); 1696 - } else if (vt != T_UNDEF && vt != T_NULL) n += tostr(js, val, buf + n, len - n); 1698 + n += cpy(buf + n, REMAIN(n, len), (const char *)&js->mem[soff], slen); 1699 + } else if (vt != T_UNDEF && vt != T_NULL) n += tostr(js, val, buf + n, REMAIN(n, len)); 1697 1700 } 1698 1701 } 1699 1702 ··· 1747 1750 const char *sym_desc = get_symbol_description_from_key(str, slen); 1748 1751 if (sym_desc) { 1749 1752 size_t n = 0; 1750 - n += cpy(buf + n, len - n, "[", 1); 1751 - n += cpy(buf + n, len - n, sym_desc, strlen(sym_desc)); 1752 - n += cpy(buf + n, len - n, "]", 1); 1753 + n += cpy(buf + n, REMAIN(n, len), "[", 1); 1754 + n += cpy(buf + n, REMAIN(n, len), sym_desc, strlen(sym_desc)); 1755 + n += cpy(buf + n, REMAIN(n, len), "]", 1); 1753 1756 return n; 1754 1757 } 1755 1758 ··· 1816 1819 size_t n = 0; 1817 1820 int self_ref = get_self_ref(obj); 1818 1821 if (self_ref) { 1819 - n += (size_t) snprintf(buf + n, len - n, "<ref *%d> ", self_ref); 1822 + n += (size_t) snprintf(buf + n, REMAIN(n, len), "<ref *%d> ", self_ref); 1820 1823 } 1821 1824 1822 1825 const char *tostring_tag_key = get_toStringTag_sym_key(); ··· 1864 1867 type_len = 10; 1865 1868 } 1866 1869 1867 - n += cpy(buf + n, len - n, type_name, type_len); 1868 - n += (size_t) snprintf(buf + n, len - n, "(%zu) ", ta->length); 1869 - n += cpy(buf + n, len - n, "[ ", 2); 1870 + n += cpy(buf + n, REMAIN(n, len), type_name, type_len); 1871 + n += (size_t) snprintf(buf + n, REMAIN(n, len), "(%zu) ", ta->length); 1872 + n += cpy(buf + n, REMAIN(n, len), "[ ", 2); 1870 1873 1871 1874 uint8_t *data = ta->buffer->data + ta->byte_offset; 1872 1875 1873 1876 for (size_t i = 0; i < ta->length && i < 100; i++) { 1874 - if (i > 0) n += cpy(buf + n, len - n, ", ", 2); 1877 + if (i > 0) n += cpy(buf + n, REMAIN(n, len), ", ", 2); 1875 1878 1876 1879 switch (ta->type) { 1877 1880 case TYPED_ARRAY_INT8: 1878 - n += (size_t) snprintf(buf + n, len - n, "%d", (int)((int8_t*)data)[i]); 1881 + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%d", (int)((int8_t*)data)[i]); 1879 1882 break; 1880 1883 case TYPED_ARRAY_UINT8: 1881 1884 case TYPED_ARRAY_UINT8_CLAMPED: 1882 - n += (size_t) snprintf(buf + n, len - n, "%u", (unsigned)data[i]); 1885 + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%u", (unsigned)data[i]); 1883 1886 break; 1884 1887 case TYPED_ARRAY_INT16: 1885 - n += (size_t) snprintf(buf + n, len - n, "%d", (int)((int16_t*)data)[i]); 1888 + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%d", (int)((int16_t*)data)[i]); 1886 1889 break; 1887 1890 case TYPED_ARRAY_UINT16: 1888 - n += (size_t) snprintf(buf + n, len - n, "%u", (unsigned)((uint16_t*)data)[i]); 1891 + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%u", (unsigned)((uint16_t*)data)[i]); 1889 1892 break; 1890 1893 case TYPED_ARRAY_INT32: 1891 - n += (size_t) snprintf(buf + n, len - n, "%d", ((int32_t*)data)[i]); 1894 + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%d", ((int32_t*)data)[i]); 1892 1895 break; 1893 1896 case TYPED_ARRAY_UINT32: 1894 - n += (size_t) snprintf(buf + n, len - n, "%u", ((uint32_t*)data)[i]); 1897 + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%u", ((uint32_t*)data)[i]); 1895 1898 break; 1896 1899 case TYPED_ARRAY_FLOAT32: 1897 - n += (size_t) snprintf(buf + n, len - n, "%g", (double)((float*)data)[i]); 1900 + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%g", (double)((float*)data)[i]); 1898 1901 break; 1899 1902 case TYPED_ARRAY_FLOAT64: 1900 - n += (size_t) snprintf(buf + n, len - n, "%g", ((double*)data)[i]); 1903 + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%g", ((double*)data)[i]); 1901 1904 break; 1902 1905 case TYPED_ARRAY_BIGINT64: 1903 - n += (size_t) snprintf(buf + n, len - n, "%lldn", (long long)((int64_t*)data)[i]); 1906 + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%lldn", (long long)((int64_t*)data)[i]); 1904 1907 break; 1905 1908 case TYPED_ARRAY_BIGUINT64: 1906 - n += (size_t) snprintf(buf + n, len - n, "%llun", (unsigned long long)((uint64_t*)data)[i]); 1909 + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%llun", (unsigned long long)((uint64_t*)data)[i]); 1907 1910 break; 1908 1911 default: 1909 - n += (size_t) snprintf(buf + n, len - n, "%u", (unsigned)data[i]); 1912 + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%u", (unsigned)data[i]); 1910 1913 break; 1911 1914 } 1912 1915 } 1913 1916 1914 - if (ta->length > 100) n += cpy(buf + n, len - n, ", ...", 5); 1915 - n += cpy(buf + n, len - n, " ]", 2); 1917 + if (ta->length > 100) n += cpy(buf + n, REMAIN(n, len), ", ...", 5); 1918 + n += cpy(buf + n, REMAIN(n, len), " ]", 2); 1916 1919 pop_stringify(); 1917 1920 return n; 1918 1921 } ··· 1924 1927 ArrayBufferData *ab_data = (ArrayBufferData *)(uintptr_t)tod(buf_val); 1925 1928 size_t bytelen = ab_data ? ab_data->length : 0; 1926 1929 1927 - n += cpy(buf + n, len - n, tag_str, tlen); 1928 - n += cpy(buf + n, len - n, " {\n", 3); 1929 - n += cpy(buf + n, len - n, " [Uint8Contents]: <", 20); 1930 + n += cpy(buf + n, REMAIN(n, len), tag_str, tlen); 1931 + n += cpy(buf + n, REMAIN(n, len), " {\n", 3); 1932 + n += cpy(buf + n, REMAIN(n, len), " [Uint8Contents]: <", 20); 1930 1933 1931 1934 if (ab_data && ab_data->data && bytelen > 0) { 1932 1935 for (size_t i = 0; i < bytelen; i++) { 1933 - if (i > 0) n += cpy(buf + n, len - n, " ", 1); 1934 - n += (size_t) snprintf(buf + n, len - n, "%02x", ab_data->data[i]); 1936 + if (i > 0) n += cpy(buf + n, REMAIN(n, len), " ", 1); 1937 + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%02x", ab_data->data[i]); 1935 1938 } 1936 1939 } 1937 1940 1938 - n += cpy(buf + n, len - n, ">,\n", 3); 1939 - n += cpy(buf + n, len - n, " [byteLength]: ", 16); 1940 - n += (size_t) snprintf(buf + n, len - n, "%zu", bytelen); 1941 - n += cpy(buf + n, len - n, "\n}", 2); 1941 + n += cpy(buf + n, REMAIN(n, len), ">,\n", 3); 1942 + n += cpy(buf + n, REMAIN(n, len), " [byteLength]: ", 16); 1943 + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%zu", bytelen); 1944 + n += cpy(buf + n, REMAIN(n, len), "\n}", 2); 1942 1945 pop_stringify(); 1943 1946 return n; 1944 1947 } ··· 1950 1953 if (js_type(dv_data_val) == JS_NUM) { 1951 1954 DataViewData *dv = (DataViewData *)(uintptr_t)tod(dv_data_val); 1952 1955 if (dv && dv->buffer) { 1953 - n += cpy(buf + n, len - n, "DataView {\n", 11); 1954 - n += cpy(buf + n, len - n, " [byteLength]: ", 16); 1955 - n += (size_t) snprintf(buf + n, len - n, "%zu", dv->byte_length); 1956 - n += cpy(buf + n, len - n, ",\n", 2); 1957 - n += cpy(buf + n, len - n, " [byteOffset]: ", 16); 1958 - n += (size_t) snprintf(buf + n, len - n, "%zu", dv->byte_offset); 1959 - n += cpy(buf + n, len - n, ",\n", 2); 1960 - n += cpy(buf + n, len - n, " [buffer]: ArrayBuffer {\n", 26); 1961 - n += cpy(buf + n, len - n, " [Uint8Contents]: <", 22); 1956 + n += cpy(buf + n, REMAIN(n, len), "DataView {\n", 11); 1957 + n += cpy(buf + n, REMAIN(n, len), " [byteLength]: ", 16); 1958 + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%zu", dv->byte_length); 1959 + n += cpy(buf + n, REMAIN(n, len), ",\n", 2); 1960 + n += cpy(buf + n, REMAIN(n, len), " [byteOffset]: ", 16); 1961 + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%zu", dv->byte_offset); 1962 + n += cpy(buf + n, REMAIN(n, len), ",\n", 2); 1963 + n += cpy(buf + n, REMAIN(n, len), " [buffer]: ArrayBuffer {\n", 26); 1964 + n += cpy(buf + n, REMAIN(n, len), " [Uint8Contents]: <", 22); 1962 1965 1963 1966 if (dv->buffer->data && dv->buffer->length > 0) { 1964 1967 for (size_t i = 0; i < dv->buffer->length; i++) { 1965 - if (i > 0) n += cpy(buf + n, len - n, " ", 1); 1966 - n += (size_t) snprintf(buf + n, len - n, "%02x", dv->buffer->data[i]); 1968 + if (i > 0) n += cpy(buf + n, REMAIN(n, len), " ", 1); 1969 + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%02x", dv->buffer->data[i]); 1967 1970 } 1968 1971 } 1969 1972 1970 - n += cpy(buf + n, len - n, ">,\n", 3); 1971 - n += cpy(buf + n, len - n, " [byteLength]: ", 18); 1972 - n += (size_t) snprintf(buf + n, len - n, "%zu", dv->buffer->length); 1973 - n += cpy(buf + n, len - n, "\n }\n}", 6); 1973 + n += cpy(buf + n, REMAIN(n, len), ">,\n", 3); 1974 + n += cpy(buf + n, REMAIN(n, len), " [byteLength]: ", 18); 1975 + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%zu", dv->buffer->length); 1976 + n += cpy(buf + n, REMAIN(n, len), "\n }\n}", 6); 1974 1977 pop_stringify(); 1975 1978 return n; 1976 1979 } ··· 1982 1985 if (vtype(map_val) == T_UNDEF) goto print_tagged_object; 1983 1986 1984 1987 map_entry_t **map_ptr = (map_entry_t**)(size_t)tod(map_val); 1985 - n += cpy(buf + n, len - n, "Map(", 4); 1988 + n += cpy(buf + n, REMAIN(n, len), "Map(", 4); 1986 1989 1987 1990 unsigned int count = 0; 1988 1991 if (map_ptr && *map_ptr) count = HASH_COUNT(*map_ptr); 1989 - n += (size_t) snprintf(buf + n, len - n, "%u", count); 1990 - n += cpy(buf + n, len - n, ") ", 2); 1992 + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%u", count); 1993 + n += cpy(buf + n, REMAIN(n, len), ") ", 2); 1991 1994 1992 1995 if (count == 0) { 1993 - n += cpy(buf + n, len - n, "{}", 2); 1996 + n += cpy(buf + n, REMAIN(n, len), "{}", 2); 1994 1997 } else { 1995 - n += cpy(buf + n, len - n, "{\n", 2); 1998 + n += cpy(buf + n, REMAIN(n, len), "{\n", 2); 1996 1999 stringify_indent++; 1997 2000 bool first = true; 1998 2001 if (map_ptr && *map_ptr) { 1999 2002 map_entry_t *entry, *tmp; 2000 2003 HASH_ITER(hh, *map_ptr, entry, tmp) { 2001 - if (!first) n += cpy(buf + n, len - n, ",\n", 2); 2004 + if (!first) n += cpy(buf + n, REMAIN(n, len), ",\n", 2); 2002 2005 first = false; 2003 - n += add_indent(buf + n, len - n, stringify_indent); 2006 + n += add_indent(buf + n, REMAIN(n, len), stringify_indent); 2004 2007 2005 2008 size_t key_len = strlen(entry->key); 2006 - n += cpy(buf + n, len - n, "'", 1); 2007 - n += cpy(buf + n, len - n, entry->key, key_len); 2008 - n += cpy(buf + n, len - n, "'", 1); 2009 - n += cpy(buf + n, len - n, " => ", 4); 2010 - n += tostr(js, entry->value, buf + n, len - n); 2009 + n += cpy(buf + n, REMAIN(n, len), "'", 1); 2010 + n += cpy(buf + n, REMAIN(n, len), entry->key, key_len); 2011 + n += cpy(buf + n, REMAIN(n, len), "'", 1); 2012 + n += cpy(buf + n, REMAIN(n, len), " => ", 4); 2013 + n += tostr(js, entry->value, buf + n, REMAIN(n, len)); 2011 2014 } 2012 2015 } 2013 2016 stringify_indent--; 2014 - n += cpy(buf + n, len - n, "\n", 1); 2015 - n += add_indent(buf + n, len - n, stringify_indent); 2016 - n += cpy(buf + n, len - n, "}", 1); 2017 + n += cpy(buf + n, REMAIN(n, len), "\n", 1); 2018 + n += add_indent(buf + n, REMAIN(n, len), stringify_indent); 2019 + n += cpy(buf + n, REMAIN(n, len), "}", 1); 2017 2020 } 2018 2021 pop_stringify(); 2019 2022 return n; ··· 2024 2027 if (vtype(set_val) == T_UNDEF) goto print_tagged_object; 2025 2028 2026 2029 set_entry_t **set_ptr = (set_entry_t**)(size_t)tod(set_val); 2027 - n += cpy(buf + n, len - n, "Set(", 4); 2030 + n += cpy(buf + n, REMAIN(n, len), "Set(", 4); 2028 2031 2029 2032 unsigned int count = 0; 2030 2033 if (set_ptr && *set_ptr) count = HASH_COUNT(*set_ptr); 2031 - n += (size_t) snprintf(buf + n, len - n, "%u", count); 2032 - n += cpy(buf + n, len - n, ") ", 2); 2034 + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%u", count); 2035 + n += cpy(buf + n, REMAIN(n, len), ") ", 2); 2033 2036 2034 2037 if (count == 0) { 2035 - n += cpy(buf + n, len - n, "{}", 2); 2038 + n += cpy(buf + n, REMAIN(n, len), "{}", 2); 2036 2039 } else { 2037 - n += cpy(buf + n, len - n, "{\n", 2); 2040 + n += cpy(buf + n, REMAIN(n, len), "{\n", 2); 2038 2041 stringify_indent++; 2039 2042 bool first = true; 2040 2043 if (set_ptr && *set_ptr) { 2041 2044 set_entry_t *entry, *tmp; 2042 2045 HASH_ITER(hh, *set_ptr, entry, tmp) { 2043 - if (!first) n += cpy(buf + n, len - n, ",\n", 2); 2046 + if (!first) n += cpy(buf + n, REMAIN(n, len), ",\n", 2); 2044 2047 first = false; 2045 - n += add_indent(buf + n, len - n, stringify_indent); 2046 - n += tostr(js, entry->value, buf + n, len - n); 2048 + n += add_indent(buf + n, REMAIN(n, len), stringify_indent); 2049 + n += tostr(js, entry->value, buf + n, REMAIN(n, len)); 2047 2050 } 2048 2051 } 2049 2052 stringify_indent--; 2050 - n += cpy(buf + n, len - n, "\n", 1); 2051 - n += add_indent(buf + n, len - n, stringify_indent); 2052 - n += cpy(buf + n, len - n, "}", 1); 2053 + n += cpy(buf + n, REMAIN(n, len), "\n", 1); 2054 + n += add_indent(buf + n, REMAIN(n, len), stringify_indent); 2055 + n += cpy(buf + n, REMAIN(n, len), "}", 1); 2053 2056 } 2054 2057 pop_stringify(); 2055 2058 return n; 2056 2059 } 2057 2060 2058 2061 print_tagged_object: 2059 - n += cpy(buf + n, len - n, "Object [", 8); 2060 - n += cpy(buf + n, len - n, (const char *) &js->mem[toff], tlen); 2061 - n += cpy(buf + n, len - n, "] {\n", 4); 2062 + n += cpy(buf + n, REMAIN(n, len), "Object [", 8); 2063 + n += cpy(buf + n, REMAIN(n, len), (const char *) &js->mem[toff], tlen); 2064 + n += cpy(buf + n, REMAIN(n, len), "] {\n", 4); 2062 2065 goto continue_object_print; 2063 2066 2064 2067 print_plain_object: ··· 2085 2088 2086 2089 if (prop_count == 0) { 2087 2090 if (is_null_proto) { 2088 - n += cpy(buf + n, len - n, "[Object: null prototype] {}", 27); 2091 + n += cpy(buf + n, REMAIN(n, len), "[Object: null prototype] {}", 27); 2089 2092 } else if (class_name && class_name_len > 0) { 2090 - n += cpy(buf + n, len - n, class_name, class_name_len); 2093 + n += cpy(buf + n, REMAIN(n, len), class_name, class_name_len); 2091 2094 if (proto_is_null_proto) { 2092 - n += cpy(buf + n, len - n, " <[Object: null prototype] {}> {}", 33); 2093 - } else n += cpy(buf + n, len - n, " {}", 3); 2095 + n += cpy(buf + n, REMAIN(n, len), " <[Object: null prototype] {}> {}", 33); 2096 + } else n += cpy(buf + n, REMAIN(n, len), " {}", 3); 2094 2097 } else if (proto_is_null_proto) { 2095 - n += cpy(buf + n, len - n, "<[Object: null prototype] {}> {}", 32); 2096 - } else n += cpy(buf + n, len - n, "{}", 2); 2098 + n += cpy(buf + n, REMAIN(n, len), "<[Object: null prototype] {}> {}", 32); 2099 + } else n += cpy(buf + n, REMAIN(n, len), "{}", 2); 2097 2100 pop_stringify(); 2098 2101 return n; 2099 2102 } 2100 2103 2101 2104 if (is_null_proto) { 2102 - n += cpy(buf + n, len - n, "[Object: null prototype] ", 25); 2105 + n += cpy(buf + n, REMAIN(n, len), "[Object: null prototype] ", 25); 2103 2106 } else if (class_name && class_name_len > 0) { 2104 - n += cpy(buf + n, len - n, class_name, class_name_len); 2107 + n += cpy(buf + n, REMAIN(n, len), class_name, class_name_len); 2105 2108 if (proto_is_null_proto) { 2106 - n += cpy(buf + n, len - n, " <[Object: null prototype] {}> ", 31); 2107 - } else n += cpy(buf + n, len - n, " ", 1); 2109 + n += cpy(buf + n, REMAIN(n, len), " <[Object: null prototype] {}> ", 31); 2110 + } else n += cpy(buf + n, REMAIN(n, len), " ", 1); 2108 2111 } else if (proto_is_null_proto) { 2109 - n += cpy(buf + n, len - n, "<[Object: null prototype] {}> ", 30); 2112 + n += cpy(buf + n, REMAIN(n, len), "<[Object: null prototype] {}> ", 30); 2110 2113 } 2111 2114 2112 - n += cpy(buf + n, len - n, inline_mode ? "{ " : "{\n", 2); 2115 + n += cpy(buf + n, REMAIN(n, len), inline_mode ? "{ " : "{\n", 2); 2113 2116 2114 2117 continue_object_print:; 2115 2118 ··· 2156 2159 const char *key = (char *) &js->mem[koff + sizeof(koff)]; 2157 2160 jsval_t val = loadval(js, prop + (jsoff_t) (sizeof(prop) + sizeof(koff))); 2158 2161 2159 - if (!first) n += cpy(buf + n, len - n, inline_mode ? ", " : ",\n", 2); 2162 + if (!first) n += cpy(buf + n, REMAIN(n, len), inline_mode ? ", " : ",\n", 2); 2160 2163 first = false; 2161 - if (!inline_mode) n += add_indent(buf + n, len - n, stringify_indent); 2164 + if (!inline_mode) n += add_indent(buf + n, REMAIN(n, len), stringify_indent); 2162 2165 2163 2166 bool is_special_global = false; 2164 2167 if (vtype(val) == T_UNDEF && streq(key, klen, "undefined", 9)) { ··· 2171 2174 } 2172 2175 2173 2176 if (is_special_global) { 2174 - n += tostr(js, val, buf + n, len - n); 2177 + n += tostr(js, val, buf + n, REMAIN(n, len)); 2175 2178 } else { 2176 - n += strkey(js, mkval(T_STR, koff), buf + n, len - n); 2177 - n += cpy(buf + n, len - n, ": ", 2); 2178 - n += tostr(js, val, buf + n, len - n); 2179 + n += strkey(js, mkval(T_STR, koff), buf + n, REMAIN(n, len)); 2180 + n += cpy(buf + n, REMAIN(n, len), ": ", 2); 2181 + n += tostr(js, val, buf + n, REMAIN(n, len)); 2179 2182 } 2180 2183 } 2181 2184 free(prop_offsets); ··· 2186 2189 if (!desc->enumerable) continue; 2187 2190 if (!desc->has_getter && !desc->has_setter) continue; 2188 2191 2189 - if (!first) n += cpy(buf + n, len - n, inline_mode ? ", " : ",\n", 2); 2192 + if (!first) n += cpy(buf + n, REMAIN(n, len), inline_mode ? ", " : ",\n", 2); 2190 2193 first = false; 2191 - if (!inline_mode) n += add_indent(buf + n, len - n, stringify_indent); 2192 - n += cpy(buf + n, len - n, desc->prop_name, desc->prop_len); 2193 - n += cpy(buf + n, len - n, ": ", 2); 2194 + if (!inline_mode) n += add_indent(buf + n, REMAIN(n, len), stringify_indent); 2195 + n += cpy(buf + n, REMAIN(n, len), desc->prop_name, desc->prop_len); 2196 + n += cpy(buf + n, REMAIN(n, len), ": ", 2); 2194 2197 2195 2198 if (desc->has_getter && desc->has_setter) { 2196 - n += cpy(buf + n, len - n, "[Getter/Setter]", 15); 2199 + n += cpy(buf + n, REMAIN(n, len), "[Getter/Setter]", 15); 2197 2200 } else if (desc->has_getter) { 2198 - n += cpy(buf + n, len - n, "[Getter]", 8); 2199 - } else n += cpy(buf + n, len - n, "[Setter]", 8); 2201 + n += cpy(buf + n, REMAIN(n, len), "[Getter]", 8); 2202 + } else n += cpy(buf + n, REMAIN(n, len), "[Setter]", 8); 2200 2203 } 2201 2204 2202 2205 if (!inline_mode) stringify_indent--; 2203 2206 if (inline_mode) { 2204 - n += cpy(buf + n, len - n, " }", 2); 2207 + n += cpy(buf + n, REMAIN(n, len), " }", 2); 2205 2208 } else { 2206 - if (!first) n += cpy(buf + n, len - n, "\n", 1); 2207 - n += add_indent(buf + n, len - n, stringify_indent); 2208 - n += cpy(buf + n, len - n, "}", 1); 2209 + if (!first) n += cpy(buf + n, REMAIN(n, len), "\n", 1); 2210 + n += add_indent(buf + n, REMAIN(n, len), stringify_indent); 2211 + n += cpy(buf + n, REMAIN(n, len), "}", 1); 2209 2212 } 2210 2213 pop_stringify(); 2211 2214 return n; ··· 2246 2249 double iv; 2247 2250 double frac = modf(adv, &iv); 2248 2251 if (frac == 0.0 && adv < 9007199254740992.0) { 2249 - return (size_t) snprintf(buf, len, "%.0f", dv); 2252 + int result = snprintf(temp, sizeof(temp), "%.0f", dv); 2253 + fix_exponent(temp, (size_t)result); 2254 + return cpy(buf, len, temp, strlen(temp)); 2250 2255 } 2251 2256 2252 2257 for (int prec = 1; prec <= 17; prec++) { 2253 2258 int n = snprintf(temp, sizeof(temp), "%.*g", prec, dv); 2254 2259 double parsed = strtod(temp, NULL); 2255 2260 if (parsed == dv) { 2256 - size_t result = (size_t)snprintf(buf, len, "%s", temp); 2257 - return fix_exponent(buf, result); 2261 + fix_exponent(temp, (size_t)n); 2262 + return cpy(buf, len, temp, strlen(temp)); 2258 2263 } 2259 2264 (void)n; 2260 2265 } 2261 2266 2262 - size_t result = (size_t)snprintf(buf, len, "%.17g", dv); 2263 - return fix_exponent(buf, result); 2267 + int result = snprintf(temp, sizeof(temp), "%.17g", dv); 2268 + fix_exponent(temp, (size_t)result); 2269 + return cpy(buf, len, temp, strlen(temp)); 2264 2270 } 2265 2271 2266 2272 static jsoff_t vstr(struct js *js, jsval_t value, jsoff_t *len) { ··· 2273 2279 jsoff_t slen, off = vstr(js, value, &slen); 2274 2280 const char *str = (const char *) &js->mem[off]; 2275 2281 size_t n = 0; 2276 - n += cpy(buf + n, len - n, "'", 1); 2282 + n += cpy(buf + n, REMAIN(n, len), "'", 1); 2277 2283 for (jsoff_t i = 0; i < slen && n < len - 1; i++) { 2278 2284 char c = str[i]; 2279 - if (c == '\n') { n += cpy(buf + n, len - n, "\\n", 2); } 2280 - else if (c == '\r') { n += cpy(buf + n, len - n, "\\r", 2); } 2281 - else if (c == '\t') { n += cpy(buf + n, len - n, "\\t", 2); } 2282 - else if (c == '\\') { n += cpy(buf + n, len - n, "\\\\", 2); } 2283 - else if (c == '\'') { n += cpy(buf + n, len - n, "\\'", 2); } 2285 + if (c == '\n') { n += cpy(buf + n, REMAIN(n, len), "\\n", 2); } 2286 + else if (c == '\r') { n += cpy(buf + n, REMAIN(n, len), "\\r", 2); } 2287 + else if (c == '\t') { n += cpy(buf + n, REMAIN(n, len), "\\t", 2); } 2288 + else if (c == '\\') { n += cpy(buf + n, REMAIN(n, len), "\\\\", 2); } 2289 + else if (c == '\'') { n += cpy(buf + n, REMAIN(n, len), "\\'", 2); } 2284 2290 else { if (n < len) buf[n++] = c; } 2285 2291 } 2286 - n += cpy(buf + n, len - n, "'", 1); 2292 + n += cpy(buf + n, REMAIN(n, len), "'", 1); 2287 2293 2288 2294 return n; 2289 2295 } ··· 2347 2353 if (vtype(builtin_slot) == T_NUM) { 2348 2354 if (name && name_len > 0) { 2349 2355 size_t n = cpy(buf, len, fmt->prefix, fmt->prefix_len); 2350 - n += cpy(buf + n, len - n, name, name_len); 2351 - n += cpy(buf + n, len - n, "]", 1); 2356 + n += cpy(buf + n, REMAIN(n, len), name, name_len); 2357 + n += cpy(buf + n, REMAIN(n, len), "]", 1); 2352 2358 return n; 2353 2359 } 2354 2360 return cpy(buf, len, fmt->anon, fmt->anon_len); ··· 2361 2367 2362 2368 if (name && name_len > 0) { 2363 2369 n = cpy(buf, len, fmt->prefix, fmt->prefix_len); 2364 - n += cpy(buf + n, len - n, name, name_len); 2365 - n += cpy(buf + n, len - n, "]", 1); 2370 + n += cpy(buf + n, REMAIN(n, len), name, name_len); 2371 + n += cpy(buf + n, REMAIN(n, len), "]", 1); 2366 2372 } else { 2367 2373 n = cpy(buf, len, fmt->anon, fmt->anon_len); 2368 2374 } ··· 2383 2389 jsoff_t ctor_name_len = 0; 2384 2390 const char *ctor_name = get_func_name(js, ctor, &ctor_name_len); 2385 2391 if (ctor_name && ctor_name_len > 0) { 2386 - n += cpy(buf + n, len - n, " ", 1); 2387 - n += cpy(buf + n, len - n, ctor_name, ctor_name_len); 2392 + n += cpy(buf + n, REMAIN(n, len), " ", 1); 2393 + n += cpy(buf + n, REMAIN(n, len), ctor_name, ctor_name_len); 2388 2394 } 2389 2395 return n; 2390 2396 } 2391 2397 2392 2398 if (name && name_len > 0) { 2393 2399 size_t n = cpy(buf, len, fmt->prefix, fmt->prefix_len); 2394 - n += cpy(buf + n, len - n, name, name_len); 2395 - n += cpy(buf + n, len - n, "]", 1); 2400 + n += cpy(buf + n, REMAIN(n, len), name, name_len); 2401 + n += cpy(buf + n, REMAIN(n, len), "]", 1); 2396 2402 return n; 2397 2403 } 2398 2404 ··· 2408 2414 } 2409 2415 2410 2416 static void get_error_line(const char *code, jsoff_t clen, jsoff_t pos, char *buf, size_t bufsize, int *line_start_col) { 2417 + if (!code || bufsize == 0) { 2418 + if (bufsize > 0) buf[0] = '\0'; 2419 + if (line_start_col) *line_start_col = 1; 2420 + return; 2421 + } 2422 + 2423 + if (pos > clen) pos = clen; 2424 + 2425 + if (clen == 0) { 2426 + buf[0] = '\0'; 2427 + if (line_start_col) *line_start_col = 1; 2428 + return; 2429 + } 2430 + 2411 2431 jsoff_t line_start = pos; 2412 2432 while (line_start > 0 && code[line_start - 1] != '\n') { 2413 2433 line_start--; ··· 3110 3130 size_t dlen; 3111 3131 const char *digits = bigint_digits(js, value, &dlen); 3112 3132 size_t n = 0; 3113 - if (neg) n += cpy(buf + n, len - n, "-", 1); 3114 - n += cpy(buf + n, len - n, digits, dlen); 3133 + if (neg) n += cpy(buf + n, REMAIN(n, len), "-", 1); 3134 + n += cpy(buf + n, REMAIN(n, len), digits, dlen); 3115 3135 return n; 3116 3136 } 3117 3137