aboutsummaryrefslogtreecommitdiffstats
path: root/vm_args.c
diff options
context:
space:
mode:
authorJeremy Evans <code@jeremyevans.net>2019-09-17 14:32:19 -0700
committerJeremy Evans <code@jeremyevans.net>2019-09-17 16:22:44 -0700
commit775365cbd2bf17195e694771fc1c15698273a640 (patch)
treeffed420e45f7a91d203acf2a22ac66650af4e214 /vm_args.c
parent9b35dc38644c10eed008f9ba19a7224f2fb49af2 (diff)
downloadruby-775365cbd2bf17195e694771fc1c15698273a640.tar.gz
Fix keyword argument separation issues with sym procs when using refinements
Make sure that vm_yield_with_cfunc can correctly set the empty keyword flag by passing 2 as the kw_splat value when calling it in vm_invoke_ifunc_block. Make sure calling.kw_splat is set to 1 and not 128 in vm_sendish, so we can safely check for different kw_splat values. vm_args.c needs to call add_empty_keyword, and to make JIT happy, the function needs to be exported. Rename the function to rb_adjust_argv_kw_splat to more accurately reflect what it does, and mark it as MJIT exported.
Diffstat (limited to 'vm_args.c')
-rw-r--r--vm_args.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/vm_args.c b/vm_args.c
index 459f60ea76..b235072d32 100644
--- a/vm_args.c
+++ b/vm_args.c
@@ -14,6 +14,7 @@ NORETURN(static void argument_kw_error(rb_execution_context_t *ec, const rb_iseq
VALUE rb_keyword_error_new(const char *error, VALUE keys); /* class.c */
static VALUE method_missing(VALUE obj, ID id, int argc, const VALUE *argv,
enum method_missing_reason call_status, int kw_splat);
+extern VALUE rb_adjust_argv_kw_splat(int *argc, const VALUE **argv, int *kw_splat);
struct args_info {
/* basic args info */
@@ -1051,6 +1052,9 @@ refine_sym_proc_call(RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg))
rb_execution_context_t *ec;
const VALUE symbol = RARRAY_AREF(callback_arg, 0);
const VALUE refinements = RARRAY_AREF(callback_arg, 1);
+ int kw_splat = RB_PASS_CALLED_KEYWORDS;
+ VALUE v;
+ VALUE ret;
VALUE klass;
if (argc-- < 1) {
@@ -1071,10 +1075,15 @@ refine_sym_proc_call(RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg))
if (!NIL_P(blockarg)) {
vm_passed_block_handler_set(ec, blockarg);
}
+ v = rb_adjust_argv_kw_splat(&argc, &argv, &kw_splat);
if (!me) {
- return method_missing(obj, mid, argc, argv, MISSING_NOENTRY, VM_NO_KEYWORDS);
+ ret = method_missing(obj, mid, argc, argv, MISSING_NOENTRY, kw_splat);
}
- return rb_vm_call0(ec, obj, mid, argc, argv, me, VM_NO_KEYWORDS);
+ else {
+ ret = rb_vm_call0(ec, obj, mid, argc, argv, me, kw_splat);
+ }
+ rb_free_tmp_buffer(&v);
+ return ret;
}
static VALUE