From 4b7d5447bbe5f8b6b0c760660fcd2ae183544c40 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 10 Mar 2020 02:56:37 +0900 Subject: [PATCH] [ruamoko] Correct obj_msg_sendv for __obj_forward Until I implemented forwarding, I didn't know how obj_msg_sendv was meant to be used, so no surprise I got the implementation wrong. --- libs/ruamoko/rua_obj.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/libs/ruamoko/rua_obj.c b/libs/ruamoko/rua_obj.c index c249e2b6a..f02bedcc3 100644 --- a/libs/ruamoko/rua_obj.c +++ b/libs/ruamoko/rua_obj.c @@ -1386,22 +1386,41 @@ static void rua_obj_msg_sendv (progs_t *pr) { probj_t *probj = pr->pr_objective_resources; + pointer_t obj = P_POINTER (pr, 0); pr_id_t *receiver = &P_STRUCT (pr, pr_id_t, 0); + pointer_t sel = P_POINTER (pr, 1); pr_sel_t *op = &P_STRUCT (pr, pr_sel_t, 1); - pr_va_list_t *args = (pr_va_list_t *) &P_POINTER (pr, 2); - pr_type_t *params = G_GPOINTER (pr, args->list); - int count = args->count; func_t imp = obj_msg_lookup (probj, receiver, op); - count = bound (0, count, 6); - if (count && pr_boundscheck->int_val) + __auto_type args = &P_PACKED (pr, pr_va_list_t, 2); + int count = args->count; + pr_type_t *params = G_GPOINTER (pr, args->list); + + if (count < 2 || count > MAX_PARMS) { + PR_RunError (pr, "bad args count in obj_msg_sendv: %d", count); + } + if (pr_boundscheck->int_val) { PR_BoundsCheckSize (pr, args->list, count * pr->pr_param_size); - if (!imp) + } + + if (!imp) { PR_RunError (pr, "%s does not respond to %s", PR_GetString (pr, object_get_class_name (probj, receiver)), PR_GetString (pr, probj->selector_names[op->sel_id])); - if (count) - memcpy (pr->pr_params[2], params, count * 4 * pr->pr_param_size); + } + + pr->pr_argc = count; + // skip over the first two parameters because receiver and op will + // replace them + count -= 2; + params += 2 * pr->pr_param_size; + PR_RESET_PARAMS (pr); + P_POINTER (pr, 0) = obj; + P_POINTER (pr, 1) = sel; + if (count) { + memcpy (&P_INT (pr, 2), params, + count * sizeof (pr_type_t) * pr->pr_param_size); + } PR_CallFunction (pr, imp); }