Page MenuHomePhorge

symbol.c
No OneTemporary

Size
6 KB
Referenced Files
None
Subscribers
None

symbol.c

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "ant.h"
#include "runtime.h"
#include "modules/symbol.h"
#define MAX_REGISTRY 256
static struct {
char *key;
jsval_t symbol;
} g_symbol_registry[MAX_REGISTRY];
static int g_registry_count = 0;
static jsval_t g_iterator_sym = 0;
static jsval_t g_toStringTag_sym = 0;
static jsval_t g_hasInstance_sym = 0;
static char g_iter_sym_key[32] = {0};
static char g_toStringTag_sym_key[32] = {0};
jsval_t get_iterator_symbol(void) { return g_iterator_sym; }
const char *get_iterator_sym_key(void) { return g_iter_sym_key; }
const char *get_toStringTag_sym_key(void) { return g_toStringTag_sym_key; }
static jsval_t builtin_Symbol(struct js *js, jsval_t *args, int nargs) {
const char *desc = NULL;
if (nargs > 0 && js_type(args[0]) == JS_STR) {
desc = js_getstr(js, args[0], NULL);
}
return js_mksym(js, desc);
}
static jsval_t builtin_Symbol_for(struct js *js, jsval_t *args, int nargs) {
if (nargs < 1 || js_type(args[0]) != JS_STR) {
return js_mkerr(js, "Symbol.for requires a string argument");
}
char *key = js_getstr(js, args[0], NULL);
if (!key) return js_mkerr(js, "Invalid key");
for (int i = 0; i < g_registry_count; i++) {
if (g_symbol_registry[i].key && strcmp(g_symbol_registry[i].key, key) == 0) {
return g_symbol_registry[i].symbol;
}
}
if (g_registry_count >= MAX_REGISTRY) {
return js_mkerr(js, "Symbol registry full");
}
jsval_t sym = js_mksym(js, key);
g_symbol_registry[g_registry_count].key = strdup(key);
g_symbol_registry[g_registry_count].symbol = sym;
jsval_t sym_obj = js_mkobj(js);
js_set(js, sym_obj, "__sym_id", js_get(js, sym, "__sym_id"));
js_set(js, sym_obj, "description", js_get(js, sym, "description"));
js_set(js, sym_obj, "__registry_key", js_mkstr(js, key, strlen(key)));
g_symbol_registry[g_registry_count].symbol = sym;
g_registry_count++;
return sym;
}
static bool is_symbol_val(struct js *js, jsval_t v) {
if (js_type(v) != JS_OBJ) return false;
jsval_t marker = js_get(js, v, "__sym__");
return js_type(marker) == JS_TRUE;
}
static jsval_t builtin_Symbol_keyFor(struct js *js, jsval_t *args, int nargs) {
if (nargs < 1 || !is_symbol_val(js, args[0])) {
return js_mkundef();
}
jsval_t sym = args[0];
jsval_t sym_id = js_get(js, sym, "__sym_id");
for (int i = 0; i < g_registry_count; i++) {
jsval_t reg_id = js_get(js, g_symbol_registry[i].symbol, "__sym_id");
if (js_type(sym_id) == JS_NUM && js_type(reg_id) == JS_NUM &&
js_getnum(sym_id) == js_getnum(reg_id)) {
return js_mkstr(js, g_symbol_registry[i].key, strlen(g_symbol_registry[i].key));
}
}
return js_mkundef();
}
static jsval_t iterator_next(struct js *js, jsval_t *args, int nargs) {
(void)args; (void)nargs;
jsval_t this_val = js_getthis(js);
jsval_t arr = js_get(js, this_val, "__arr");
jsval_t idx_val = js_get(js, this_val, "__idx");
jsval_t len_val = js_get(js, this_val, "__len");
int idx = (int)js_getnum(idx_val);
int len = (int)js_getnum(len_val);
jsval_t result = js_mkobj(js);
if (idx >= len) {
js_set(js, result, "done", js_mktrue());
js_set(js, result, "value", js_mkundef());
} else {
char idxstr[16];
snprintf(idxstr, sizeof(idxstr), "%d", idx);
jsval_t value = js_get(js, arr, idxstr);
js_set(js, result, "value", value);
js_set(js, result, "done", js_mkfalse());
js_set(js, this_val, "__idx", js_mknum(idx + 1));
}
return result;
}
static jsval_t array_iterator(struct js *js, jsval_t *args, int nargs) {
(void)args; (void)nargs;
jsval_t arr = js_getthis(js);
jsval_t len_val = js_get(js, arr, "length");
int len = js_type(len_val) == JS_NUM ? (int)js_getnum(len_val) : 0;
jsval_t iter = js_mkobj(js);
js_set(js, iter, "__arr", arr);
js_set(js, iter, "__idx", js_mknum(0));
js_set(js, iter, "__len", js_mknum(len));
js_set(js, iter, "next", js_mkfun(iterator_next));
return iter;
}
static jsval_t string_iterator_next(struct js *js, jsval_t *args, int nargs) {
(void)args; (void)nargs;
jsval_t this_val = js_getthis(js);
jsval_t str = js_get(js, this_val, "__str");
jsval_t idx_val = js_get(js, this_val, "__idx");
jsval_t len_val = js_get(js, this_val, "__len");
int idx = (int)js_getnum(idx_val);
int len = (int)js_getnum(len_val);
jsval_t result = js_mkobj(js);
if (idx >= len) {
js_set(js, result, "done", js_mktrue());
js_set(js, result, "value", js_mkundef());
} else {
char *s = js_getstr(js, str, NULL);
char ch[2] = {s[idx], 0};
js_set(js, result, "value", js_mkstr(js, ch, 1));
js_set(js, result, "done", js_mkfalse());
js_set(js, this_val, "__idx", js_mknum(idx + 1));
}
return result;
}
static jsval_t string_iterator(struct js *js, jsval_t *args, int nargs) {
(void)args; (void)nargs;
jsval_t str = js_getthis(js);
size_t len;
js_getstr(js, str, &len);
jsval_t iter = js_mkobj(js);
js_set(js, iter, "__str", str);
js_set(js, iter, "__idx", js_mknum(0));
js_set(js, iter, "__len", js_mknum((double)len));
js_set(js, iter, "next", js_mkfun(string_iterator_next));
return iter;
}
void init_symbol_module(void) {
struct js *js = rt->js;
g_iterator_sym = js_mksym(js, "Symbol.iterator");
g_toStringTag_sym = js_mksym(js, "Symbol.toStringTag");
g_hasInstance_sym = js_mksym(js, "Symbol.hasInstance");
jsval_t iter_sym_id = js_get(js, g_iterator_sym, "__sym_id");
snprintf(g_iter_sym_key, sizeof(g_iter_sym_key), "__sym_%.0f__", js_getnum(iter_sym_id));
jsval_t tag_sym_id = js_get(js, g_toStringTag_sym, "__sym_id");
snprintf(g_toStringTag_sym_key, sizeof(g_toStringTag_sym_key), "__sym_%.0f__", js_getnum(tag_sym_id));
jsval_t symbol_ctor = js_mkobj(js);
js_set(js, symbol_ctor, "__native_func", js_mkfun(builtin_Symbol));
js_setprop(js, symbol_ctor, js_mkstr(js, "for", 3), js_mkfun(builtin_Symbol_for));
js_set(js, symbol_ctor, "keyFor", js_mkfun(builtin_Symbol_keyFor));
js_set(js, symbol_ctor, "iterator", g_iterator_sym);
js_set(js, symbol_ctor, "toStringTag", g_toStringTag_sym);
js_set(js, symbol_ctor, "hasInstance", g_hasInstance_sym);
jsval_t func_symbol = symbol_ctor;
*(uint64_t*)&func_symbol = (func_symbol & ~((uint64_t)0xF << 48)) | ((uint64_t)0x7 << 48);
js_set(js, js_glob(js), "Symbol", func_symbol);
jsval_t array_ctor = js_get(js, js_glob(js), "Array");
jsval_t array_proto = js_get(js, array_ctor, "prototype");
js_set(js, array_proto, g_iter_sym_key, js_mkfun(array_iterator));
jsval_t string_ctor = js_get(js, js_glob(js), "String");
jsval_t string_proto = js_get(js, string_ctor, "prototype");
js_set(js, string_proto, g_iter_sym_key, js_mkfun(string_iterator));
}

File Metadata

Mime Type
text/x-c
Expires
Sun, May 3, 8:02 AM (1 d, 21 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
523262
Default Alt Text
symbol.c (6 KB)

Event Timeline