ZJIT: Support guarding *Exact types (#13797)

ZJIT already can generate guard type instructions for *Exact types.

For example:

```
def test(strings)
  strings.map do |string|
    string.bytesize
  end
end

test(["foo", "bar"])
```

```
HIR:
fn block in test:
bb0(v0:BasicObject, v1:BasicObject):
  PatchPoint MethodRedefined(String@0x1014be890, bytesize@0x19f1)
  v7:StringExact = GuardType v1, StringExact
  v8:Fixnum = CCall bytesize@0x16fa4cc18, v7
  Return v8

```

But zjit only supported guarding fixnums so this script would panic.

This commit adds support for guarding *Exact types.
This commit is contained in:
Stan Lo 2025-07-09 04:56:52 +01:00 committed by GitHub
parent 5aaedc052c
commit e9cd3060ac
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 203 additions and 0 deletions

View file

@ -974,6 +974,14 @@ fn gen_guard_type(jit: &mut JITState, asm: &mut Assembler, val: lir::Opnd, guard
// Check if opnd is Fixnum
asm.test(val, Opnd::UImm(RUBY_FIXNUM_FLAG as u64));
asm.jz(side_exit(jit, state)?);
} else if let Some(expected_class) = guard_type.runtime_exact_ruby_class() {
asm_comment!(asm, "guard exact class");
// Get the class of the value
let klass = asm.ccall(rb_yarv_class_of as *const u8, vec![val]);
asm.cmp(klass, Opnd::Value(expected_class));
asm.jne(side_exit(jit, state)?);
} else {
unimplemented!("unsupported type: {guard_type}");
}