From 74e33662fe987e5418fc277c8a7ba1f9805f8673 Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Mon, 23 Sep 2019 08:44:38 -0700 Subject: Make public_send and rb_f_send handle keyword argument separation Kernel#send takes a different optimized code path that was already handled. --- vm_eval.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'vm_eval.c') diff --git a/vm_eval.c b/vm_eval.c index 4b3cb47072..0fd4f573ef 100644 --- a/vm_eval.c +++ b/vm_eval.c @@ -1123,6 +1123,29 @@ send_internal(int argc, const VALUE *argv, VALUE recv, call_type scope) return ret; } +static VALUE +send_internal_kw(int argc, const VALUE *argv, VALUE recv, call_type scope) +{ + VALUE v=0, ret; + int kw_splat = RB_PASS_CALLED_KEYWORDS; + v = rb_adjust_argv_kw_splat(&argc, &argv, &kw_splat); + if (kw_splat) { + switch (scope) { + case CALL_PUBLIC: + scope = CALL_PUBLIC_KW; + break; + case CALL_FCALL: + scope = CALL_FCALL_KW; + break; + default: + break; + } + } + ret = send_internal(argc, argv, recv, scope); + rb_free_tmp_buffer(&v); + return ret; +} + /* * call-seq: * foo.send(symbol [, args...]) -> obj @@ -1150,7 +1173,7 @@ send_internal(int argc, const VALUE *argv, VALUE recv, call_type scope) VALUE rb_f_send(int argc, VALUE *argv, VALUE recv) { - return send_internal(argc, argv, recv, CALL_FCALL); + return send_internal_kw(argc, argv, recv, CALL_FCALL); } /* @@ -1170,7 +1193,7 @@ rb_f_send(int argc, VALUE *argv, VALUE recv) static VALUE rb_f_public_send(int argc, VALUE *argv, VALUE recv) { - return send_internal(argc, argv, recv, CALL_PUBLIC); + return send_internal_kw(argc, argv, recv, CALL_PUBLIC); } /* yield */ -- cgit v1.2.3