Fixed function calls

This commit is contained in:
Mia
2025-11-11 21:53:30 +01:00
parent f50c68e440
commit 02f2ddfc67
2 changed files with 46 additions and 33 deletions
+20 -13
View File
@@ -26,15 +26,18 @@ pub enum AnyValue {
Ptr(*const u8), 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> { pub struct Interpreter<'l> {
ctx: Ctx<'l>, ctx: Ctx<'l>,
stack: Vec<u8>, stack: Vec<u8>,
layouts: Arc<LayoutCache<'l>>, layouts: Arc<LayoutCache<'l>>,
instructions: Arc<InstructionCache<'l>>, instructions: Arc<InstructionCache<'l>>,
native_funcs: FxHashMap< native_funcs: FxHashMap<*const Function<'l>, NativeFunction>,
*const Function<'l>,
Arc<dyn Fn(&mut Self, &[Range<usize>]) -> Result<AnyValue, Error> + 'l>,
>,
} }
impl<'l> Interpreter<'l> { impl<'l> Interpreter<'l> {
@@ -49,12 +52,8 @@ impl<'l> Interpreter<'l> {
} }
} }
pub fn register_function( pub fn register_function(&mut self, func: &'l Function<'l>, native_function: NativeFunction) {
&mut self, self.native_funcs.insert(func, native_function);
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 run(&mut self, func: &'l Function<'l>, args: Vec<Value<'l>>) -> Result<AnyValue, Error> { 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) => { 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>; let key = *func as *const Function<'l>;
match self.native_funcs.get(&key).cloned() { match self.native_funcs.get(&key).cloned() {
Some(native_func) => { Some(NativeFunction::Plain(native_func)) => {
let res = native_func(self, args).unwrap(); 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); self.write_any_val(out, &res);
} }
None => { None => {
let func = self.instructions.get(func); 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); self.stack.copy_within(res, out.start);
} }
} }
+26 -20
View File
@@ -2,7 +2,7 @@ use leaf_allocators::SyncArenaAllocator;
use leaf_assembly::context::{Context, CreateConst}; use leaf_assembly::context::{Context, CreateConst};
use leaf_assembly::functions::ir::Cmp; use leaf_assembly::functions::ir::Cmp;
use leaf_assembly::types::derivations::MakeTypeDerivations; 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::ffi::CStr;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
@@ -67,26 +67,32 @@ fn main() {
let mut interpreter = Interpreter::new(context); let mut interpreter = Interpreter::new(context);
interpreter.register_function(puts, |int, args| match args { interpreter.register_function(
[range] => unsafe { puts,
let mem = &int.stack()[range.clone()]; NativeFunction::Plain(|int, args| match args {
let ptr = usize::from_ne_bytes(mem.try_into().unwrap()); [range] => unsafe {
let cstr = CStr::from_ptr(ptr as *const i8); let mem = &int.stack()[range.clone()];
print!("{cstr:?}"); let ptr = usize::from_ne_bytes(mem.try_into().unwrap());
Ok(AnyValue::Void) let cstr = CStr::from_ptr(ptr as *const i8);
}, print!("{cstr:?}");
_ => Err(Error::InvalidParameterCount), Ok(AnyValue::Void)
}); },
_ => Err(Error::InvalidParameterCount),
}),
);
interpreter.register_function(print_u32, |int, args| match args { interpreter.register_function(
[range] => { print_u32,
let mem = &int.stack()[range.clone()]; NativeFunction::Plain(|int, args| match args {
let val = u32::from_ne_bytes(mem.try_into().unwrap()); [range] => {
println!("{val}"); let mem = &int.stack()[range.clone()];
Ok(AnyValue::Void) let val = u32::from_ne_bytes(mem.try_into().unwrap());
} println!("{val}");
_ => Err(Error::InvalidParameterCount), Ok(AnyValue::Void)
}); }
_ => Err(Error::InvalidParameterCount),
}),
);
{ {
let now = Instant::now(); let now = Instant::now();