diff --git a/yjit/bindgen/src/main.rs b/yjit/bindgen/src/main.rs index 7bdfdade77..f7ebb88577 100644 --- a/yjit/bindgen/src/main.rs +++ b/yjit/bindgen/src/main.rs @@ -66,6 +66,9 @@ fn main() { // From include/ruby/internal/config.h .allowlist_var("USE_RVARGC") + // From include/ruby/internal/special_consts.h + .allowlist_type("ruby_special_consts") + // From include/ruby/internal/intern/string.h .allowlist_function("rb_utf8_str_new") .allowlist_function("rb_str_buf_append") diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index 196baf9689..5d144458e8 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -3296,8 +3296,7 @@ fn gen_branchunless( gen_direct_jump(jit, ctx, target, asm); } else { // Test if any bit (outside of the Qnil bit) is on - // RUBY_Qfalse /* ...0000 0000 */ - // RUBY_Qnil /* ...0000 1000 */ + // See RB_TEST() let not_qnil = !Qnil.as_i64(); asm.test(val_opnd, not_qnil.into()); @@ -3368,7 +3367,6 @@ fn gen_branchnil( gen_direct_jump(jit, ctx, target, asm); } else { // Test if the value is Qnil - // RUBY_Qnil /* ...0000 1000 */ asm.cmp(val_opnd, Opnd::UImm(Qnil.into())); // Generate the branch instructions gen_branch( diff --git a/yjit/src/cruby.rs b/yjit/src/cruby.rs index 81db0deab3..d8dbdb4019 100644 --- a/yjit/src/cruby.rs +++ b/yjit/src/cruby.rs @@ -322,7 +322,8 @@ impl VALUE { /// Return true if the number is an immediate integer, flonum or static symbol fn immediate_p(self) -> bool { let VALUE(cval) = self; - (cval & 7) != 0 + let mask = RUBY_IMMEDIATE_MASK as usize; + (cval & mask) != 0 } /// Return true if the value is a Ruby immediate integer, flonum, static symbol, nil or false @@ -333,19 +334,23 @@ impl VALUE { /// Return true if the value is a Ruby Fixnum (immediate-size integer) pub fn fixnum_p(self) -> bool { let VALUE(cval) = self; - (cval & 1) == 1 + let flag = RUBY_FIXNUM_FLAG as usize; + (cval & flag) == flag } /// Return true if the value is an immediate Ruby floating-point number (flonum) pub fn flonum_p(self) -> bool { let VALUE(cval) = self; - (cval & 3) == 2 + let mask = RUBY_FLONUM_MASK as usize; + let flag = RUBY_FLONUM_FLAG as usize; + (cval & mask) == flag } /// Return true for a static (non-heap) Ruby symbol pub fn static_sym_p(self) -> bool { let VALUE(cval) = self; - (cval & 0xff) == RUBY_SYMBOL_FLAG + let flag = RUBY_SYMBOL_FLAG as usize; + (cval & 0xff) == flag } /// Returns true or false depending on whether the value is nil @@ -595,13 +600,13 @@ where // Non-idiomatic capitalization for consistency with CRuby code #[allow(non_upper_case_globals)] -pub const Qfalse: VALUE = VALUE(0); +pub const Qfalse: VALUE = VALUE(RUBY_Qfalse as usize); #[allow(non_upper_case_globals)] -pub const Qnil: VALUE = VALUE(4); +pub const Qnil: VALUE = VALUE(RUBY_Qnil as usize); #[allow(non_upper_case_globals)] -pub const Qtrue: VALUE = VALUE(20); +pub const Qtrue: VALUE = VALUE(RUBY_Qtrue as usize); #[allow(non_upper_case_globals)] -pub const Qundef: VALUE = VALUE(0x24); +pub const Qundef: VALUE = VALUE(RUBY_Qundef as usize); #[allow(unused)] mod manual_defs { @@ -615,16 +620,6 @@ mod manual_defs { pub const RUBY_FIXNUM_MIN: isize = RUBY_LONG_MIN / 2; pub const RUBY_FIXNUM_MAX: isize = RUBY_LONG_MAX / 2; - pub const RUBY_FIXNUM_FLAG: usize = 0x1; - - // All these are defined in include/ruby/internal/special_consts.h, - // in the same enum as RUBY_Qfalse, etc. - // Do we want to switch to using Ruby's definition of Qnil, Qfalse, etc? - pub const RUBY_SYMBOL_FLAG: usize = 0x0c; - pub const RUBY_FLONUM_FLAG: usize = 0x2; - pub const RUBY_FLONUM_MASK: usize = 0x3; - pub const RUBY_SPECIAL_SHIFT: usize = 8; - pub const RUBY_IMMEDIATE_MASK: usize = 0x7; // From vm_callinfo.h - uses calculation that seems to confuse bindgen pub const VM_CALL_ARGS_SPLAT: u32 = 1 << VM_CALL_ARGS_SPLAT_bit; diff --git a/yjit/src/cruby_bindings.inc.rs b/yjit/src/cruby_bindings.inc.rs index 00bade6b70..ab5db31f93 100644 --- a/yjit/src/cruby_bindings.inc.rs +++ b/yjit/src/cruby_bindings.inc.rs @@ -152,6 +152,17 @@ extern "C" { extern "C" { pub fn rb_method_basic_definition_p(klass: VALUE, mid: ID) -> ::std::os::raw::c_int; } +pub const RUBY_Qfalse: ruby_special_consts = 0; +pub const RUBY_Qnil: ruby_special_consts = 4; +pub const RUBY_Qtrue: ruby_special_consts = 20; +pub const RUBY_Qundef: ruby_special_consts = 36; +pub const RUBY_IMMEDIATE_MASK: ruby_special_consts = 7; +pub const RUBY_FIXNUM_FLAG: ruby_special_consts = 1; +pub const RUBY_FLONUM_MASK: ruby_special_consts = 3; +pub const RUBY_FLONUM_FLAG: ruby_special_consts = 2; +pub const RUBY_SYMBOL_FLAG: ruby_special_consts = 12; +pub const RUBY_SPECIAL_SHIFT: ruby_special_consts = 8; +pub type ruby_special_consts = u32; #[repr(C)] pub struct RBasic { pub flags: VALUE,