From a4a0745385722965741e2ab713cda9691a127e4d Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Sun, 13 Feb 2022 22:39:22 +0000 Subject: [PATCH] Send prints to the browser console. Obvious in retrospect. git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3840 ed5197a5-7fde-0310-b194-c3ffbd925b24 --- core/client.js | 2 ++ core/core.js | 3 +++ src/task.c | 34 +++++++++++++++++++++++++++++++--- src/task.h | 2 ++ src/taskstub.js.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/taskstub.js.h | 1 + src/util.js.c | 1 + 7 files changed, 85 insertions(+), 3 deletions(-) diff --git a/core/client.js b/core/client.js index 4ec19653e..a668a4e3f 100644 --- a/core/client.js +++ b/core/client.js @@ -486,6 +486,8 @@ function receive(message) { } } console.log('error', message); + } else if (message && message.action == "print") { + console.log('app>', ...message.args); } else if (message && message.action == "stats") { var now = new Date().getTime(); for (var key of Object.keys(message.stats)) { diff --git a/core/core.js b/core/core.js index d43b0ef6a..f48075c92 100644 --- a/core/core.js +++ b/core/core.js @@ -200,6 +200,9 @@ async function getProcessBlob(blobId, key, options) { imports.app[api[0]] = process.app.makeFunction(api); } } + process.task.onPrint = function(args) { + process.app.send({action: 'print', args: args}); + }; process.task.onError = function(error) { try { process.app.send({action: 'error', error: error}); diff --git a/src/task.c b/src/task.c index eb708a76c..27dff7e06 100644 --- a/src/task.c +++ b/src/task.c @@ -167,6 +167,8 @@ static void _tf_task_sendPromiseExportMessage(tf_task_t* from, tf_taskstub_t* to static JSValue _tf_task_executeSource(tf_task_t* task, const char* source, const char* name); static tf_taskstub_t* _tf_task_get_stub(tf_task_t* task, taskid_t id); static void _tf_task_release_export(tf_taskstub_t* stub, exportid_t exportId); +static void _tf_task_run_jobs_idle(uv_idle_t* idle); +static void _tf_task_run_jobs_prepare(uv_prepare_t* prepare); typedef struct _import_record_t { @@ -774,6 +776,7 @@ const char* _tf_task_get_message_type(tf_task_message_t type) case kLoadFile: return "kLoadFile"; case kTaskError: return "kTaskError"; case kTaskTrace: return "kTaskTrace"; + case kPrint: return "kPrint"; } return "unknown"; } @@ -852,6 +855,7 @@ void tf_task_on_receive_packet(int packetType, const char* begin, size_t length, } break; case kSetRequires: + JS_FreeValue(to->_context, to->_requires); to->_requires = tf_serialize_load(to, from, begin, length); break; case kLoadFile: @@ -945,6 +949,13 @@ void tf_task_on_receive_packet(int packetType, const char* begin, size_t length, JS_FreeValue(to->_context, error); } break; + case kPrint: + { + JSValue arguments = tf_serialize_load(to, from, begin, length); + tf_taskstub_on_print(from, arguments); + JS_FreeValue(to->_context, arguments); + } + break; case kTaskTrace: tf_trace_raw(to->_trace, begin, length); break; @@ -1323,9 +1334,6 @@ static void _tf_task_trace_timer(uv_timer_t* timer) tf_trace_counter(task->_trace, "task", sizeof(k_names) / sizeof(*k_names), k_names, values); } -static void _tf_task_run_jobs_idle(uv_idle_t* idle); -static void _tf_task_run_jobs_prepare(uv_prepare_t* prepare); - static bool _tf_task_run_jobs(tf_task_t* task) { if (JS_IsJobPending(task->_runtime)) @@ -1653,6 +1661,26 @@ JSValue tf_task_add_import(tf_task_t* task, taskid_t stub_id, exportid_t export_ return JS_DupValue(task->_context, function); } +void tf_task_print(tf_task_t* task, int argc, JSValueConst* argv) +{ + if (task->_parent) + { + JSValue array = JS_NewArray(task->_context); + for (int i = 0; i < argc; i++) + { + JS_SetPropertyUint32(task->_context, array, i, argv[i]); + } + + void* buffer; + size_t size; + tf_serialize_store(task, task->_parent, &buffer, &size, array); + tf_packetstream_send(tf_taskstub_get_stream(task->_parent), kPrint, buffer, size); + free(buffer); + + JS_FreeValue(task->_context, array); + } +} + tf_task_t* tf_task_get(JSContext* context) { return JS_GetContextOpaque(context); diff --git a/src/task.h b/src/task.h index 0f7707068..1127646a0 100644 --- a/src/task.h +++ b/src/task.h @@ -33,6 +33,7 @@ typedef enum _tf_task_message_t { kLoadFile, kTaskError, kTaskTrace, + kPrint, } tf_task_message_t; tf_task_t* tf_task_create(); @@ -56,6 +57,7 @@ tf_task_t* tf_task_get(JSContext* context); tf_trace_t* tf_task_get_trace(tf_task_t* task); tf_ssb_t* tf_task_get_ssb(tf_task_t* task); const char* tf_task_get_name(tf_task_t* task); +void tf_task_print(tf_task_t* task, int argc, JSValueConst* argv); JSValue tf_task_allocate_promise(tf_task_t* task, promiseid_t* out_promise); void tf_task_reject_promise(tf_task_t* task, promiseid_t promise, JSValue error); diff --git a/src/taskstub.js.c b/src/taskstub.js.c index 6cd5e57de..7dd1cff1c 100644 --- a/src/taskstub.js.c +++ b/src/taskstub.js.c @@ -32,6 +32,7 @@ typedef struct _tf_taskstub_t { JSValue _on_exit; JSValue _on_error; + JSValue _on_print; tf_task_t* _owner; tf_packetstream_t* _stream; @@ -61,6 +62,8 @@ static JSValue _taskstub_get_on_exit(JSContext* context, JSValueConst this_val, static JSValue _taskstub_set_on_exit(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); static JSValue _taskstub_get_on_error(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); static JSValue _taskstub_set_on_error(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); +static JSValue _taskstub_get_on_print(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); +static JSValue _taskstub_set_on_print(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); static JSValue _taskstub_loadFile(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); static void _taskstub_on_process_exit(uv_process_t* process, int64_t status, int terminationSignal); static void _taskstub_finalizer(JSRuntime *runtime, JSValue value); @@ -77,6 +80,7 @@ static JSValue _taskstub_create(JSContext* context, JSValueConst this_val, int a stub->_owner = parent; stub->_on_exit = JS_UNDEFINED; stub->_on_error = JS_UNDEFINED; + stub->_on_print = JS_UNDEFINED; stub->_object = JS_DupValue(context, taskObject); JSAtom atom = JS_NewAtom(context, "onExit"); @@ -99,6 +103,16 @@ static JSValue _taskstub_create(JSContext* context, JSValueConst this_val, int a 0); JS_FreeAtom(context, atom); + atom = JS_NewAtom(context, "onPrint"); + JS_DefinePropertyGetSet( + context, + taskObject, + atom, + JS_NewCFunction(context, _taskstub_get_on_print, "getOnPrint", 0), + JS_NewCFunction(context, _taskstub_set_on_print, "setOnPrint", 0), + 0); + JS_FreeAtom(context, atom); + JS_SetPropertyStr(context, taskObject, "activate", JS_NewCFunction(context, _taskstub_activate, "activate", 0)); JS_SetPropertyStr(context, taskObject, "execute", JS_NewCFunction(context, _taskstub_execute, "execute", 1)); JSAtom imports = JS_NewAtom(context, "imports"); @@ -166,6 +180,7 @@ void _taskstub_gc_mark(JSRuntime* rt, JSValueConst value, JS_MarkFunc mark_func) { JS_MarkValue(rt, stub->_on_exit, mark_func); JS_MarkValue(rt, stub->_on_error, mark_func); + JS_MarkValue(rt, stub->_on_print, mark_func); } } @@ -211,6 +226,7 @@ tf_taskstub_t* tf_taskstub_create_parent(tf_task_t* task, uv_file file) parentStub->_stream = tf_packetstream_create(); parentStub->_on_exit = JS_UNDEFINED; parentStub->_on_error = JS_UNDEFINED; + parentStub->_on_print = JS_UNDEFINED; parentStub->_taskObject = parentObject; JS_SetOpaque(parentObject, parentStub); @@ -247,6 +263,7 @@ static void _taskstub_finalizer(JSRuntime* runtime, JSValue value) tf_taskstub_t* stub = JS_GetOpaque(value, _classId); stub->_on_exit = JS_UNDEFINED; stub->_on_error = JS_UNDEFINED; + stub->_on_print = JS_UNDEFINED; tf_packetstream_destroy(stub->_stream); stub->_stream = NULL; stub->_finalized = true; @@ -353,6 +370,23 @@ static JSValue _taskstub_set_on_error(JSContext* context, JSValueConst this_val, return JS_UNDEFINED; } +static JSValue _taskstub_get_on_print(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ + tf_taskstub_t* stub = JS_GetOpaque(this_val, _classId); + return JS_DupValue(context, stub->_on_print); +} + +static JSValue _taskstub_set_on_print(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ + tf_taskstub_t* stub = JS_GetOpaque(this_val, _classId); + if (!JS_IsUndefined(stub->_on_print)) + { + JS_FreeValue(context, stub->_on_print); + } + stub->_on_print = JS_DupValue(context, argv[0]); + return JS_UNDEFINED; +} + static JSValue _taskstub_activate(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { tf_taskstub_t* stub = JS_GetOpaque(this_val, _classId); @@ -399,3 +433,14 @@ void tf_taskstub_on_error(tf_taskstub_t* stub, JSValue error) JS_FreeValue(context, result); } } + +void tf_taskstub_on_print(tf_taskstub_t* stub, JSValue arguments) +{ + JSContext* context = tf_task_get_context(stub->_owner); + if (!JS_IsUndefined(stub->_on_print)) + { + JSValue result = JS_Call(context, stub->_on_print, JS_NULL, 1, &arguments); + tf_util_report_error(context, result); + JS_FreeValue(context, result); + } +} diff --git a/src/taskstub.js.h b/src/taskstub.js.h index 31235c41e..089597069 100644 --- a/src/taskstub.js.h +++ b/src/taskstub.js.h @@ -19,3 +19,4 @@ tf_task_t* tf_taskstub_get_owner(const tf_taskstub_t* stub); tf_taskstub_t* tf_taskstub_create_parent(tf_task_t* task, uv_file file); void tf_taskstub_destroy(tf_taskstub_t* stub); void tf_taskstub_on_error(tf_taskstub_t* stub, JSValue error); +void tf_taskstub_on_print(tf_taskstub_t* stub, JSValue arguments); diff --git a/src/util.js.c b/src/util.js.c index c35e86346..c9c9a3af7 100644 --- a/src/util.js.c +++ b/src/util.js.c @@ -84,6 +84,7 @@ JSValue _util_print(JSContext* context, JSValueConst this_val, int argc, JSValue if (task) { printf("Task[%p:%s]>", task, tf_task_get_name(task)); + tf_task_print(task, argc, argv); } for (int i = 0; i < argc; ++i) {