Fixed function calls
This commit is contained in:
@@ -26,15 +26,18 @@ pub enum AnyValue {
|
||||
Ptr(*const u8),
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum NativeFunction {
|
||||
Plain(fn(&mut Interpreter, &[Range<usize>]) -> Result<AnyValue, Error>),
|
||||
Closure(Arc<dyn Fn(&mut Interpreter, &[Range<usize>]) -> Result<AnyValue, Error>>),
|
||||
}
|
||||
|
||||
pub struct Interpreter<'l> {
|
||||
ctx: Ctx<'l>,
|
||||
stack: Vec<u8>,
|
||||
layouts: Arc<LayoutCache<'l>>,
|
||||
instructions: Arc<InstructionCache<'l>>,
|
||||
native_funcs: FxHashMap<
|
||||
*const Function<'l>,
|
||||
Arc<dyn Fn(&mut Self, &[Range<usize>]) -> Result<AnyValue, Error> + 'l>,
|
||||
>,
|
||||
native_funcs: FxHashMap<*const Function<'l>, NativeFunction>,
|
||||
}
|
||||
|
||||
impl<'l> Interpreter<'l> {
|
||||
@@ -49,12 +52,8 @@ impl<'l> Interpreter<'l> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn register_function(
|
||||
&mut self,
|
||||
func: &'l Function<'l>,
|
||||
fn_impl: impl Fn(&mut Self, &[Range<usize>]) -> Result<AnyValue, Error> + 'l,
|
||||
) {
|
||||
self.native_funcs.insert(func, Arc::new(fn_impl));
|
||||
pub fn register_function(&mut self, func: &'l Function<'l>, native_function: NativeFunction) {
|
||||
self.native_funcs.insert(func, native_function);
|
||||
}
|
||||
|
||||
pub fn run(&mut self, func: &'l Function<'l>, args: Vec<Value<'l>>) -> Result<AnyValue, Error> {
|
||||
@@ -172,15 +171,23 @@ impl<'l> Interpreter<'l> {
|
||||
}
|
||||
|
||||
OpCode::Call(func, args, out) => {
|
||||
let args: SmallVec<[Range<usize>; 4]> = args
|
||||
.iter()
|
||||
.map(|range| sp + range.start..sp + range.end)
|
||||
.collect();
|
||||
let key = *func as *const Function<'l>;
|
||||
match self.native_funcs.get(&key).cloned() {
|
||||
Some(native_func) => {
|
||||
let res = native_func(self, args).unwrap();
|
||||
Some(NativeFunction::Plain(native_func)) => {
|
||||
let res = native_func(self, &args).unwrap();
|
||||
self.write_any_val(out, &res);
|
||||
}
|
||||
Some(NativeFunction::Closure(native_func)) => {
|
||||
let res = native_func(self, &args).unwrap();
|
||||
self.write_any_val(out, &res);
|
||||
}
|
||||
None => {
|
||||
let func = self.instructions.get(func);
|
||||
let res = self.call(sp, args, &func);
|
||||
let res = self.call(sp, &args, &func);
|
||||
self.stack.copy_within(res, out.start);
|
||||
}
|
||||
}
|
||||
|
||||
+11
-5
@@ -2,7 +2,7 @@ use leaf_allocators::SyncArenaAllocator;
|
||||
use leaf_assembly::context::{Context, CreateConst};
|
||||
use leaf_assembly::functions::ir::Cmp;
|
||||
use leaf_assembly::types::derivations::MakeTypeDerivations;
|
||||
use leaf_interpreter::interpreter::{AnyValue, Error, Interpreter};
|
||||
use leaf_interpreter::interpreter::{AnyValue, Error, Interpreter, NativeFunction};
|
||||
use std::ffi::CStr;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
@@ -67,7 +67,9 @@ fn main() {
|
||||
|
||||
let mut interpreter = Interpreter::new(context);
|
||||
|
||||
interpreter.register_function(puts, |int, args| match args {
|
||||
interpreter.register_function(
|
||||
puts,
|
||||
NativeFunction::Plain(|int, args| match args {
|
||||
[range] => unsafe {
|
||||
let mem = &int.stack()[range.clone()];
|
||||
let ptr = usize::from_ne_bytes(mem.try_into().unwrap());
|
||||
@@ -76,9 +78,12 @@ fn main() {
|
||||
Ok(AnyValue::Void)
|
||||
},
|
||||
_ => Err(Error::InvalidParameterCount),
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
interpreter.register_function(print_u32, |int, args| match args {
|
||||
interpreter.register_function(
|
||||
print_u32,
|
||||
NativeFunction::Plain(|int, args| match args {
|
||||
[range] => {
|
||||
let mem = &int.stack()[range.clone()];
|
||||
let val = u32::from_ne_bytes(mem.try_into().unwrap());
|
||||
@@ -86,7 +91,8 @@ fn main() {
|
||||
Ok(AnyValue::Void)
|
||||
}
|
||||
_ => Err(Error::InvalidParameterCount),
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
{
|
||||
let now = Instant::now();
|
||||
|
||||
Reference in New Issue
Block a user