removal of old code
This commit is contained in:
@@ -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),
|
||||
|
||||
12
net/enet.c
12
net/enet.c
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
738
source/runtime.c
738
source/runtime.c
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user