artichoke_backend/extn/core/kernel/
mruby.rs1use std::ffi::CStr;
2
3use crate::extn::core::artichoke;
4use crate::extn::core::kernel::{self, trampoline};
5use crate::extn::prelude::*;
6
7const KERNEL_CSTR: &CStr = c"Kernel";
8static KERNEL_RUBY_SOURCE: &[u8] = include_bytes!("kernel.rb");
9
10pub fn init(interp: &mut Artichoke) -> InitializeResult<()> {
11 if interp.is_module_defined::<kernel::Kernel>() {
12 return Ok(());
13 }
14
15 let spec = module::Spec::new(interp, "Kernel", KERNEL_CSTR, None)?;
16 module::Builder::for_spec(interp, &spec)
17 .add_method("require", kernel_require, sys::mrb_args_rest())?
18 .add_method("require_relative", kernel_require_relative, sys::mrb_args_rest())?
19 .add_method("load", kernel_load, sys::mrb_args_rest())?
20 .add_method("p", kernel_p, sys::mrb_args_rest())?
21 .add_method("print", kernel_print, sys::mrb_args_rest())?
22 .add_method("puts", kernel_puts, sys::mrb_args_rest())?
23 .define()?;
24 interp.def_module::<kernel::Kernel>(spec)?;
25 interp.eval(KERNEL_RUBY_SOURCE)?;
26
27 let scope = interp
32 .module_spec::<artichoke::Artichoke>()?
33 .map(EnclosingRubyScope::module)
34 .ok_or_else(|| NotDefinedError::module("Artichoke"))?;
35 let spec = module::Spec::new(interp, "Kernel", KERNEL_CSTR, Some(scope))?;
36 module::Builder::for_spec(interp, &spec)
37 .add_method("Integer", kernel_integer, sys::mrb_args_req_and_opt(1, 1))?
38 .add_self_method("Integer", kernel_integer, sys::mrb_args_req_and_opt(1, 1))?
39 .define()?;
40 interp.def_module::<artichoke::Kernel>(spec)?;
41
42 Ok(())
43}
44
45unsafe extern "C-unwind" fn kernel_integer(mrb: *mut sys::mrb_state, _slf: sys::mrb_value) -> sys::mrb_value {
46 let (arg, base) = mrb_get_args!(mrb, required = 1, optional = 1);
47 unwrap_interpreter!(mrb, to => guard);
48 let arg = Value::from(arg);
49 let base = base.map(Value::from);
50 let result = trampoline::integer(&mut guard, arg, base);
51 match result {
52 Ok(value) => value.inner(),
53 Err(exception) => {
54 unsafe { error::raise(guard, exception) }
56 }
57 }
58}
59
60unsafe extern "C-unwind" fn kernel_load(mrb: *mut sys::mrb_state, _slf: sys::mrb_value) -> sys::mrb_value {
61 let file = mrb_get_args!(mrb, required = 1);
62 unwrap_interpreter!(mrb, to => guard);
63 let file = Value::from(file);
64 let result = trampoline::load(&mut guard, file);
65 match result {
66 Ok(value) => value.inner(),
67 Err(exception) => {
68 unsafe { error::raise(guard, exception) }
70 }
71 }
72}
73
74unsafe extern "C-unwind" fn kernel_p(mrb: *mut sys::mrb_state, _slf: sys::mrb_value) -> sys::mrb_value {
75 let args = mrb_get_args!(mrb, *args);
76 unwrap_interpreter!(mrb, to => guard);
77 let args = args.iter().copied().map(Value::from);
78 let result = trampoline::p(&mut guard, args);
79 match result {
80 Ok(value) => value.inner(),
81 Err(exception) => {
82 unsafe { error::raise(guard, exception) }
84 }
85 }
86}
87
88unsafe extern "C-unwind" fn kernel_print(mrb: *mut sys::mrb_state, _slf: sys::mrb_value) -> sys::mrb_value {
89 let args = mrb_get_args!(mrb, *args);
90 unwrap_interpreter!(mrb, to => guard);
91 let args = args.iter().copied().map(Value::from);
92 let result = trampoline::print(&mut guard, args);
93 match result {
94 Ok(value) => value.inner(),
95 Err(exception) => {
96 unsafe { error::raise(guard, exception) }
98 }
99 }
100}
101
102unsafe extern "C-unwind" fn kernel_puts(mrb: *mut sys::mrb_state, _slf: sys::mrb_value) -> sys::mrb_value {
103 let args = mrb_get_args!(mrb, *args);
104 unwrap_interpreter!(mrb, to => guard);
105 let args = args.iter().copied().map(Value::from);
106 let result = trampoline::puts(&mut guard, args);
107 match result {
108 Ok(value) => value.inner(),
109 Err(exception) => {
110 unsafe { error::raise(guard, exception) }
112 }
113 }
114}
115
116unsafe extern "C-unwind" fn kernel_require(mrb: *mut sys::mrb_state, _slf: sys::mrb_value) -> sys::mrb_value {
117 let file = mrb_get_args!(mrb, required = 1);
118 unwrap_interpreter!(mrb, to => guard);
119 let file = Value::from(file);
120 let result = trampoline::require(&mut guard, file);
121 match result {
122 Ok(value) => value.inner(),
123 Err(exception) => {
124 unsafe { error::raise(guard, exception) }
126 }
127 }
128}
129
130unsafe extern "C-unwind" fn kernel_require_relative(mrb: *mut sys::mrb_state, _slf: sys::mrb_value) -> sys::mrb_value {
131 let file = mrb_get_args!(mrb, required = 1);
132 unwrap_interpreter!(mrb, to => guard);
133 let file = Value::from(file);
134 let result = trampoline::require_relative(&mut guard, file);
135 match result {
136 Ok(value) => value.inner(),
137 Err(exception) => {
138 unsafe { error::raise(guard, exception) }
140 }
141 }
142}