diff --git a/package/utils/ucode/Makefile b/package/utils/ucode/Makefile index d92979af48f..4b3b67c688a 100644 --- a/package/utils/ucode/Makefile +++ b/package/utils/ucode/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ucode -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=https://github.com/jow-/ucode.git diff --git a/package/utils/ucode/patches/100-vm-export-function-for-converting-exception-to-ucode.patch b/package/utils/ucode/patches/100-vm-export-function-for-converting-exception-to-ucode.patch index e849510f58c..3aa47c849d8 100644 --- a/package/utils/ucode/patches/100-vm-export-function-for-converting-exception-to-ucode.patch +++ b/package/utils/ucode/patches/100-vm-export-function-for-converting-exception-to-ucode.patch @@ -15,20 +15,20 @@ Signed-off-by: Felix Fietkau void __attribute__((format(printf, 3, 0))) uc_vm_raise_exception(uc_vm_t *vm, uc_exception_type_t type, const char *fmt, ...); -+uc_value_t *uc_vm_exception_value(uc_vm_t *vm); ++uc_value_t *uc_vm_exception_object(uc_vm_t *vm); uc_vm_status_t uc_vm_execute(uc_vm_t *vm, uc_program_t *fn, uc_value_t **retval); uc_value_t *uc_vm_invoke(uc_vm_t *vm, const char *fname, size_t nargs, ...); --- a/vm.c +++ b/vm.c -@@ -814,9 +814,12 @@ uc_vm_exception_tostring(uc_vm_t *vm, si +@@ -813,9 +813,12 @@ uc_vm_exception_tostring(uc_vm_t *vm, si return message ? ucv_get(message) : ucv_string_new("Exception"); } -static uc_value_t * -uc_vm_exception_new(uc_vm_t *vm, uc_exception_type_t type, const char *message, uc_value_t *stacktrace) +uc_value_t * -+uc_vm_exception_value(uc_vm_t *vm) ++uc_vm_exception_object(uc_vm_t *vm) { + uc_exception_type_t type = vm->exception.type; + const char *message = vm->exception.message; @@ -36,12 +36,12 @@ Signed-off-by: Felix Fietkau uc_value_t *exception_prototype = uc_vm_registry_get(vm, "vm.exception.proto"); uc_value_t *exo; -@@ -881,7 +884,7 @@ uc_vm_handle_exception(uc_vm_t *vm) +@@ -880,7 +883,7 @@ uc_vm_handle_exception(uc_vm_t *vm) ucv_put(uc_vm_stack_pop(vm)); /* prepare exception object and expose it to user handler code */ - exo = uc_vm_exception_new(vm, vm->exception.type, vm->exception.message, vm->exception.stacktrace); -+ exo = uc_vm_exception_value(vm); ++ exo = uc_vm_exception_object(vm); uc_vm_stack_push(vm, exo); diff --git a/package/utils/ucode/patches/101-uloop-add-exception_handler_set-function.patch b/package/utils/ucode/patches/101-uloop-add-guard-function.patch similarity index 88% rename from package/utils/ucode/patches/101-uloop-add-exception_handler_set-function.patch rename to package/utils/ucode/patches/101-uloop-add-guard-function.patch index 9ff2bd4b9db..a0a2e2584ac 100644 --- a/package/utils/ucode/patches/101-uloop-add-exception_handler_set-function.patch +++ b/package/utils/ucode/patches/101-uloop-add-guard-function.patch @@ -1,6 +1,6 @@ From: Felix Fietkau Date: Wed, 11 Jun 2025 18:31:39 +0200 -Subject: [PATCH] uloop: add exception_handler_set function +Subject: [PATCH] uloop: add guard() function This allows calling the provided handler on exceptions, avoiding the existing behavior of calling uloop_end(). @@ -25,9 +25,9 @@ Signed-off-by: Felix Fietkau + if (!ucv_is_callable(exh)) + goto error; + -+ val = uc_vm_exception_value(vm); ++ val = uc_vm_exception_object(vm); + uc_vm_stack_push(vm, ucv_get(exh)); -+ uc_vm_stack_push(vm, ucv_get(val)); ++ uc_vm_stack_push(vm, val); + + if (uc_vm_call(vm, false, 1) != EXCEPTION_NONE) + goto error; @@ -109,15 +109,18 @@ Signed-off-by: Felix Fietkau res = uc_vm_stack_pop(vm); uc_uloop_pipe_send_common(vm, res, tpipe->output); ucv_put(res); -@@ -2167,6 +2181,19 @@ uc_uloop_signal(uc_vm_t *vm, size_t narg +@@ -2167,6 +2181,22 @@ uc_uloop_signal(uc_vm_t *vm, size_t narg } #endif +static uc_value_t * -+uc_uloop_exception_handler_set(uc_vm_t *vm, size_t nargs) ++uc_uloop_guard(uc_vm_t *vm, size_t nargs) +{ + uc_value_t *arg = uc_fn_arg(0); + ++ if (!nargs) ++ return ucv_get(uc_vm_registry_get(vm, "uloop.ex_handler")); ++ + if (arg && !ucv_is_callable(arg)) + return NULL; + @@ -129,11 +132,11 @@ Signed-off-by: Felix Fietkau static const uc_function_list_t timer_fns[] = { { "set", uc_uloop_timer_set }, -@@ -2233,6 +2260,7 @@ static const uc_function_list_t global_f +@@ -2233,6 +2263,7 @@ static const uc_function_list_t global_f #ifdef HAVE_ULOOP_SIGNAL { "signal", uc_uloop_signal }, #endif -+ { "exception_handler_set", uc_uloop_exception_handler_set }, ++ { "guard", uc_uloop_guard }, }; diff --git a/package/utils/ucode/patches/102-ubus-add-exception_handler_set-function.patch b/package/utils/ucode/patches/102-ubus-add-guard-function.patch similarity index 79% rename from package/utils/ucode/patches/102-ubus-add-exception_handler_set-function.patch rename to package/utils/ucode/patches/102-ubus-add-guard-function.patch index 6b6508d06fc..cb6f382d283 100644 --- a/package/utils/ucode/patches/102-ubus-add-exception_handler_set-function.patch +++ b/package/utils/ucode/patches/102-ubus-add-guard-function.patch @@ -1,6 +1,6 @@ From: Felix Fietkau Date: Wed, 11 Jun 2025 18:40:10 +0200 -Subject: [PATCH] ubus: add exception_handler_set function +Subject: [PATCH] ubus: add guard() function This allows calling the provided handler on exceptions, avoiding the existing behavior of calling uloop_end(). @@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau --- a/lib/ubus.c +++ b/lib/ubus.c -@@ -573,6 +573,40 @@ uc_ubus_call_cb(struct ubus_request *req +@@ -575,6 +575,40 @@ uc_ubus_call_cb(struct ubus_request *req } static void @@ -22,9 +22,9 @@ Signed-off-by: Felix Fietkau + if (!ucv_is_callable(exh)) + goto error; + -+ val = uc_vm_exception_value(vm); ++ val = uc_vm_exception_object(vm); + uc_vm_stack_push(vm, ucv_get(exh)); -+ uc_vm_stack_push(vm, ucv_get(val)); ++ uc_vm_stack_push(vm, val); + + if (uc_vm_call(vm, false, 1) != EXCEPTION_NONE) + goto error; @@ -51,7 +51,7 @@ Signed-off-by: Felix Fietkau uc_ubus_call_user_cb(uc_ubus_deferred_t *defer, int ret, uc_value_t *reply) { uc_value_t *this = ucv_get(defer->res); -@@ -623,10 +657,8 @@ uc_ubus_call_data_user_cb(struct ubus_re +@@ -625,10 +659,8 @@ uc_ubus_call_data_user_cb(struct ubus_re uc_vm_stack_push(vm, ucv_get(func)); uc_vm_stack_push(vm, ucv_get(reply)); @@ -63,7 +63,7 @@ Signed-off-by: Felix Fietkau } } -@@ -645,10 +677,8 @@ uc_ubus_call_fd_cb(struct ubus_request * +@@ -647,10 +679,8 @@ uc_ubus_call_fd_cb(struct ubus_request * uc_vm_stack_push(vm, ucv_get(func)); uc_vm_stack_push(vm, ucv_int64_new(fd)); @@ -75,7 +75,7 @@ Signed-off-by: Felix Fietkau } } -@@ -927,10 +957,8 @@ uc_ubus_defer_common(uc_vm_t *vm, uc_ubu +@@ -929,10 +959,8 @@ uc_ubus_defer_common(uc_vm_t *vm, uc_ubu uc_vm_stack_push(vm, ucv_get(replycb)); uc_vm_stack_push(vm, ucv_int64_new(rv)); @@ -87,7 +87,7 @@ Signed-off-by: Felix Fietkau ucv_put(res->res); } -@@ -1199,10 +1227,8 @@ uc_ubus_object_notify_data_cb(struct ubu +@@ -1201,10 +1229,8 @@ uc_ubus_object_notify_data_cb(struct ubu uc_vm_stack_push(vm, ucv_int64_new(type)); uc_vm_stack_push(vm, blob_array_to_ucv(vm, blob_data(msg), blob_len(msg), true)); @@ -99,7 +99,7 @@ Signed-off-by: Felix Fietkau } } -@@ -1222,10 +1248,8 @@ uc_ubus_object_notify_status_cb(struct u +@@ -1224,10 +1250,8 @@ uc_ubus_object_notify_status_cb(struct u uc_vm_stack_push(vm, ucv_int64_new(idx)); uc_vm_stack_push(vm, ucv_int64_new(ret)); @@ -111,7 +111,7 @@ Signed-off-by: Felix Fietkau } } -@@ -1245,10 +1269,8 @@ uc_ubus_object_notify_complete_cb(struct +@@ -1247,10 +1271,8 @@ uc_ubus_object_notify_complete_cb(struct uc_vm_stack_push(vm, ucv_int64_new(idx)); uc_vm_stack_push(vm, ucv_int64_new(ret)); @@ -123,7 +123,7 @@ Signed-off-by: Felix Fietkau } notifyctx->complete = true; -@@ -1579,7 +1601,7 @@ uc_ubus_handle_reply_common(struct ubus_ +@@ -1581,7 +1603,7 @@ uc_ubus_handle_reply_common(struct ubus_ /* treat other exceptions as fatal and halt uloop */ default: uc_ubus_request_finish_common(callctx, UBUS_STATUS_UNKNOWN_ERROR); @@ -132,7 +132,7 @@ Signed-off-by: Felix Fietkau break; } -@@ -1638,10 +1660,8 @@ uc_ubus_object_subscribe_cb(struct ubus_ +@@ -1640,10 +1662,8 @@ uc_ubus_object_subscribe_cb(struct ubus_ uc_vm_stack_push(uuobj->vm, ucv_get(uuobj->res)); uc_vm_stack_push(uuobj->vm, ucv_get(func)); @@ -144,7 +144,7 @@ Signed-off-by: Felix Fietkau } static bool -@@ -1917,10 +1937,8 @@ uc_ubus_listener_cb(struct ubus_context +@@ -1919,10 +1939,8 @@ uc_ubus_listener_cb(struct ubus_context uc_vm_stack_push(vm, ucv_string_new(type)); uc_vm_stack_push(vm, blob_array_to_ucv(vm, blob_data(msg), blob_len(msg), true)); @@ -156,7 +156,7 @@ Signed-off-by: Felix Fietkau } static uc_value_t * -@@ -2040,10 +2058,8 @@ uc_ubus_subscriber_remove_cb(struct ubus +@@ -2042,10 +2060,8 @@ uc_ubus_subscriber_remove_cb(struct ubus uc_vm_stack_push(vm, ucv_get(func)); uc_vm_stack_push(vm, ucv_uint64_new(id)); @@ -168,7 +168,7 @@ Signed-off-by: Felix Fietkau } static uc_value_t * -@@ -2334,10 +2350,8 @@ uc_ubus_channel_disconnect_cb(struct ubu +@@ -2370,10 +2386,8 @@ uc_ubus_channel_disconnect_cb(struct ubu uc_vm_stack_push(c->vm, ucv_get(c->res)); uc_vm_stack_push(c->vm, ucv_get(func)); @@ -180,15 +180,18 @@ Signed-off-by: Felix Fietkau } blob_buf_free(&c->buf); -@@ -2438,10 +2452,25 @@ uc_ubus_channel_connect(uc_vm_t *vm, siz +@@ -2474,10 +2488,28 @@ uc_ubus_channel_connect(uc_vm_t *vm, siz } +static uc_value_t * -+uc_ubus_exception_handler_set(uc_vm_t *vm, size_t nargs) ++uc_ubus_guard(uc_vm_t *vm, size_t nargs) +{ + uc_value_t *arg = uc_fn_arg(0); + ++ if (!nargs) ++ return ucv_get(uc_vm_registry_get(vm, "ubus.ex_handler")); ++ + if (arg && !ucv_is_callable(arg)) + return NULL; + @@ -202,7 +205,7 @@ Signed-off-by: Felix Fietkau { "error", uc_ubus_error }, { "connect", uc_ubus_connect }, { "open_channel", uc_ubus_channel_connect }, -+ { "exception_handler_set", uc_ubus_exception_handler_set }, ++ { "guard", uc_ubus_guard }, }; static const uc_function_list_t conn_fns[] = {