artichoke_backend/extn/core/matchdata/
mruby.rs

1use std::ffi::CStr;
2
3use crate::extn::core::matchdata::{self, trampoline};
4use crate::extn::prelude::*;
5
6const MATCH_DATA_CSTR: &CStr = c"MatchData";
7static MATCH_DATA_RUBY_SOURCE: &[u8] = include_bytes!("matchdata.rb");
8
9pub fn init(interp: &mut Artichoke) -> InitializeResult<()> {
10    if interp.is_class_defined::<matchdata::MatchData>() {
11        return Ok(());
12    }
13
14    let spec = class::Spec::new(
15        "MatchData",
16        MATCH_DATA_CSTR,
17        None,
18        Some(def::box_unbox_free::<matchdata::MatchData>),
19    )?;
20    class::Builder::for_spec(interp, &spec)
21        .value_is_rust_object()
22        .add_method("begin", matchdata_begin, sys::mrb_args_req(1))?
23        .add_method("captures", matchdata_captures, sys::mrb_args_none())?
24        .add_method("[]", matchdata_element_reference, sys::mrb_args_req_and_opt(1, 1))?
25        .add_method("length", matchdata_length, sys::mrb_args_none())?
26        .add_method("named_captures", matchdata_named_captures, sys::mrb_args_none())?
27        .add_method("names", matchdata_names, sys::mrb_args_none())?
28        .add_method("offset", matchdata_offset, sys::mrb_args_req(1))?
29        .add_method("post_match", matchdata_post_match, sys::mrb_args_none())?
30        .add_method("pre_match", matchdata_pre_match, sys::mrb_args_none())?
31        .add_method("regexp", matchdata_regexp, sys::mrb_args_none())?
32        .add_method("size", matchdata_length, sys::mrb_args_none())?
33        .add_method("string", matchdata_string, sys::mrb_args_none())?
34        .add_method("to_a", matchdata_to_a, sys::mrb_args_none())?
35        .add_method("to_s", matchdata_to_s, sys::mrb_args_none())?
36        .add_method("end", matchdata_end, sys::mrb_args_req(1))?
37        .define()?;
38    interp.def_class::<matchdata::MatchData>(spec)?;
39    interp.eval(MATCH_DATA_RUBY_SOURCE)?;
40
41    Ok(())
42}
43
44unsafe extern "C-unwind" fn matchdata_begin(mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value {
45    let begin = mrb_get_args!(mrb, required = 1);
46    unwrap_interpreter!(mrb, to => guard);
47    let value = Value::from(slf);
48    let begin = Value::from(begin);
49    let result = trampoline::begin(&mut guard, value, begin);
50    match result {
51        Ok(result) => result.inner(),
52        Err(exception) => {
53            // SAFETY: only Copy objects remain on the stack
54            unsafe { error::raise(guard, exception) }
55        }
56    }
57}
58
59unsafe extern "C-unwind" fn matchdata_captures(mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value {
60    mrb_get_args!(mrb, none);
61    unwrap_interpreter!(mrb, to => guard);
62    let value = Value::from(slf);
63    let result = trampoline::captures(&mut guard, value);
64    match result {
65        Ok(result) => result.inner(),
66        Err(exception) => {
67            // SAFETY: only Copy objects remain on the stack
68            unsafe { error::raise(guard, exception) }
69        }
70    }
71}
72
73unsafe extern "C-unwind" fn matchdata_element_reference(
74    mrb: *mut sys::mrb_state,
75    slf: sys::mrb_value,
76) -> sys::mrb_value {
77    let (elem, len) = mrb_get_args!(mrb, required = 1, optional = 1);
78    unwrap_interpreter!(mrb, to => guard);
79    let value = Value::from(slf);
80    let elem = Value::from(elem);
81    let len = len.map(Value::from);
82    let result = trampoline::element_reference(&mut guard, value, elem, len);
83    match result {
84        Ok(result) => result.inner(),
85        Err(exception) => {
86            // SAFETY: only Copy objects remain on the stack
87            unsafe { error::raise(guard, exception) }
88        }
89    }
90}
91
92unsafe extern "C-unwind" fn matchdata_end(mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value {
93    let end = mrb_get_args!(mrb, required = 1);
94    unwrap_interpreter!(mrb, to => guard);
95    let value = Value::from(slf);
96    let end = Value::from(end);
97    let result = trampoline::end(&mut guard, value, end);
98    match result {
99        Ok(result) => result.inner(),
100        Err(exception) => {
101            // SAFETY: only Copy objects remain on the stack
102            unsafe { error::raise(guard, exception) }
103        }
104    }
105}
106
107unsafe extern "C-unwind" fn matchdata_length(mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value {
108    mrb_get_args!(mrb, none);
109    unwrap_interpreter!(mrb, to => guard);
110    let value = Value::from(slf);
111    let result = trampoline::length(&mut guard, value);
112    match result {
113        Ok(result) => result.inner(),
114        Err(exception) => {
115            // SAFETY: only Copy objects remain on the stack
116            unsafe { error::raise(guard, exception) }
117        }
118    }
119}
120
121unsafe extern "C-unwind" fn matchdata_named_captures(mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value {
122    mrb_get_args!(mrb, none);
123    unwrap_interpreter!(mrb, to => guard);
124    let value = Value::from(slf);
125    let result = trampoline::named_captures(&mut guard, value);
126    match result {
127        Ok(result) => result.inner(),
128        Err(exception) => {
129            // SAFETY: only Copy objects remain on the stack
130            unsafe { error::raise(guard, exception) }
131        }
132    }
133}
134
135unsafe extern "C-unwind" fn matchdata_names(mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value {
136    mrb_get_args!(mrb, none);
137    unwrap_interpreter!(mrb, to => guard);
138    let value = Value::from(slf);
139    let result = trampoline::names(&mut guard, value);
140    match result {
141        Ok(result) => result.inner(),
142        Err(exception) => {
143            // SAFETY: only Copy objects remain on the stack
144            unsafe { error::raise(guard, exception) }
145        }
146    }
147}
148
149unsafe extern "C-unwind" fn matchdata_offset(mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value {
150    let offset = mrb_get_args!(mrb, required = 1);
151    unwrap_interpreter!(mrb, to => guard);
152    let value = Value::from(slf);
153    let offset = Value::from(offset);
154    let result = trampoline::offset(&mut guard, value, offset);
155    match result {
156        Ok(result) => result.inner(),
157        Err(exception) => {
158            // SAFETY: only Copy objects remain on the stack
159            unsafe { error::raise(guard, exception) }
160        }
161    }
162}
163
164unsafe extern "C-unwind" fn matchdata_post_match(mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value {
165    mrb_get_args!(mrb, none);
166    unwrap_interpreter!(mrb, to => guard);
167    let value = Value::from(slf);
168    let result = trampoline::post_match(&mut guard, value);
169    match result {
170        Ok(result) => result.inner(),
171        Err(exception) => {
172            // SAFETY: only Copy objects remain on the stack
173            unsafe { error::raise(guard, exception) }
174        }
175    }
176}
177
178unsafe extern "C-unwind" fn matchdata_pre_match(mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value {
179    mrb_get_args!(mrb, none);
180    unwrap_interpreter!(mrb, to => guard);
181    let value = Value::from(slf);
182    let result = trampoline::pre_match(&mut guard, value);
183    match result {
184        Ok(result) => result.inner(),
185        Err(exception) => {
186            // SAFETY: only Copy objects remain on the stack
187            unsafe { error::raise(guard, exception) }
188        }
189    }
190}
191
192unsafe extern "C-unwind" fn matchdata_regexp(mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value {
193    mrb_get_args!(mrb, none);
194    unwrap_interpreter!(mrb, to => guard);
195    let value = Value::from(slf);
196    let result = trampoline::regexp(&mut guard, value);
197    match result {
198        Ok(result) => result.inner(),
199        Err(exception) => {
200            // SAFETY: only Copy objects remain on the stack
201            unsafe { error::raise(guard, exception) }
202        }
203    }
204}
205
206unsafe extern "C-unwind" fn matchdata_string(mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value {
207    mrb_get_args!(mrb, none);
208    unwrap_interpreter!(mrb, to => guard);
209    let value = Value::from(slf);
210    let result = trampoline::string(&mut guard, value);
211    match result {
212        Ok(result) => result.inner(),
213        Err(exception) => {
214            // SAFETY: only Copy objects remain on the stack
215            unsafe { error::raise(guard, exception) }
216        }
217    }
218}
219
220unsafe extern "C-unwind" fn matchdata_to_a(mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value {
221    mrb_get_args!(mrb, none);
222    unwrap_interpreter!(mrb, to => guard);
223    let value = Value::from(slf);
224    let result = trampoline::to_a(&mut guard, value);
225    match result {
226        Ok(result) => result.inner(),
227        Err(exception) => {
228            // SAFETY: only Copy objects remain on the stack
229            unsafe { error::raise(guard, exception) }
230        }
231    }
232}
233
234unsafe extern "C-unwind" fn matchdata_to_s(mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value {
235    mrb_get_args!(mrb, none);
236    unwrap_interpreter!(mrb, to => guard);
237    let value = Value::from(slf);
238    let result = trampoline::to_s(&mut guard, value);
239    match result {
240        Ok(result) => result.inner(),
241        Err(exception) => {
242            // SAFETY: only Copy objects remain on the stack
243            unsafe { error::raise(guard, exception) }
244        }
245    }
246}