Page MenuHomePhorge

property.h
No OneTemporary

Size
8 KB
Referenced Files
None
Subscribers
None

property.h

#ifndef SV_PROPERTY_H
#define SV_PROPERTY_H
#include "silver/engine.h"
#include "utf8.h"
#include <math.h>
#include <stdlib.h>
static inline jsval_t sv_getprop_fallback_len(
ant_t *js, jsval_t obj,
const char *key, jsoff_t key_len
) {
char small[64];
char *tmp = small;
if (key_len + 1 > (jsoff_t)sizeof(small)) {
tmp = malloc((size_t)key_len + 1);
if (!tmp) return js_mkerr(js, "out of memory");
}
memcpy(tmp, key, (size_t)key_len);
tmp[key_len] = '\0';
jsval_t out = js_getprop_fallback(js, obj, tmp);
if (tmp != small) free(tmp);
return out;
}
static inline jsval_t sv_key_to_propstr(ant_t *js, jsval_t key) {
return coerce_to_str(js, key);
}
static inline jsval_t sv_getprop_by_key(ant_t *js, jsval_t obj, jsval_t key) {
if (vtype(key) == T_SYMBOL) return js_get_sym(js, obj, key);
jsval_t key_str = sv_key_to_propstr(js, key);
if (is_err(key_str) || vtype(key_str) != T_STR) return js_mkundef();
jsoff_t klen = 0;
jsoff_t koff = vstr(js, key_str, &klen);
const char *kptr = (const char *)&js->mem[koff];
return sv_getprop_fallback_len(js, obj, kptr, klen);
}
static inline jsval_t sv_prop_get_at(
ant_t *js, jsval_t obj, const char *str, uint32_t len,
sv_func_t *func, uint8_t *ip
) {
uint8_t t = vtype(obj);
if (t == T_NULL || t == T_UNDEF) {
if (func && ip) js_set_error_site_from_bc(js, func, (int)(ip - func->code), func->filename);
return js_mkerr_typed(js, JS_ERR_TYPE,
"Cannot read properties of %s (reading '%.*s')",
t == T_NULL ? "null" : "undefined", (int)len, str);
}
jsval_t str_prim = js_mkundef();
jsval_t sym_prim = js_mkundef();
if (t == T_STR) {
str_prim = obj;
} else if (t == T_SYMBOL) {
sym_prim = obj;
} else if (t == T_OBJ) {
jsval_t prim = js_get_slot(js, obj, SLOT_PRIMITIVE);
if (vtype(prim) == T_STR) str_prim = prim;
else if (vtype(prim) == T_SYMBOL) sym_prim = prim;
}
if (vtype(str_prim) == T_STR && len == 6 && memcmp(str, "length", 6) == 0) {
jsoff_t byte_len = 0;
jsoff_t str_off = vstr(js, str_prim, &byte_len);
const char *str_data = (const char *)&js->mem[str_off];
return tov((double)utf16_strlen(str_data, byte_len));
}
if (vtype(sym_prim) == T_SYMBOL && len == 11 &&
memcmp(str, "description", 11) == 0) {
const char *desc = js_sym_desc(js, sym_prim);
if (desc) return js_mkstr(js, desc, strlen(desc));
return js_mkundef();
}
return sv_getprop_fallback_len(js, obj, str, (jsoff_t)len);
}
static inline jsval_t sv_prop_get(ant_t *js, jsval_t obj, const char *str, uint32_t len) {
return sv_prop_get_at(js, obj, str, len, NULL, NULL);
}
static inline bool sv_parse_string_index_key(ant_t *js, jsval_t key, size_t *out_idx) {
if (vtype(key) == T_NUM) {
double d = tod(key);
if (!isfinite(d) || d < 0.0) return false;
double di = floor(d);
if (di != d || di > (double)SIZE_MAX) return false;
*out_idx = (size_t)di;
return true;
}
if (vtype(key) != T_STR) return false;
jsoff_t klen = 0;
jsoff_t koff = vstr(js, key, &klen);
const char *k = (const char *)&js->mem[koff];
if (klen == 0) return false;
if (klen > 1 && k[0] == '0') return false;
size_t idx = 0;
for (jsoff_t i = 0; i < klen; i++) {
if (k[i] < '0' || k[i] > '9') return false;
size_t digit = (size_t)(k[i] - '0');
if (idx > (SIZE_MAX - digit) / 10) return false;
idx = idx * 10 + digit;
}
*out_idx = idx;
return true;
}
static inline bool sv_try_string_index_get(ant_t *js, jsval_t obj, jsval_t key, jsval_t *out) {
jsval_t str = obj;
if (vtype(obj) == T_OBJ) {
jsval_t prim = js_get_slot(js, obj, SLOT_PRIMITIVE);
if (vtype(prim) == T_STR) str = prim;
}
if (vtype(str) != T_STR) return false;
size_t idx = 0;
if (!sv_parse_string_index_key(js, key, &idx)) return false;
jsoff_t byte_len = 0;
jsoff_t str_off = vstr(js, str, &byte_len);
const char *str_data = (const char *)&js->mem[str_off];
size_t char_bytes = 0;
int byte_offset = utf16_index_to_byte_offset(str_data, byte_len, idx, &char_bytes);
if (byte_offset < 0 || char_bytes == 0) {
*out = js_mkundef();
return true;
}
*out = js_mkstr(js, str_data + byte_offset, char_bytes);
return true;
}
static inline jsval_t sv_op_get_field(
sv_vm_t *vm, ant_t *js,
sv_func_t *func, uint8_t *ip
) {
uint32_t idx = sv_get_u32(ip + 1);
sv_atom_t *a = &func->atoms[idx];
jsval_t obj = vm->stack[--vm->sp];
jsval_t res = sv_prop_get_at(js, obj, a->str, a->len, func, ip);
if (is_err(res)) return res;
vm->stack[vm->sp++] = res;
return js_mkundef();
}
static inline jsval_t sv_op_get_field2(
sv_vm_t *vm, ant_t *js,
sv_func_t *func, uint8_t *ip
) {
uint32_t idx = sv_get_u32(ip + 1);
sv_atom_t *a = &func->atoms[idx];
jsval_t obj = vm->stack[vm->sp - 1];
jsval_t res = sv_prop_get_at(js, obj, a->str, a->len, func, ip);
if (is_err(res)) return res;
vm->stack[vm->sp++] = res;
return js_mkundef();
}
static inline jsval_t sv_op_put_field(
sv_vm_t *vm, ant_t *js,
sv_func_t *func, uint8_t *ip
) {
uint32_t idx = sv_get_u32(ip + 1);
sv_atom_t *a = &func->atoms[idx];
jsval_t val = vm->stack[--vm->sp];
jsval_t obj = vm->stack[--vm->sp];
jsval_t key = js_mkstr(js, a->str, a->len);
return js_setprop(js, obj, key, val);
}
static inline jsval_t sv_op_get_elem(
sv_vm_t *vm, ant_t *js,
sv_func_t *func, uint8_t *ip
) {
jsval_t key = vm->stack[--vm->sp];
jsval_t obj = vm->stack[--vm->sp];
uint8_t ot = vtype(obj);
if (ot == T_NULL || ot == T_UNDEF) {
if (func && ip) js_set_error_site_from_bc(js, func, (int)(ip - func->code), func->filename);
return js_mkerr_typed(js, JS_ERR_TYPE,
"Cannot read properties of %s", ot == T_NULL ? "null" : "undefined");
}
if (vtype(obj) == T_ARR && vtype(key) == T_NUM) {
double d = tod(key);
if (d >= 0 && d == (uint32_t)d) {
vm->stack[vm->sp++] = js_arr_get(js, obj, (uint32_t)d);
return js_mkundef();
}
}
jsval_t str_elem = js_mkundef();
if (sv_try_string_index_get(js, obj, key, &str_elem)) {
vm->stack[vm->sp++] = str_elem;
return js_mkundef();
}
jsval_t res = sv_getprop_by_key(js, obj, key);
if (is_err(res)) return res;
vm->stack[vm->sp++] = res;
return js_mkundef();
}
static inline jsval_t sv_op_get_elem2(
sv_vm_t *vm, ant_t *js,
sv_func_t *func, uint8_t *ip
) {
jsval_t key = vm->stack[--vm->sp];
jsval_t obj = vm->stack[vm->sp - 1];
uint8_t ot = vtype(obj);
if (ot == T_NULL || ot == T_UNDEF) {
if (func && ip) js_set_error_site_from_bc(js, func, (int)(ip - func->code), func->filename);
return js_mkerr_typed(js, JS_ERR_TYPE,
"Cannot read properties of %s", ot == T_NULL ? "null" : "undefined");
}
if (vtype(obj) == T_ARR && vtype(key) == T_NUM) {
double d = tod(key);
if (d >= 0 && d == (uint32_t)d) {
vm->stack[vm->sp++] = js_arr_get(js, obj, (uint32_t)d);
return js_mkundef();
}
}
jsval_t str_elem = js_mkundef();
if (sv_try_string_index_get(js, obj, key, &str_elem)) {
vm->stack[vm->sp++] = str_elem;
return js_mkundef();
}
jsval_t res = sv_getprop_by_key(js, obj, key);
if (is_err(res)) return res;
vm->stack[vm->sp++] = res;
return js_mkundef();
}
static inline jsval_t sv_op_put_elem(sv_vm_t *vm, ant_t *js) {
jsval_t val = vm->stack[--vm->sp];
jsval_t key = vm->stack[--vm->sp];
jsval_t obj = vm->stack[--vm->sp];
if (vtype(key) == T_SYMBOL) return js_setprop(js, obj, key, val);
jsval_t key_jv = sv_key_to_propstr(js, key);
return js_setprop(js, obj, key_jv, val);
}
static inline void sv_op_define_field(
sv_vm_t *vm, ant_t *js,
sv_func_t *func, uint8_t *ip
) {
uint32_t idx = sv_get_u32(ip + 1);
sv_atom_t *a = &func->atoms[idx];
jsval_t val = vm->stack[--vm->sp];
jsval_t obj = vm->stack[vm->sp - 1];
js_define_own_prop(js, obj, a->str, a->len, val);
}
static inline jsval_t sv_op_get_length(sv_vm_t *vm, ant_t *js) {
jsval_t obj = vm->stack[--vm->sp];
if (vtype(obj) == T_ARR) {
vm->stack[vm->sp++] = tov((double)(uint32_t)js_arr_len(js, obj));
return js_mkundef();
}
if (vtype(obj) == T_STR) {
jsoff_t byte_len = 0;
jsoff_t off = vstr(js, obj, &byte_len);
const char *str_data = (const char *)&js->mem[off];
vm->stack[vm->sp++] = tov((double)(uint32_t)utf16_strlen(str_data, byte_len));
return js_mkundef();
}
jsval_t res = js_getprop_fallback(js, obj, "length");
if (is_err(res)) return res;
vm->stack[vm->sp++] = res;
return js_mkundef();
}
#endif

File Metadata

Mime Type
text/x-c
Expires
Thu, Mar 26, 4:48 PM (1 d, 18 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
512017
Default Alt Text
property.h (8 KB)

Event Timeline