condense jsruntime and jscontext

This commit is contained in:
2026-02-08 10:10:42 -06:00
parent d18ea1b330
commit 1fee8f9f8b
12 changed files with 215 additions and 231 deletions

View File

@@ -382,13 +382,13 @@ static const JSCFunctionListEntry js_reader_funcs[] = {
JSValue js_miniz_use(JSContext *js)
{
JS_NewClassID(&js_reader_class_id);
JS_NewClass(JS_GetRuntime(js), js_reader_class_id, &js_reader_class);
JS_NewClass(js, js_reader_class_id, &js_reader_class);
JSValue reader_proto = JS_NewObject(js);
JS_SetPropertyFunctionList(js, reader_proto, js_reader_funcs, sizeof(js_reader_funcs) / sizeof(JSCFunctionListEntry));
JS_SetClassProto(js, js_reader_class_id, reader_proto);
JS_NewClassID(&js_writer_class_id);
JS_NewClass(JS_GetRuntime(js), js_writer_class_id, &js_writer_class);
JS_NewClass(js, js_writer_class_id, &js_writer_class);
JSValue writer_proto = JS_NewObject(js);
JS_SetPropertyFunctionList(js, writer_proto, js_writer_funcs, sizeof(js_writer_funcs) / sizeof(JSCFunctionListEntry));
JS_SetClassProto(js, js_writer_class_id, writer_proto);

View File

@@ -577,7 +577,7 @@ static const JSCFunctionListEntry js_os_funcs[] = {
JSValue js_os_use(JSContext *js) {
JS_NewClassID(&js_dylib_class_id);
JS_NewClass(JS_GetRuntime(js), js_dylib_class_id, &js_dylib_class);
JS_NewClass(js, js_dylib_class_id, &js_dylib_class);
JSValue mod = JS_NewObject(js);
JS_SetPropertyFunctionList(js,mod,js_os_funcs,countof(js_os_funcs));

View File

@@ -571,13 +571,13 @@ static const JSCFunctionListEntry js_enet_peer_funcs[] = {
JSValue js_enet_use(JSContext *ctx)
{
JS_NewClassID(&enet_host_id);
JS_NewClass(JS_GetRuntime(ctx), enet_host_id, &enet_host);
JS_NewClass(ctx, enet_host_id, &enet_host);
JSValue host_proto = JS_NewObject(ctx);
JS_SetPropertyFunctionList(ctx, host_proto, js_enet_host_funcs, countof(js_enet_host_funcs));
JS_SetClassProto(ctx, enet_host_id, host_proto);
JS_NewClassID(&enet_peer_class_id);
JS_NewClass(JS_GetRuntime(ctx), enet_peer_class_id, &enet_peer_class);
JS_NewClass(ctx, enet_peer_class_id, &enet_peer_class);
JSValue peer_proto = JS_NewObject(ctx);
JS_SetPropertyFunctionList(ctx, peer_proto, js_enet_peer_funcs, countof(js_enet_peer_funcs));
JS_SetClassProto(ctx, enet_peer_class_id, peer_proto);

4
qop.c
View File

@@ -458,13 +458,13 @@ static const JSCFunctionListEntry js_qop_funcs[] = {
JSValue js_qop_use(JSContext *js) {
JS_NewClassID(&js_qop_archive_class_id);
JS_NewClass(JS_GetRuntime(js), js_qop_archive_class_id, &js_qop_archive_class);
JS_NewClass(js, js_qop_archive_class_id, &js_qop_archive_class);
JSValue archive_proto = JS_NewObject(js);
JS_SetPropertyFunctionList(js, archive_proto, js_qop_archive_funcs, countof(js_qop_archive_funcs));
JS_SetClassProto(js, js_qop_archive_class_id, archive_proto);
JS_NewClassID(&js_qop_writer_class_id);
JS_NewClass(JS_GetRuntime(js), js_qop_writer_class_id, &js_qop_writer_class);
JS_NewClass(js, js_qop_writer_class_id, &js_qop_writer_class);
JSValue writer_proto = JS_NewObject(js);
JS_SetPropertyFunctionList(js, writer_proto, js_qop_writer_funcs, countof(js_qop_writer_funcs));
JS_SetClassProto(js, js_qop_writer_class_id, writer_proto);

View File

@@ -26,6 +26,7 @@ static int run_test_suite(size_t heap_size);
cell_rt *root_cell = NULL;
static char *core_path = NULL;
static JSRuntime *g_runtime = NULL;
// Get the home directory
static const char* get_home_dir(void) {
@@ -165,13 +166,27 @@ JSValue js_wota_use(JSContext *js);
void script_startup(cell_rt *prt)
{
JSRuntime *rt = JS_NewRuntime();
JS_SetInterruptHandler(rt, (JSInterruptHandler *)actor_interrupt_cb, prt);
JSContext *js = JS_NewContext(rt);
if (!g_runtime) {
g_runtime = JS_NewRuntime();
}
JSContext *js = JS_NewContext(g_runtime);
JS_SetInterruptHandler(js, (JSInterruptHandler *)actor_interrupt_cb, prt);
JS_SetContextOpaque(js, prt);
prt->context = js;
/* Register all GCRef fields so the Cheney GC can relocate them. */
JS_AddGCRef(js, &prt->idx_buffer_ref);
JS_AddGCRef(js, &prt->on_exception_ref);
JS_AddGCRef(js, &prt->message_handle_ref);
JS_AddGCRef(js, &prt->unneeded_ref);
JS_AddGCRef(js, &prt->actor_sym_ref);
prt->idx_buffer_ref.val = JS_NULL;
prt->on_exception_ref.val = JS_NULL;
prt->message_handle_ref.val = JS_NULL;
prt->unneeded_ref.val = JS_NULL;
prt->actor_sym_ref.val = JS_NULL;
cell_rt *crt = JS_GetContextOpaque(js);
JS_FreeValue(js, js_blob_use(js));
@@ -202,8 +217,8 @@ void script_startup(cell_rt *prt)
JS_SetPropertyStr(js, hidden_env, "nota", js_nota_use(js));
JS_SetPropertyStr(js, hidden_env, "wota", js_wota_use(js));
crt->actor_sym = JS_NewObject(js);
JS_SetPropertyStr(js, hidden_env, "actorsym", JS_DupValue(js, crt->actor_sym));
crt->actor_sym_ref.val = JS_NewObject(js);
JS_SetPropertyStr(js, hidden_env, "actorsym", JS_DupValue(js, crt->actor_sym_ref.val));
// Always set init (even if null)
if (crt->init_wota) {

View File

@@ -144,7 +144,7 @@ JS_SetPropertyFunctionList(js, TYPE##_proto, js_##TYPE##_funcs, countof(js_##TYP
#define QJSCLASSPREP_NO_FUNCS(TYPE) \
JS_NewClassID(&js_##TYPE##_id);\
JS_NewClass(JS_GetRuntime(js), js_##TYPE##_id, &js_##TYPE##_class);\
JS_NewClass(js, js_##TYPE##_id, &js_##TYPE##_class);\
JSValue TYPE##_proto = JS_NewObject(js); \
JS_SetClassProto(js, js_##TYPE##_id, TYPE##_proto); \

View File

@@ -24,21 +24,26 @@ typedef struct letter {
typedef struct cell_rt {
JSContext *context;
JSValue idx_buffer;
JSValue on_exception;
JSValue message_handle;
/* JSValues on the GC heap — each paired with a JSGCRef so the
Cheney GC can relocate them during compaction. */
JSGCRef idx_buffer_ref;
JSGCRef on_exception_ref;
JSGCRef message_handle_ref;
JSGCRef unneeded_ref;
JSGCRef actor_sym_ref;
void *init_wota;
/* Protects JSContext usage */
pthread_mutex_t *mutex; /* for everything else */
pthread_mutex_t *msg_mutex; /* For message queue and timers queue */
char *id;
int idx_count;
/* The mailbox for incoming messages + a dedicated lock for it: */
/* The "mailbox" for incoming messages + a dedicated lock for it: */
letter *letters;
/* CHANGED FOR EVENTS: a separate lock for the actor->events queue */
@@ -47,14 +52,11 @@ typedef struct cell_rt {
int state;
uint32_t ar; // timer for unneeded
double ar_secs; // time for unneeded
JSValue unneeded; // fn to call before unneeded
int disrupt;
int main_thread_only;
int affinity;
JSValue actor_sym;
const char *name; // human friendly name
cell_hook trace_hook;
} cell_rt;
@@ -63,8 +65,6 @@ cell_rt *create_actor(void *wota);
const char *register_actor(const char *id, cell_rt *actor, int mainthread, double ar);
void actor_disrupt(cell_rt *actor);
JSValue actor_sym(cell_rt *actor);
const char *send_message(const char *id, void *msg);
const char *register_actor(const char *id, cell_rt *actor, int mainthread, double ar);
void actor_unneeded(cell_rt *actor, JSValue fn, double seconds);

View File

@@ -74,7 +74,7 @@ JSC_CCALL(os_register_actor,
JS_ToFloat64(js, &ar, argv[3]);
const char *err = register_actor(id, rt, JS_ToBool(js, argv[2]), ar);
if (err) return JS_ThrowInternalError(js, "Could not register actor: %s", err);
rt->message_handle = JS_DupValue(js, argv[1]);
rt->message_handle_ref.val = argv[1];
rt->context = js;
JS_FreeCString(js, id);
)
@@ -106,8 +106,7 @@ JSC_SCALL(actor_setname,
JSC_CCALL(actor_on_exception,
cell_rt *rt = JS_GetContextOpaque(js);
JS_FreeValue(js, rt->on_exception);
rt->on_exception = JS_DupValue(js,argv[0]);
rt->on_exception_ref.val = argv[0];
)
JSC_CCALL(actor_clock,

View File

@@ -373,31 +373,11 @@ struct JSRuntime {
/* Buddy allocator for actor memory blocks */
BuddyAllocator buddy;
int class_count; /* size of class_array */
JSClass *class_array;
/* see JS_SetStripInfo() */
uint8_t strip_flags;
/* Stack overflow protection */
size_t stack_size;
const uint8_t *stack_top;
const uint8_t *stack_limit;
/* Current exception (for error propagation) */
JSValue current_exception;
struct JSStackFrame *current_stack_frame;
/* User data */
void *user_opaque;
/* Interrupt handler for checking execution limits */
JSInterruptHandler *interrupt_handler;
void *interrupt_opaque;
/* Register VM frame tracking for stack traces */
void *current_register_frame; /* JSFrameRegister* at exception time */
uint32_t current_register_pc; /* PC at exception time */
};
struct JSClass {
@@ -1052,6 +1032,8 @@ struct JSContext {
JSGCRef *top_gc_ref; /* used to reference temporary GC roots (stack top) */
JSGCRef *last_gc_ref; /* used to reference temporary GC roots (list) */
int class_count; /* size of class_array and class_proto */
JSClass *class_array;
JSValue *class_proto;
JSValue regexp_ctor;
JSValue native_error_proto[JS_NATIVE_ERROR_COUNT];
@@ -1082,14 +1064,22 @@ struct JSContext {
/* 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;
/* Stack overflow protection */
size_t stack_size;
const uint8_t *stack_top;
const uint8_t *stack_limit;
/* Parser state (for GC to scan cpool during parsing) */
struct JSFunctionDef *current_parse_fd;
};
@@ -2066,7 +2056,7 @@ static JSValue js_new_string8_len (JSContext *ctx, const char *buf, int len);
static JSValue pretext_end (JSContext *ctx, JSText *s);
static JSValue js_compile_regexp (JSContext *ctx, JSValue pattern, JSValue flags);
static JSValue js_regexp_constructor_internal (JSContext *ctx, JSValue pattern, JSValue bc);
static int JS_NewClass1 (JSRuntime *rt, JSClassID class_id, const JSClassDef *class_def, const char *name);
static int JS_NewClass1 (JSContext *ctx, JSClassID class_id, const JSClassDef *class_def, const char *name);
static BOOL js_strict_eq (JSContext *ctx, JSValue op1, JSValue op2);
static JSValue js_cell_text (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
@@ -2450,7 +2440,7 @@ static JSClass const js_std_class_def[] = {
{ "blob", NULL, NULL }, /* JS_CLASS_BLOB - registered separately */
};
static int init_class_range (JSRuntime *rt, JSClass const *tab, int start, int count) {
static int init_class_range (JSContext *ctx, JSClass const *tab, int start, int count) {
JSClassDef cm_s, *cm = &cm_s;
int i, class_id;
@@ -2459,7 +2449,7 @@ static int init_class_range (JSRuntime *rt, JSClass const *tab, int start, int c
memset (cm, 0, sizeof (*cm));
cm->finalizer = tab[i].finalizer;
cm->gc_mark = tab[i].gc_mark;
if (JS_NewClass1 (rt, class_id, cm, tab[i].class_name) < 0) return -1;
if (JS_NewClass1 (ctx, class_id, cm, tab[i].class_name) < 0) return -1;
}
return 0;
}
@@ -2468,7 +2458,7 @@ static int init_class_range (JSRuntime *rt, JSClass const *tab, int start, int c
/* no stack limitation */
static inline uintptr_t js_get_stack_pointer (void) { return 0; }
static inline BOOL js_check_stack_overflow (JSRuntime *rt,
static inline BOOL js_check_stack_overflow (JSContext *ctx,
size_t alloca_size) {
return FALSE;
}
@@ -2478,11 +2468,11 @@ static inline uintptr_t js_get_stack_pointer (void) {
return (uintptr_t)__builtin_frame_address (0);
}
static inline BOOL js_check_stack_overflow (JSRuntime *rt,
static inline BOOL js_check_stack_overflow (JSContext *ctx,
size_t alloca_size) {
uintptr_t sp;
sp = js_get_stack_pointer () - alloca_size;
return unlikely (sp < (uintptr_t)rt->stack_limit);
return unlikely (sp < (uintptr_t)ctx->stack_limit);
}
#endif
@@ -2849,7 +2839,7 @@ static int ctx_gc (JSContext *ctx, int allow_grow, size_t alloc_size) {
#ifdef DUMP_GC_DETAIL
printf(" roots: current_exception\n"); fflush(stdout);
#endif
rt->current_exception = gc_copy_value (ctx, rt->current_exception, from_base, from_end, to_base, &to_free, to_end);
ctx->current_exception = gc_copy_value (ctx, ctx->current_exception, from_base, from_end, to_base, &to_free, to_end);
#ifdef DUMP_GC_DETAIL
printf(" roots: native_error_proto\n"); fflush(stdout);
@@ -2860,9 +2850,9 @@ static int ctx_gc (JSContext *ctx, int allow_grow, size_t alloc_size) {
/* Copy class prototypes */
#ifdef DUMP_GC_DETAIL
printf(" roots: class_proto (count=%d)\n", rt->class_count); fflush(stdout);
printf(" roots: class_proto (count=%d)\n", ctx->class_count); fflush(stdout);
#endif
for (int i = 0; i < rt->class_count; i++) {
for (int i = 0; i < ctx->class_count; i++) {
ctx->class_proto[i] = gc_copy_value (ctx, ctx->class_proto[i], from_base, from_end, to_base, &to_free, to_end);
}
@@ -2894,7 +2884,7 @@ static int ctx_gc (JSContext *ctx, int allow_grow, size_t alloc_size) {
#ifdef DUMP_GC_DETAIL
printf(" roots: current_stack_frame chain\n"); fflush(stdout);
#endif
for (JSStackFrame *sf = rt->current_stack_frame; sf != NULL; sf = sf->prev_frame) {
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);
/* Also scan bytecode cpool if it's a bytecode object outside GC heap */
gc_scan_bytecode_cpool (ctx, sf->cur_func, from_base, from_end, to_base, &to_free, to_end);
@@ -3036,20 +3026,7 @@ JSRuntime *JS_NewRuntime (void) {
if (!rt) return NULL;
memset (rt, 0, sizeof (*rt));
/* create the object, array and function classes */
if (init_class_range (rt, js_std_class_def, JS_CLASS_OBJECT, countof (js_std_class_def))
< 0)
goto fail;
rt->stack_size = JS_DEFAULT_STACK_SIZE;
JS_UpdateStackTop (rt);
rt->current_exception = JS_UNINITIALIZED;
return rt;
fail:
JS_FreeRuntime (rt);
return NULL;
}
void *JS_GetRuntimeOpaque (JSRuntime *rt) { return rt->user_opaque; }
@@ -3071,9 +3048,9 @@ static void *sys_realloc (void *ptr, size_t size) { return realloc (ptr, size);
#define free(p) free_is_forbidden (p)
#define realloc(p, s) realloc_is_forbidden (p, s)
void JS_SetInterruptHandler (JSRuntime *rt, JSInterruptHandler *cb, void *opaque) {
rt->interrupt_handler = cb;
rt->interrupt_opaque = opaque;
void JS_SetInterruptHandler (JSContext *ctx, JSInterruptHandler *cb, void *opaque) {
ctx->interrupt_handler = cb;
ctx->interrupt_opaque = opaque;
}
void JS_SetStripInfo (JSRuntime *rt, int flags) { rt->strip_flags = flags; }
@@ -3104,11 +3081,9 @@ void JS_SetRuntimeInfo (JSRuntime *rt, const char *s) {
}
void JS_FreeRuntime (JSRuntime *rt) {
/* free the classes */
js_free_rt (rt->class_array);
/* Destroy buddy allocator */
buddy_destroy (&rt->buddy);
sys_free (rt);
}
/* Forward declarations for intrinsics */
@@ -3118,7 +3093,6 @@ static void JS_AddIntrinsicRegExp (JSContext *ctx);
JSContext *JS_NewContextRawWithHeapSize (JSRuntime *rt, size_t heap_size) {
JSContext *ctx;
int i;
/* Round up to buddy allocator minimum */
size_t min_size = 1ULL << BUDDY_MIN_ORDER;
@@ -3135,17 +3109,15 @@ JSContext *JS_NewContextRawWithHeapSize (JSRuntime *rt, size_t heap_size) {
if (!ctx) return NULL;
ctx->trace_hook = NULL;
ctx->rt = rt;
ctx->class_proto
= js_malloc_rt (sizeof (ctx->class_proto[0]) * rt->class_count);
if (!ctx->class_proto) {
/* Bootstrap class_array and class_proto together via JS_NewClass1 */
if (init_class_range (ctx, js_std_class_def, JS_CLASS_OBJECT, countof (js_std_class_def)) < 0) {
js_free_rt (ctx->class_array);
js_free_rt (ctx->class_proto);
js_free_rt (ctx);
return NULL;
}
ctx->rt = rt;
for (i = 0; i < rt->class_count; i++)
ctx->class_proto[i] = JS_NULL;
ctx->regexp_ctor = JS_NULL;
@@ -3154,6 +3126,7 @@ JSContext *JS_NewContextRawWithHeapSize (JSRuntime *rt, size_t heap_size) {
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;
@@ -3165,6 +3138,7 @@ JSContext *JS_NewContextRawWithHeapSize (JSRuntime *rt, size_t heap_size) {
= 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;
@@ -3174,6 +3148,12 @@ JSContext *JS_NewContextRawWithHeapSize (JSRuntime *rt, size_t heap_size) {
/* 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 */
ctx->st_pages = NULL;
ctx->st_text_array = NULL;
@@ -3184,6 +3164,7 @@ JSContext *JS_NewContextRawWithHeapSize (JSRuntime *rt, size_t heap_size) {
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);
return NULL;
@@ -3198,6 +3179,7 @@ JSContext *JS_NewContextRawWithHeapSize (JSRuntime *rt, size_t heap_size) {
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);
return NULL;
@@ -3253,14 +3235,12 @@ static inline void set_value (JSContext *ctx, JSValue *pval, JSValue new_val) {
}
void JS_SetClassProto (JSContext *ctx, JSClassID class_id, JSValue obj) {
JSRuntime *rt = ctx->rt;
assert (class_id < rt->class_count);
assert (class_id < ctx->class_count);
set_value (ctx, &ctx->class_proto[class_id], obj);
}
JSValue JS_GetClassProto (JSContext *ctx, JSClassID class_id) {
JSRuntime *rt = ctx->rt;
assert (class_id < rt->class_count);
assert (class_id < ctx->class_count);
return ctx->class_proto[class_id];
}
@@ -3278,8 +3258,9 @@ void JS_FreeContext (JSContext *ctx) {
for (i = 0; i < JS_NATIVE_ERROR_COUNT; i++) {
}
for (i = 0; i < rt->class_count; i++) {
for (i = 0; i < ctx->class_count; i++) {
}
js_free_rt (ctx->class_array);
js_free_rt (ctx->class_proto);
/* Free VM stacks */
@@ -3298,26 +3279,28 @@ void JS_FreeContext (JSContext *ctx) {
ctx->heap_free = NULL;
ctx->heap_end = NULL;
}
js_free_rt (ctx);
}
JSRuntime *JS_GetRuntime (JSContext *ctx) { return ctx->rt; }
static void update_stack_limit (JSRuntime *rt) {
if (rt->stack_size == 0) {
rt->stack_limit = 0; /* no limit */
static void update_stack_limit (JSContext *ctx) {
if (ctx->stack_size == 0) {
ctx->stack_limit = 0; /* no limit */
} else {
rt->stack_limit = rt->stack_top - rt->stack_size;
ctx->stack_limit = ctx->stack_top - ctx->stack_size;
}
}
void JS_SetMaxStackSize (JSRuntime *rt, size_t stack_size) {
rt->stack_size = stack_size;
update_stack_limit (rt);
void JS_SetMaxStackSize (JSContext *ctx, size_t stack_size) {
ctx->stack_size = stack_size;
update_stack_limit (ctx);
}
void JS_UpdateStackTop (JSRuntime *rt) {
rt->stack_top = (const uint8_t *)js_get_stack_pointer ();
update_stack_limit (rt);
void JS_UpdateStackTop (JSContext *ctx) {
ctx->stack_top = (const uint8_t *)js_get_stack_pointer ();
update_stack_limit (ctx);
}
static JSText *js_alloc_string (JSContext *ctx, int max_len);
@@ -3376,46 +3359,54 @@ JSClassID JS_GetClassID (JSValue v) {
return REC_GET_CLASS_ID(rec);
}
BOOL JS_IsRegisteredClass (JSRuntime *rt, JSClassID class_id) {
return (class_id < rt->class_count
&& rt->class_array[class_id].class_id != 0);
BOOL JS_IsRegisteredClass (JSContext *ctx, JSClassID class_id) {
return (class_id < ctx->class_count
&& ctx->class_array[class_id].class_id != 0);
}
/* create a new object internal class. Return -1 if error, 0 if
OK. The finalizer can be NULL if none is needed. */
static int JS_NewClass1 (JSRuntime *rt, JSClassID class_id, const JSClassDef *class_def, const char *name) {
int new_size;
static int JS_NewClass1 (JSContext *ctx, JSClassID class_id, const JSClassDef *class_def, const char *name) {
int new_size, i;
JSClass *cl, *new_class_array;
JSValue *new_class_proto;
if (class_id >= (1 << 16)) return -1;
if (class_id < rt->class_count && rt->class_array[class_id].class_id != 0)
if (class_id < ctx->class_count && ctx->class_array[class_id].class_id != 0)
return -1;
if (class_id >= rt->class_count) {
if (class_id >= ctx->class_count) {
new_size = max_int (JS_CLASS_INIT_COUNT,
max_int (class_id + 1, rt->class_count * 3 / 2));
max_int (class_id + 1, ctx->class_count * 3 / 2));
/* reallocate the class array */
new_class_array
= js_realloc_rt (rt->class_array, sizeof (JSClass) * new_size);
= js_realloc_rt (ctx->class_array, sizeof (JSClass) * new_size);
if (!new_class_array) return -1;
memset (new_class_array + rt->class_count, 0, (new_size - rt->class_count) * sizeof (JSClass));
rt->class_array = new_class_array;
rt->class_count = new_size;
memset (new_class_array + ctx->class_count, 0, (new_size - ctx->class_count) * sizeof (JSClass));
ctx->class_array = new_class_array;
/* reallocate the class proto array */
new_class_proto
= js_realloc_rt (ctx->class_proto, sizeof (JSValue) * new_size);
if (!new_class_proto) return -1;
for (i = ctx->class_count; i < new_size; i++)
new_class_proto[i] = JS_NULL;
ctx->class_proto = new_class_proto;
ctx->class_count = new_size;
}
cl = &rt->class_array[class_id];
cl = &ctx->class_array[class_id];
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;
/* call field removed from JSClass - use class_def->call directly if needed
*/
return 0;
}
int JS_NewClass (JSRuntime *rt, JSClassID class_id, const JSClassDef *class_def) {
int JS_NewClass (JSContext *ctx, JSClassID class_id, const JSClassDef *class_def) {
/* class_name is stored directly as const char* */
return JS_NewClass1 (rt, class_id, class_def, class_def->class_name);
return JS_NewClass1 (ctx, class_id, class_def, class_def->class_name);
}
static JSValue js_new_string8_len (JSContext *ctx, const char *buf, int len) {
@@ -4250,24 +4241,20 @@ void JS_DumpMemoryUsage (FILE *fp, const JSMemoryUsage *s, JSRuntime *rt) {
/* WARNING: obj is freed */
JSValue JS_Throw (JSContext *ctx, JSValue obj) {
JSRuntime *rt = ctx->rt;
rt->current_exception = obj;
/* uncatchable flag removed - not needed with copying GC */
ctx->current_exception = obj;
return JS_EXCEPTION;
}
/* return the pending exception (cannot be called twice). */
JSValue JS_GetException (JSContext *ctx) {
JSValue val;
JSRuntime *rt = ctx->rt;
val = rt->current_exception;
rt->current_exception = JS_UNINITIALIZED;
JSValue val = ctx->current_exception;
ctx->current_exception = JS_UNINITIALIZED;
return val;
}
JS_BOOL
JS_HasException (JSContext *ctx) {
return !JS_IsUninitialized (ctx->rt->current_exception);
return !JS_IsUninitialized (ctx->current_exception);
}
static void dbuf_put_leb128 (DynBuf *s, uint32_t v) {
@@ -4438,7 +4425,7 @@ static void build_backtrace (JSContext *ctx, JSValue error_obj, const char *file
return;
}
}
for (sf = ctx->rt->current_stack_frame; sf != NULL; sf = sf->prev_frame) {
for (sf = ctx->current_stack_frame; sf != NULL; sf = sf->prev_frame) {
if (sf->js_mode & JS_MODE_BACKTRACE_BARRIER) break;
if (backtrace_flags & JS_BACKTRACE_FLAG_SKIP_FIRST_LEVEL) {
backtrace_flags &= ~JS_BACKTRACE_FLAG_SKIP_FIRST_LEVEL;
@@ -4527,12 +4514,11 @@ static JSValue JS_ThrowError2 (JSContext *ctx, JSErrorEnum error_num, const char
}
static JSValue JS_ThrowError (JSContext *ctx, JSErrorEnum error_num, const char *fmt, va_list ap) {
JSRuntime *rt = ctx->rt;
JSStackFrame *sf;
BOOL add_backtrace;
/* the backtrace is added later if called from a bytecode function */
sf = rt->current_stack_frame;
sf = ctx->current_stack_frame;
add_backtrace = (!sf || (JS_GetFunctionBytecode (sf->cur_func) == NULL));
return JS_ThrowError2 (ctx, error_num, fmt, ap, add_backtrace);
}
@@ -4628,8 +4614,7 @@ static JSValue JS_ThrowReferenceErrorUninitialized2 (JSContext *ctx,
}
static JSValue JS_ThrowTypeErrorInvalidClass (JSContext *ctx, int class_id) {
JSRuntime *rt = ctx->rt;
const char *name = rt->class_array[class_id].class_name;
const char *name = ctx->class_array[class_id].class_name;
return JS_ThrowTypeError (ctx, "%s object expected", name ? name : "unknown");
}
@@ -4639,10 +4624,9 @@ static void JS_ThrowInterrupted (JSContext *ctx) {
}
static no_inline __exception int __js_poll_interrupts (JSContext *ctx) {
JSRuntime *rt = ctx->rt;
ctx->interrupt_counter = JS_INTERRUPT_COUNTER_INIT;
if (rt->interrupt_handler) {
if (rt->interrupt_handler (rt, rt->interrupt_opaque)) {
if (ctx->interrupt_handler) {
if (ctx->interrupt_handler (ctx->rt, ctx->interrupt_opaque)) {
JS_ThrowInterrupted (ctx);
return -1;
}
@@ -6609,7 +6593,6 @@ fail:
#define JS_CALL_FLAG_COPY_ARGV (1 << 1)
static JSValue js_call_c_function (JSContext *ctx, JSValue func_obj, JSValue this_obj, int argc, JSValue *argv) {
JSRuntime *rt = ctx->rt;
JSCFunctionType func;
JSFunction *f;
JSStackFrame sf_s, *sf = &sf_s, *prev_sf;
@@ -6624,12 +6607,12 @@ static JSValue js_call_c_function (JSContext *ctx, JSValue func_obj, JSValue thi
arg_count = f->length;
/* better to always check stack overflow */
if (js_check_stack_overflow (rt, sizeof (arg_buf[0]) * arg_count))
if (js_check_stack_overflow (ctx, sizeof (arg_buf[0]) * arg_count))
return JS_ThrowStackOverflow (ctx);
prev_sf = rt->current_stack_frame;
prev_sf = ctx->current_stack_frame;
sf->prev_frame = prev_sf;
rt->current_stack_frame = sf;
ctx->current_stack_frame = sf;
sf->js_mode = 0;
sf->cur_func = (JSValue)func_obj;
sf->arg_count = argc;
@@ -6728,7 +6711,7 @@ static JSValue js_call_c_function (JSContext *ctx, JSValue func_obj, JSValue thi
abort ();
}
rt->current_stack_frame = sf->prev_frame;
ctx->current_stack_frame = sf->prev_frame;
/* Restore value stack if we used it for arg padding */
if (saved_vs_top >= 0)
@@ -6748,7 +6731,6 @@ typedef enum {
/* argv[] is modified if (flags & JS_CALL_FLAG_COPY_ARGV) = 0. */
static JSValue JS_CallInternal (JSContext *caller_ctx, JSValue func_obj, JSValue this_obj, int argc, JSValue *argv, int flags) {
JSRuntime *rt = caller_ctx->rt;
JSContext *ctx = caller_ctx;
JSFunction *f;
JSFunctionBytecode *b;
@@ -6830,7 +6812,7 @@ static JSValue JS_CallInternal (JSContext *caller_ctx, JSValue func_obj, JSValue
alloca_size
= sizeof (JSValue) * (arg_allocated_size + b->var_count + b->stack_size);
if (js_check_stack_overflow (rt, alloca_size))
if (js_check_stack_overflow (ctx, alloca_size))
return JS_ThrowStackOverflow (caller_ctx);
sf->js_mode = b->js_mode;
@@ -6877,8 +6859,8 @@ static JSValue JS_CallInternal (JSContext *caller_ctx, JSValue func_obj, JSValue
pc = b->byte_code_buf;
sf->stack_buf = stack_buf;
sf->p_sp = &sp; /* GC uses this to find current stack top */
sf->prev_frame = rt->current_stack_frame;
rt->current_stack_frame = sf;
sf->prev_frame = ctx->current_stack_frame;
ctx->current_stack_frame = sf;
restart:
for (;;) {
@@ -8579,12 +8561,12 @@ restart:
}
}
exception:
if (is_backtrace_needed (ctx, rt->current_exception)) {
if (is_backtrace_needed (ctx, ctx->current_exception)) {
/* add the backtrace information now (it is not done
before if the exception happens in a bytecode
operation */
sf->cur_pc = pc;
build_backtrace (ctx, rt->current_exception, NULL, 0, 0, 0);
build_backtrace (ctx, ctx->current_exception, NULL, 0, 0, 0);
}
/* All exceptions are catchable in the simplified runtime */
while (sp > stack_buf) {
@@ -8592,8 +8574,8 @@ exception:
if (JS_VALUE_GET_TAG (val) == JS_TAG_CATCH_OFFSET) {
int pos = JS_VALUE_GET_INT (val);
if (pos != 0) {
*sp++ = rt->current_exception;
rt->current_exception = JS_UNINITIALIZED;
*sp++ = ctx->current_exception;
ctx->current_exception = JS_UNINITIALIZED;
pc = b->byte_code_buf + pos;
goto restart;
}
@@ -8601,7 +8583,7 @@ exception:
}
ret_val = JS_EXCEPTION;
done:
rt->current_stack_frame = sf->prev_frame;
ctx->current_stack_frame = sf->prev_frame;
if (unlikely (caller_ctx->trace_hook)
&& (caller_ctx->trace_type & JS_HOOK_RET))
@@ -9549,7 +9531,7 @@ static int js_parse_error_v (JSParseState *s, const uint8_t *ptr, const char *fm
int line_num, col_num;
line_num = get_line_col (&col_num, s->buf_start, ptr - s->buf_start);
JS_ThrowError2 (ctx, JS_SYNTAX_ERROR, fmt, ap, FALSE);
build_backtrace (ctx, ctx->rt->current_exception, s->filename, line_num + 1, col_num + 1, 0);
build_backtrace (ctx, ctx->current_exception, s->filename, line_num + 1, col_num + 1, 0);
return -1;
}
@@ -10098,7 +10080,7 @@ static __exception int next_token (JSParseState *s) {
BOOL ident_has_escape;
JSValue ident_str;
if (js_check_stack_overflow (s->ctx->rt, 0)) {
if (js_check_stack_overflow (s->ctx, 0)) {
return js_parse_error (s, "stack overflow");
}
@@ -10711,7 +10693,7 @@ static __exception int json_next_token (JSParseState *s) {
int c;
JSValue ident_str;
if (js_check_stack_overflow (s->ctx->rt, 0)) {
if (js_check_stack_overflow (s->ctx, 0)) {
return js_parse_error (s, "stack overflow");
}
@@ -12490,7 +12472,7 @@ static __exception int js_parse_postfix_expr (JSParseState *s,
int line_num, col_num;
line_num
= get_line_col (&col_num, s->buf_start, s->token.ptr - s->buf_start);
build_backtrace (s->ctx, s->ctx->rt->current_exception, s->filename, line_num + 1, col_num + 1, 0);
build_backtrace (s->ctx, s->ctx->current_exception, s->filename, line_num + 1, col_num + 1, 0);
return -1;
}
ret = emit_push_const (s, str);
@@ -17479,7 +17461,7 @@ fail:
static int JS_WriteObjectRec (BCWriterState *s, JSValue obj) {
uint32_t tag;
if (js_check_stack_overflow (s->ctx->rt, 0)) {
if (js_check_stack_overflow (s->ctx, 0)) {
JS_ThrowStackOverflow (s->ctx);
return -1;
}
@@ -18127,7 +18109,7 @@ static JSValue JS_ReadObjectRec (BCReaderState *s) {
uint8_t tag;
JSValue obj = JS_NULL;
if (js_check_stack_overflow (ctx->rt, 0)) return JS_ThrowStackOverflow (ctx);
if (js_check_stack_overflow (ctx, 0)) return JS_ThrowStackOverflow (ctx);
if (bc_get_u8 (s, &tag)) return JS_EXCEPTION;
@@ -20129,14 +20111,13 @@ static JSValue js_regexp_toString (JSContext *ctx, JSValue this_val, int argc, J
int lre_check_stack_overflow (void *opaque, size_t alloca_size) {
JSContext *ctx = opaque;
return js_check_stack_overflow (ctx->rt, alloca_size);
return js_check_stack_overflow (ctx, alloca_size);
}
int lre_check_timeout (void *opaque) {
JSContext *ctx = opaque;
JSRuntime *rt = ctx->rt;
return (rt->interrupt_handler
&& rt->interrupt_handler (rt, rt->interrupt_opaque));
return (ctx->interrupt_handler
&& ctx->interrupt_handler (ctx->rt, ctx->interrupt_opaque));
}
void *lre_realloc (void *opaque, void *ptr, size_t size) {
@@ -20653,7 +20634,7 @@ static JSValue internalize_json_property (JSContext *ctx, JSValue holder, JSValu
uint32_t i, len = 0;
JSValue prop;
if (js_check_stack_overflow (ctx->rt, 0)) {
if (js_check_stack_overflow (ctx, 0)) {
return JS_ThrowStackOverflow (ctx);
}
@@ -20808,7 +20789,7 @@ static int js_json_to_str (JSContext *ctx, JSONStringifyContext *jsc, JSValue ho
tab_ref.val = JS_NULL;
prop_ref.val = JS_NULL;
if (js_check_stack_overflow (ctx->rt, 0)) {
if (js_check_stack_overflow (ctx, 0)) {
JS_ThrowStackOverflow (ctx);
goto exception;
}
@@ -26397,7 +26378,7 @@ static void JS_AddIntrinsicBaseObjects (JSContext *ctx) {
.class_name = "blob",
.finalizer = js_blob_finalizer,
};
JS_NewClass (JS_GetRuntime (ctx), JS_CLASS_BLOB, &blob_class);
JS_NewClass (ctx, JS_CLASS_BLOB, &blob_class);
ctx->class_proto[JS_CLASS_BLOB] = JS_NewObject (ctx);
JS_SetPropertyFunctionList (ctx, ctx->class_proto[JS_CLASS_BLOB], js_blob_proto_funcs, countof (js_blob_proto_funcs));
@@ -26559,7 +26540,7 @@ 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->rt->current_stack_frame;
JSStackFrame *sf = ctx->current_stack_frame;
while (sf != NULL) {
sf = sf->prev_frame;
stack_index++;
@@ -26572,7 +26553,7 @@ JSValue js_debugger_backtrace_fns (JSContext *ctx, const uint8_t *cur_pc) {
JSStackFrame *sf;
uint32_t stack_index = 0;
for (sf = ctx->rt->current_stack_frame; sf != NULL; sf = sf->prev_frame) {
for (sf = ctx->current_stack_frame; sf != NULL; sf = sf->prev_frame) {
uint32_t id = stack_index++;
JS_SetPropertyUint32 (ctx, ret, id, sf->cur_func);
}
@@ -26586,7 +26567,7 @@ JSValue js_debugger_build_backtrace (JSContext *ctx, const uint8_t *cur_pc) {
JSValue ret = JS_NewArray (ctx);
uint32_t stack_index = 0;
for (sf = ctx->rt->current_stack_frame; sf != NULL; sf = sf->prev_frame) {
for (sf = ctx->current_stack_frame; sf != NULL; sf = sf->prev_frame) {
JSValue current_frame = JS_NewObject (ctx);
uint32_t id = stack_index++;
@@ -26607,7 +26588,7 @@ JSValue js_debugger_build_backtrace (JSContext *ctx, const uint8_t *cur_pc) {
b = f->u.func.function_bytecode;
if (b->has_debug) {
const uint8_t *pc = sf != ctx->rt->current_stack_frame || !cur_pc
const uint8_t *pc = sf != ctx->current_stack_frame || !cur_pc
? sf->cur_pc
: cur_pc;
int col_num;
@@ -27099,7 +27080,7 @@ JSValue js_debugger_local_variables (JSContext *ctx, int stack_index) {
JSStackFrame *sf;
int cur_index = 0;
for (sf = ctx->rt->current_stack_frame; sf != NULL; sf = sf->prev_frame) {
for (sf = ctx->current_stack_frame; sf != NULL; sf = sf->prev_frame) {
// this val is one frame up
if (cur_index == stack_index - 1) {
if (js_is_bytecode_function (sf->cur_func)) {
@@ -31675,6 +31656,8 @@ char *JS_Tokenize (const char *source, size_t len, const char *filename) {
s.function_nr = 0;
s.errors = NULL;
s.has_error = 0;
s.lc_cache.ptr = s.buf_start;
s.lc_cache.buf_start = s.buf_start;
cJSON *root = cJSON_CreateObject ();
cJSON_AddStringToObject (root, "filename", filename);
@@ -33876,11 +33859,10 @@ static JSValue reg_vm_binop(JSContext *ctx, int op, JSValue a, JSValue b) {
/* Check for interrupt */
static int reg_vm_check_interrupt(JSContext *ctx) {
JSRuntime *rt = ctx->rt;
if (--ctx->interrupt_counter <= 0) {
ctx->interrupt_counter = JS_INTERRUPT_COUNTER_INIT;
if (rt->interrupt_handler) {
if (rt->interrupt_handler(rt, rt->interrupt_opaque)) {
if (ctx->interrupt_handler) {
if (ctx->interrupt_handler(ctx->rt, ctx->interrupt_opaque)) {
return -1;
}
}
@@ -33894,7 +33876,7 @@ void __asan_on_error(void) {
if (!ctx) return;
if (JS_IsNull(ctx->reg_current_frame)) return;
JSFrameRegister *frame = (JSFrameRegister *)JS_VALUE_GET_PTR(ctx->reg_current_frame);
uint32_t cur_pc = ctx->rt->current_register_pc;
uint32_t cur_pc = ctx->current_register_pc;
fprintf(stderr, "\n=== ASAN error: VM stack trace ===\n");
int is_first = 1;
while (frame) {
@@ -34018,7 +34000,7 @@ static JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
MachInstr32 instr = code->instructions[pc++];
ctx->reg_current_frame = frame_ref.val;
ctx->rt->current_register_pc = pc > 0 ? pc - 1 : 0;
ctx->current_register_pc = pc > 0 ? pc - 1 : 0;
int op = MACH_GET_OP(instr);
int a = MACH_GET_A(instr);
int b = MACH_GET_B(instr);
@@ -34347,7 +34329,7 @@ static JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
ctx->value_stack[vs_base + i] = frame->slots[base + 1 + i];
ctx->value_stack_top = vs_base + nargs;
ctx->reg_current_frame = frame_ref.val;
ctx->rt->current_register_pc = pc > 0 ? pc - 1 : 0;
ctx->current_register_pc = pc > 0 ? pc - 1 : 0;
JSValue ret = js_call_c_function(ctx, func_val, JS_NULL, nargs, &ctx->value_stack[vs_base]);
ctx->value_stack_top = vs_base;
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
@@ -34423,7 +34405,7 @@ static JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
ctx->value_stack[vs_base + 1] = frame->slots[base + 1]; /* the array */
ctx->value_stack_top = vs_base + 2;
ctx->reg_current_frame = frame_ref.val;
ctx->rt->current_register_pc = pc > 0 ? pc - 1 : 0;
ctx->current_register_pc = pc > 0 ? pc - 1 : 0;
JSValue ret = JS_CallInternal(ctx, frame->slots[base], JS_NULL, 2, &ctx->value_stack[vs_base], 0);
ctx->value_stack_top = vs_base;
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
@@ -34452,7 +34434,7 @@ static JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code,
ctx->value_stack[vs_base + i] = frame->slots[base + 2 + i];
ctx->value_stack_top = vs_base + nargs;
ctx->reg_current_frame = frame_ref.val;
ctx->rt->current_register_pc = pc > 0 ? pc - 1 : 0;
ctx->current_register_pc = pc > 0 ? pc - 1 : 0;
JSValue ret = js_call_c_function(ctx, method, frame->slots[base], nargs, &ctx->value_stack[vs_base]);
ctx->value_stack_top = vs_base;
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
@@ -34686,7 +34668,7 @@ done:
ctx->reg_current_frame = JS_NULL;
if (JS_IsException(result)) {
ctx->reg_current_frame = frame_ref.val;
ctx->rt->current_register_pc = pc > 0 ? pc - 1 : 0;
ctx->current_register_pc = pc > 0 ? pc - 1 : 0;
}
JS_DeleteGCRef(ctx, &frame_ref);
return result;
@@ -37606,7 +37588,7 @@ static JSValue mcode_exec(JSContext *ctx, JSMCode *code, JSValue this_obj,
}
ctx->value_stack_top = vs_base + c_argc;
ctx->reg_current_frame = frame_ref.val;
ctx->rt->current_register_pc = pc > 0 ? pc - 1 : 0;
ctx->current_register_pc = pc > 0 ? pc - 1 : 0;
JSValue c_result = JS_Call(ctx, new_frame->function, new_frame->slots[0], c_argc, &ctx->value_stack[vs_base]);
ctx->value_stack_top = vs_base;
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
@@ -37651,7 +37633,7 @@ static JSValue mcode_exec(JSContext *ctx, JSMCode *code, JSValue this_obj,
ctx->value_stack[vs_base + 1] = frame->slots[dest];
ctx->value_stack_top = vs_base + 2;
ctx->reg_current_frame = frame_ref.val;
ctx->rt->current_register_pc = pc > 0 ? pc - 1 : 0;
ctx->current_register_pc = pc > 0 ? pc - 1 : 0;
JSValue ret = JS_CallInternal(ctx, frame->slots[obj_reg], JS_NULL, 2, &ctx->value_stack[vs_base], 0);
ctx->value_stack_top = vs_base;
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
@@ -37703,7 +37685,7 @@ static JSValue mcode_exec(JSContext *ctx, JSMCode *code, JSValue this_obj,
}
ctx->value_stack_top = vs_base + nargs;
ctx->reg_current_frame = frame_ref.val;
ctx->rt->current_register_pc = pc > 0 ? pc - 1 : 0;
ctx->current_register_pc = pc > 0 ? pc - 1 : 0;
JSValue ret = JS_Call(ctx, method, frame->slots[obj_reg], nargs, &ctx->value_stack[vs_base]);
ctx->value_stack_top = vs_base;
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
@@ -37747,7 +37729,7 @@ static JSValue mcode_exec(JSContext *ctx, JSMCode *code, JSValue this_obj,
ctx->value_stack[vs_base + 1] = frame->slots[dest];
ctx->value_stack_top = vs_base + 2;
ctx->reg_current_frame = frame_ref.val;
ctx->rt->current_register_pc = pc > 0 ? pc - 1 : 0;
ctx->current_register_pc = pc > 0 ? pc - 1 : 0;
JSValue ret = JS_CallInternal(ctx, frame->slots[obj_reg], JS_NULL, 2, &ctx->value_stack[vs_base], 0);
ctx->value_stack_top = vs_base;
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
@@ -37797,7 +37779,7 @@ static JSValue mcode_exec(JSContext *ctx, JSMCode *code, JSValue this_obj,
}
ctx->value_stack_top = vs_base + nargs;
ctx->reg_current_frame = frame_ref.val;
ctx->rt->current_register_pc = pc > 0 ? pc - 1 : 0;
ctx->current_register_pc = pc > 0 ? pc - 1 : 0;
JSValue ret = JS_Call(ctx, method, frame->slots[obj_reg], nargs, &ctx->value_stack[vs_base]);
ctx->value_stack_top = vs_base;
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
@@ -37897,7 +37879,7 @@ static JSValue mcode_exec(JSContext *ctx, JSMCode *code, JSValue this_obj,
}
ctx->value_stack_top = vs_base + len;
ctx->reg_current_frame = frame_ref.val;
ctx->rt->current_register_pc = pc > 0 ? pc - 1 : 0;
ctx->current_register_pc = pc > 0 ? pc - 1 : 0;
result = JS_Call(ctx, frame->slots[func_slot], JS_NULL, len, &ctx->value_stack[vs_base]);
ctx->value_stack_top = vs_base;
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val);
@@ -38091,7 +38073,7 @@ static JSValue mcode_exec(JSContext *ctx, JSMCode *code, JSValue this_obj,
done:
if (JS_IsException(result)) {
ctx->reg_current_frame = frame_ref.val;
ctx->rt->current_register_pc = pc > 0 ? pc - 1 : 0;
ctx->current_register_pc = pc > 0 ? pc - 1 : 0;
}
JS_DeleteGCRef(ctx, &frame_ref);
return result;
@@ -38099,10 +38081,9 @@ done:
/* Public API: get stack trace as cJSON array */
cJSON *JS_GetStack(JSContext *ctx) {
JSRuntime *rt = ctx->rt;
if (JS_IsNull(ctx->reg_current_frame)) return NULL;
JSFrameRegister *frame = (JSFrameRegister *)JS_VALUE_GET_PTR(ctx->reg_current_frame);
uint32_t cur_pc = rt->current_register_pc;
uint32_t cur_pc = ctx->current_register_pc;
cJSON *arr = cJSON_CreateArray();
int is_first = 1;

View File

@@ -367,10 +367,10 @@ JSRuntime *JS_NewRuntime (void);
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 (JSRuntime *rt, size_t stack_size);
void JS_SetMaxStackSize (JSContext *ctx, size_t stack_size);
/* should be called when changing thread to update the stack top value
used to check stack overflow. */
void JS_UpdateStackTop (JSRuntime *rt);
void JS_UpdateStackTop (JSContext *ctx);
void JS_FreeRuntime (JSRuntime *rt);
void *JS_GetRuntimeOpaque (JSRuntime *rt);
void JS_SetRuntimeOpaque (JSRuntime *rt, void *opaque);
@@ -429,9 +429,9 @@ JSClassID JS_NewClassID (JSClassID *pclass_id);
/* Returns the class ID if `v` is an object, otherwise returns
* JS_INVALID_CLASS_ID. */
JSClassID JS_GetClassID (JSValue v);
int JS_NewClass (JSRuntime *rt, JSClassID class_id,
int JS_NewClass (JSContext *ctx, JSClassID class_id,
const JSClassDef *class_def);
int JS_IsRegisteredClass (JSRuntime *rt, JSClassID class_id);
int JS_IsRegisteredClass (JSContext *ctx, JSClassID class_id);
extern JSClassID js_class_id_alloc;
@@ -740,7 +740,7 @@ JSValue JS_JSONStringify (JSContext *ctx, JSValue obj,
/* return != 0 if the JS code needs to be interrupted */
typedef int JSInterruptHandler (JSRuntime *rt, void *opaque);
void JS_SetInterruptHandler (JSRuntime *rt, JSInterruptHandler *cb,
void JS_SetInterruptHandler (JSContext *ctx, JSInterruptHandler *cb,
void *opaque);
/* select which debug info is stripped from the compiled code */
#define JS_STRIP_SOURCE (1 << 0) /* strip source code */

View File

@@ -266,11 +266,11 @@ void actor_free(cell_rt *actor)
JSContext *js = actor->context;
JS_FreeValue(js, actor->idx_buffer);
JS_FreeValue(js, actor->message_handle);
JS_FreeValue(js, actor->on_exception);
JS_FreeValue(js, actor->unneeded);
JS_FreeValue(js, actor->actor_sym);
JS_DeleteGCRef(js, &actor->idx_buffer_ref);
JS_DeleteGCRef(js, &actor->on_exception_ref);
JS_DeleteGCRef(js, &actor->message_handle_ref);
JS_DeleteGCRef(js, &actor->unneeded_ref);
JS_DeleteGCRef(js, &actor->actor_sym_ref);
for (int i = 0; i < hmlen(actor->timers); i++) {
JS_FreeValue(js, actor->timers[i].value);
@@ -289,10 +289,8 @@ void actor_free(cell_rt *actor)
arrfree(actor->letters);
JSRuntime *rt = JS_GetRuntime(js);
JS_SetInterruptHandler(rt, NULL, NULL);
JS_SetInterruptHandler(js, NULL, NULL);
JS_FreeContext(js);
JS_FreeRuntime(rt);
free(actor->id);
pthread_mutex_unlock(actor->mutex);
@@ -419,8 +417,8 @@ uint32_t actor_remove_cb(cell_rt *actor, uint32_t id, uint32_t interval)
actor->disrupt = 1;
if (!JS_IsNull(actor->unneeded)) {
JSValue ret = JS_Call(actor->context, actor->unneeded, JS_NULL, 0, NULL);
if (!JS_IsNull(actor->unneeded_ref.val)) {
JSValue ret = JS_Call(actor->context, actor->unneeded_ref.val, JS_NULL, 0, NULL);
uncaught_exception(actor->context, ret);
}
@@ -434,14 +432,13 @@ uint32_t actor_remove_cb(cell_rt *actor, uint32_t id, uint32_t interval)
void actor_unneeded(cell_rt *actor, JSValue fn, double seconds)
{
if (actor->disrupt) return;
JS_FreeValue(actor->context, actor->unneeded);
if (!JS_IsFunction(fn)) {
actor->unneeded = JS_NULL;
actor->unneeded_ref.val = JS_NULL;
goto END;
}
actor->unneeded = JS_DupValue(actor->context, fn);
actor->unneeded_ref.val = fn;
actor->ar_secs = seconds;
END:
@@ -493,11 +490,10 @@ cell_rt *create_actor(void *wota)
actor->heap = mi_heap_new();
#endif
actor->init_wota = wota;
actor->idx_buffer = JS_NULL;
actor->message_handle = JS_NULL;
actor->unneeded = JS_NULL;
actor->on_exception = JS_NULL;
actor->actor_sym = JS_NULL;
/* GCRef fields are registered after JSContext creation in script_startup.
For now, zero-init from calloc is sufficient (val = 0 = JS_MKVAL(JS_TAG_INT,0),
which is not a pointer so GC-safe). The actual JS_NULL assignment and
JS_AddGCRef happen in script_startup. */
arrsetcap(actor->letters, 5);
@@ -587,7 +583,7 @@ void actor_turn(cell_rt *actor)
size_t size = blob_length(l.blob_data) / 8; // Convert bits to bytes
JSValue arg = js_new_blob_stoned_copy(actor->context, (void*)blob_data(l.blob_data), size);
blob_destroy(l.blob_data);
result = JS_Call(actor->context, actor->message_handle, JS_NULL, 1, &arg);
result = JS_Call(actor->context, actor->message_handle_ref.val, JS_NULL, 1, &arg);
uncaught_exception(actor->context, result);
JS_FreeValue(actor->context, arg);
} else if (l.type == LETTER_CALLBACK) {

View File

@@ -118,11 +118,11 @@ void actor_free(cell_rt *actor)
JSContext *js = actor->context;
JS_FreeValue(js, actor->idx_buffer);
JS_FreeValue(js, actor->message_handle);
JS_FreeValue(js, actor->on_exception);
JS_FreeValue(js, actor->unneeded);
JS_FreeValue(js, actor->actor_sym);
JS_DeleteGCRef(js, &actor->idx_buffer_ref);
JS_DeleteGCRef(js, &actor->on_exception_ref);
JS_DeleteGCRef(js, &actor->message_handle_ref);
JS_DeleteGCRef(js, &actor->unneeded_ref);
JS_DeleteGCRef(js, &actor->actor_sym_ref);
/* Free timer callbacks stored in actor */
for (int i = 0; i < hmlen(actor->timers); i++) {
@@ -142,10 +142,8 @@ void actor_free(cell_rt *actor)
arrfree(actor->letters);
JSRuntime *rt = JS_GetRuntime(js);
JS_SetInterruptHandler(rt, NULL, NULL);
JS_SetInterruptHandler(js, NULL, NULL);
JS_FreeContext(js);
JS_FreeRuntime(rt);
free(actor->id);
free(actor);
@@ -157,14 +155,13 @@ void actor_free(cell_rt *actor)
void actor_unneeded(cell_rt *actor, JSValue fn, double seconds)
{
if (actor->disrupt) return;
JS_FreeValue(actor->context, actor->unneeded);
if (!JS_IsFunction(actor->context, fn)) {
actor->unneeded = JS_NULL;
if (!JS_IsFunction(fn)) {
actor->unneeded_ref.val = JS_NULL;
goto END;
}
actor->unneeded = JS_DupValue(actor->context, fn);
actor->unneeded_ref.val = fn;
actor->ar_secs = seconds;
END:
@@ -257,8 +254,8 @@ uint32_t actor_remove_cb(cell_rt *actor, uint32_t id, uint32_t interval)
actor->disrupt = 1;
if (!JS_IsNull(actor->unneeded)) {
JSValue ret = JS_Call(actor->context, actor->unneeded, JS_NULL, 0, NULL);
if (!JS_IsNull(actor->unneeded_ref.val)) {
JSValue ret = JS_Call(actor->context, actor->unneeded_ref.val, JS_NULL, 0, NULL);
uncaught_exception(actor->context, ret);
}
@@ -328,11 +325,7 @@ cell_rt *create_actor(void *wota)
{
cell_rt *actor = calloc(sizeof(*actor), 1);
actor->init_wota = wota;
actor->idx_buffer = JS_NULL;
actor->message_handle = JS_NULL;
actor->unneeded = JS_NULL;
actor->on_exception = JS_NULL;
actor->actor_sym = JS_NULL;
/* GCRef fields are registered after JSContext creation in script_startup. */
arrsetcap(actor->letters, 5);
@@ -408,7 +401,7 @@ void actor_turn(cell_rt *actor)
size_t size = blob_length(l.blob_data) / 8; // Convert bits to bytes
JSValue arg = js_new_blob_stoned_copy(actor->context, (void *)blob_data(l.blob_data), size);
blob_destroy(l.blob_data);
result = JS_Call(actor->context, actor->message_handle, JS_NULL, 1, &arg);
result = JS_Call(actor->context, actor->message_handle_ref.val, JS_NULL, 1, &arg);
uncaught_exception(actor->context, result);
JS_FreeValue(actor->context, arg);
} else if (l.type == LETTER_CALLBACK) {