diff --git a/src/ssb.js.c b/src/ssb.js.c index 5bf99cea..6b0c7eae 100644 --- a/src/ssb.js.c +++ b/src/ssb.js.c @@ -160,34 +160,6 @@ static JSValue _tf_ssb_connections(JSContext* context, JSValueConst this_val, in return result; } -static void _check_call(JSContext* context, JSValue result) -{ - if (JS_IsError(context, result)) - { - const char* value = JS_ToCString(context, result); - printf("ERROR: %s\n", value); - JS_FreeCString(context, value); - JSValue stack = JS_GetPropertyStr(context, result, "stack"); - if (!JS_IsUndefined(stack)) - { - const char* stack_str = JS_ToCString(context, stack); - printf("%s\n", stack_str); - JS_FreeCString(context, stack_str); - } - JS_FreeValue(context, stack); - } - else if (JS_IsException(result)) - { - js_std_dump_error(context); - JSValue error = JS_GetException(context); - const char* value = JS_ToCString(context, error); - printf("Exception: %s\n", value); - JS_FreeCString(context, value); - JS_FreeValue(context, error); - abort(); - } -} - typedef struct _sqlStream_callback_t { JSContext* context; @@ -198,7 +170,7 @@ static void _tf_ssb_sqlStream_callback(JSValue row, void* user_data) { sqlStream_callback_t* info = user_data; JSValue response = JS_Call(info->context, info->callback, JS_UNDEFINED, 1, &row); - _check_call(info->context, response); + tf_util_report_error(info->context, response); JS_FreeValue(info->context, response); if (tf_task_get(info->context)) { @@ -214,7 +186,7 @@ static void _tf_ssb_sqlStream_callback(JSValue row, void* user_data) if (context) { JSValue result = JS_GetException(context); - _check_call(context, result); + tf_util_report_error(context, result); } if (r < 0) { @@ -373,7 +345,7 @@ static void _tf_ssb_call_callback(tf_ssb_t* ssb, const char* name, void* user_da { JSValue args = JS_UNDEFINED; JSValue response = JS_Call(context, callback, JS_UNDEFINED, 0, &args); - _check_call(context, response); + tf_util_report_error(context, response); if (tf_task_get(context)) { tf_task_run_jobs(tf_task_get(context)); @@ -463,7 +435,7 @@ void _tf_ssb_on_rpc(tf_ssb_connection_t* connection, uint8_t flags, int32_t requ JS_SetPropertyStr(context, object, "send_binary", JS_NewCFunction(context, _tf_ssb_rpc_send_binary, "send_binary", 1)); JSValue result = JS_Call(context, callback, JS_UNDEFINED, 1, &object); - _check_call(context, result); + tf_util_report_error(context, result); JS_FreeValue(context, result); JS_FreeValue(context, object); } @@ -521,7 +493,7 @@ static void _tf_ssb_on_blob_want_added(tf_ssb_t* ssb, const char* id, void* user JSValue callback = JS_MKPTR(JS_TAG_OBJECT, user_data); JSValue string = JS_NewString(context, id); JSValue response = JS_Call(context, callback, JS_UNDEFINED, 1, &string); - _check_call(context, response); + tf_util_report_error(context, response); JS_FreeValue(context, response); JS_FreeValue(context, string); } @@ -562,7 +534,7 @@ static void _tf_ssb_rpc_on_connections_changed_callback(tf_ssb_t* ssb, tf_ssb_ch }; printf("calling function for ptr %p IsFunction=%d\n", user_data, JS_IsFunction(context, callback)); response = JS_Call(context, callback, JS_UNDEFINED, 2, args); - _check_call(context, response); + tf_util_report_error(context, response); JS_FreeValue(context, args[0]); JS_FreeValue(context, object); } @@ -576,7 +548,7 @@ static void _tf_ssb_rpc_on_connections_changed_callback(tf_ssb_t* ssb, tf_ssb_ch object, }; response = JS_Call(context, callback, JS_UNDEFINED, 2, args); - _check_call(context, response); + tf_util_report_error(context, response); JS_FreeValue(context, args[0]); JS_FreeValue(context, object); } @@ -649,7 +621,7 @@ void tf_ssb_run_file(JSContext* context, const char* file_name) JSContext* context2 = NULL; int r = JS_ExecutePendingJob(runtime, &context2); JSValue result = JS_GetException(context2); - _check_call(context, result); + tf_util_report_error(context, result); if (r == 0) { break; diff --git a/src/task.c b/src/task.c index f0ade915..52ae23f4 100644 --- a/src/task.c +++ b/src/task.c @@ -247,9 +247,9 @@ static void _export_record_release_for_task(tf_task_t* task, taskid_t task_id) } } -static void _tf_task_send_error_to_parent(tf_task_t* task, JSValue error) +void tf_task_send_error_to_parent(tf_task_t* task, JSValue error) { - if (task->_parent) + if (task && task->_parent) { void* buffer = NULL; size_t size = 0; @@ -259,36 +259,6 @@ static void _tf_task_send_error_to_parent(tf_task_t* task, JSValue error) } } -void tf_task_report_error(tf_task_t* task, JSValue error) -{ - JSContext* context = task->_context; - if (JS_IsError(context, error)) - { - const char* value = JS_ToCString(context, error); - printf("ERROR: %s\n", value); - JS_FreeCString(context, value); - - JSValue stack = JS_GetPropertyStr(context, error, "stack"); - if (!JS_IsUndefined(stack)) - { - const char* stack_str = JS_ToCString(context, stack); - printf("%s\n", stack_str); - JS_FreeCString(context, stack_str); - } - JS_FreeValue(context, stack); - - _tf_task_send_error_to_parent(task, error); - } - else if (JS_IsException(error)) - { - error = JS_GetException(context); - const char* value = JS_ToCString(context, error); - printf("Exception: %s\n", value); - JS_FreeCString(context, value); - _tf_task_send_error_to_parent(task, error); - } -} - static const char* _task_loadFile(const char* fileName) { char* result = NULL; @@ -348,7 +318,7 @@ static void _task_timeoutCallback(uv_timer_t* handle) JS_NULL, 0, NULL); - tf_task_report_error(timeout->_task, result); + tf_util_report_error(timeout->_task->_context, result); JS_FreeValue(timeout->_task->_context, result); tf_task_run_jobs(timeout->_task); tf_trace_end(timeout->_task->_trace); @@ -394,7 +364,7 @@ int tf_task_execute(tf_task_t* task, const char* fileName) if (source) { JSValue result = JS_Eval(task->_context, source, strlen(source), fileName, 0); - tf_task_report_error(task, result); + tf_util_report_error(task->_context, result); if (!JS_IsError(task->_context, result) && !JS_IsException(result)) { executed = true; @@ -514,7 +484,7 @@ JSValue _task_invokeExport_internal(tf_taskstub_t* from, tf_task_t* to, exportid } result = JS_Call(to->_context, function, this_val, length - 1, argument_array); tf_trace_end(to->_trace); - tf_task_report_error(to, result); + tf_util_report_error(to->_context, result); tf_task_run_jobs(to); } else @@ -563,10 +533,10 @@ static void _forward_promise(tf_task_t* from, tf_taskstub_t* to, promiseid_t pro JSValue catch_handler = JS_NewCFunctionData(from->_context, _invokeCatch, 0, 0, 2, data); JSValue error = JS_Call(from->_context, promise_then, result, 1, &then_handler); - tf_task_report_error(from, error); + tf_util_report_error(from->_context, error); JS_FreeValue(from->_context, error); error = JS_Call(from->_context, promise_catch, result, 1, &catch_handler); - tf_task_report_error(from, error); + tf_util_report_error(from->_context, error); JS_FreeValue(from->_context, error); tf_task_run_jobs(from); @@ -971,7 +941,7 @@ JSValue _tf_task_require(JSContext* context, JSValueConst this_val, int argc, JS JSValue oldExports = JS_GetPropertyStr(task->_context, global, "exports"); JS_SetPropertyStr(task->_context, global, "exports", JS_DupValue(task->_context, exports)); JSValue eval = JS_Eval(task->_context, source, strlen(source), path, 0); - tf_task_report_error(task, eval); + tf_util_report_error(task->_context, eval); tf_task_run_jobs(task); if (JS_IsError(task->_context, eval) || JS_IsException(eval)) @@ -1008,7 +978,7 @@ static JSValue _tf_task_executeSource(tf_task_t* task, const char* source, const { tf_trace_begin(task->_trace, "_tf_task_executeSource"); JSValue result = JS_Eval(task->_context, source, strlen(source), name, 0); - tf_task_report_error(task, result); + tf_util_report_error(task->_context, result); if (!*task->_scriptName) { snprintf(task->_scriptName, sizeof(task->_scriptName), "%s", name); @@ -1046,7 +1016,7 @@ JSValue _tf_task_sandbox_require(JSContext* context, JSValueConst this_val, int JSValue oldExports = JS_GetPropertyStr(context, global, "exports"); JS_SetPropertyStr(context, global, "exports", JS_DupValue(context, exports)); JSValue result = JS_Eval(context, source, length, name, 0); - tf_task_report_error(task, result); + tf_util_report_error(context, result); JS_SetPropertyStr(context, global, "exports", oldExports); JS_FreeValue(context, global); tf_task_run_jobs(task); @@ -1061,7 +1031,7 @@ JSValue _tf_task_sandbox_require(JSContext* context, JSValueConst this_val, int JSValue oldExports = JS_GetPropertyStr(context, global, "exports"); JS_SetPropertyStr(context, global, "exports", JS_DupValue(context, exports)); JSValue result = JS_Eval(context, source, length, name, 0); - tf_task_report_error(task, result); + tf_util_report_error(context, result); JS_SetPropertyStr(context, global, "exports", oldExports); JS_FreeValue(context, global); tf_task_run_jobs(task); @@ -1142,7 +1112,7 @@ void tf_task_resolve_promise(tf_task_t* task, promiseid_t promise, JSValue value if (it) { JSValue result = JS_Call(task->_context, it->values[1], JS_UNDEFINED, 1, &value); - tf_task_report_error(task, result); + tf_util_report_error(task->_context, result); JS_FreeValue(task->_context, it->values[1]); JS_FreeValue(task->_context, it->values[2]); JS_FreeValue(task->_context, result); @@ -1162,7 +1132,7 @@ void tf_task_reject_promise(tf_task_t* task, promiseid_t promise, JSValue value) if (it) { JSValue result = JS_Call(task->_context, it->values[2], JS_UNDEFINED, 1, &value); - tf_task_report_error(task, result); + tf_util_report_error(task->_context, result); JS_FreeValue(task->_context, it->values[1]); JS_FreeValue(task->_context, it->values[2]); JS_FreeValue(task->_context, result); @@ -1239,10 +1209,9 @@ static void _import_mark_func(JSRuntime* runtime, JSValueConst value, JS_MarkFun static void _tf_task_promise_rejection_tracker(JSContext* context, JSValueConst promise, JSValueConst reason, JS_BOOL is_handled, void* user_data) { - tf_task_t* task = user_data; if (!is_handled) { - tf_task_report_error(task, reason); + tf_util_report_error(context, reason); } } @@ -1448,7 +1417,10 @@ void tf_task_run_jobs(tf_task_t* task) JSContext* context = NULL; int r = JS_ExecutePendingJob(task->_runtime, &context); JSValue result = JS_GetException(context); - tf_task_report_error(task, result); + if (context) + { + tf_util_report_error(context, result); + } if (r < 0) { js_std_dump_error(context); diff --git a/src/task.h b/src/task.h index 65e753f4..3c30aca5 100644 --- a/src/task.h +++ b/src/task.h @@ -67,3 +67,5 @@ void tf_task_report_error(tf_task_t* task, JSValue error); JSValue tf_try_get_typed_array_buffer(JSContext *ctx, JSValueConst obj, size_t *pbyte_offset, size_t *pbyte_length, size_t *pbytes_per_element); uint8_t *tf_try_get_array_buffer(JSContext *ctx, size_t *psize, JSValueConst obj); + +void tf_task_send_error_to_parent(tf_task_t* task, JSValue error); diff --git a/src/taskstub.js.c b/src/taskstub.js.c index 8484e6ba..3044fe82 100644 --- a/src/taskstub.js.c +++ b/src/taskstub.js.c @@ -3,6 +3,7 @@ #include "packetstream.h" #include "serialize.h" #include "task.h" +#include "util.js.h" #include #include @@ -269,7 +270,7 @@ static void _taskstub_on_process_exit(uv_process_t* process, int64_t status, int { JSValue argv[] = { JS_NewInt32(context, status), JS_NewInt32(context, terminationSignal) }; JSValue result = JS_Call(context, stub->_on_exit, JS_NULL, 2, argv); - tf_task_report_error(stub->_owner, result); + tf_util_report_error(context, result); JS_FreeValue(context, result); tf_task_run_jobs(stub->_owner); JS_FreeValue(context, argv[0]); @@ -393,7 +394,7 @@ void tf_taskstub_on_error(tf_taskstub_t* stub, JSValue error) if (!JS_IsUndefined(stub->_on_error)) { JSValue result = JS_Call(context, stub->_on_error, JS_NULL, 1, &error); - tf_task_report_error(stub->_owner, result); + tf_util_report_error(context, result); JS_FreeValue(context, result); tf_task_run_jobs(stub->_owner); } diff --git a/src/util.js.c b/src/util.js.c index aa8e110a..dbe946b8 100644 --- a/src/util.js.c +++ b/src/util.js.c @@ -2,6 +2,8 @@ #include "task.h" +#include "quickjs-libc.h" + static JSValue _util_utf8_decode(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { JSValue result = JS_NULL; @@ -42,17 +44,17 @@ JSValue tf_util_utf8_decode(JSContext* context, JSValue value) return _util_utf8_decode(context, JS_NULL, 1, &value); } -uint8_t* tf_util_try_get_array_buffer(JSContext *ctx, size_t *psize, JSValueConst obj) +uint8_t* tf_util_try_get_array_buffer(JSContext* context, size_t* psize, JSValueConst obj) { - uint8_t* result = JS_GetArrayBuffer(ctx, psize, obj); - JS_FreeValue(ctx, JS_GetException(ctx)); + uint8_t* result = JS_GetArrayBuffer(context, psize, obj); + JS_FreeValue(context, JS_GetException(context)); return result; } -JSValue tf_util_try_get_typed_array_buffer(JSContext *ctx, JSValueConst obj, size_t *pbyte_offset, size_t *pbyte_length, size_t *pbytes_per_element) +JSValue tf_util_try_get_typed_array_buffer(JSContext* context, JSValueConst obj, size_t* pbyte_offset, size_t* pbyte_length, size_t* pbytes_per_element) { - JSValue result = JS_GetTypedArrayBuffer(ctx, obj, pbyte_offset, pbyte_length, pbytes_per_element); - JS_FreeValue(ctx, JS_GetException(ctx)); + JSValue result = JS_GetTypedArrayBuffer(context, obj, pbyte_offset, pbyte_length, pbytes_per_element); + JS_FreeValue(context, JS_GetException(context)); return result; } @@ -80,6 +82,45 @@ JSValue _util_print(JSContext* context, JSValueConst this_val, int argc, JSValue return JS_NULL; } +void tf_util_report_error(JSContext* context, JSValue value) +{ + if (JS_IsError(context, value)) + { + const char* string = JS_ToCString(context, value); + printf("ERROR: %s\n", string); + JS_FreeCString(context, string); + + JSValue stack = JS_GetPropertyStr(context, value, "stack"); + if (!JS_IsUndefined(stack)) + { + const char* stack_str = JS_ToCString(context, stack); + printf("%s\n", stack_str); + JS_FreeCString(context, stack_str); + } + JS_FreeValue(context, stack); + + tf_task_t* task = tf_task_get(context); + if (task) + { + tf_task_send_error_to_parent(task, value); + } + } + else if (JS_IsException(value)) + { + js_std_dump_error(context); + JSValue exception = JS_GetException(context); + const char* string = JS_ToCString(context, exception); + printf("Exception: %s\n", string); + JS_FreeCString(context, string); + tf_task_t* task = tf_task_get(context); + if (task) + { + tf_task_send_error_to_parent(task, exception); + } + JS_FreeValue(context, exception); + } +} + void tf_util_register(JSContext* context) { JSValue global = JS_GetGlobalObject(context); diff --git a/src/util.js.h b/src/util.js.h index b588fe5e..0038f660 100644 --- a/src/util.js.h +++ b/src/util.js.h @@ -4,5 +4,6 @@ void tf_util_register(JSContext* context); JSValue tf_util_utf8_decode(JSContext* context, JSValue value); -uint8_t* tf_util_try_get_array_buffer(JSContext *ctx, size_t *psize, JSValueConst obj); -JSValue tf_util_try_get_typed_array_buffer(JSContext *ctx, JSValueConst obj, size_t *pbyte_offset, size_t *pbyte_length, size_t *pbytes_per_element); +uint8_t* tf_util_try_get_array_buffer(JSContext* context, size_t* psize, JSValueConst obj); +JSValue tf_util_try_get_typed_array_buffer(JSContext* context, JSValueConst obj, size_t* pbyte_offset, size_t* pbyte_length, size_t* pbytes_per_element); +void tf_util_report_error(JSContext* context, JSValue value);