diff --git a/vm_core.h b/vm_core.h index fd49c243e3..81455e18bc 100644 --- a/vm_core.h +++ b/vm_core.h @@ -1688,17 +1688,17 @@ MJIT_STATIC const rb_callable_method_entry_t *rb_vm_frame_method_entry(const rb_ #define sysstack_error GET_VM()->special_exceptions[ruby_error_sysstack] -#define RUBY_CONST_ASSERT(expr) (1/!!(expr)) /* expr must be a compile-time constant */ -#define VM_STACK_OVERFLOWED_P(cfp, sp, margin) \ - (!RUBY_CONST_ASSERT(sizeof(*(sp)) == sizeof(VALUE)) || \ - !RUBY_CONST_ASSERT(sizeof(*(cfp)) == sizeof(rb_control_frame_t)) || \ - ((rb_control_frame_t *)((sp) + (margin)) + 1) >= (cfp)) -#define WHEN_VM_STACK_OVERFLOWED(cfp, sp, margin) \ - if (LIKELY(!VM_STACK_OVERFLOWED_P(cfp, sp, margin))) {(void)0;} else /* overflowed */ -#define CHECK_VM_STACK_OVERFLOW0(cfp, sp, margin) \ - WHEN_VM_STACK_OVERFLOWED(cfp, sp, margin) vm_stackoverflow() +#define CHECK_VM_STACK_OVERFLOW0(cfp, sp, margin) do { \ + STATIC_ASSERT(sizeof_sp, sizeof(*(sp)) == sizeof(VALUE)); \ + STATIC_ASSERT(sizeof_cfp, sizeof(*(cfp)) == sizeof(rb_control_frame_t)); \ + const struct rb_control_frame_struct *bound = (void *)&(sp)[(margin)]; \ + if (UNLIKELY((cfp) <= &bound[1])) { \ + vm_stackoverflow(); \ + } \ +} while (0) + #define CHECK_VM_STACK_OVERFLOW(cfp, margin) \ - WHEN_VM_STACK_OVERFLOWED(cfp, (cfp)->sp, margin) vm_stackoverflow() + CHECK_VM_STACK_OVERFLOW0((cfp), (cfp)->sp, (margin)) VALUE rb_catch_protect(VALUE t, rb_block_call_func *func, VALUE data, enum ruby_tag_type *stateptr); diff --git a/vm_exec.c b/vm_exec.c index 2c7e22228a..ce2e053ee7 100644 --- a/vm_exec.c +++ b/vm_exec.c @@ -62,17 +62,6 @@ static void vm_insns_counter_count_insn(int insn) {} #endif /* #define DECL_SC_REG(r, reg) VALUE reg_##r */ -#if VM_DEBUG_STACKOVERFLOW -NORETURN(static void vm_stack_overflow_for_insn(void)); -static void -vm_stack_overflow_for_insn(void) -{ - rb_bug("CHECK_VM_STACK_OVERFLOW_FOR_INSN: should not overflow here. " - "Please contact ruby-core/dev with your (a part of) script. " - "This check will be removed soon."); -} -#endif - #if !OPT_CALL_THREADED_CODE static VALUE vm_exec_core(rb_execution_context_t *ec, VALUE initial) diff --git a/vm_exec.h b/vm_exec.h index 1be3f64576..1f2a052ff4 100644 --- a/vm_exec.h +++ b/vm_exec.h @@ -185,8 +185,7 @@ default: \ #define VM_DEBUG_STACKOVERFLOW 0 #if VM_DEBUG_STACKOVERFLOW -#define CHECK_VM_STACK_OVERFLOW_FOR_INSN(cfp, margin) \ - WHEN_VM_STACK_OVERFLOWED(cfp, (cfp)->sp, margin) vm_stack_overflow_for_insn() +#define CHECK_VM_STACK_OVERFLOW_FOR_INSN CHECK_VM_STACK_OVERFLOW #else #define CHECK_VM_STACK_OVERFLOW_FOR_INSN(cfp, margin) #endif