From f3f3e76882d01d5e0a006ff731b70053997396e8 Mon Sep 17 00:00:00 2001 From: Jacob Date: Tue, 18 Nov 2025 17:32:11 -0500 Subject: [PATCH] Extract `KW_SPECIFIED_BITS_MAX` for JITs (GH-15039) Rename to `VM_KW_SPECIFIED_BITS_MAX` now that it's in `vm_core.h`. --- vm_args.c | 10 ++++------ vm_core.h | 2 ++ vm_insnhelper.c | 2 +- yjit/bindgen/src/main.rs | 1 + yjit/src/codegen.rs | 2 +- yjit/src/cruby_bindings.inc.rs | 1 + zjit/bindgen/src/main.rs | 1 + zjit/src/cruby_bindings.inc.rs | 1 + zjit/src/hir.rs | 3 +-- 9 files changed, 13 insertions(+), 10 deletions(-) diff --git a/vm_args.c b/vm_args.c index 5952b32f1f..64ed88d0e1 100644 --- a/vm_args.c +++ b/vm_args.c @@ -318,8 +318,6 @@ args_setup_kw_parameters_lookup(const ID key, VALUE *ptr, const VALUE *const pas return FALSE; } -#define KW_SPECIFIED_BITS_MAX (32-1) /* TODO: 32 -> Fixnum's max bits */ - static void args_setup_kw_parameters(rb_execution_context_t *const ec, const rb_iseq_t *const iseq, const rb_callable_method_entry_t *cme, VALUE *const passed_values, const int passed_keyword_len, const VALUE *const passed_keywords, @@ -355,7 +353,7 @@ args_setup_kw_parameters(rb_execution_context_t *const ec, const rb_iseq_t *cons if (UNDEF_P(default_values[di])) { locals[i] = Qnil; - if (LIKELY(i < KW_SPECIFIED_BITS_MAX)) { + if (LIKELY(i < VM_KW_SPECIFIED_BITS_MAX)) { unspecified_bits |= 0x01 << di; } else { @@ -364,7 +362,7 @@ args_setup_kw_parameters(rb_execution_context_t *const ec, const rb_iseq_t *cons int j; unspecified_bits_value = rb_hash_new(); - for (j=0; j Fixnum's max bits */ + # define CALLING_ARGC(calling) ((calling)->heap_argv ? RARRAY_LENINT((calling)->heap_argv) : (calling)->argc) struct rb_execution_context_struct; diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 63dcaba8a3..1b1eeb69d9 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -5808,7 +5808,7 @@ vm_check_keyword(lindex_t bits, lindex_t idx, const VALUE *ep) if (FIXNUM_P(kw_bits)) { unsigned int b = (unsigned int)FIX2ULONG(kw_bits); - if ((idx < KW_SPECIFIED_BITS_MAX) && (b & (0x01 << idx))) + if ((idx < VM_KW_SPECIFIED_BITS_MAX) && (b & (0x01 << idx))) return Qfalse; } else { diff --git a/yjit/bindgen/src/main.rs b/yjit/bindgen/src/main.rs index 100abbb33f..67a461cd16 100644 --- a/yjit/bindgen/src/main.rs +++ b/yjit/bindgen/src/main.rs @@ -155,6 +155,7 @@ fn main() { .opaque_type("rb_callcache.*") .allowlist_type("rb_callinfo") .allowlist_var("VM_ENV_DATA_INDEX_ME_CREF") + .allowlist_var("VM_KW_SPECIFIED_BITS_MAX") .allowlist_var("rb_block_param_proxy") .allowlist_function("rb_range_new") .allowlist_function("rb_intern") diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index a04c95ca09..9eeccddf6c 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -2747,7 +2747,7 @@ fn gen_checkkeyword( ) -> Option { // When a keyword is unspecified past index 32, a hash will be used // instead. This can only happen in iseqs taking more than 32 keywords. - if unsafe { (*get_iseq_body_param_keyword(jit.iseq)).num >= 32 } { + if unsafe { (*get_iseq_body_param_keyword(jit.iseq)).num >= VM_KW_SPECIFIED_BITS_MAX.try_into().unwrap() } { return None; } diff --git a/yjit/src/cruby_bindings.inc.rs b/yjit/src/cruby_bindings.inc.rs index 253598bce1..a6aef48313 100644 --- a/yjit/src/cruby_bindings.inc.rs +++ b/yjit/src/cruby_bindings.inc.rs @@ -165,6 +165,7 @@ pub const NIL_REDEFINED_OP_FLAG: u32 = 512; pub const TRUE_REDEFINED_OP_FLAG: u32 = 1024; pub const FALSE_REDEFINED_OP_FLAG: u32 = 2048; pub const PROC_REDEFINED_OP_FLAG: u32 = 4096; +pub const VM_KW_SPECIFIED_BITS_MAX: u32 = 31; pub const VM_ENV_DATA_SIZE: u32 = 3; pub const VM_ENV_DATA_INDEX_ME_CREF: i32 = -2; pub const VM_ENV_DATA_INDEX_SPECVAL: i32 = -1; diff --git a/zjit/bindgen/src/main.rs b/zjit/bindgen/src/main.rs index 95209375dc..7873a20977 100644 --- a/zjit/bindgen/src/main.rs +++ b/zjit/bindgen/src/main.rs @@ -101,6 +101,7 @@ fn main() { .allowlist_function("rb_shape_get_iv_index") .allowlist_function("rb_shape_transition_add_ivar_no_warnings") .allowlist_var("rb_invalid_shape_id") + .allowlist_var("VM_KW_SPECIFIED_BITS_MAX") .allowlist_var("SHAPE_ID_NUM_BITS") .allowlist_function("rb_obj_is_kind_of") .allowlist_function("rb_obj_frozen_p") diff --git a/zjit/src/cruby_bindings.inc.rs b/zjit/src/cruby_bindings.inc.rs index 457cd584cf..0fde4e3ab7 100644 --- a/zjit/src/cruby_bindings.inc.rs +++ b/zjit/src/cruby_bindings.inc.rs @@ -227,6 +227,7 @@ pub const NIL_REDEFINED_OP_FLAG: u32 = 512; pub const TRUE_REDEFINED_OP_FLAG: u32 = 1024; pub const FALSE_REDEFINED_OP_FLAG: u32 = 2048; pub const PROC_REDEFINED_OP_FLAG: u32 = 4096; +pub const VM_KW_SPECIFIED_BITS_MAX: u32 = 31; pub const VM_ENV_DATA_SIZE: u32 = 3; pub const VM_ENV_DATA_INDEX_ME_CREF: i32 = -2; pub const VM_ENV_DATA_INDEX_SPECVAL: i32 = -1; diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs index c96e0357a0..58638f30f0 100644 --- a/zjit/src/hir.rs +++ b/zjit/src/hir.rs @@ -4848,8 +4848,7 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result { // When a keyword is unspecified past index 32, a hash will be used instead. // This can only happen in iseqs taking more than 32 keywords. // In this case, we side exit to the interpreter. - // TODO(Jacob): Replace the magic number 32 with a named constant. (Can be completed after PR 15039) - if unsafe {(*rb_get_iseq_body_param_keyword(iseq)).num >= 32} { + if unsafe {(*rb_get_iseq_body_param_keyword(iseq)).num >= VM_KW_SPECIFIED_BITS_MAX.try_into().unwrap()} { fun.push_insn(block, Insn::SideExit { state: exit_id, reason: SideExitReason::TooManyKeywordParameters }); break; }