Fixed function calls
This commit is contained in:
@@ -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
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user