diff options
author | Jeremy Evans <code@jeremyevans.net> | 2019-09-17 14:32:19 -0700 |
---|---|---|
committer | Jeremy Evans <code@jeremyevans.net> | 2019-09-17 16:22:44 -0700 |
commit | 775365cbd2bf17195e694771fc1c15698273a640 (patch) | |
tree | ffed420e45f7a91d203acf2a22ac66650af4e214 /vm_args.c | |
parent | 9b35dc38644c10eed008f9ba19a7224f2fb49af2 (diff) |
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.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/2462
Diffstat (limited to 'vm_args.c')
-rw-r--r-- | vm_args.c | 13 |
1 files changed, 11 insertions, 2 deletions
@@ -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 |