diff options
author | Koichi Sasada <[email protected]> | 2021-02-03 15:29:26 +0900 |
---|---|---|
committer | Koichi Sasada <[email protected]> | 2021-02-03 17:28:12 +0900 |
commit | 583f364f7187337b284061b78a47b29875398e33 (patch) | |
tree | eb3848f5f36a7e34f59c0a303b698a44a51a4bd9 /vm_eval.c | |
parent | f600226fb4ad7e3faa9a184bfe9b2de6404551f3 (diff) |
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.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/4148
Diffstat (limited to 'vm_eval.c')
-rw-r--r-- | vm_eval.c | 17 |
1 files changed, 16 insertions, 1 deletions
@@ -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); |