Skip to content

Commit

Permalink
Move forwardable conditional
Browse files Browse the repository at this point in the history
This is not common, so we should do it last
  • Loading branch information
tenderlove committed Apr 12, 2024
1 parent 91b1ff4 commit 192b1b8
Showing 1 changed file with 41 additions and 44 deletions.
85 changes: 41 additions & 44 deletions vm_insnhelper.c
Original file line number Diff line number Diff line change
Expand Up @@ -2987,50 +2987,6 @@ vm_callee_setup_arg(rb_execution_context_t *ec, struct rb_calling_info *calling,
const struct rb_callcache *cc = calling->cc;
bool cacheable_ci = vm_ci_cacheable(ci);

// Called iseq is using ... param
// def foo(...) # <- iseq for foo will have "forwardable"
//
// We want to set the `...` local to the caller's CI
// foo(1, 2) # <- the ci for this should end up as `...`
//
// So hopefully the stack looks like:
//
// => 1
// => 2
// => *
// => **
// => &
// => ... # <- points at `foo`s CI
// => cref_or_me
// => specval
// => type
//
if (ISEQ_BODY(iseq)->param.flags.forwardable) {
if ((vm_ci_flag(ci) & VM_CALL_FORWARDING)) {
struct rb_forwarding_call_data * forward_cd = (struct rb_forwarding_call_data *)calling->cd;
if (vm_ci_argc(ci) != vm_ci_argc(forward_cd->caller_ci)) {
ci = vm_ci_new_runtime(
vm_ci_mid(ci),
vm_ci_flag(ci),
vm_ci_argc(ci),
vm_ci_kwarg(ci));
} else {
ci = forward_cd->caller_ci;
}
}
// C functions calling iseqs will stack allocate a CI,
// so we need to convert it to heap allocated
if (!vm_ci_markable(ci)) {
ci = vm_ci_new_runtime(
vm_ci_mid(ci),
vm_ci_flag(ci),
vm_ci_argc(ci),
vm_ci_kwarg(ci));
}
argv[param_size - 1] = (VALUE)ci;
return 0;
}

if (LIKELY(!(vm_ci_flag(ci) & VM_CALL_KW_SPLAT))) {
if (LIKELY(rb_simple_iseq_p(iseq))) {
rb_control_frame_t *cfp = ec->cfp;
Expand Down Expand Up @@ -3126,6 +3082,47 @@ vm_callee_setup_arg(rb_execution_context_t *ec, struct rb_calling_info *calling,
return 0;
}
}
else if (ISEQ_BODY(iseq)->param.flags.forwardable) {
// Called iseq is using ... param
// def foo(...) # <- iseq for foo will have "forwardable"
//
// We want to set the `...` local to the caller's CI
// foo(1, 2) # <- the ci for this should end up as `...`
//
// So hopefully the stack looks like:
//
// => 1
// => 2
// => ... # <- points at `foo`s CI
// => cref_or_me
// => specval
// => type
//

if ((vm_ci_flag(ci) & VM_CALL_FORWARDING)) {
struct rb_forwarding_call_data * forward_cd = (struct rb_forwarding_call_data *)calling->cd;
if (vm_ci_argc(ci) != vm_ci_argc(forward_cd->caller_ci)) {
ci = vm_ci_new_runtime(
vm_ci_mid(ci),
vm_ci_flag(ci),
vm_ci_argc(ci),
vm_ci_kwarg(ci));
} else {
ci = forward_cd->caller_ci;
}
}
// C functions calling iseqs will stack allocate a CI,
// so we need to convert it to heap allocated
if (!vm_ci_markable(ci)) {
ci = vm_ci_new_runtime(
vm_ci_mid(ci),
vm_ci_flag(ci),
vm_ci_argc(ci),
vm_ci_kwarg(ci));
}
argv[param_size - 1] = (VALUE)ci;
return 0;
}
}

return setup_parameters_complex(ec, iseq, calling, ci, argv, arg_setup_method);
Expand Down

0 comments on commit 192b1b8

Please sign in to comment.