From 02f2ddfc67c2bfd8aaeebff9ca898c814bde186b Mon Sep 17 00:00:00 2001 From: Mia Date: Tue, 11 Nov 2025 21:53:30 +0100 Subject: [PATCH] Fixed function calls --- interpreter/src/interpreter.rs | 33 ++++++++++++++---------- interpreter/src/main.rs | 46 +++++++++++++++++++--------------- 2 files changed, 46 insertions(+), 33 deletions(-) diff --git a/interpreter/src/interpreter.rs b/interpreter/src/interpreter.rs index 2ba1b28..9869871 100644 --- a/interpreter/src/interpreter.rs +++ b/interpreter/src/interpreter.rs @@ -26,15 +26,18 @@ pub enum AnyValue { Ptr(*const u8), } +#[derive(Clone)] +pub enum NativeFunction { + Plain(fn(&mut Interpreter, &[Range]) -> Result), + Closure(Arc]) -> Result>), +} + pub struct Interpreter<'l> { ctx: Ctx<'l>, stack: Vec, layouts: Arc>, instructions: Arc>, - native_funcs: FxHashMap< - *const Function<'l>, - Arc]) -> Result + '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]) -> Result + '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>) -> Result { @@ -172,15 +171,23 @@ impl<'l> Interpreter<'l> { } OpCode::Call(func, args, out) => { + let args: SmallVec<[Range; 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); } } diff --git a/interpreter/src/main.rs b/interpreter/src/main.rs index 58317ec..e6b6e9f 100644 --- a/interpreter/src/main.rs +++ b/interpreter/src/main.rs @@ -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,26 +67,32 @@ fn main() { let mut interpreter = Interpreter::new(context); - interpreter.register_function(puts, |int, args| match args { - [range] => unsafe { - let mem = &int.stack()[range.clone()]; - let ptr = usize::from_ne_bytes(mem.try_into().unwrap()); - let cstr = CStr::from_ptr(ptr as *const i8); - print!("{cstr:?}"); - Ok(AnyValue::Void) - }, - _ => Err(Error::InvalidParameterCount), - }); + 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()); + let cstr = CStr::from_ptr(ptr as *const i8); + print!("{cstr:?}"); + Ok(AnyValue::Void) + }, + _ => Err(Error::InvalidParameterCount), + }), + ); - interpreter.register_function(print_u32, |int, args| match args { - [range] => { - let mem = &int.stack()[range.clone()]; - let val = u32::from_ne_bytes(mem.try_into().unwrap()); - println!("{val}"); - Ok(AnyValue::Void) - } - _ => Err(Error::InvalidParameterCount), - }); + 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()); + println!("{val}"); + Ok(AnyValue::Void) + } + _ => Err(Error::InvalidParameterCount), + }), + ); { let now = Instant::now();