rb_sys_test_helpers/
utils.rs1#[macro_export]
3macro_rules! memoized {
4 ($e:expr) => {{
5 pub static INIT: std::sync::Once = std::sync::Once::new();
6 pub static mut MEMOIZED_VAL: Option<rb_sys::VALUE> = None;
7
8 INIT.call_once(|| unsafe {
9 MEMOIZED_VAL.replace($e);
10 });
11
12 unsafe { *MEMOIZED_VAL.as_ref().unwrap() }
13 }};
14}
15
16#[macro_export]
18macro_rules! rstring {
19 ($s:expr) => {
20 unsafe { rb_sys::rb_utf8_str_new($s.as_ptr() as _, $s.len() as _) }
21 };
22}
23
24#[macro_export]
26macro_rules! rsymbol {
27 ($s:literal) => {
28 unsafe { rb_sys::rb_id2sym(rb_sys::rb_intern(concat!($s, "\0").as_ptr() as _)) }
29 };
30}
31
32#[macro_export]
34macro_rules! eval {
35 () => {
36 unsafe { rb_sys::rb_eval_string("\0".as_ptr() as _) }
37 };
38 ($s:expr) => {
39 unsafe { rb_sys::rb_eval_string(concat!($s, "\0").as_ptr() as _) }
40 };
41}
42
43#[macro_export]
45macro_rules! capture_gc_stat_for {
46 ($id:literal, $e:expr) => {{
47 let id = $crate::memoized! { $crate::rsymbol!($id) };
48
49 unsafe {
50 $crate::trigger_full_gc!();
51
52 let before = unsafe { rb_sys::rb_gc_stat(id) };
53 let result = $e;
54 let after = unsafe { rb_sys::rb_gc_stat(id) };
55
56 (result, after as isize - before as isize)
57 }
58 }};
59}
60
61#[macro_export]
63macro_rules! rstring_to_string {
64 ($v:expr) => {{
65 let cstr = rb_sys::rb_string_value_cstr(&mut $v);
66
67 std::ffi::CStr::from_ptr(cstr)
68 .to_string_lossy()
69 .into_owned()
70 }};
71}
72
73#[macro_export]
77macro_rules! rb_funcall_typed {
78 ($v:expr, $m:expr, $args:expr, $t:expr) => {{
79 {
80 let args: &mut [rb_sys::VALUE] = &mut $args[..];
81 let id = rb_sys::rb_intern(concat!($m, "\0").as_ptr() as _);
82 let argv = $args.as_ptr();
83 let result = rb_sys::rb_check_funcall($v, id, args.len() as _, argv);
84
85 if !RB_TYPE_P(result, $t as _) {
86 None
87 } else {
88 Some(result)
89 }
90 }
91 }};
92}
93
94#[macro_export]
96macro_rules! trigger_full_gc {
97 () => {
98 let cmd = "GC.start(full_mark: false, immediate_sweep: false)\0".as_ptr() as *const _;
99
100 for _ in 0..20 {
101 unsafe { rb_sys::rb_eval_string(cmd) };
102 std::thread::yield_now();
103 }
104 };
105}