disruption
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#include "cell.h"
|
||||
#include "cell_internal.h"
|
||||
#include "quickjs-internal.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -7,24 +8,24 @@
|
||||
JSC_CCALL(os_createactor,
|
||||
cell_rt *rt = JS_GetContextOpaque(js);
|
||||
if (rt->disrupt)
|
||||
return JS_ThrowInternalError(js, "Can't start a new actor while disrupting.");
|
||||
return JS_RaiseDisrupt(js, "Can't start a new actor while disrupting.");
|
||||
|
||||
void *startup = value2wota(js, argv[0], JS_NULL, NULL);
|
||||
if (!startup)
|
||||
return JS_ThrowInternalError(js, "Failed to encode startup data");
|
||||
return JS_RaiseDisrupt(js, "Failed to encode startup data");
|
||||
create_actor(startup);
|
||||
)
|
||||
|
||||
JSC_CCALL(os_mailbox_push,
|
||||
if (argc < 2) return JS_ThrowInternalError(js, "Need an actor and a message");
|
||||
if (!js_is_blob(js, argv[1])) return JS_ThrowInternalError(js, "Can only send blobs.");
|
||||
if (argc < 2) return JS_RaiseDisrupt(js, "Need an actor and a message");
|
||||
if (!js_is_blob(js, argv[1])) return JS_RaiseDisrupt(js, "Can only send blobs.");
|
||||
|
||||
const char *id = JS_ToCString(js, argv[0]);
|
||||
int exist = actor_exists(id);
|
||||
|
||||
if (!exist) {
|
||||
JS_FreeCString(js, id);
|
||||
return JS_ThrowInternalError(js, "No mailbox found for given ID");
|
||||
return JS_RaiseDisrupt(js, "No mailbox found for given ID");
|
||||
}
|
||||
|
||||
size_t size;
|
||||
@@ -35,13 +36,13 @@ JSC_CCALL(os_mailbox_push,
|
||||
}
|
||||
if (size == 0) {
|
||||
JS_FreeCString(js, id);
|
||||
return JS_ThrowInternalError(js, "No data present in blob");
|
||||
return JS_RaiseDisrupt(js, "No data present in blob");
|
||||
}
|
||||
|
||||
blob *msg_blob = blob_new(size * 8);
|
||||
if (!msg_blob) {
|
||||
JS_FreeCString(js, id);
|
||||
return JS_ThrowInternalError(js, "Could not allocate blob");
|
||||
return JS_RaiseDisrupt(js, "Could not allocate blob");
|
||||
}
|
||||
|
||||
blob_write_bytes(msg_blob, data, size);
|
||||
@@ -51,7 +52,7 @@ JSC_CCALL(os_mailbox_push,
|
||||
JS_FreeCString(js, id);
|
||||
if (err) {
|
||||
blob_destroy(msg_blob);
|
||||
return JS_ThrowInternalError(js, "Could not send message: %s", err);
|
||||
return JS_RaiseDisrupt(js, "Could not send message: %s", err);
|
||||
}
|
||||
)
|
||||
|
||||
@@ -61,7 +62,7 @@ JSC_CCALL(os_register_actor,
|
||||
double ar;
|
||||
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);
|
||||
if (err) return JS_RaiseDisrupt(js, "Could not register actor: %s", err);
|
||||
rt->message_handle_ref.val = argv[1];
|
||||
rt->context = js;
|
||||
JS_FreeCString(js, id);
|
||||
@@ -99,7 +100,7 @@ JSC_CCALL(actor_on_exception,
|
||||
|
||||
JSC_CCALL(actor_clock,
|
||||
if (!JS_IsFunction(argv[0]))
|
||||
return JS_ThrowReferenceError(js, "Argument must be a function.");
|
||||
return JS_RaiseDisrupt(js, "Argument must be a function.");
|
||||
|
||||
cell_rt *actor = JS_GetContextOpaque(js);
|
||||
actor_clock(actor, argv[0]);
|
||||
@@ -107,7 +108,7 @@ JSC_CCALL(actor_clock,
|
||||
|
||||
JSC_CCALL(actor_delay,
|
||||
if (!JS_IsFunction(argv[0]))
|
||||
return JS_ThrowReferenceError(js, "Argument must be a function.");
|
||||
return JS_RaiseDisrupt(js, "Argument must be a function.");
|
||||
|
||||
cell_rt *actor = JS_GetContextOpaque(js);
|
||||
double seconds;
|
||||
@@ -129,6 +130,32 @@ JSC_CCALL(actor_removetimer,
|
||||
JS_FreeValue(js, removed);
|
||||
)
|
||||
|
||||
/* Log callback bridge: called from JS_Log, calls ƿit log(channel, [msg, stack])
|
||||
Captures the register VM stack trace so the log system can show the real error site. */
|
||||
static void js_log_callback(JSContext *ctx, const char *channel, const char *msg) {
|
||||
if (JS_IsNull(ctx->log_callback_js)) {
|
||||
fprintf(stderr, "%s\n", msg);
|
||||
return;
|
||||
}
|
||||
JS_FRAME(ctx);
|
||||
JS_ROOT(stack, JS_GetStack(ctx));
|
||||
JS_ROOT(args_array, JS_NewArray(ctx));
|
||||
JS_SetPropertyNumber(ctx, args_array.val, 0, JS_NewString(ctx, msg));
|
||||
JS_SetPropertyNumber(ctx, args_array.val, 1, stack.val);
|
||||
JSValue argv[2];
|
||||
argv[0] = JS_NewString(ctx, channel);
|
||||
argv[1] = args_array.val;
|
||||
JS_Call(ctx, ctx->log_callback_js, JS_NULL, 2, argv);
|
||||
JS_RestoreFrame(ctx, _js_gc_frame, _js_local_frame);
|
||||
}
|
||||
|
||||
JSC_CCALL(actor_set_log,
|
||||
if (argc < 1 || !JS_IsFunction(argv[0]))
|
||||
return JS_RaiseDisrupt(js, "set_log requires a function");
|
||||
js->log_callback_js = argv[0];
|
||||
js->log_callback = js_log_callback;
|
||||
)
|
||||
|
||||
static const JSCFunctionListEntry js_actor_funcs[] = {
|
||||
MIST_FUNC_DEF(os, createactor, 1),
|
||||
MIST_FUNC_DEF(os, mailbox_push, 2),
|
||||
@@ -141,6 +168,7 @@ static const JSCFunctionListEntry js_actor_funcs[] = {
|
||||
MIST_FUNC_DEF(actor, setname, 1),
|
||||
MIST_FUNC_DEF(actor, on_exception, 1),
|
||||
MIST_FUNC_DEF(actor, clock, 1),
|
||||
MIST_FUNC_DEF(actor, set_log, 1),
|
||||
};
|
||||
|
||||
JSValue js_core_actor_use(JSContext *js) {
|
||||
|
||||
Reference in New Issue
Block a user