removal of old code

This commit is contained in:
2026-02-11 09:47:30 -06:00
parent b327e16463
commit a252412eca
5 changed files with 27 additions and 834 deletions

View File

@@ -4,7 +4,7 @@
JSC_CCALL(debug_stack_depth, return number2js(js,js_debugger_stack_depth(js)))
// Return a backtrace of the current call stack.
JSC_CCALL(debug_build_backtrace, return js_debugger_build_backtrace(js,NULL))
JSC_CCALL(debug_build_backtrace, return js_debugger_build_backtrace(js))
// Return the closure variables for a given function.
JSC_CCALL(debug_closure_vars, return js_debugger_closure_variables(js,argv[0]))
@@ -21,7 +21,7 @@ JSC_CCALL(debug_local_vars, return js_debugger_local_variables(js, js2number(js,
JSC_CCALL(debug_fn_info, return js_debugger_fn_info(js, argv[0]))
// Return an array of functions in the current backtrace.
JSC_CCALL(debug_backtrace_fns, return js_debugger_backtrace_fns(js,NULL))
JSC_CCALL(debug_backtrace_fns, return js_debugger_backtrace_fns(js))
static const JSCFunctionListEntry js_debug_funcs[] = {
MIST_FUNC_DEF(debug, stack_depth, 0),

View File

@@ -14,11 +14,11 @@ static void js_enet_host_finalizer(JSRuntime *rt, JSValue val)
if (host) enet_host_destroy(host);
}
static void js_enet_peer_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func)
{
ENetPeer *peer = JS_GetOpaque(val, enet_peer_class_id);
JS_MarkValue(rt, *(JSValue*)peer->data, mark_func);
}
//static void js_enet_peer_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func)
//{
// ENetPeer *peer = JS_GetOpaque(val, enet_peer_class_id);
// JS_MarkValue(rt, *(JSValue*)peer->data, mark_func);
//}
static void js_enet_peer_finalizer(JSRuntime *rt, JSValue val)
{
@@ -414,7 +414,7 @@ static JSClassDef enet_host = {
static JSClassDef enet_peer_class = {
"ENetPeer",
.finalizer = js_enet_peer_finalizer,
.gc_mark = js_enet_peer_mark
// .gc_mark = js_enet_peer_mark
};
JSValue js_enet_resolve_hostname(JSContext *js, JSValue self, int argc, JSValue *argv)

View File

@@ -361,70 +361,21 @@ typedef struct BuddyAllocator {
/* Forward declarations for buddy allocator functions */
static void buddy_destroy (BuddyAllocator *b);
/* controls a host of contexts, handing out memory and scheduling */
struct JSRuntime {
const char *rt_info;
size_t malloc_limit;
/* Buddy allocator for actor memory blocks */
BuddyAllocator buddy;
/* see JS_SetStripInfo() */
uint8_t strip_flags;
/* User data */
void *user_opaque;
};
struct JSClass {
const char *class_name;
JSClassFinalizer *finalizer;
JSClassGCMark *gc_mark;
uint32_t class_id; /* 0 means free entry */
};
#define JS_MODE_BACKTRACE_BARRIER \
(1 << 3) /* stop backtrace before this frame */
typedef struct JSStackFrame {
struct JSStackFrame *prev_frame; /* NULL if first stack frame */
JSValue cur_func; /* current function, JS_NULL if the frame is detached */
JSValue *arg_buf; /* arguments */
JSValue *var_buf; /* variables */
const uint8_t *cur_pc; /* only used in bytecode functions : PC of the
instruction after the call */
int arg_count;
int js_mode; /* not supported for C functions */
JSValue js_frame; /* GC-managed JSFrame (use JS_VALUE_GET_FRAME to access) */
JSValue *stack_buf; /* operand stack base (for GC scanning) */
JSValue **p_sp; /* pointer to current sp (for GC scanning) */
} JSStackFrame;
/* Heap-allocated VM frame for trampoline execution */
struct VMFrame {
struct JSFunctionBytecode *b; /* current function bytecode */
JSContext *ctx; /* execution context / realm */
const uint8_t *pc; /* program counter */
/* Offset-based storage (safe with realloc) */
int value_stack_base; /* base index into ctx->value_stack */
int sp_offset; /* sp offset from base */
int arg_buf_offset; /* arg buffer offset from base (or -1 if aliased) */
int var_buf_offset; /* var buffer offset from base */
/* Continuation info for return */
const uint8_t *ret_pc; /* where to resume in caller */
int ret_sp_offset; /* caller's sp before call (for cleanup) */
int call_argc; /* number of args to clean up */
int call_has_this; /* whether call had this (method call) */
JSValue cur_func; /* current function object */
JSValue this_obj; /* this binding */
int arg_count;
int js_mode;
int stack_size_allocated; /* total size allocated for this frame */
};
typedef struct JSFrameRegister {
objhdr_t hdr; // capacity in this is the total number of words of the object, including the 4 words of overhead and all slots
JSValue function; // JSFunction, function object being invoked
@@ -675,7 +626,7 @@ typedef struct JSFrame {
JSValue function; /* JSValue for GC safety (use JS_VALUE_GET_FUNCTION) */
JSValue caller; /* JSValue for GC safety (unused currently) */
uint32_t return_pc;
JSValue slots[]; /* args, captured, locals, temps */
JSValue slots[]; /* [this][args][captured][locals][temps] */
} JSFrame;
/* Execution state returned by vm_execute_frame */
@@ -957,31 +908,19 @@ struct JSContext {
int trace_type;
void *trace_data;
/* Trampoline VM stacks (per actor/context) */
struct VMFrame *frame_stack; /* array of frames */
int frame_stack_top; /* current frame index (-1 = empty) */
int frame_stack_capacity; /* allocated capacity */
JSValue *value_stack; /* array of JSValues for locals/operands */
int value_stack_top; /* current top index */
int value_stack_capacity; /* allocated capacity */
/* Register VM frame root (updated by GC when frame moves) */
JSValue reg_current_frame; /* current JSFrameRegister being executed */
uint32_t current_register_pc; /* PC at exception time */
/* Execution state (moved from JSRuntime — per-actor) */
JSValue current_exception;
struct JSStackFrame *current_stack_frame;
BOOL current_exception_is_uncatchable : 8;
BOOL in_out_of_memory : 8;
JSInterruptHandler *interrupt_handler;
void *interrupt_opaque;
JSValue current_exception;
/* Stack overflow protection */
size_t stack_size;
const uint8_t *stack_top;
const uint8_t *stack_limit;
// todo: want this, but should be a simple increment/decrement counter while frames are pushed
size_t stack_depth;
size_t stack_limit;
/* Parser state (for GC to scan cpool during parsing) */
struct JSFunctionDef *current_parse_fd;
@@ -1399,8 +1338,6 @@ static JSValue js_cell_text (JSContext *ctx, JSValue this_val, int argc, JSValue
static JSValue js_cell_push (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_pop (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_array_find (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_eval (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_mach_eval (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_stone (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_length (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_reverse (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);

View File

@@ -344,27 +344,10 @@ typedef JSValue JSCFunctionData (JSContext *ctx, JSValue this_val,
int argc, JSValue *argv, int magic,
JSValue *data);
typedef struct JSMallocState {
size_t malloc_count;
size_t malloc_size;
size_t malloc_limit;
void *opaque; /* user opaque */
} JSMallocState;
typedef struct JSMallocFunctions {
void *(*js_malloc) (JSMallocState *s, size_t size);
void (*js_free) (JSMallocState *s, void *ptr);
void *(*js_realloc) (JSMallocState *s, void *ptr, size_t size);
size_t (*js_malloc_usable_size) (const void *ptr);
} JSMallocFunctions;
typedef struct JSGCObjectHeader JSGCObjectHeader;
JSValue JS_Stone (JSContext *ctx, JSValue this_val);
JSRuntime *JS_NewRuntime (void);
/* info lifetime must exceed that of rt */
void JS_SetRuntimeInfo (JSRuntime *rt, const char *info);
void JS_SetMemoryLimit (JSRuntime *rt, size_t limit);
/* use 0 to disable maximum stack size check */
void JS_SetMaxStackSize (JSContext *ctx, size_t stack_size);
@@ -372,11 +355,6 @@ void JS_SetMaxStackSize (JSContext *ctx, size_t stack_size);
used to check stack overflow. */
void JS_UpdateStackTop (JSContext *ctx);
void JS_FreeRuntime (JSRuntime *rt);
void *JS_GetRuntimeOpaque (JSRuntime *rt);
void JS_SetRuntimeOpaque (JSRuntime *rt, void *opaque);
typedef void JS_MarkFunc (JSRuntime *rt, JSGCObjectHeader *gp);
/* JS_MarkValue is a no-op with copying GC (values are traced from roots) */
void JS_MarkValue (JSRuntime *rt, JSValue val, JS_MarkFunc *mark_func);
JS_BOOL JS_IsLiveObject (JSRuntime *rt, JSValue obj);
JSContext *JS_NewContext (JSRuntime *rt);
@@ -410,8 +388,6 @@ void JS_ComputeMemoryUsage (JSRuntime *rt, JSMemoryUsage *s);
void JS_DumpMemoryUsage (FILE *fp, const JSMemoryUsage *s, JSRuntime *rt);
typedef void JSClassFinalizer (JSRuntime *rt, JSValue val);
typedef void JSClassGCMark (JSRuntime *rt, JSValue val,
JS_MarkFunc *mark_func);
typedef JSValue JSClassCall (JSContext *ctx, JSValue func_obj,
JSValue this_val, int argc,
JSValue *argv, int flags);
@@ -419,8 +395,6 @@ typedef JSValue JSClassCall (JSContext *ctx, JSValue func_obj,
typedef struct JSClassDef {
const char *class_name;
JSClassFinalizer *finalizer;
JSClassGCMark *gc_mark;
/* if call != NULL, the object is a function */
JSClassCall *call;
} JSClassDef;
@@ -1046,12 +1020,12 @@ typedef void (*js_hook) (JSContext *, int type, js_debug *dbg, void *user);
void js_debug_sethook (JSContext *ctx, js_hook, int type, void *user);
uint32_t js_debugger_stack_depth (JSContext *ctx);
JSValue js_debugger_backtrace_fns (JSContext *ctx, const uint8_t *cur_pc);
JSValue js_debugger_backtrace_fns (JSContext *ctx);
JSValue js_debugger_closure_variables (JSContext *ctx, JSValue fn);
JSValue js_debugger_local_variables (JSContext *ctx, int stack_index);
void js_debugger_set_closure_variable (JSContext *js, JSValue fn,
JSValue var_name, JSValue val);
JSValue js_debugger_build_backtrace (JSContext *ctx, const uint8_t *cur_pc);
JSValue js_debugger_build_backtrace (JSContext *ctx);
JSValue js_debugger_fn_info (JSContext *ctx, JSValue fn);
JSValue js_debugger_fn_bytecode (JSContext *js, JSValue fn);
void *js_debugger_val_address (JSContext *js, JSValue val);

View File

@@ -250,13 +250,6 @@ void *js_realloc (JSContext *ctx, void *ptr, size_t size) {
return new_ptr;
}
void JS_MarkValue (JSRuntime *rt, JSValue val, JS_MarkFunc *mark_func) {
(void)rt;
(void)val;
(void)mark_func;
/* No-op with copying GC - values are discovered by tracing from roots */
}
JSValue intern_text_to_value (JSContext *ctx, const uint32_t *utf32, uint32_t len) {
/* Pack UTF-32 for hashing and comparison */
size_t word_count = (len + 1) / 2;
@@ -923,7 +916,6 @@ static int init_class_range (JSContext *ctx, JSClass const *tab, int start, int
class_id = i + start;
memset (cm, 0, sizeof (*cm));
cm->finalizer = tab[i].finalizer;
cm->gc_mark = tab[i].gc_mark;
if (JS_NewClass1 (ctx, class_id, cm, tab[i].class_name) < 0) return -1;
}
return 0;
@@ -1260,38 +1252,12 @@ int ctx_gc (JSContext *ctx, int allow_grow, size_t alloc_size) {
ctx->class_proto[i] = gc_copy_value (ctx, ctx->class_proto[i], from_base, from_end, to_base, &to_free, to_end);
}
/* Copy value stack */
#ifdef DUMP_GC_DETAIL
printf(" roots: value_stack (top=%d)\n", ctx->value_stack_top); fflush(stdout);
#endif
for (int i = 0; i < ctx->value_stack_top; i++) {
ctx->value_stack[i] = gc_copy_value (ctx, ctx->value_stack[i], from_base, from_end, to_base, &to_free, to_end);
}
/* Copy frame stack references */
#ifdef DUMP_GC_DETAIL
printf(" roots: frame_stack (top=%d)\n", ctx->frame_stack_top); fflush(stdout);
#endif
for (int i = 0; i <= ctx->frame_stack_top; i++) {
struct VMFrame *frame = &ctx->frame_stack[i];
frame->cur_func = gc_copy_value (ctx, frame->cur_func, from_base, from_end, to_base, &to_free, to_end);
frame->this_obj = gc_copy_value (ctx, frame->this_obj, from_base, from_end, to_base, &to_free, to_end);
}
/* Copy register VM current frame */
#ifdef DUMP_GC_DETAIL
printf(" roots: reg_current_frame\n"); fflush(stdout);
#endif
ctx->reg_current_frame = gc_copy_value (ctx, ctx->reg_current_frame, from_base, from_end, to_base, &to_free, to_end);
/* Copy JSStackFrame chain (C stack frames) */
#ifdef DUMP_GC_DETAIL
printf(" roots: current_stack_frame chain\n"); fflush(stdout);
#endif
for (JSStackFrame *sf = ctx->current_stack_frame; sf != NULL; sf = sf->prev_frame) {
sf->cur_func = gc_copy_value (ctx, sf->cur_func, from_base, from_end, to_base, &to_free, to_end);
}
/* Copy JS_PUSH_VALUE/JS_POP_VALUE roots */
#ifdef DUMP_GC_DETAIL
printf(" roots: top_gc_ref\n"); fflush(stdout);
@@ -1395,12 +1361,6 @@ JSRuntime *JS_NewRuntime (void) {
return rt;
}
void *JS_GetRuntimeOpaque (JSRuntime *rt) { return rt->user_opaque; }
void JS_SetRuntimeOpaque (JSRuntime *rt, void *opaque) {
rt->user_opaque = opaque;
}
void JS_SetMemoryLimit (JSRuntime *rt, size_t limit) {
rt->malloc_limit = limit;
}
@@ -1416,9 +1376,6 @@ void JS_SetInterruptHandler (JSContext *ctx, JSInterruptHandler *cb, void *opaqu
ctx->interrupt_opaque = opaque;
}
void JS_SetStripInfo (JSRuntime *rt, int flags) { rt->strip_flags = flags; }
int JS_GetStripInfo (JSRuntime *rt) { return rt->strip_flags; }
/* Allocate a string using bump allocation from context heap.
Note: the string contents are uninitialized */
JSText *js_alloc_string (JSContext *ctx, int max_len) {
@@ -1439,10 +1396,6 @@ JSText *js_alloc_string (JSContext *ctx, int max_len) {
return str;
}
void JS_SetRuntimeInfo (JSRuntime *rt, const char *s) {
if (rt) rt->rt_info = s;
}
void JS_FreeRuntime (JSRuntime *rt) {
/* Destroy buddy allocator */
buddy_destroy (&rt->buddy);
@@ -1450,7 +1403,6 @@ void JS_FreeRuntime (JSRuntime *rt) {
}
/* Forward declarations for intrinsics */
static void JS_AddIntrinsicBasicObjects (JSContext *ctx);
static void JS_AddIntrinsicBaseObjects (JSContext *ctx);
static void JS_AddIntrinsicRegExp (JSContext *ctx);
@@ -1484,37 +1436,11 @@ JSContext *JS_NewContextRawWithHeapSize (JSRuntime *rt, size_t heap_size) {
ctx->regexp_ctor = JS_NULL;
/* Initialize VM stacks for trampoline */
ctx->frame_stack_capacity = 512;
ctx->frame_stack
= js_malloc_rt (sizeof (struct VMFrame) * ctx->frame_stack_capacity);
if (!ctx->frame_stack) {
js_free_rt (ctx->class_array);
js_free_rt (ctx->class_proto);
js_free_rt (ctx);
return NULL;
}
ctx->frame_stack_top = -1;
ctx->value_stack_capacity = 65536; /* 64K JSValue slots */
ctx->value_stack
= js_malloc_rt (sizeof (JSValue) * ctx->value_stack_capacity);
if (!ctx->value_stack) {
js_free_rt (ctx->frame_stack);
js_free_rt (ctx->class_array);
js_free_rt (ctx->class_proto);
js_free_rt (ctx);
return NULL;
}
ctx->value_stack_top = 0;
/* Initialize register VM frame root */
ctx->reg_current_frame = JS_NULL;
/* Initialize per-context execution state (moved from JSRuntime) */
ctx->current_exception = JS_UNINITIALIZED;
ctx->current_stack_frame = NULL;
ctx->stack_size = JS_DEFAULT_STACK_SIZE;
JS_UpdateStackTop (ctx);
/* Initialize stone text intern table */
@@ -1525,8 +1451,6 @@ JSContext *JS_NewContextRawWithHeapSize (JSRuntime *rt, size_t heap_size) {
ctx->st_text_size = 0;
ctx->st_text_resize = 0;
if (st_text_resize (ctx) < 0) {
js_free_rt (ctx->value_stack);
js_free_rt (ctx->frame_stack);
js_free_rt (ctx->class_array);
js_free_rt (ctx->class_proto);
js_free_rt (ctx);
@@ -1540,8 +1464,6 @@ JSContext *JS_NewContextRawWithHeapSize (JSRuntime *rt, size_t heap_size) {
if (!ctx->heap_base) {
js_free_rt (ctx->st_text_hash);
js_free_rt (ctx->st_text_array);
js_free_rt (ctx->value_stack);
js_free_rt (ctx->frame_stack);
js_free_rt (ctx->class_array);
js_free_rt (ctx->class_proto);
js_free_rt (ctx);
@@ -1620,10 +1542,6 @@ void JS_FreeContext (JSContext *ctx) {
js_free_rt (ctx->class_array);
js_free_rt (ctx->class_proto);
/* Free VM stacks */
if (ctx->frame_stack) js_free_rt (ctx->frame_stack);
if (ctx->value_stack) js_free_rt (ctx->value_stack);
/* Free stone arena and intern table */
st_free_all (ctx);
js_free_rt (ctx->st_text_hash);
@@ -1642,28 +1560,12 @@ void JS_FreeContext (JSContext *ctx) {
JSRuntime *JS_GetRuntime (JSContext *ctx) { return ctx->rt; }
static void update_stack_limit (JSContext *ctx) {
if (ctx->stack_size == 0) {
ctx->stack_limit = 0; /* no limit */
} else {
ctx->stack_limit = ctx->stack_top - ctx->stack_size;
}
}
void JS_SetMaxStackSize (JSContext *ctx, size_t stack_size) {
ctx->stack_size = stack_size;
update_stack_limit (ctx);
}
void JS_UpdateStackTop (JSContext *ctx) {
ctx->stack_top = (const uint8_t *)js_get_stack_pointer ();
update_stack_limit (ctx);
ctx->stack_limit = stack_size;
}
JSText *js_alloc_string (JSContext *ctx, int max_len);
static inline int is_num (int c) { return c >= '0' && c <= '9'; }
static __maybe_unused void JS_DumpChar (FILE *fo, int c, int sep) {
if (c == sep || c == '\\') {
fputc ('\\', fo);
@@ -1757,7 +1659,6 @@ int JS_NewClass1 (JSContext *ctx, JSClassID class_id, const JSClassDef *class_de
cl->class_id = class_id;
cl->class_name = name; /* name is already a const char* */
cl->finalizer = class_def->finalizer;
cl->gc_mark = class_def->gc_mark;
return 0;
}
@@ -2390,21 +2291,6 @@ JSValue JS_NewObject (JSContext *ctx) {
return JS_NewObjectProtoClass (ctx, ctx->class_proto[JS_CLASS_OBJECT], JS_CLASS_OBJECT);
}
/* Helper to check if a value is a bytecode function */
static BOOL js_is_bytecode_function (JSValue val) {
if (!JS_IsFunction (val)) return FALSE;
JSFunction *f = JS_VALUE_GET_FUNCTION (val);
return f->kind == JS_FUNC_KIND_BYTECODE;
}
/* return NULL without exception if not a function or no bytecode */
static JSFunctionBytecode *JS_GetFunctionBytecode (JSValue val) {
JSFunction *f;
if (!JS_IsFunction (val)) return NULL;
f = JS_VALUE_GET_FUNCTION (val);
if (f->kind != JS_FUNC_KIND_BYTECODE) return NULL;
return f->u.func.function_bytecode;
}
// TODO: needs reworked
int js_method_set_properties (JSContext *ctx, JSValue func_obj, JSValue name, int flags, JSValue home_obj) {
@@ -2665,65 +2551,6 @@ int get_line_col_cached (GetLineColCache *s, int *pcol_num, const uint8_t *ptr)
return s->line_num;
}
/* use pc_value = -1 to get the position of the function definition */
static int find_line_num (JSContext *ctx, JSFunctionBytecode *b, uint32_t pc_value, int *pcol_num) {
const uint8_t *p_end, *p;
int new_line_num, line_num, pc, v, ret, new_col_num, col_num;
uint32_t val;
unsigned int op;
if (!b->has_debug || !b->debug.pc2line_buf)
goto fail; /* function was stripped */
p = b->debug.pc2line_buf;
p_end = p + b->debug.pc2line_len;
/* get the function line and column numbers */
ret = get_leb128 (&val, p, p_end);
if (ret < 0) goto fail;
p += ret;
line_num = val + 1;
ret = get_leb128 (&val, p, p_end);
if (ret < 0) goto fail;
p += ret;
col_num = val + 1;
if (pc_value != -1) {
pc = 0;
while (p < p_end) {
op = *p++;
if (op == 0) {
ret = get_leb128 (&val, p, p_end);
if (ret < 0) goto fail;
pc += val;
p += ret;
ret = get_sleb128 (&v, p, p_end);
if (ret < 0) goto fail;
p += ret;
new_line_num = line_num + v;
} else {
op -= PC2LINE_OP_FIRST;
pc += (op / PC2LINE_RANGE);
new_line_num = line_num + (op % PC2LINE_RANGE) + PC2LINE_BASE;
}
ret = get_sleb128 (&v, p, p_end);
if (ret < 0) goto fail;
p += ret;
new_col_num = col_num + v;
if (pc_value < pc) goto done;
line_num = new_line_num;
col_num = new_col_num;
}
}
done:
*pcol_num = col_num;
return line_num;
fail:
*pcol_num = 0;
return 0;
}
/* in order to avoid executing arbitrary code during the stack trace
generation, we only look at simple 'name' properties containing a
@@ -2781,16 +2608,6 @@ void print_backtrace (JSContext *ctx, const char *filename, int line_num, int co
}
return;
}
/* Fallback: walk C stack frame chain (old bytecode VM) */
for (JSStackFrame *sf = ctx->current_stack_frame; sf != NULL; sf = sf->prev_frame) {
if (sf->js_mode & JS_MODE_BACKTRACE_BARRIER) break;
const char *func_name_str = get_func_name (ctx, sf->cur_func);
const char *str1 = (func_name_str && func_name_str[0] != '\0')
? func_name_str : "<anonymous>";
fprintf (stderr, " at %s (native)\n", str1);
JS_FreeCString (ctx, func_name_str);
}
}
/* Print error message + backtrace to stderr, then set exception flag.
@@ -4171,39 +3988,6 @@ static void js_print_string (JSPrintValueState *s, JSValue val) {
}
}
static void js_print_raw_string2 (JSPrintValueState *s, JSValue val, BOOL remove_last_lf) {
const char *cstr;
size_t len;
cstr = JS_ToCStringLen (s->ctx, &len, val);
if (cstr) {
if (remove_last_lf && len > 0 && cstr[len - 1] == '\n') len--;
s->write_func (s->write_opaque, cstr, len);
JS_FreeCString (s->ctx, cstr);
}
}
static void js_print_raw_string (JSPrintValueState *s, JSValue val) {
js_print_raw_string2 (s, val, FALSE);
}
static void js_print_comma (JSPrintValueState *s, int *pcomma_state) {
switch (*pcomma_state) {
case 0:
break;
case 1:
js_printf (s, ", ");
break;
case 2:
js_printf (s, " { ");
break;
}
*pcomma_state = 1;
}
static void js_print_more_items (JSPrintValueState *s, int *pcomma_state, uint32_t n) {
js_print_comma (s, pcomma_state);
js_printf (s, "... %u more item%s", n, n > 1 ? "s" : "");
}
static void js_print_value (JSPrintValueState *s, JSValue val) {
uint32_t tag = JS_VALUE_GET_NORM_TAG (val);
@@ -4355,15 +4139,6 @@ __maybe_unused void JS_DumpGCObject (JSRuntime *rt,
}
}
/* return -1 if exception (proxy case) or TRUE/FALSE */
static double js_pow (double a, double b) {
if (unlikely (!isfinite (b)) && fabs (a) == 1) {
/* not compatible with IEEE 754 */
return NAN;
} else {
return pow (a, b);
}
}
/* Simplified equality: no NaN (becomes null), no coercion, no SameValue distinction */
BOOL js_strict_eq (JSContext *ctx, JSValue op1, JSValue op2) {
@@ -4486,7 +4261,6 @@ exception:
JSValue js_call_c_function (JSContext *ctx, JSValue func_obj, JSValue this_obj, int argc, JSValue *argv) {
JSCFunctionType func;
JSFunction *f;
JSStackFrame sf_s, *sf = &sf_s, *prev_sf;
JSValue ret_val;
JSValue *arg_buf;
int arg_count, i;
@@ -4501,30 +4275,8 @@ JSValue js_call_c_function (JSContext *ctx, JSValue func_obj, JSValue this_obj,
if (js_check_stack_overflow (ctx, sizeof (arg_buf[0]) * arg_count))
return JS_ThrowStackOverflow (ctx);
prev_sf = ctx->current_stack_frame;
sf->prev_frame = prev_sf;
ctx->current_stack_frame = sf;
sf->js_mode = 0;
sf->cur_func = (JSValue)func_obj;
sf->arg_count = argc;
sf->js_frame = JS_NULL; /* C functions don't have JSFrame */
sf->stack_buf = NULL; /* C functions don't have operand stack */
sf->p_sp = NULL;
arg_buf = argv;
if (unlikely (argc < arg_count)) {
/* Pad args on the value stack (GC-scanned) instead of alloca */
saved_vs_top = ctx->value_stack_top;
for (i = 0; i < argc; i++)
ctx->value_stack[saved_vs_top + i] = argv[i];
for (i = argc; i < arg_count; i++)
ctx->value_stack[saved_vs_top + i] = JS_NULL;
ctx->value_stack_top = saved_vs_top + arg_count;
arg_buf = &ctx->value_stack[saved_vs_top];
sf->arg_count = arg_count;
}
sf->arg_buf = (JSValue *)arg_buf;
func = f->u.cfunc.c_function;
if (unlikely (ctx->trace_hook) && (ctx->trace_type & JS_HOOK_CALL)) {
@@ -4602,12 +4354,6 @@ JSValue js_call_c_function (JSContext *ctx, JSValue func_obj, JSValue this_obj,
abort ();
}
ctx->current_stack_frame = sf->prev_frame;
/* Restore value stack if we used it for arg padding */
if (saved_vs_top >= 0)
ctx->value_stack_top = saved_vs_top;
if (unlikely (ctx->trace_hook) && (ctx->trace_type & JS_HOOK_RET))
ctx->trace_hook (ctx, JS_HOOK_RET, NULL, ctx->trace_data);
@@ -5518,49 +5264,6 @@ static void JS_AddIntrinsicRegExp (JSContext *ctx) {
}
static JSValue internalize_json_property (JSContext *ctx, JSValue holder, JSValue name, JSValue reviver) {
JSValue val, new_el, res;
JSValue args[2];
int ret, is_array;
uint32_t i, len = 0;
JSValue prop;
if (js_check_stack_overflow (ctx, 0)) {
return JS_ThrowStackOverflow (ctx);
}
val = JS_GetProperty (ctx, holder, name);
if (JS_IsException (val)) return val;
is_array = JS_IsArray (val);
if (is_array < 0) goto fail;
if (is_array || JS_IsObject (val)) {
if (is_array) {
if (js_get_length32 (ctx, &len, val)) goto fail;
} else {
/* Object property iteration not yet implemented for JSValue keys */
len = 0;
}
for (i = 0; i < len; i++) {
/* For arrays, use integer index as key */
prop = JS_NewInt32 (ctx, i);
new_el = internalize_json_property (ctx, val, prop, reviver);
if (JS_IsException (new_el)) { goto fail; }
if (JS_IsNull (new_el)) {
ret = JS_DeleteProperty (ctx, val, prop);
} else {
ret = JS_SetPropertyInternal (ctx, val, prop, new_el);
}
if (ret < 0) goto fail;
}
}
/* name is already a JSValue, use it directly */
args[0] = name;
args[1] = val;
res = JS_Call (ctx, reviver, holder, 2, args);
return res;
fail:
return JS_EXCEPTION;
}
/* Convert a cJSON node to a JSValue */
static JSValue cjson_to_jsvalue (JSContext *ctx, const cJSON *item) {
@@ -5606,30 +5309,6 @@ JSValue JS_ParseJSON2 (JSContext *ctx, const char *buf, size_t buf_len,
return JS_ParseJSON (ctx, buf, buf_len, filename);
}
static JSValue js_json_parse (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) {
JSValue obj, root;
JSValue reviver;
const char *str;
size_t len;
str = JS_ToCStringLen (ctx, &len, argv[0]);
if (!str) return JS_EXCEPTION;
obj = JS_ParseJSON (ctx, str, len, "<input>");
JS_FreeCString (ctx, str);
if (JS_IsException (obj)) return obj;
if (argc > 1 && JS_IsFunction (argv[1])) {
reviver = argv[1];
root = JS_NewObject (ctx);
if (JS_IsException (root)) {
return JS_EXCEPTION;
}
if (JS_SetPropertyInternal (ctx, root, JS_KEY_empty, obj) < 0) {
return JS_EXCEPTION;
}
obj = internalize_json_property (ctx, root, JS_KEY_empty, reviver);
}
return obj;
}
typedef struct JSONStringifyContext {
JSContext *ctx;
@@ -7594,32 +7273,7 @@ fail_rx_search:
return JS_EXCEPTION;
}
#undef SEARCH_CLEANUP
static inline uint32_t js_str_get (JSText *s, int idx) {
return string_get (s, idx);
}
static int js_str_find_range (JSText *hay, int from, int to, JSText *needle) {
int nlen = (int)JSText_len (needle);
int hlen = (int)JSText_len (hay);
if (from < 0) from = 0;
if (to < 0) to = 0;
if (to > hlen) to = hlen;
if (from > to) return -1;
if (nlen == 0) return from;
if (nlen > (to - from)) return -1;
int limit = to - nlen;
for (int i = from; i <= limit; i++) {
int j = 0;
for (; j < nlen; j++) {
if (js_str_get (hay, i + j) != js_str_get (needle, j)) break;
}
if (j == nlen) return i;
}
return -1;
}
/* text_extract(text, pattern, from?, to?) - return array of matches or null
- literal pattern: [match]
@@ -10985,8 +10639,6 @@ static JSValue js_cell_length (JSContext *ctx, JSValue this_val, int argc, JSVal
return JS_NewInt32 (ctx, f->length);
}
int tag = JS_VALUE_GET_TAG (val);
/* Strings return codepoint count */
if (MIST_IsImmediateASCII (val)) {
return JS_NewInt32 (ctx, MIST_GetImmediateASCIILen (val));
@@ -11217,11 +10869,6 @@ static JSValue js_cell_is_proto (JSContext *ctx, JSValue this_val, int argc, JSV
return JS_FALSE;
}
/* Minimum amount of objects to be able to compile code and display
error messages. */
static void JS_AddIntrinsicBasicObjects (JSContext *ctx) {
ctx->class_proto[JS_CLASS_OBJECT] = JS_NewObjectProto (ctx, JS_NULL);
}
/* logical(val) — false for 0/false/"false"/null, true for 1/true/"true", null otherwise */
static JSValue js_cell_logical(JSContext *ctx, JSValue this_val, int argc, JSValue *argv) {
@@ -11315,8 +10962,6 @@ static void js_set_global_cfunc(JSContext *ctx, const char *name, JSCFunction *f
}
static void JS_AddIntrinsicBaseObjects (JSContext *ctx) {
JSValue obj1;
ctx->throw_type_error = JS_NewCFunction (ctx, js_throw_type_error, NULL, 0);
ctx->global_obj = JS_NewObject (ctx);
@@ -11489,18 +11134,12 @@ void js_debug_sethook (JSContext *ctx, js_hook hook, int type, void *user) {
}
uint32_t js_debugger_stack_depth (JSContext *ctx) {
uint32_t stack_index = 0;
JSStackFrame *sf = ctx->current_stack_frame;
while (sf != NULL) {
sf = sf->prev_frame;
stack_index++;
}
return stack_index;
return ctx->stack_depth;
}
JSValue js_debugger_backtrace_fns (JSContext *ctx, const uint8_t *cur_pc) {
JSValue ret = JS_NewArray (ctx);
JSStackFrame *sf;
/* return an array of the actual fn objects as a backtrace */
JSValue js_debugger_backtrace_fns (JSContext *ctx) {
/* JSValue ret = JS_NewArray (ctx);
uint32_t stack_index = 0;
for (sf = ctx->current_stack_frame; sf != NULL; sf = sf->prev_frame) {
@@ -11508,10 +11147,12 @@ JSValue js_debugger_backtrace_fns (JSContext *ctx, const uint8_t *cur_pc) {
JS_SetPropertyUint32 (ctx, ret, id, sf->cur_func);
}
return ret;
*/
}
JSValue js_debugger_build_backtrace (JSContext *ctx, const uint8_t *cur_pc) {
(void)cur_pc;
/* build a backtrace of info for printing */
JSValue js_debugger_build_backtrace (JSContext *ctx) {
/*
JSStackFrame *sf;
JSValue ret = JS_NewArray (ctx);
uint32_t stack_index = 0;
@@ -11531,6 +11172,7 @@ JSValue js_debugger_build_backtrace (JSContext *ctx, const uint8_t *cur_pc) {
JS_SetPropertyUint32 (ctx, ret, id, current_frame);
}
return ret;
*/
}
JSValue js_debugger_fn_info (JSContext *ctx, JSValue fn) {
@@ -11543,366 +11185,6 @@ JSValue js_debugger_fn_bytecode (JSContext *ctx, JSValue fn) {
return JS_NewArray (ctx);
}
#if 0 /* Old bytecode VM debugger — dead code */
static JSValue js_debugger_fn_bytecode_OLD (JSContext *ctx, JSValue fn) {
if (!js_is_bytecode_function (fn)) return JS_NULL;
JSFunction *f = JS_VALUE_GET_FUNCTION (fn);
JSFunctionBytecode *b = f->u.func.function_bytecode;
JSValue ret = JS_NewArray (ctx);
const uint8_t *tab = b->byte_code_buf;
int len = b->byte_code_len;
int pos = 0;
int idx = 0;
BOOL use_short_opcodes = TRUE;
char opcode_str[256];
while (pos < len) {
int op = tab[pos];
const JSOpCode *oi;
if (use_short_opcodes)
oi = &short_opcode_info (op);
else
oi = &opcode_info[op];
int size = oi->size;
if (pos + size > len) { break; }
if (op >= sizeof (opcode_names) / sizeof (opcode_names[0])) {
snprintf (opcode_str, sizeof (opcode_str), "unknown");
} else {
const char *opcode_name = opcode_names[op];
snprintf (opcode_str, sizeof (opcode_str), "%s", opcode_name);
// Add arguments based on opcode format
int arg_pos = pos + 1;
switch (oi->fmt) {
case OP_FMT_none_int:
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %d",
op - OP_push_0);
break;
case OP_FMT_npopx:
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %d",
op - OP_call0);
break;
case OP_FMT_u8:
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %u",
get_u8 (tab + arg_pos));
break;
case OP_FMT_i8:
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %d",
get_i8 (tab + arg_pos));
break;
case OP_FMT_u16:
case OP_FMT_npop:
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %u",
get_u16 (tab + arg_pos));
break;
case OP_FMT_npop_u16:
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %u %u",
get_u16 (tab + arg_pos),
get_u16 (tab + arg_pos + 2));
break;
case OP_FMT_i16:
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %d",
get_i16 (tab + arg_pos));
break;
case OP_FMT_i32:
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %d",
get_i32 (tab + arg_pos));
break;
case OP_FMT_u32:
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %u",
get_u32 (tab + arg_pos));
break;
#if SHORT_OPCODES
case OP_FMT_label8:
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %u",
get_i8 (tab + arg_pos) + arg_pos);
break;
case OP_FMT_label16:
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %u",
get_i16 (tab + arg_pos) + arg_pos);
break;
case OP_FMT_const8:
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %u",
get_u8 (tab + arg_pos));
break;
#endif
case OP_FMT_const:
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %u",
get_u32 (tab + arg_pos));
break;
case OP_FMT_label:
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %u",
get_u32 (tab + arg_pos) + arg_pos);
break;
case OP_FMT_label_u16:
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %u %u",
get_u32 (tab + arg_pos) + arg_pos,
get_u16 (tab + arg_pos + 4));
break;
case OP_FMT_key: {
/* Key operand is a cpool index */
uint32_t key_idx = get_u32 (tab + arg_pos);
if (key_idx < b->cpool_count) {
JSValue key = b->cpool[key_idx];
const char *key_str = JS_ToCString (ctx, key);
if (key_str) {
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" key:%s",
key_str);
JS_FreeCString (ctx, key_str);
} else {
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" key[%u]",
key_idx);
}
} else {
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" key[%u]",
key_idx);
}
} break;
case OP_FMT_key_u8: {
uint32_t cpool_idx = get_u32 (tab + arg_pos);
const char *key_str = NULL;
if (cpool_idx < b->cpool_count)
key_str = JS_ToCString (ctx, b->cpool[cpool_idx]);
if (key_str) {
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %s %d",
key_str,
get_u8 (tab + arg_pos + 4));
JS_FreeCString (ctx, key_str);
} else {
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" cpool[%u] %d",
cpool_idx,
get_u8 (tab + arg_pos + 4));
}
} break;
case OP_FMT_key_u16: {
uint32_t cpool_idx = get_u32 (tab + arg_pos);
const char *key_str = NULL;
if (cpool_idx < b->cpool_count)
key_str = JS_ToCString (ctx, b->cpool[cpool_idx]);
if (key_str) {
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %s %d",
key_str,
get_u16 (tab + arg_pos + 4));
JS_FreeCString (ctx, key_str);
} else {
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" cpool[%u] %d",
cpool_idx,
get_u16 (tab + arg_pos + 4));
}
} break;
case OP_FMT_key_label_u16: {
uint32_t cpool_idx = get_u32 (tab + arg_pos);
int addr = get_u32 (tab + arg_pos + 4);
int extra = get_u16 (tab + arg_pos + 8);
const char *key_str = NULL;
if (cpool_idx < b->cpool_count)
key_str = JS_ToCString (ctx, b->cpool[cpool_idx]);
if (key_str) {
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %s %u %u",
key_str,
addr + arg_pos + 4,
extra);
JS_FreeCString (ctx, key_str);
} else {
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" cpool[%u] %u %u",
cpool_idx,
addr + arg_pos + 4,
extra);
}
} break;
case OP_FMT_none_loc: {
int idx = (op - OP_get_loc0) % 4;
if (idx < b->var_count) {
const char *var_name
= JS_ToCString (ctx, b->vardefs[idx].var_name);
if (var_name) {
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %d: %s",
idx,
var_name);
JS_FreeCString (ctx, var_name);
} else {
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %d",
idx);
}
} else {
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %d",
idx);
}
} break;
case OP_FMT_loc8: {
int idx = get_u8 (tab + arg_pos);
if (idx < b->var_count) {
const char *var_name
= JS_ToCString (ctx, b->vardefs[idx].var_name);
if (var_name) {
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %u: %s",
idx,
var_name);
JS_FreeCString (ctx, var_name);
} else {
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %u",
idx);
}
} else {
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %u",
idx);
}
} break;
case OP_FMT_loc: {
int idx = get_u16 (tab + arg_pos);
if (idx < b->var_count) {
const char *var_name
= JS_ToCString (ctx, b->vardefs[idx].var_name);
if (var_name) {
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %u: %s",
idx,
var_name);
JS_FreeCString (ctx, var_name);
} else {
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %u",
idx);
}
} else {
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %u",
idx);
}
} break;
case OP_FMT_none_arg: {
int idx = (op - OP_get_arg0) % 4;
if (idx < b->arg_count) {
const char *arg_name
= JS_ToCString (ctx, b->vardefs[idx].var_name);
if (arg_name) {
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %d: %s",
idx,
arg_name);
JS_FreeCString (ctx, arg_name);
} else {
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %d",
idx);
}
} else {
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %d",
idx);
}
} break;
case OP_FMT_arg: {
int idx = get_u16 (tab + arg_pos);
if (idx < b->arg_count) {
const char *arg_name
= JS_ToCString (ctx, b->vardefs[idx].var_name);
if (arg_name) {
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %u: %s",
idx,
arg_name);
JS_FreeCString (ctx, arg_name);
} else {
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %u",
idx);
}
} else {
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %u",
idx);
}
} break;
default:
break;
}
}
JSValue js_opcode_str = JS_NewString (ctx, opcode_str);
JS_SetPropertyUint32 (ctx, ret, idx++, js_opcode_str);
pos += size;
}
return ret;
}
#endif /* Old bytecode VM debugger */
JSValue js_debugger_local_variables (JSContext *ctx, int stack_index) {
(void)stack_index;
return JS_NewObject (ctx);