diff --git a/src/jit/helpers.rs b/src/jit/helpers.rs index e3fbf4b..6e101a5 100644 --- a/src/jit/helpers.rs +++ b/src/jit/helpers.rs @@ -11,7 +11,7 @@ use crate::jit::JITValueData; use crate::ty::internal::{Thunk, Value}; use crate::vm::{LetEnv, VM}; -use super::{JITFunc, JITValue, ValueTag}; +use super::{JITValue, ValueTag}; pub struct Helpers<'ctx> { pub int_type: IntType<'ctx>, @@ -93,7 +93,7 @@ impl<'ctx> Helpers<'ctx> { let call = module.add_function( "call", value_type.fn_type( - &[value_type.into(), value_type.into(), ptr_type.into()], + &[value_type.into(), ptr_type.into(), ptr_int_type.into(), ptr_type.into()], false, ), None, @@ -224,7 +224,13 @@ extern "C" fn helper_neg(rhs: JITValue, _env: *const LetEnv) -> JITValue { int: -unsafe { rhs.data.int }, }, }, - _ => todo!(), + Float => JITValue { + tag: Float, + data: JITValueData { + float: -unsafe { rhs.data.float }, + }, + }, + _ => unreachable!(), } } @@ -238,7 +244,7 @@ extern "C" fn helper_not(rhs: JITValue, _env: *const LetEnv) -> JITValue { bool: !unsafe { rhs.data.bool }, }, }, - _ => todo!(), + _ => unreachable!(), } } @@ -317,14 +323,16 @@ extern "C" fn helper_or(lhs: JITValue, rhs: JITValue) -> JITValue { #[unsafe(no_mangle)] extern "C" fn helper_call<'jit, 'vm>( func: JITValue, - arg: JITValue, + args: *mut JITValue, + arity: usize, vm: *const VM<'jit>, ) -> JITValue { use ValueTag::*; + let args = unsafe { Vec::from_raw_parts(args, arity, arity) }.into_iter().map(Value::from).collect(); match func.tag { Function => { let func: Value = func.into(); - func.call(unsafe { vm.as_ref() }.unwrap(), vec![arg.into()]) + func.call(unsafe { vm.as_ref() }.unwrap(), args) .unwrap() .into() } diff --git a/src/jit/mod.rs b/src/jit/mod.rs index 5dd80ba..ae27c97 100644 --- a/src/jit/mod.rs +++ b/src/jit/mod.rs @@ -40,12 +40,14 @@ pub enum ValueTag { } #[repr(C)] +#[derive(Clone, Copy)] pub struct JITValue { tag: ValueTag, data: JITValueData, } #[repr(C)] +#[derive(Clone, Copy)] pub union JITValueData { int: i64, float: f64, @@ -365,11 +367,21 @@ impl<'vm, 'ctx: 'vm> JITContext<'ctx> { .unwrap(), )?, OpCode::Call { arity } => { - // TODO: - assert_eq!(arity, 1); - let mut args = Vec::with_capacity(arity); - for _ in 0..arity { - args.insert(0, stack.pop()); + let args = self.builder.build_array_malloc( + self.helpers.value_type, + self.helpers.int_type.const_int(arity as u64, false), + "malloc_args", + )?; + for i in 0..arity { + let ptr = unsafe { + self.builder.build_in_bounds_gep( + self.helpers.value_type, + args, + &[self.helpers.int_type.const_int(i as u64, false)], + "gep_arg", + )? + }; + self.builder.build_store(ptr, stack.pop())?; } let func = self .builder @@ -385,7 +397,15 @@ impl<'vm, 'ctx: 'vm> JITContext<'ctx> { .builder .build_direct_call( self.helpers.call, - &[func.into(), args[0].into(), self.new_ptr(vm).into()], + &[ + func.into(), + args.into(), + self.helpers + .ptr_int_type + .const_int(arity as u64, false) + .into(), + self.new_ptr(vm).into(), + ], "call", )? .try_as_basic_value()