From 583f364f7187337b284061b78a47b29875398e33 Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Wed, 3 Feb 2021 15:29:26 +0900 Subject: 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. --- vm_eval.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/vm_eval.c b/vm_eval.c index 0f3d1e4e1f..eae9464a1b 100644 --- a/vm_eval.c +++ b/vm_eval.c @@ -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); -- cgit v1.2.3