diff --git a/net/socket.c b/net/socket.c index 3c94097c..0264287f 100644 --- a/net/socket.c +++ b/net/socket.c @@ -648,6 +648,24 @@ JSC_CCALL(socket_getsockopt, return JS_NewInt32(js, optval); ) +JSC_CCALL(socket_send_self, + if (argc < 1 || !JS_IsText(argv[0])) + return JS_RaiseDisrupt(js, "send_self: expects a text argument"); + const char *msg = JS_ToCString(js, argv[0]); + WotaBuffer wb; + wota_buffer_init(&wb, 16); + wota_write_record(&wb, 1); + wota_write_text(&wb, "text"); + wota_write_text(&wb, msg); + JS_FreeCString(js, msg); + const char *err = JS_SendMessage(js, &wb); + if (err) { + wota_buffer_free(&wb); + return JS_RaiseDisrupt(js, "send_self failed: %s", err); + } + return JS_NULL; +) + static const JSCFunctionListEntry js_socket_funcs[] = { MIST_FUNC_DEF(socket, getaddrinfo, 3), MIST_FUNC_DEF(socket, socket, 3), @@ -670,6 +688,7 @@ static const JSCFunctionListEntry js_socket_funcs[] = { MIST_FUNC_DEF(socket, unwatch, 1), MIST_FUNC_DEF(socket, setnonblock, 1), MIST_FUNC_DEF(socket, getsockopt, 3), + MIST_FUNC_DEF(socket, send_self, 1), }; JSValue js_core_socket_use(JSContext *js) { diff --git a/source/scheduler.c b/source/scheduler.c index 085db44e..45725c8b 100644 --- a/source/scheduler.c +++ b/source/scheduler.c @@ -1065,12 +1065,38 @@ const char *JS_SendMessage(JSContext *ctx, WotaBuffer *wb) if (!wb || !wb->data || wb->size == 0) return "Empty WOTA buffer"; - size_t byte_len = wb->size * sizeof(uint64_t); - blob *msg = blob_new(byte_len * 8); - if (!msg) return "Could not allocate blob"; + /* Wrap the caller's payload in the engine protocol envelope: + {type: "user", data: } + The header takes ~6 words; pre-allocate enough for header + payload. */ + WotaBuffer envelope; + wota_buffer_init(&envelope, wb->size + 8); + wota_write_record(&envelope, 2); + wota_write_text(&envelope, "type"); + wota_write_text(&envelope, "user"); + wota_write_text(&envelope, "data"); - blob_write_bytes(msg, wb->data, byte_len); + /* Append the caller's pre-encoded WOTA payload words directly. */ + size_t need = envelope.size + wb->size; + if (need > envelope.capacity) { + size_t new_cap = envelope.capacity ? envelope.capacity * 2 : 8; + while (new_cap < need) new_cap *= 2; + envelope.data = realloc(envelope.data, new_cap * sizeof(uint64_t)); + envelope.capacity = new_cap; + } + memcpy(envelope.data + envelope.size, wb->data, + wb->size * sizeof(uint64_t)); + envelope.size += wb->size; + + size_t byte_len = envelope.size * sizeof(uint64_t); + blob *msg = blob_new(byte_len * 8); + if (!msg) { + wota_buffer_free(&envelope); + return "Could not allocate blob"; + } + + blob_write_bytes(msg, envelope.data, byte_len); blob_make_stone(msg); + wota_buffer_free(&envelope); const char *err = send_message(ctx->id, msg); if (!err) {