aboutsummaryrefslogtreecommitdiffstats
path: root/vm_insnhelper.c
diff options
context:
space:
mode:
authorAlan Wu <XrXr@users.noreply.github.com>2023-09-14 17:18:45 -0400
committerGitHub <noreply@github.com>2023-09-14 17:18:45 -0400
commit1961c5bb767a451928dc719d37c2b38f89d248c6 (patch)
tree9e92d1585057253c5349ed458af97c6d5f66ad07 /vm_insnhelper.c
parent66ffa15ce01e1b8d46738032e714be18194af3ca (diff)
downloadruby-1961c5bb767a451928dc719d37c2b38f89d248c6.tar.gz
YJIT: Plug native stack overflow
Previously, TestStack#test_machine_stack_size failed pretty consistently on ARM64 macOS, with Rust code and part of the interpreter used for per-instruction fallback (rb_vm_invokeblock() and friends) touching the stack guard page and crashing with SEGV. I've also seen the same test fail on x64 Linux, though with a different symptom.
Diffstat (limited to 'vm_insnhelper.c')
-rw-r--r--vm_insnhelper.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index a325d070a2..f98e6c6e75 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -93,6 +93,7 @@ rb_ec_stack_overflow(rb_execution_context_t *ec, int crit)
#endif
}
+static inline void stack_check(rb_execution_context_t *ec);
#if VM_CHECK_MODE > 0
static int
@@ -5565,6 +5566,7 @@ vm_sendish(
VALUE
rb_vm_send(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, CALL_DATA cd, ISEQ blockiseq)
{
+ stack_check(ec);
VALUE bh = vm_caller_setup_arg_block(ec, GET_CFP(), cd->ci, blockiseq, false);
VALUE val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_method);
VM_EXEC(ec, val);
@@ -5574,6 +5576,7 @@ rb_vm_send(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, CALL_DATA cd
VALUE
rb_vm_opt_send_without_block(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, CALL_DATA cd)
{
+ stack_check(ec);
VALUE bh = VM_BLOCK_HANDLER_NONE;
VALUE val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_method);
VM_EXEC(ec, val);
@@ -5583,6 +5586,7 @@ rb_vm_opt_send_without_block(rb_execution_context_t *ec, rb_control_frame_t *reg
VALUE
rb_vm_invokesuper(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, CALL_DATA cd, ISEQ blockiseq)
{
+ stack_check(ec);
VALUE bh = vm_caller_setup_arg_block(ec, GET_CFP(), cd->ci, blockiseq, true);
VALUE val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_super);
VM_EXEC(ec, val);
@@ -5592,6 +5596,7 @@ rb_vm_invokesuper(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, CALL_
VALUE
rb_vm_invokeblock(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, CALL_DATA cd)
{
+ stack_check(ec);
VALUE bh = VM_BLOCK_HANDLER_NONE;
VALUE val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_invokeblock);
VM_EXEC(ec, val);