Skip to content

Commit

Permalink
use goto intead of recursion on vm_call0_body()
Browse files Browse the repository at this point in the history
"alias" type method entries can chain another aliased method
so that machine stack can be overflow on nested alias chain.
http://ci.rvm.jp/results/trunk-repeat20@phosphorus-docker/3344209

This patch fix this issue by use goto instead of recursion if possible.

TODO: Essentially, the alias method should not points another aliased
method entry. Try to fix it later.
  • Loading branch information
ko1 committed Feb 3, 2021
1 parent f600226 commit 583f364
Showing 1 changed file with 16 additions and 1 deletion.
17 changes: 16 additions & 1 deletion vm_eval.c
Expand Up @@ -157,6 +157,8 @@ vm_call0_body(rb_execution_context_t *ec, struct rb_calling_info *calling, const
const struct rb_callcache *cc = calling->cc;
VALUE ret;

retry:

switch (vm_cc_cme(cc)->def->type) {
case VM_METHOD_TYPE_ISEQ:
{
Expand Down Expand Up @@ -222,7 +224,20 @@ vm_call0_body(rb_execution_context_t *ec, struct rb_calling_info *calling, const
return vm_call0_super(ec, calling, argv, klass, 0);
}
case VM_METHOD_TYPE_ALIAS:
return vm_call0_cme(ec, calling, argv, aliased_callable_method_entry(vm_cc_cme(cc)));
{
const rb_callable_method_entry_t *cme = vm_cc_cme(cc);
const rb_callable_method_entry_t *orig_cme = aliased_callable_method_entry(cme);

if (cme == orig_cme) rb_bug("same!!");

if (vm_cc_markable(cc)) {
return vm_call0_cme(ec, calling, argv, orig_cme);
}
else {
*((const rb_callable_method_entry_t **)&cc->cme_) = orig_cme;
goto retry;
}
}
case VM_METHOD_TYPE_MISSING:
{
vm_passed_block_handler_set(ec, calling->block_handler);
Expand Down

0 comments on commit 583f364

Please sign in to comment.