From 94394c68458a7e5be68c44744db5bcf5aca42fec Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Sat, 21 Jun 2025 13:12:23 -0500 Subject: [PATCH] initial attempt --- prosperon/prosperon.ce | 2 +- prosperon/sdl_video.ce | 4 +++- scripts/engine.cm | 6 ++++-- source/cell.c | 17 +++++++++++++++-- source/jsffi.c | 14 ++++++++------ source/qjs_sdl_video.c | 2 -- source/quickjs.c | 26 ++++++++++++++++++++++++-- 7 files changed, 55 insertions(+), 16 deletions(-) diff --git a/prosperon/prosperon.ce b/prosperon/prosperon.ce index 6da6bae5..750e0698 100644 --- a/prosperon/prosperon.ce +++ b/prosperon/prosperon.ce @@ -310,7 +310,7 @@ var input_state = { // 1) input runs completely independently function poll_input() { - send(video, {kind:'input', op:'get'}, evs => { + send(video, {kind:'input', op:'get'}, (evs=[]) => { for (var ev of evs) { if (ev.type == 'quit') $_.stop() diff --git a/prosperon/sdl_video.ce b/prosperon/sdl_video.ce index b56c872e..4ce121df 100644 --- a/prosperon/sdl_video.ce +++ b/prosperon/sdl_video.ce @@ -117,7 +117,9 @@ $_.receiver(function(msg) { response = {error: "Unknown kind: " + msg.kind}; } } catch (e) { - response = {error: e.toString()}; + log.console(typeof e) + log.console(typeof null) + response = {error: e}; log.error(e) } diff --git a/scripts/engine.cm b/scripts/engine.cm index c487c7d6..3ac2f696 100644 --- a/scripts/engine.cm +++ b/scripts/engine.cm @@ -267,7 +267,7 @@ config.system ??= {} config.system.__proto__ = default_config ENETSERVICE = config.system.net_service -REPLYTIMEOUT = config.system.reply_timeout +REPLYTIMEOUT = Number(config.system.reply_timeout) globalThis.text = use('text') @@ -510,6 +510,7 @@ $_.start = function start(cb, program, ...args) { $_.stop = function stop(actor) { if (!actor) { + log.system(`actor stopping.`) need_stop = true return } @@ -607,6 +608,7 @@ function actor_send(actor, message) { return } log.system(`Unable to send message to actor ${json.encode(actor[ACTORDATA])}`) + log.system(`message was ${json.encode(message)}`) } // Holds all messages queued during the current turn. @@ -677,7 +679,7 @@ function turn(msg) load_actor_config(cell.args.program) -actor_mod.register_actor(cell.id, turn, cell.args.main, Number(config.system.ar_timer)) +actor_mod.register_actor(cell.id, turn, cell.args.main, 60) if (Number(config.system.actor_memory)) js.mem_limit(Number(config.system.actor_memory)) diff --git a/source/cell.c b/source/cell.c index 558739bc..c342bff0 100644 --- a/source/cell.c +++ b/source/cell.c @@ -117,6 +117,7 @@ static void exit_handler(void) void actor_free(cell_rt *actor) { // Delete it out of actors first so it can no longer get messages + printf("killing off %s\n", actor->id); SDL_LockMutex(actors_mutex); shdel(actors, actor->id); int remaining = shlen(actors); @@ -788,8 +789,20 @@ int uncaught_exception(JSContext *js, JSValue v) } JSValue exp = JS_GetException(js); - JSValue ret = JS_Call(js, rt->on_exception, JS_NULL, 1, &exp); - JS_FreeValue(js,ret); + + if (JS_IsNull(rt->on_exception)) { + JSValue stack = JS_GetPropertyStr(js, exp, "stack"); + const char *ss = JS_ToCString(js,stack); + const char *se = JS_ToCString(js, exp); + printf("Uncaught exception %s:\n%s\n", se, ss); + JS_FreeCString(js,ss); + JS_FreeCString(js,se); + JS_FreeValue(js,stack); + } else { + JSValue ret = JS_Call(js, rt->on_exception, JS_NULL, 1, &exp); + JS_FreeValue(js,ret); + } + JS_FreeValue(js, exp); JS_FreeValue(js,v); SDL_UnlockMutex(rt->mutex); diff --git a/source/jsffi.c b/source/jsffi.c index 4245f9c2..29910b3c 100644 --- a/source/jsffi.c +++ b/source/jsffi.c @@ -180,7 +180,11 @@ int js2bool(JSContext *js, JSValue v) { return JS_ToBool(js,v); } JSValue number2js(JSContext *js, double g) { return JS_NewFloat64(js,g); } double js2number(JSContext *js, JSValue v) { double g; - JS_ToFloat64(js, &g, v); + if (JS_ToFloat64(js, &g, v) < 0) { + // If conversion fails, clear the exception and return 0 + JS_FreeValue(js, JS_GetException(js)); + return 0; + } if (isnan(g)) g = 0; return g; } @@ -696,9 +700,9 @@ JSValue js_util_camera_globals(JSContext *js, JSValue self, int argc, JSValue *a JSValue camera = argv[0]; if(JS_IsNull(camera)) return JS_NULL; - HMM_Vec2 size; HMM_Vec3 pos; HMM_Quat rotation; - double fov = 0; int ortho; double near_z = 0; double far_z = 0; - HMM_Vec2 anchor; + HMM_Vec2 size = {0}; HMM_Vec3 pos = {0}; HMM_Quat rotation = {0,0,0,1}; + double fov = 0; int ortho = 0; double near_z = 0; double far_z = 0; + HMM_Vec2 anchor = {0}; JS_GETPROP(js, size, camera, size, vec2) JS_GETPROP(js, fov, camera, fov, number) @@ -708,8 +712,6 @@ JSValue js_util_camera_globals(JSContext *js, JSValue self, int argc, JSValue *a JS_GETPROP(js, anchor, camera, anchor, vec2) JS_GETPROP(js, pos, camera, pos, vec3) JS_GETPROP(js, rotation, camera, rotation, quat) - - rotation.w = 1; HMM_Mat4 proj, view; diff --git a/source/qjs_sdl_video.c b/source/qjs_sdl_video.c index 7df95f3d..5d095b67 100644 --- a/source/qjs_sdl_video.c +++ b/source/qjs_sdl_video.c @@ -1781,8 +1781,6 @@ JSC_CCALL(sdl_createWindowAndRenderer, #include "qjs_wota.h" JSValue js_sdl_video_use(JSContext *js) { - printf("initing on thread %d\n", SDL_GetThreadID(NULL)); - if (!SDL_Init(SDL_INIT_VIDEO)) return JS_ThrowInternalError(js, "Unable to initialize video subsystem: %s", SDL_GetError()); diff --git a/source/quickjs.c b/source/quickjs.c index 302c32d2..13c0da4a 100644 --- a/source/quickjs.c +++ b/source/quickjs.c @@ -864,7 +864,7 @@ static JSProperty *add_property(JSContext *ctx, JSObject *p, JSAtom prop, int prop_flags); JSValue JS_ThrowOutOfMemory(JSContext *ctx); static JSValue JS_ThrowTypeErrorRevokedProxy(JSContext *ctx); - +static __exception int js_operator_typeof(JSContext *ctx, JSValueConst op1); static int js_resolve_proxy(JSContext *ctx, JSValueConst *pval, int throw_exception); static int JS_CreateProperty(JSContext *ctx, JSObject *p, JSAtom prop, JSValueConst val, @@ -10655,8 +10655,30 @@ static no_inline int js_relational_slow(JSContext *ctx, JSValue *sp, /* anything else → TypeError */ } else { + /* Get type names */ + JSAtom type1_atom = js_operator_typeof(ctx, op1); + JSAtom type2_atom = js_operator_typeof(ctx, op2); + const char *type1_name = JS_AtomToCString(ctx, type1_atom); + const char *type2_name = JS_AtomToCString(ctx, type2_atom); + + /* Convert values to strings for display */ + const char *val1_str = JS_ToCString(ctx, op1); + const char *val2_str = JS_ToCString(ctx, op2); + + /* Create detailed error message */ JS_ThrowTypeError(ctx, - "Relational operators only supported on two strings or two numbers"); + "TypeError: cannot compare \"%s\" (%s) with \"%s\" (%s)", + val1_str ? val1_str : "(conversion failed)", + type1_name ? type1_name : "unknown", + val2_str ? val2_str : "(conversion failed)", + type2_name ? type2_name : "unknown"); + + /* Free the C strings */ + if (val1_str) JS_FreeCString(ctx, val1_str); + if (val2_str) JS_FreeCString(ctx, val2_str); + JS_FreeCString(ctx, type1_name); + JS_FreeCString(ctx, type2_name); + JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); sp[-2] = JS_NULL;