summaryrefslogtreecommitdiff
path: root/vm_insnhelper.c
diff options
context:
space:
mode:
Diffstat (limited to 'vm_insnhelper.c')
-rw-r--r--vm_insnhelper.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index a83e3a952a..1dd88781db 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -2888,6 +2888,7 @@ vm_yield_with_cfunc(rb_execution_context_t *ec,
{
int is_lambda = FALSE; /* TODO */
VALUE val, arg, blockarg;
+ int frame_flag;
const struct vm_ifunc *ifunc = captured->code.ifunc;
if (is_lambda) {
@@ -2902,9 +2903,18 @@ vm_yield_with_cfunc(rb_execution_context_t *ec,
blockarg = rb_vm_bh_to_procval(ec, block_handler);
+ frame_flag = VM_FRAME_MAGIC_IFUNC | VM_FRAME_FLAG_CFRAME | (me ? VM_FRAME_FLAG_BMETHOD : 0);
+ switch(kw_splat) {
+ case 1:
+ frame_flag |= VM_FRAME_FLAG_CFRAME_KW;
+ break;
+ case 2:
+ frame_flag |= VM_FRAME_FLAG_CFRAME_EMPTY_KW;
+ break;
+ }
+
vm_push_frame(ec, (const rb_iseq_t *)captured->code.ifunc,
- VM_FRAME_MAGIC_IFUNC | VM_FRAME_FLAG_CFRAME |
- (me ? VM_FRAME_FLAG_BMETHOD : 0) | (kw_splat ? VM_FRAME_FLAG_CFRAME_KW : 0),
+ frame_flag,
self,
VM_GUARDED_PREV_EP(captured->ep),
(VALUE)me,
@@ -3060,9 +3070,17 @@ vm_invoke_ifunc_block(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp,
{
VALUE val;
int argc;
+ int frame_flag = 0;
+ int kw_splat = calling->kw_splat;
CALLER_SETUP_ARG(ec->cfp, calling, ci);
+ if (kw_splat && !calling->kw_splat) {
+ kw_splat = 2;
+ }
+ else {
+ kw_splat = calling->kw_splat;
+ }
argc = calling->argc;
- val = vm_yield_with_cfunc(ec, captured, captured->self, argc, STACK_ADDR_FROM_TOP(argc), calling->kw_splat, calling->block_handler, NULL);
+ val = vm_yield_with_cfunc(ec, captured, captured->self, argc, STACK_ADDR_FROM_TOP(argc), kw_splat, calling->block_handler, NULL);
POPN(argc); /* TODO: should put before C/yield? */
return val;
}
@@ -3695,7 +3713,7 @@ vm_sendish(
struct rb_calling_info calling;
calling.block_handler = block_handler;
- calling.kw_splat = IS_ARGS_KW_SPLAT(ci);
+ calling.kw_splat = IS_ARGS_KW_SPLAT(ci) > 0;
calling.recv = recv;
calling.argc = argc;