From c570de7f41b958d93cfd58d63d394da883477989 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Fri, 6 Jun 2025 10:07:56 -0500 Subject: [PATCH] closes #18: actor data now behind private symbol --- prosperon/tests/window.ce | 7 +++---- scripts/engine.cm | 6 ++---- source/cell.c | 3 ++- source/jsffi.c | 13 ++++++++----- source/qjs_actor.c | 6 +++--- source/qjs_actor.h | 1 + source/qjs_nota.c | 27 +++++++++++++++++++++++---- source/qjs_wota.c | 18 +++++++++++++++++- tests/send.ce | 1 + 9 files changed, 60 insertions(+), 22 deletions(-) diff --git a/prosperon/tests/window.ce b/prosperon/tests/window.ce index 7595f4ee..d7db8efe 100644 --- a/prosperon/tests/window.ce +++ b/prosperon/tests/window.ce @@ -38,10 +38,9 @@ $_.delay($_.stop, 3) var os = use('os') var actor = use('actor') -var ioguy = { - __ACTORDATA__: { - id: actor.ioactor() - } +var ioguy = {} +ioguy[cell.actor_sym] = { + id: actor.ioactor() } send(ioguy, { diff --git a/scripts/engine.cm b/scripts/engine.cm index f304abb0..825d91b6 100644 --- a/scripts/engine.cm +++ b/scripts/engine.cm @@ -1,8 +1,7 @@ (function engine() { globalThis.cell = prosperon cell.DOC = Symbol() -var ACTORDATA = cell.hidden.ACTORSYM -ACTORDATA = '__ACTORDATA__' // TODO: implement the actual actorsym +var ACTORDATA = cell.hidden.actorsym var SYSYM = '__SYSTEM__' var ENETSERVICE = 0.1 @@ -112,7 +111,6 @@ function disrupt(err) actor_mod.on_exception(disrupt) var js = use_embed('js') - var io = use_embed('io') if (!io.exists('.cell')) { @@ -596,7 +594,7 @@ function actor_send(actor, message) { } return } - log.system(`Unable to send message to actor ${json.encode(actor)}`) + log.system(`Unable to send message to actor ${json.encode(actor[ACTORDATA])}`) } // Holds all messages queued during the current turn. diff --git a/source/cell.c b/source/cell.c index 87ec93d1..75410a63 100644 --- a/source/cell.c +++ b/source/cell.c @@ -341,6 +341,7 @@ cell_rt *create_actor(void *wota) actor->message_handle = JS_UNDEFINED; actor->unneeded = JS_UNDEFINED; actor->on_exception = JS_UNDEFINED; + actor->actor_sym = JS_ATOM_NULL; arrsetcap(actor->letters, 5); @@ -672,7 +673,7 @@ void script_startup(cell_rt *prt) JS_SetContextOpaque(js, prt); prt->context = js; ffi_load(js); - + PHYSFS_File *eng = PHYSFS_openRead(ENGINE); if (!eng) { printf("ERROR: Could not open file %s! %s\n", ENGINE, PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode())); diff --git a/source/jsffi.c b/source/jsffi.c index 749a580d..4c43f6f2 100644 --- a/source/jsffi.c +++ b/source/jsffi.c @@ -1613,6 +1613,14 @@ void ffi_load(JSContext *js) JS_SetPropertyStr(js, hidden_fn, "use_dyn", JS_NewCFunction(js, js_os_use_dyn, "use_dyn", 1)); JS_SetPropertyStr(js, hidden_fn, "use_embed", JS_NewCFunction(js, js_os_use_embed, "use_embed", 1)); + const char actorsym_script[] = "var sym = Symbol(`actordata`); sym;"; + + JSValue actorsym = JS_Eval(js, actorsym_script, sizeof(actorsym_script)-1, "internal", JS_EVAL_FLAG_STRICT); + + JS_SetPropertyStr(js, hidden_fn, "actorsym", actorsym); + + rt->actor_sym = JS_ValueToAtom(js, actorsym); + if (rt->init_wota) { JS_SetPropertyStr(js, hidden_fn, "init", wota2value(js, rt->init_wota)); // init wota can now be freed @@ -1620,11 +1628,6 @@ void ffi_load(JSContext *js) rt->init_wota = NULL; } -// cell_rt *actor = JS_GetContextOpaque(js); -// JSValue actorsym = js_newsymbol(js, "actor symbol", 0); -// actor->actor_sym = JS_ValueToAtom(js, actorsym); -// JS_SetPropertyStr(js, hidden_fn, "ACTORDATA", JS_DupValue(js,actorsym)); -// JS_FreeValue(js, actorsym); JS_SetPropertyStr(js, prosp, "hidden", hidden_fn); JS_FreeValue(js,globalThis); diff --git a/source/qjs_actor.c b/source/qjs_actor.c index 712205bc..ea0df91a 100644 --- a/source/qjs_actor.c +++ b/source/qjs_actor.c @@ -17,8 +17,8 @@ cell_rt *js2actor(JSContext *js, JSValue v) if (!JS_IsObject(v)) return NULL; - cell_rt *crt = JS_GetContextOpaque(js); - JSValue actor_data = JS_GetPropertyStr(js, v, "__ACTORDATA__"); + cell_rt *crt = JS_GetContextOpaque(js); + JSValue actor_data = JS_GetProperty(js, v, crt->actor_sym); if (JS_IsUndefined(actor_data)) { JS_FreeValue(js, actor_data); @@ -68,7 +68,7 @@ JSValue actor2js(JSContext *js, cell_rt *actor) cell_rt *crt = JS_GetContextOpaque(js); - JS_SetPropertyStr(js, actor_obj, "__ACTORDATA__", actor_data); + JS_SetProperty(js, actor_obj, crt->actor_sym, actor_data); return actor_obj; } diff --git a/source/qjs_actor.h b/source/qjs_actor.h index fc058560..1aaa3d9f 100644 --- a/source/qjs_actor.h +++ b/source/qjs_actor.h @@ -6,5 +6,6 @@ JSValue js_actor_use(JSContext *js); cell_rt *js2actor(JSContext *js, JSValue v); JSValue actor2js(JSContext *js, cell_rt *actor); +JSValue js_actor_set_symbol(JSContext *js, JSValue self, int argc, JSValue *argv); #endif \ No newline at end of file diff --git a/source/qjs_nota.c b/source/qjs_nota.c index 83acd3fa..5f853a73 100755 --- a/source/qjs_nota.c +++ b/source/qjs_nota.c @@ -102,10 +102,20 @@ char *js_do_nota_decode(JSContext *js, JSValue *tmp, char *nota, JSValue holder, break; case NOTA_SYM: nota = nota_read_sym(&b, nota); - switch(b) { - case NOTA_NULL: *tmp = JS_UNDEFINED; break; - case NOTA_FALSE: *tmp = JS_NewBool(js, 0); break; - case NOTA_TRUE: *tmp = JS_NewBool(js, 1); break; + if (b == NOTA_PRIVATE) { + JSValue inner; + nota = js_do_nota_decode(js, &inner, nota, holder, JS_UNDEFINED, reviver); + JSValue obj = JS_NewObject(js); + cell_rt *crt = JS_GetContextOpaque(js); + JS_SetProperty(js, obj, crt->actor_sym, inner); + *tmp = obj; + } else { + switch(b) { + case NOTA_NULL: *tmp = JS_UNDEFINED; break; + case NOTA_FALSE: *tmp = JS_NewBool(js, 0); break; + case NOTA_TRUE: *tmp = JS_NewBool(js, 1); break; + default: *tmp = JS_UNDEFINED; break; + } } break; default: @@ -191,6 +201,15 @@ static void nota_encode_value(NotaEncodeContext *enc, JSValueConst val, JSValueC break; } + cell_rt *crt = JS_GetContextOpaque(ctx); + JSValue adata = JS_GetProperty(ctx, replaced, crt->actor_sym); + if (!JS_IsUndefined(adata)) { + nota_write_sym(&enc->nb, NOTA_PRIVATE); + nota_encode_value(enc, adata, replaced, JS_UNDEFINED); + JS_FreeValue(ctx, adata); + break; + } + JS_FreeValue(ctx, adata); if (nota_stack_has(enc, replaced)) { enc->cycle = 1; break; diff --git a/source/qjs_wota.c b/source/qjs_wota.c index 7d3a54c4..109d5f35 100644 --- a/source/qjs_wota.c +++ b/source/qjs_wota.c @@ -152,6 +152,15 @@ static void wota_encode_value(WotaEncodeContext *enc, JSValueConst val, JSValueC wota_stack_pop(enc); break; } + cell_rt *crt = JS_GetContextOpaque(ctx); + JSValue adata = JS_GetProperty(ctx, replaced, crt->actor_sym); + if (!JS_IsUndefined(adata)) { + wota_write_sym(&enc->wb, WOTA_PRIVATE); + wota_encode_value(enc, adata, replaced, JS_UNDEFINED); + JS_FreeValue(ctx, adata); + break; + } + JS_FreeValue(ctx, adata); if (wota_stack_has(enc, replaced)) { enc->cycle = 1; break; @@ -201,7 +210,14 @@ static char *decode_wota_value(JSContext *ctx, char *data_ptr, JSValue *out_val, case WOTA_SYM: { int scode; data_ptr = wota_read_sym(&scode, data_ptr); - if (scode == WOTA_NULL) *out_val = JS_UNDEFINED; + if (scode == WOTA_PRIVATE) { + JSValue inner = JS_UNDEFINED; + data_ptr = decode_wota_value(ctx, data_ptr, &inner, holder, JS_UNDEFINED, reviver); + JSValue obj = JS_NewObject(ctx); + cell_rt *crt = JS_GetContextOpaque(ctx); + JS_SetProperty(ctx, obj, crt->actor_sym, inner); + *out_val = obj; + } else if (scode == WOTA_NULL) *out_val = JS_UNDEFINED; else if (scode == WOTA_FALSE) *out_val = JS_NewBool(ctx, 0); else if (scode == WOTA_TRUE) *out_val = JS_NewBool(ctx, 1); else *out_val = JS_UNDEFINED; diff --git a/tests/send.ce b/tests/send.ce index 8770c45c..2f5931e6 100644 --- a/tests/send.ce +++ b/tests/send.ce @@ -1,4 +1,5 @@ $_.start(e => { + log.console("SENDING!") send(e.actor, { message: "Hello! Good to go?" }, msg => { log.console(`Original sender got message back: ${json.encode(msg)}. Stopping!`) $_.stop()