artichoke_backend/extn/core/integer/
mruby.rs

1use std::ffi::CStr;
2
3use crate::extn::core::integer::Integer;
4use crate::extn::core::integer::trampoline;
5use crate::extn::prelude::*;
6
7const INTEGER_CSTR: &CStr = c"Integer";
8static INTEGER_RUBY_SOURCE: &[u8] = include_bytes!("integer.rb");
9
10pub fn init(interp: &mut Artichoke) -> InitializeResult<()> {
11    if interp.is_class_defined::<Integer>() {
12        return Ok(());
13    }
14
15    let spec = class::Spec::new("Integer", INTEGER_CSTR, None, None)?;
16    class::Builder::for_spec(interp, &spec)
17        .add_method("chr", integer_chr, sys::mrb_args_opt(1))?
18        .add_method("[]", integer_element_reference, sys::mrb_args_req(1))?
19        .add_method("/", integer_div, sys::mrb_args_req(1))?
20        .add_method("allbits?", integer_is_allbits, sys::mrb_args_req(1))?
21        .add_method("anybits?", integer_is_anybits, sys::mrb_args_req(1))?
22        .add_method("nobits?", integer_is_nobits, sys::mrb_args_req(1))?
23        .add_method("size", integer_size, sys::mrb_args_none())?
24        .define()?;
25    interp.def_class::<Integer>(spec)?;
26    interp.eval(INTEGER_RUBY_SOURCE)?;
27
28    Ok(())
29}
30
31unsafe extern "C-unwind" fn integer_chr(mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value {
32    let encoding = mrb_get_args!(mrb, optional = 1);
33    unwrap_interpreter!(mrb, to => guard);
34    let value = Value::from(slf);
35    let encoding = encoding.map(Value::from);
36    let result = trampoline::chr(&mut guard, value, encoding);
37    match result {
38        Ok(value) => value.inner(),
39        Err(exception) => {
40            // SAFETY: only Copy objects remain on the stack
41            unsafe { error::raise(guard, exception) }
42        }
43    }
44}
45
46unsafe extern "C-unwind" fn integer_element_reference(
47    mrb: *mut sys::mrb_state,
48    slf: sys::mrb_value,
49) -> sys::mrb_value {
50    let bit = mrb_get_args!(mrb, required = 1);
51    unwrap_interpreter!(mrb, to => guard);
52    let value = Value::from(slf);
53    let bit = Value::from(bit);
54    let result = trampoline::element_reference(&mut guard, value, bit);
55    match result {
56        Ok(value) => value.inner(),
57        Err(exception) => {
58            // SAFETY: only Copy objects remain on the stack
59            unsafe { error::raise(guard, exception) }
60        }
61    }
62}
63
64unsafe extern "C-unwind" fn integer_div(mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value {
65    let denominator = mrb_get_args!(mrb, required = 1);
66    unwrap_interpreter!(mrb, to => guard);
67    let value = Value::from(slf);
68    let denominator = Value::from(denominator);
69    let result = trampoline::div(&mut guard, value, denominator);
70    match result {
71        Ok(value) => value.inner(),
72        Err(exception) => {
73            // SAFETY: only Copy objects remain on the stack
74            unsafe { error::raise(guard, exception) }
75        }
76    }
77}
78
79unsafe extern "C-unwind" fn integer_is_allbits(mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value {
80    let mask = mrb_get_args!(mrb, required = 1);
81    unwrap_interpreter!(mrb, to => guard);
82    let value = Value::from(slf);
83    let mask = Value::from(mask);
84    let result = trampoline::is_allbits(&mut guard, value, mask);
85    match result {
86        Ok(value) => value.inner(),
87        Err(exception) => {
88            // SAFETY: only Copy objects remain on the stack
89            unsafe { error::raise(guard, exception) }
90        }
91    }
92}
93
94unsafe extern "C-unwind" fn integer_is_anybits(mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value {
95    let mask = mrb_get_args!(mrb, required = 1);
96    unwrap_interpreter!(mrb, to => guard);
97    let value = Value::from(slf);
98    let mask = Value::from(mask);
99    let result = trampoline::is_anybits(&mut guard, value, mask);
100    match result {
101        Ok(value) => value.inner(),
102        Err(exception) => {
103            // SAFETY: only Copy objects remain on the stack
104            unsafe { error::raise(guard, exception) }
105        }
106    }
107}
108
109unsafe extern "C-unwind" fn integer_is_nobits(mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value {
110    let mask = mrb_get_args!(mrb, required = 1);
111    unwrap_interpreter!(mrb, to => guard);
112    let value = Value::from(slf);
113    let mask = Value::from(mask);
114    let result = trampoline::is_nobits(&mut guard, value, mask);
115    match result {
116        Ok(value) => value.inner(),
117        Err(exception) => {
118            // SAFETY: only Copy objects remain on the stack
119            unsafe { error::raise(guard, exception) }
120        }
121    }
122}
123
124unsafe extern "C-unwind" fn integer_size(mrb: *mut sys::mrb_state, _slf: sys::mrb_value) -> sys::mrb_value {
125    mrb_get_args!(mrb, none);
126    unwrap_interpreter!(mrb, to => guard);
127    let result = trampoline::size(&guard);
128    match result {
129        Ok(value) => value.inner(),
130        Err(exception) => {
131            // SAFETY: only Copy objects remain on the stack
132            unsafe { error::raise(guard, exception) }
133        }
134    }
135}