1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
use log::{debug, error};
use std::cell::RefCell;
use std::ffi::c_void;
use std::rc::Rc;
use crate::eval::MrbEval;
use crate::extn;
use crate::fs::MrbFilesystem;
use crate::gc::MrbGarbageCollection;
use crate::state::State;
use crate::sys::{self, DescribeState};
use crate::{Mrb, MrbError};
pub fn interpreter() -> Result<Mrb, MrbError> {
let vfs = MrbFilesystem::new()?;
let mrb = unsafe { sys::mrb_open() };
if mrb.is_null() {
error!("Failed to allocate mrb interprter");
return Err(MrbError::New);
}
let context = unsafe { sys::mrbc_context_new(mrb) };
let api = Rc::new(RefCell::new(State::new(mrb, context, vfs)));
let ptr = Rc::into_raw(api);
unsafe {
(*mrb).ud = ptr as *mut c_void;
}
let interp = unsafe { Rc::from_raw(ptr) };
extn::patch(&interp)?;
debug!("Allocated {}", mrb.debug());
let arena = interp.create_arena_savepoint();
interp.eval("").map_err(|_| MrbError::New)?;
arena.restore();
interp.full_gc();
Ok(interp)
}
#[cfg(test)]
mod tests {
#[test]
fn open_close() {
let interp = super::interpreter().unwrap();
drop(interp);
}
}