diff options
author | Jeremy Evans <code@jeremyevans.net> | 2019-09-23 08:44:38 -0700 |
---|---|---|
committer | Jeremy Evans <code@jeremyevans.net> | 2019-09-23 09:28:27 -0700 |
commit | 74e33662fe987e5418fc277c8a7ba1f9805f8673 (patch) | |
tree | 9fd7ecaa2eab1dc08241cb218196a93b890d8264 /vm_eval.c | |
parent | 9e4be78ea88f882e1562dbb3eeb24304d0049b8d (diff) | |
download | bundler-74e33662fe987e5418fc277c8a7ba1f9805f8673.tar.gz |
Make public_send and rb_f_send handle keyword argument separation
Kernel#send takes a different optimized code path that was already
handled.
Diffstat (limited to 'vm_eval.c')
-rw-r--r-- | vm_eval.c | 27 |
1 files changed, 25 insertions, 2 deletions
@@ -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 */ |