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.

implement dynamic object keys accessor support for custom objects

+124 -14
+2
include/ant.h
··· 169 169 170 170 typedef jsval_t (*js_getter_fn)(ant_t *js, jsval_t obj, const char *key, size_t key_len); 171 171 typedef bool (*js_setter_fn)(ant_t *js, jsval_t obj, const char *key, size_t key_len, jsval_t value); 172 + typedef jsval_t (*js_keys_fn)(ant_t *js, jsval_t obj); 172 173 173 174 void js_set_getter(ant_t *js, jsval_t obj, js_getter_fn getter); 174 175 void js_set_setter(ant_t *js, jsval_t obj, js_setter_fn setter); 176 + void js_set_keys(ant_t *js, jsval_t obj, js_keys_fn keys); 175 177 176 178 void js_set_descriptor(ant_t *js, jsval_t obj, const char *key, size_t klen, int flags); 177 179 void js_set_getter_desc(ant_t *js, jsval_t obj, const char *key, size_t klen, jsval_t getter, int flags);
+79 -14
src/ant.c
··· 219 219 jsoff_t obj_offset; 220 220 js_getter_fn getter; 221 221 js_setter_fn setter; 222 + js_keys_fn keys; 222 223 UT_hash_handle hh; 223 224 } dynamic_accessors_t; 224 225 ··· 14053 14054 if (vtype(obj) != T_OBJ && vtype(obj) != T_ARR && vtype(obj) != T_FUNC) return mkarr(js); 14054 14055 if (vtype(obj) == T_FUNC) obj = mkval(T_OBJ, vdata(obj)); 14055 14056 14057 + jsoff_t obj_off = (jsoff_t)vdata(obj); 14058 + dynamic_accessors_t *acc = NULL; 14059 + HASH_FIND(hh, accessor_registry, &obj_off, sizeof(jsoff_t), acc); 14060 + if (acc && acc->keys) return acc->keys(js, obj); 14061 + 14056 14062 jsval_t arr = mkarr(js); 14057 14063 jsoff_t idx = 0; 14058 - 14059 - jsoff_t obj_off = (jsoff_t)vdata(obj); 14060 14064 jsoff_t next = loadoff(js, obj_off) & ~(3U | FLAGMASK); 14061 14065 14062 14066 while (next < js->brk && next != 0) { ··· 14107 14111 if (vtype(obj) != T_OBJ && vtype(obj) != T_ARR && vtype(obj) != T_FUNC) return mkarr(js); 14108 14112 if (vtype(obj) == T_FUNC) obj = mkval(T_OBJ, vdata(obj)); 14109 14113 14110 - jsval_t arr = mkarr(js); 14111 - jsoff_t idx = 0; 14112 - jsoff_t next = loadoff(js, (jsoff_t) vdata(obj)) & ~(3U | FLAGMASK); 14114 + jsoff_t obj_off = (jsoff_t)vdata(obj); 14115 + dynamic_accessors_t *acc = NULL; 14116 + HASH_FIND(hh, accessor_registry, &obj_off, sizeof(jsoff_t), acc); 14117 + if (acc && acc->keys && acc->getter) { 14118 + jsval_t keys_arr = acc->keys(js, obj); 14119 + jsval_t arr = mkarr(js); 14120 + jsoff_t len = get_array_length(js, keys_arr); 14121 + for (jsoff_t i = 0; i < len; i++) { 14122 + char idx_buf[16]; 14123 + size_t idx_len = uint_to_str(idx_buf, sizeof(idx_buf), (unsigned)i); 14124 + jsoff_t prop_off = lkp(js, keys_arr, idx_buf, idx_len); 14125 + if (!prop_off) continue; 14126 + jsval_t key_val = resolveprop(js, mkval(T_PROP, prop_off)); 14127 + if (vtype(key_val) != T_STR) continue; 14128 + jsoff_t klen; jsoff_t str_off = vstr(js, key_val, &klen); 14129 + const char *key = (const char *)&js->mem[str_off]; 14130 + jsval_t val = acc->getter(js, obj, key, klen); 14131 + js_arr_push(js, arr, val); 14132 + } 14133 + return mkval(T_ARR, vdata(arr)); 14134 + } 14135 + 14136 + jsval_t arr = mkarr(js); jsoff_t idx = 0; 14137 + jsoff_t next = loadoff(js, obj_off) & ~(3U | FLAGMASK); 14113 14138 14114 14139 while (next < js->brk && next != 0) { 14115 14140 jsoff_t header = loadoff(js, next); ··· 14124 14149 if (is_internal_prop(key, klen)) continue; 14125 14150 14126 14151 bool should_include = true; 14127 - jsoff_t obj_off = (jsoff_t)vdata(obj); 14128 14152 descriptor_entry_t *desc = lookup_descriptor(obj_off, key, klen); 14129 - if (desc) { 14130 - should_include = desc->enumerable; 14131 - } 14153 + if (desc) should_include = desc->enumerable; 14132 14154 14133 14155 if (should_include) { 14134 14156 char idxstr[16]; ··· 14151 14173 if (vtype(obj) != T_OBJ && vtype(obj) != T_ARR && vtype(obj) != T_FUNC) return mkarr(js); 14152 14174 if (vtype(obj) == T_FUNC) obj = mkval(T_OBJ, vdata(obj)); 14153 14175 14176 + jsoff_t obj_off = (jsoff_t)vdata(obj); 14177 + dynamic_accessors_t *acc = NULL; 14178 + HASH_FIND(hh, accessor_registry, &obj_off, sizeof(jsoff_t), acc); 14179 + if (acc && acc->keys && acc->getter) { 14180 + jsval_t keys_arr = acc->keys(js, obj); 14181 + jsval_t arr = mkarr(js); 14182 + jsoff_t len = get_array_length(js, keys_arr); 14183 + for (jsoff_t i = 0; i < len; i++) { 14184 + char idx_buf[16]; 14185 + size_t idx_len = uint_to_str(idx_buf, sizeof(idx_buf), (unsigned)i); 14186 + jsoff_t prop_off = lkp(js, keys_arr, idx_buf, idx_len); 14187 + if (!prop_off) continue; 14188 + jsval_t key_val = resolveprop(js, mkval(T_PROP, prop_off)); 14189 + if (vtype(key_val) != T_STR) continue; 14190 + jsoff_t klen; 14191 + jsoff_t str_off = vstr(js, key_val, &klen); 14192 + const char *key = (const char *)&js->mem[str_off]; 14193 + jsval_t val = acc->getter(js, obj, key, klen); 14194 + jsval_t pair = mkarr(js); 14195 + js_mkprop_fast(js, pair, "0", 1, key_val); 14196 + js_mkprop_fast(js, pair, "1", 1, val); 14197 + js_mkprop_fast(js, pair, "length", 6, tov(2.0)); 14198 + js_arr_push(js, arr, mkval(T_ARR, vdata(pair))); 14199 + } 14200 + return mkval(T_ARR, vdata(arr)); 14201 + } 14202 + 14154 14203 jsval_t arr = mkarr(js); 14155 14204 jsoff_t idx = 0; 14156 - jsoff_t next = loadoff(js, (jsoff_t) vdata(obj)) & ~(3U | FLAGMASK); 14205 + jsoff_t next = loadoff(js, obj_off) & ~(3U | FLAGMASK); 14157 14206 14158 14207 while (next < js->brk && next != 0) { 14159 14208 jsoff_t header = loadoff(js, next); ··· 14169 14218 if (is_internal_prop(key, klen)) continue; 14170 14219 14171 14220 bool should_include = true; 14172 - jsoff_t obj_off = (jsoff_t)vdata(obj); 14173 14221 descriptor_entry_t *desc = lookup_descriptor(obj_off, key, klen); 14174 - if (desc) { 14175 - should_include = desc->enumerable; 14176 - } 14222 + if (desc) should_include = desc->enumerable; 14177 14223 14178 14224 if (should_include) { 14179 14225 jsval_t pair = mkarr(js); ··· 22222 22268 entry->obj_offset = obj_off; 22223 22269 entry->getter = NULL; 22224 22270 entry->setter = NULL; 22271 + entry->keys = NULL; 22225 22272 HASH_ADD(hh, accessor_registry, obj_offset, sizeof(jsoff_t), entry); 22226 22273 } 22227 22274 entry->getter = getter; ··· 22238 22285 entry->obj_offset = obj_off; 22239 22286 entry->getter = NULL; 22240 22287 entry->setter = NULL; 22288 + entry->keys = NULL; 22241 22289 HASH_ADD(hh, accessor_registry, obj_offset, sizeof(jsoff_t), entry); 22242 22290 } 22243 22291 entry->setter = setter; 22292 + } 22293 + 22294 + void js_set_keys(struct js *js, jsval_t obj, js_keys_fn keys) { 22295 + if (vtype(obj) != T_OBJ) return; 22296 + jsoff_t obj_off = (jsoff_t)vdata(obj); 22297 + dynamic_accessors_t *entry = NULL; 22298 + HASH_FIND(hh, accessor_registry, &obj_off, sizeof(jsoff_t), entry); 22299 + if (!entry) { 22300 + entry = (dynamic_accessors_t *)malloc(sizeof(dynamic_accessors_t)); 22301 + if (!entry) return; 22302 + entry->obj_offset = obj_off; 22303 + entry->getter = NULL; 22304 + entry->setter = NULL; 22305 + entry->keys = NULL; 22306 + HASH_ADD(hh, accessor_registry, obj_offset, sizeof(jsoff_t), entry); 22307 + } 22308 + entry->keys = keys; 22244 22309 } 22245 22310 22246 22311 static inline uint64_t make_desc_key(jsoff_t obj_off, const char *key, size_t klen) {
+43
src/modules/process.c
··· 1363 1363 return obj; 1364 1364 } 1365 1365 1366 + static jsval_t env_toString(ant_t *js, jsval_t *args, int nargs) { 1367 + size_t buf_cap = 4096; 1368 + char *buf = malloc(buf_cap); 1369 + size_t pos = 0; 1370 + 1371 + for (char **env = environ; *env != NULL; env++) { 1372 + char *entry = *env; 1373 + size_t entry_len = strlen(entry); 1374 + 1375 + if (pos + entry_len + 2 >= buf_cap) { 1376 + buf_cap = buf_cap * 2 + entry_len; 1377 + buf = realloc(buf, buf_cap); 1378 + } 1379 + 1380 + if (pos > 0) buf[pos++] = '\n'; 1381 + memcpy(buf + pos, entry, entry_len); 1382 + pos += entry_len; 1383 + } 1384 + 1385 + buf[pos] = '\0'; 1386 + jsval_t ret = js_mkstr(js, buf, pos); 1387 + free(buf); return ret; 1388 + } 1389 + 1390 + static jsval_t env_keys(ant_t *js, jsval_t obj) { 1391 + jsval_t arr = js_mkarr(js); 1392 + 1393 + for (char **env = environ; *env != NULL; env++) { 1394 + char *entry = *env; 1395 + char *equals = strchr(entry, '='); 1396 + if (equals == NULL) continue; 1397 + 1398 + size_t key_len = (size_t)(equals - entry); 1399 + js_arr_push(js, arr, js_mkstr(js, entry, key_len)); 1400 + } 1401 + 1402 + return arr; 1403 + } 1404 + 1366 1405 static jsval_t process_cwd(ant_t *js, jsval_t *args, int nargs) { 1367 1406 char cwd[4096]; 1368 1407 if (getcwd(cwd, sizeof(cwd)) != NULL) { ··· 1569 1608 1570 1609 jsval_t env_obj = js_mkobj(js); 1571 1610 load_dotenv_file(js, env_obj); 1611 + 1572 1612 js_set_getter(js, env_obj, env_getter); 1613 + js_set_keys(js, env_obj, env_keys); 1614 + 1573 1615 js_set(js, env_obj, "toObject", js_mkfun(env_to_object)); 1616 + js_set(js, env_obj, "toString", js_mkfun(env_toString)); 1574 1617 js_set(js, process_obj, "env", env_obj); 1575 1618 1576 1619 jsval_t argv_arr = js_mkarr(js);