Skip to content

Commit c7c6bcc

Browse files
authored
ZJIT: Print local names in FrameState (ruby#14571)
1 parent ae81586 commit c7c6bcc

4 files changed

Lines changed: 49 additions & 3 deletions

File tree

zjit.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,12 @@ rb_zjit_insn_leaf(int insn, const VALUE *opes)
164164
return insn_leaf(insn, opes);
165165
}
166166

167+
ID
168+
rb_zjit_local_id(const rb_iseq_t *iseq, unsigned idx)
169+
{
170+
return ISEQ_BODY(iseq)->local_table[idx];
171+
}
172+
167173
// Primitives used by zjit.rb. Don't put other functions below, which wouldn't use them.
168174
VALUE rb_zjit_assert_compiles(rb_execution_context_t *ec, VALUE self);
169175
VALUE rb_zjit_stats(rb_execution_context_t *ec, VALUE self, VALUE target_key);

zjit/bindgen/src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ fn main() {
271271
.allowlist_function("rb_zjit_iseq_builtin_attrs")
272272
.allowlist_function("rb_zjit_iseq_inspect")
273273
.allowlist_function("rb_zjit_iseq_insn_set")
274+
.allowlist_function("rb_zjit_local_id")
274275
.allowlist_function("rb_set_cfp_(pc|sp)")
275276
.allowlist_function("rb_c_method_tracing_currently_enabled")
276277
.allowlist_function("rb_full_cfunc_return")

zjit/src/cruby_bindings.inc.rs

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

zjit/src/hir.rs

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2903,9 +2903,14 @@ impl Display for FrameStatePrinter<'_> {
29032903
let inner = self.inner;
29042904
write!(f, "FrameState {{ pc: {:?}, stack: ", self.ptr_map.map_ptr(inner.pc))?;
29052905
write_vec(f, &inner.stack)?;
2906-
write!(f, ", locals: ")?;
2907-
write_vec(f, &inner.locals)?;
2908-
write!(f, " }}")
2906+
write!(f, ", locals: [")?;
2907+
for (idx, local) in inner.locals.iter().enumerate() {
2908+
let name: ID = unsafe { rb_zjit_local_id(inner.iseq, idx.try_into().unwrap()) };
2909+
let name = name.contents_lossy();
2910+
if idx > 0 { write!(f, ", ")?; }
2911+
write!(f, "{name}={local}")?;
2912+
}
2913+
write!(f, "] }}")
29092914
}
29102915
}
29112916

@@ -4228,6 +4233,39 @@ mod infer_tests {
42284233
}
42294234
}
42304235

4236+
#[cfg(test)]
4237+
mod snapshot_tests {
4238+
use super::*;
4239+
use insta::assert_snapshot;
4240+
4241+
#[track_caller]
4242+
fn hir_string(method: &str) -> String {
4243+
let iseq = crate::cruby::with_rubyvm(|| get_method_iseq("self", method));
4244+
unsafe { crate::cruby::rb_zjit_profile_disable(iseq) };
4245+
let function = iseq_to_hir(iseq).unwrap();
4246+
format!("{}", FunctionPrinter::with_snapshot(&function))
4247+
}
4248+
4249+
#[test]
4250+
fn test_new_array_with_elements() {
4251+
eval("def test(a, b) = [a, b]");
4252+
assert_snapshot!(hir_string("test"), @r"
4253+
fn test@<compiled>:1:
4254+
bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject):
4255+
v3:Any = Snapshot FrameState { pc: 0x1000, stack: [], locals: [a=v1, b=v2] }
4256+
v4:Any = Snapshot FrameState { pc: 0x1008, stack: [], locals: [a=v1, b=v2] }
4257+
PatchPoint NoTracePoint
4258+
v6:Any = Snapshot FrameState { pc: 0x1010, stack: [v1, v2], locals: [a=v1, b=v2] }
4259+
v7:ArrayExact = NewArray v1, v2
4260+
v8:Any = Snapshot FrameState { pc: 0x1018, stack: [v7], locals: [a=v1, b=v2] }
4261+
PatchPoint NoTracePoint
4262+
v10:Any = Snapshot FrameState { pc: 0x1018, stack: [v7], locals: [a=v1, b=v2] }
4263+
CheckInterrupts
4264+
Return v7
4265+
");
4266+
}
4267+
}
4268+
42314269
#[cfg(test)]
42324270
mod tests {
42334271
use super::*;

0 commit comments

Comments
 (0)