diff options
| author | Max Bernstein <ruby@bernsteinbear.com> | 2025-07-28 09:54:25 -0400 |
|---|---|---|
| committer | Max Bernstein <tekknolagi@gmail.com> | 2025-07-28 12:35:21 -0700 |
| commit | f6dccdb1ff271d391fa51935370e07747c5722a3 (patch) | |
| tree | c10456b7f137fc24561c716cf9cc68a6a1572df1 | |
| parent | 043489abc2fe9a1953e19588101e469cbc505f38 (diff) | |
ZJIT: Remove Integer subclasses from lattice
While Integer can technically be subclassed, instances of subclasses
cannot be created. Remove it from the type lattice.
| -rw-r--r-- | zjit/src/hir_type/gen_hir_type.rb | 9 | ||||
| -rw-r--r-- | zjit/src/hir_type/hir_type.inc.rs | 56 | ||||
| -rw-r--r-- | zjit/src/hir_type/mod.rs | 14 |
3 files changed, 36 insertions, 43 deletions
diff --git a/zjit/src/hir_type/gen_hir_type.rb b/zjit/src/hir_type/gen_hir_type.rb index 361026e101..27f936a389 100644 --- a/zjit/src/hir_type/gen_hir_type.rb +++ b/zjit/src/hir_type/gen_hir_type.rb @@ -68,6 +68,13 @@ def base_type name [type, exact] end +# Define a new type that cannot be subclassed. +def final_type name + type = $object.subtype name + $builtin_exact << type.name + type +end + base_type "String" base_type "Array" base_type "Hash" @@ -77,7 +84,7 @@ base_type "Regexp" module_class, _ = base_type "Module" module_class.subtype "Class" -_, integer_exact = base_type "Integer" +integer_exact = final_type "Integer" # CRuby partitions Integer into immediate and non-immediate variants. fixnum = integer_exact.subtype "Fixnum" integer_exact.subtype "Bignum" diff --git a/zjit/src/hir_type/hir_type.inc.rs b/zjit/src/hir_type/hir_type.inc.rs index 21ef8c8bdd..aaef14467b 100644 --- a/zjit/src/hir_type/hir_type.inc.rs +++ b/zjit/src/hir_type/hir_type.inc.rs @@ -9,7 +9,7 @@ mod bits { pub const BasicObjectSubclass: u64 = 1u64 << 3; pub const Bignum: u64 = 1u64 << 4; pub const BoolExact: u64 = FalseClassExact | TrueClassExact; - pub const BuiltinExact: u64 = ArrayExact | BasicObjectExact | FalseClassExact | FloatExact | HashExact | IntegerExact | ModuleExact | NilClassExact | ObjectExact | RangeExact | RegexpExact | SetExact | StringExact | SymbolExact | TrueClassExact; + pub const BuiltinExact: u64 = ArrayExact | BasicObjectExact | FalseClassExact | FloatExact | HashExact | Integer | ModuleExact | NilClassExact | ObjectExact | RangeExact | RegexpExact | SetExact | StringExact | SymbolExact | TrueClassExact; pub const CBool: u64 = 1u64 << 5; pub const CDouble: u64 = 1u64 << 6; pub const CInt: u64 = CSigned | CUnsigned; @@ -43,41 +43,39 @@ mod bits { pub const HashSubclass: u64 = 1u64 << 26; pub const HeapFloat: u64 = 1u64 << 27; pub const Immediate: u64 = FalseClassExact | Fixnum | Flonum | NilClassExact | StaticSymbol | TrueClassExact | Undef; - pub const Integer: u64 = IntegerExact | IntegerSubclass; - pub const IntegerExact: u64 = Bignum | Fixnum; - pub const IntegerSubclass: u64 = 1u64 << 28; + pub const Integer: u64 = Bignum | Fixnum; pub const Module: u64 = Class | ModuleExact | ModuleSubclass; - pub const ModuleExact: u64 = 1u64 << 29; - pub const ModuleSubclass: u64 = 1u64 << 30; + pub const ModuleExact: u64 = 1u64 << 28; + pub const ModuleSubclass: u64 = 1u64 << 29; pub const NilClass: u64 = NilClassExact | NilClassSubclass; - pub const NilClassExact: u64 = 1u64 << 31; - pub const NilClassSubclass: u64 = 1u64 << 32; + pub const NilClassExact: u64 = 1u64 << 30; + pub const NilClassSubclass: u64 = 1u64 << 31; pub const Object: u64 = Array | FalseClass | Float | Hash | Integer | Module | NilClass | ObjectExact | ObjectSubclass | Range | Regexp | Set | String | Symbol | TrueClass; - pub const ObjectExact: u64 = 1u64 << 33; - pub const ObjectSubclass: u64 = 1u64 << 34; + pub const ObjectExact: u64 = 1u64 << 32; + pub const ObjectSubclass: u64 = 1u64 << 33; pub const Range: u64 = RangeExact | RangeSubclass; - pub const RangeExact: u64 = 1u64 << 35; - pub const RangeSubclass: u64 = 1u64 << 36; + pub const RangeExact: u64 = 1u64 << 34; + pub const RangeSubclass: u64 = 1u64 << 35; pub const Regexp: u64 = RegexpExact | RegexpSubclass; - pub const RegexpExact: u64 = 1u64 << 37; - pub const RegexpSubclass: u64 = 1u64 << 38; + pub const RegexpExact: u64 = 1u64 << 36; + pub const RegexpSubclass: u64 = 1u64 << 37; pub const RubyValue: u64 = BasicObject | CallableMethodEntry | Undef; pub const Set: u64 = SetExact | SetSubclass; - pub const SetExact: u64 = 1u64 << 39; - pub const SetSubclass: u64 = 1u64 << 40; - pub const StaticSymbol: u64 = 1u64 << 41; + pub const SetExact: u64 = 1u64 << 38; + pub const SetSubclass: u64 = 1u64 << 39; + pub const StaticSymbol: u64 = 1u64 << 40; pub const String: u64 = StringExact | StringSubclass; - pub const StringExact: u64 = 1u64 << 42; - pub const StringSubclass: u64 = 1u64 << 43; - pub const Subclass: u64 = ArraySubclass | BasicObjectSubclass | FalseClassSubclass | FloatSubclass | HashSubclass | IntegerSubclass | ModuleSubclass | NilClassSubclass | ObjectSubclass | RangeSubclass | RegexpSubclass | SetSubclass | StringSubclass | SymbolSubclass | TrueClassSubclass; + pub const StringExact: u64 = 1u64 << 41; + pub const StringSubclass: u64 = 1u64 << 42; + pub const Subclass: u64 = ArraySubclass | BasicObjectSubclass | FalseClassSubclass | FloatSubclass | HashSubclass | ModuleSubclass | NilClassSubclass | ObjectSubclass | RangeSubclass | RegexpSubclass | SetSubclass | StringSubclass | SymbolSubclass | TrueClassSubclass; pub const Symbol: u64 = SymbolExact | SymbolSubclass; pub const SymbolExact: u64 = DynamicSymbol | StaticSymbol; - pub const SymbolSubclass: u64 = 1u64 << 44; + pub const SymbolSubclass: u64 = 1u64 << 43; pub const TrueClass: u64 = TrueClassExact | TrueClassSubclass; - pub const TrueClassExact: u64 = 1u64 << 45; - pub const TrueClassSubclass: u64 = 1u64 << 46; - pub const Undef: u64 = 1u64 << 47; - pub const AllBitPatterns: [(&'static str, u64); 77] = [ + pub const TrueClassExact: u64 = 1u64 << 44; + pub const TrueClassSubclass: u64 = 1u64 << 45; + pub const Undef: u64 = 1u64 << 46; + pub const AllBitPatterns: [(&'static str, u64); 75] = [ ("Any", Any), ("RubyValue", RubyValue), ("Immediate", Immediate), @@ -114,8 +112,6 @@ mod bits { ("Module", Module), ("ModuleSubclass", ModuleSubclass), ("ModuleExact", ModuleExact), - ("Integer", Integer), - ("IntegerSubclass", IntegerSubclass), ("Float", Float), ("FloatExact", FloatExact), ("HeapFloat", HeapFloat), @@ -124,7 +120,7 @@ mod bits { ("HashExact", HashExact), ("Flonum", Flonum), ("FloatSubclass", FloatSubclass), - ("IntegerExact", IntegerExact), + ("Integer", Integer), ("Fixnum", Fixnum), ("FalseClass", FalseClass), ("FalseClassSubclass", FalseClassSubclass), @@ -156,7 +152,7 @@ mod bits { ("ArrayExact", ArrayExact), ("Empty", Empty), ]; - pub const NumTypeBits: u64 = 48; + pub const NumTypeBits: u64 = 47; } pub mod types { use super::*; @@ -204,8 +200,6 @@ pub mod types { pub const HeapFloat: Type = Type::from_bits(bits::HeapFloat); pub const Immediate: Type = Type::from_bits(bits::Immediate); pub const Integer: Type = Type::from_bits(bits::Integer); - pub const IntegerExact: Type = Type::from_bits(bits::IntegerExact); - pub const IntegerSubclass: Type = Type::from_bits(bits::IntegerSubclass); pub const Module: Type = Type::from_bits(bits::Module); pub const ModuleExact: Type = Type::from_bits(bits::ModuleExact); pub const ModuleSubclass: Type = Type::from_bits(bits::ModuleSubclass); diff --git a/zjit/src/hir_type/mod.rs b/zjit/src/hir_type/mod.rs index 35d8866844..462a84ff01 100644 --- a/zjit/src/hir_type/mod.rs +++ b/zjit/src/hir_type/mod.rs @@ -442,7 +442,7 @@ impl Type { if self.is_subtype(types::FalseClassExact) { return Some(unsafe { rb_cFalseClass }); } if self.is_subtype(types::FloatExact) { return Some(unsafe { rb_cFloat }); } if self.is_subtype(types::HashExact) { return Some(unsafe { rb_cHash }); } - if self.is_subtype(types::IntegerExact) { return Some(unsafe { rb_cInteger }); } + if self.is_subtype(types::Integer) { return Some(unsafe { rb_cInteger }); } if self.is_subtype(types::ModuleExact) { return Some(unsafe { rb_cModule }); } if self.is_subtype(types::NilClassExact) { return Some(unsafe { rb_cNilClass }); } if self.is_subtype(types::ObjectExact) { return Some(unsafe { rb_cObject }); } @@ -547,10 +547,8 @@ mod tests { assert_subtype(Type::fixnum(123), Type::fixnum(123)); assert_not_subtype(Type::fixnum(123), Type::fixnum(200)); assert_subtype(Type::from_value(VALUE::fixnum_from_usize(123)), types::Fixnum); - assert_subtype(types::Fixnum, types::IntegerExact); - assert_subtype(types::Bignum, types::IntegerExact); - assert_subtype(types::IntegerExact, types::Integer); - assert_subtype(types::IntegerSubclass, types::Integer); + assert_subtype(types::Fixnum, types::Integer); + assert_subtype(types::Bignum, types::Integer); } #[test] @@ -590,7 +588,6 @@ mod tests { fn fixnum_has_ruby_object() { assert_eq!(Type::fixnum(3).ruby_object(), Some(VALUE::fixnum_from_usize(3))); assert_eq!(types::Fixnum.ruby_object(), None); - assert_eq!(types::IntegerExact.ruby_object(), None); assert_eq!(types::Integer.ruby_object(), None); } @@ -608,7 +605,6 @@ mod tests { fn integer_has_exact_ruby_class() { assert_eq!(Type::fixnum(3).exact_ruby_class(), Some(unsafe { rb_cInteger }.into())); assert_eq!(types::Fixnum.exact_ruby_class(), None); - assert_eq!(types::IntegerExact.exact_ruby_class(), None); assert_eq!(types::Integer.exact_ruby_class(), None); } @@ -636,7 +632,6 @@ mod tests { fn integer_has_ruby_class() { assert_eq!(Type::fixnum(3).inexact_ruby_class(), Some(unsafe { rb_cInteger }.into())); assert_eq!(types::Fixnum.inexact_ruby_class(), None); - assert_eq!(types::IntegerExact.inexact_ruby_class(), None); assert_eq!(types::Integer.inexact_ruby_class(), None); } @@ -670,7 +665,6 @@ mod tests { assert_eq!(format!("{}", Type::from_cbool(false)), "CBool[false]"); assert_eq!(format!("{}", types::Fixnum), "Fixnum"); assert_eq!(format!("{}", types::Integer), "Integer"); - assert_eq!(format!("{}", types::IntegerExact), "IntegerExact"); } #[test] @@ -688,12 +682,10 @@ mod tests { #[test] fn union_bits_subtype() { - assert_bit_equal(types::Fixnum.union(types::IntegerExact), types::IntegerExact); assert_bit_equal(types::Fixnum.union(types::Integer), types::Integer); assert_bit_equal(types::Fixnum.union(types::Object), types::Object); assert_bit_equal(Type::fixnum(3).union(types::Fixnum), types::Fixnum); - assert_bit_equal(types::IntegerExact.union(types::Fixnum), types::IntegerExact); assert_bit_equal(types::Integer.union(types::Fixnum), types::Integer); assert_bit_equal(types::Object.union(types::Fixnum), types::Object); assert_bit_equal(types::Fixnum.union(Type::fixnum(3)), types::Fixnum); |
