use goto intead of recursion on vm_call0_body()

"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.
This commit is contained in:
Koichi Sasada 2021-02-03 15:29:26 +09:00
Родитель f600226fb4
Коммит 583f364f71
1 изменённых файлов: 16 добавлений и 1 удалений

Просмотреть файл

@ -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:
{
@ -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);