diff --git a/package/utils/ucode/Makefile b/package/utils/ucode/Makefile index 4b3b67c688a..8ae1b91c1f2 100644 --- a/package/utils/ucode/Makefile +++ b/package/utils/ucode/Makefile @@ -8,13 +8,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ucode -PKG_RELEASE:=2 +PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=https://github.com/jow-/ucode.git -PKG_SOURCE_DATE:=2025-06-09 -PKG_SOURCE_VERSION:=37ac8f112af63e64c1ea2d13ae63c134b62a5681 -PKG_MIRROR_HASH:=f98b1d75be427e2540d5b8320834efde738899b41a0390f3af13ab56c660b7fb +PKG_SOURCE_DATE:=2025-07-18 +PKG_SOURCE_VERSION:=3f64c8089bf3ea4847c96b91df09fbfcaec19e1d +PKG_MIRROR_HASH:=55fbff7c527e1fadbda2e038636f39419649841ee63a5f3cdb50b9714b13420c PKG_MAINTAINER:=Jo-Philipp Wich PKG_LICENSE:=ISC diff --git a/package/utils/ucode/patches/010-ubus-fix-refcount-issue-in-uc_ubus_object_notify.patch b/package/utils/ucode/patches/010-ubus-fix-refcount-issue-in-uc_ubus_object_notify.patch deleted file mode 100644 index 92b955ac794..00000000000 --- a/package/utils/ucode/patches/010-ubus-fix-refcount-issue-in-uc_ubus_object_notify.patch +++ /dev/null @@ -1,39 +0,0 @@ -From: Felix Fietkau -Date: Wed, 18 Jun 2025 17:26:49 +0200 -Subject: [PATCH] ubus: fix refcount issue in uc_ubus_object_notify - -uc_ubus_object_notify_complete_cb will clear the reference in notify_ctx->res, -so in the synchronous case, an extra ucv_get call is needed. -Fixes an accidental double-unref bug - -Fixes: 94ad17d13a0d ("ubus: use ucv_resource_create_ex for ubus.notify resources") -Signed-off-by: Felix Fietkau ---- - ---- a/lib/ubus.c -+++ b/lib/ubus.c -@@ -1290,7 +1290,6 @@ uc_ubus_object_notify(uc_vm_t *vm, size_ - - notifyctx->vm = vm; - notifyctx->ctx = uuobj->ctx; -- notifyctx->res = res; - - blob_buf_init(&buf, 0); - -@@ -1306,6 +1305,7 @@ uc_ubus_object_notify(uc_vm_t *vm, size_ - err_return(rv, "Failed to send notification"); - } - -+ notifyctx->res = ucv_get(res); - notifyctx->req.data_cb = uc_ubus_object_notify_data_cb; - notifyctx->req.status_cb = uc_ubus_object_notify_status_cb; - notifyctx->req.complete_cb = uc_ubus_object_notify_complete_cb; -@@ -1326,7 +1326,7 @@ uc_ubus_object_notify(uc_vm_t *vm, size_ - ucv_resource_persistent_set(res, true); - ubus_complete_request_async(uuobj->ctx, ¬ifyctx->req.req); - -- ok_return(ucv_get(res)); -+ ok_return(res); - } - - 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 deleted file mode 100644 index 3aa47c849d8..00000000000 --- a/package/utils/ucode/patches/100-vm-export-function-for-converting-exception-to-ucode.patch +++ /dev/null @@ -1,47 +0,0 @@ -From: Felix Fietkau -Date: Wed, 11 Jun 2025 17:35:00 +0200 -Subject: [PATCH] vm: export function for converting exception to ucode - value - -This can be used to simplify implementing module execption handlers in -ucode. - -Signed-off-by: Felix Fietkau ---- - ---- a/include/ucode/vm.h -+++ b/include/ucode/vm.h -@@ -152,6 +152,7 @@ uc_exception_type_t uc_vm_call(uc_vm_t * - - 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_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 -@@ -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_object(uc_vm_t *vm) - { -+ uc_exception_type_t type = vm->exception.type; -+ const char *message = vm->exception.message; -+ uc_value_t *stacktrace = vm->exception.stacktrace; - uc_value_t *exception_prototype = uc_vm_registry_get(vm, "vm.exception.proto"); - uc_value_t *exo; - -@@ -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_object(vm); - - uc_vm_stack_push(vm, exo); - diff --git a/package/utils/ucode/patches/101-uloop-add-guard-function.patch b/package/utils/ucode/patches/101-uloop-add-guard-function.patch deleted file mode 100644 index a0a2e2584ac..00000000000 --- a/package/utils/ucode/patches/101-uloop-add-guard-function.patch +++ /dev/null @@ -1,142 +0,0 @@ -From: Felix Fietkau -Date: Wed, 11 Jun 2025 18:31:39 +0200 -Subject: [PATCH] uloop: add guard() function - -This allows calling the provided handler on exceptions, avoiding the -existing behavior of calling uloop_end(). - -Signed-off-by: Felix Fietkau ---- - ---- a/lib/uloop.c -+++ b/lib/uloop.c -@@ -114,27 +114,48 @@ uc_uloop_cb_free(uc_uloop_cb_t *cb) - } - - static bool -+uc_uloop_vm_call(uc_vm_t *vm, bool mcall, size_t nargs) -+{ -+ uc_value_t *exh, *val; -+ -+ if (uc_vm_call(vm, mcall, nargs) == EXCEPTION_NONE) -+ return true; -+ -+ exh = uc_vm_registry_get(vm, "uloop.ex_handler"); -+ if (!ucv_is_callable(exh)) -+ goto error; -+ -+ val = uc_vm_exception_object(vm); -+ uc_vm_stack_push(vm, ucv_get(exh)); -+ uc_vm_stack_push(vm, val); -+ -+ if (uc_vm_call(vm, false, 1) != EXCEPTION_NONE) -+ goto error; -+ -+ ucv_put(uc_vm_stack_pop(vm)); -+ -+ return false; -+ -+error: -+ uloop_end(); -+ return false; -+} -+ -+static void - uc_uloop_cb_invoke(uc_uloop_cb_t *cb, uc_value_t *arg) - { - uc_vm_t *vm = cb->vm; - uc_value_t *func = ucv_resource_value_get(cb->obj, 0); - - if (!ucv_is_callable(func)) -- return false; -+ return; - - uc_vm_stack_push(vm, ucv_get(cb->obj)); - uc_vm_stack_push(vm, ucv_get(func)); - uc_vm_stack_push(vm, ucv_get(arg)); - -- if (uc_vm_call(vm, true, 1) != EXCEPTION_NONE) { -- uloop_end(); -- -- return false; -- } -- -- ucv_put(uc_vm_stack_pop(vm)); -- -- return true; -+ if (uc_uloop_vm_call(vm, true, 1)) -+ ucv_put(uc_vm_stack_pop(vm)); - } - - /** -@@ -1550,11 +1571,8 @@ uc_uloop_task_output_cb(struct uloop_fd - uc_vm_stack_push(vm, ucv_get(obj)); - uc_vm_stack_push(vm, ucv_get(task->input_cb)); - -- if (uc_vm_call(vm, true, 0) != EXCEPTION_NONE) { -- uloop_end(); -- -+ if (!uc_uloop_vm_call(vm, true, 0)) - return; -- } - - msg = uc_vm_stack_pop(vm); - uc_uloop_pipe_send_common(vm, msg, task->input_fd); -@@ -1572,14 +1590,10 @@ uc_uloop_task_output_cb(struct uloop_fd - uc_vm_stack_push(vm, ucv_get(task->output_cb)); - uc_vm_stack_push(vm, msg); - -- if (uc_vm_call(vm, true, 1) == EXCEPTION_NONE) { -- ucv_put(uc_vm_stack_pop(vm)); -- } -- else { -- uloop_end(); -- -+ if (!uc_uloop_vm_call(vm, true, 1)) - return; -- } -+ -+ ucv_put(uc_vm_stack_pop(vm)); - } - else { - ucv_put(msg); -@@ -1703,7 +1717,7 @@ uc_uloop_task(uc_vm_t *vm, size_t nargs) - uc_vm_stack_push(vm, func); - uc_vm_stack_push(vm, ucv_get(p)); - -- if (uc_vm_call(vm, false, 1) == EXCEPTION_NONE) { -+ if (uc_uloop_vm_call(vm, false, 1)) { - res = uc_vm_stack_pop(vm); - uc_uloop_pipe_send_common(vm, res, tpipe->output); - ucv_put(res); -@@ -2167,6 +2181,22 @@ uc_uloop_signal(uc_vm_t *vm, size_t narg - } - #endif - -+static uc_value_t * -+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; -+ -+ uc_vm_registry_set(vm, "uloop.ex_handler", ucv_get(arg)); -+ -+ return ucv_boolean_new(true); -+} -+ - - static const uc_function_list_t timer_fns[] = { - { "set", uc_uloop_timer_set }, -@@ -2233,6 +2263,7 @@ static const uc_function_list_t global_f - #ifdef HAVE_ULOOP_SIGNAL - { "signal", uc_uloop_signal }, - #endif -+ { "guard", uc_uloop_guard }, - }; - - diff --git a/package/utils/ucode/patches/102-ubus-add-guard-function.patch b/package/utils/ucode/patches/102-ubus-add-guard-function.patch deleted file mode 100644 index cb6f382d283..00000000000 --- a/package/utils/ucode/patches/102-ubus-add-guard-function.patch +++ /dev/null @@ -1,211 +0,0 @@ -From: Felix Fietkau -Date: Wed, 11 Jun 2025 18:40:10 +0200 -Subject: [PATCH] ubus: add guard() function - -This allows calling the provided handler on exceptions, avoiding the -existing behavior of calling uloop_end(). - -Signed-off-by: Felix Fietkau ---- - ---- a/lib/ubus.c -+++ b/lib/ubus.c -@@ -575,6 +575,40 @@ uc_ubus_call_cb(struct ubus_request *req - } - - static void -+uc_ubus_vm_handle_exception(uc_vm_t *vm) -+{ -+ uc_value_t *exh, *val; -+ -+ exh = uc_vm_registry_get(vm, "ubus.ex_handler"); -+ if (!ucv_is_callable(exh)) -+ goto error; -+ -+ val = uc_vm_exception_object(vm); -+ uc_vm_stack_push(vm, ucv_get(exh)); -+ uc_vm_stack_push(vm, val); -+ -+ if (uc_vm_call(vm, false, 1) != EXCEPTION_NONE) -+ goto error; -+ -+ ucv_put(uc_vm_stack_pop(vm)); -+ return; -+ -+error: -+ uloop_end(); -+} -+ -+static bool -+uc_ubus_vm_call(uc_vm_t *vm, bool mcall, size_t nargs) -+{ -+ if (uc_vm_call(vm, mcall, nargs) == EXCEPTION_NONE) -+ return true; -+ -+ uc_ubus_vm_handle_exception(vm); -+ -+ return false; -+} -+ -+static void - uc_ubus_call_user_cb(uc_ubus_deferred_t *defer, int ret, uc_value_t *reply) - { - uc_value_t *this = ucv_get(defer->res); -@@ -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)); - -- if (uc_vm_call(vm, true, 1) == EXCEPTION_NONE) -+ if (uc_ubus_vm_call(vm, true, 1)) - ucv_put(uc_vm_stack_pop(vm)); -- else -- uloop_end(); - } - } - -@@ -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)); - -- if (uc_vm_call(vm, true, 1) == EXCEPTION_NONE) -+ if (uc_ubus_vm_call(vm, true, 1)) - ucv_put(uc_vm_stack_pop(vm)); -- else -- uloop_end(); - } - } - -@@ -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)); - -- if (uc_vm_call(vm, false, 1) == EXCEPTION_NONE) -+ if (uc_ubus_vm_call(vm, false, 1)) - ucv_put(uc_vm_stack_pop(vm)); -- else -- uloop_end(); - - ucv_put(res->res); - } -@@ -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)); - -- if (uc_vm_call(vm, true, 2) == EXCEPTION_NONE) -+ if (uc_ubus_vm_call(vm, true, 2)) - ucv_put(uc_vm_stack_pop(vm)); -- else -- uloop_end(); - } - } - -@@ -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)); - -- if (uc_vm_call(vm, true, 2) == EXCEPTION_NONE) -+ if (uc_ubus_vm_call(vm, true, 2)) - ucv_put(uc_vm_stack_pop(vm)); -- else -- uloop_end(); - } - } - -@@ -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)); - -- if (uc_vm_call(vm, true, 2) == EXCEPTION_NONE) -+ if (uc_ubus_vm_call(vm, true, 2)) - ucv_put(uc_vm_stack_pop(vm)); -- else -- uloop_end(); - } - - notifyctx->complete = true; -@@ -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); -- uloop_end(); -+ uc_ubus_vm_handle_exception(vm); - break; - } - -@@ -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)); - -- if (uc_vm_call(uuobj->vm, true, 0) == EXCEPTION_NONE) -+ if (uc_ubus_vm_call(uuobj->vm, true, 0)) - ucv_put(uc_vm_stack_pop(uuobj->vm)); -- else -- uloop_end(); - } - - static bool -@@ -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)); - -- if (uc_vm_call(vm, true, 2) == EXCEPTION_NONE) -+ if (uc_ubus_vm_call(vm, true, 2)) - ucv_put(uc_vm_stack_pop(vm)); -- else -- uloop_end(); - } - - static uc_value_t * -@@ -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)); - -- if (uc_vm_call(vm, true, 1) == EXCEPTION_NONE) -+ if (uc_ubus_vm_call(vm, true, 1)) - ucv_put(uc_vm_stack_pop(vm)); -- else -- uloop_end(); - } - - static uc_value_t * -@@ -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)); - -- if (uc_vm_call(c->vm, true, 0) == EXCEPTION_NONE) -+ if (uc_ubus_vm_call(c->vm, true, 0)) - ucv_put(uc_vm_stack_pop(c->vm)); -- else -- uloop_end(); - } - - blob_buf_free(&c->buf); -@@ -2474,10 +2488,28 @@ uc_ubus_channel_connect(uc_vm_t *vm, siz - } - - -+static uc_value_t * -+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; -+ -+ uc_vm_registry_set(vm, "ubus.ex_handler", ucv_get(arg)); -+ -+ return ucv_boolean_new(true); -+} -+ -+ - static const uc_function_list_t global_fns[] = { - { "error", uc_ubus_error }, - { "connect", uc_ubus_connect }, - { "open_channel", uc_ubus_channel_connect }, -+ { "guard", uc_ubus_guard }, - }; - - static const uc_function_list_t conn_fns[] = {