diff options
author | Noah Gibbs <the.codefolio.guy@gmail.com> | 2022-07-28 16:45:08 +0100 |
---|---|---|
committer | Takashi Kokubun <takashikkbn@gmail.com> | 2022-08-24 10:42:45 -0700 |
commit | b4be3c00c5737649166db676278fd28f768a5e3c (patch) | |
tree | 73ad75aa40351021832e44943a40a349172568d7 /yjit/src/utils.rs | |
parent | 0ad9cc16966c2e56f0fe7e5992edf76033d3a83f (diff) | |
download | ruby-b4be3c00c5737649166db676278fd28f768a5e3c.tar.gz |
add --yjit-dump-iseqs param (https://github.com/Shopify/ruby/pull/332)
Diffstat (limited to 'yjit/src/utils.rs')
-rw-r--r-- | yjit/src/utils.rs | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/yjit/src/utils.rs b/yjit/src/utils.rs index 02fbce47d8..ade573b8da 100644 --- a/yjit/src/utils.rs +++ b/yjit/src/utils.rs @@ -71,6 +71,41 @@ macro_rules! offset_of { #[allow(unused)] pub(crate) use offset_of; +// Convert a CRuby UTF-8-encoded RSTRING into a Rust string. +// This should work fine on ASCII strings and anything else +// that is considered legal UTF-8, including embedded nulls. +fn ruby_str_to_rust(v: VALUE) -> String { + // Make sure the CRuby encoding is UTF-8 compatible + let encoding = unsafe { rb_ENCODING_GET(v) } as u32; + assert!(encoding == RUBY_ENCINDEX_ASCII_8BIT || encoding == RUBY_ENCINDEX_UTF_8 || encoding == RUBY_ENCINDEX_US_ASCII); + + let str_ptr = unsafe { rb_RSTRING_PTR(v) } as *mut u8; + let str_len: usize = unsafe { rb_RSTRING_LEN(v) }.try_into().unwrap(); + let str_slice: &[u8] = unsafe { slice::from_raw_parts(str_ptr, str_len) }; + String::from_utf8(str_slice.to_vec()).unwrap() // does utf8 validation +} + +// Location is the file defining the method, colon, method name. +// Filenames are sometimes internal strings supplied to eval, +// so be careful with them. +pub fn iseq_get_location(iseq: IseqPtr) -> String { + let iseq_path = unsafe { rb_iseq_path(iseq) }; + let iseq_method = unsafe { rb_iseq_method_name(iseq) }; + + let mut s = if iseq_path == Qnil { + "None".to_string() + } else { + ruby_str_to_rust(iseq_path) + }; + s.push_str(":"); + if iseq_method == Qnil { + s.push_str("None"); + } else { + s.push_str(& ruby_str_to_rust(iseq_method)); + } + s +} + #[cfg(test)] mod tests { #[test] |