feat(jit): support multiple arg function call
note: performance regression?
This commit is contained in:
@@ -11,7 +11,7 @@ use crate::jit::JITValueData;
|
|||||||
use crate::ty::internal::{Thunk, Value};
|
use crate::ty::internal::{Thunk, Value};
|
||||||
use crate::vm::{LetEnv, VM};
|
use crate::vm::{LetEnv, VM};
|
||||||
|
|
||||||
use super::{JITFunc, JITValue, ValueTag};
|
use super::{JITValue, ValueTag};
|
||||||
|
|
||||||
pub struct Helpers<'ctx> {
|
pub struct Helpers<'ctx> {
|
||||||
pub int_type: IntType<'ctx>,
|
pub int_type: IntType<'ctx>,
|
||||||
@@ -93,7 +93,7 @@ impl<'ctx> Helpers<'ctx> {
|
|||||||
let call = module.add_function(
|
let call = module.add_function(
|
||||||
"call",
|
"call",
|
||||||
value_type.fn_type(
|
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,
|
false,
|
||||||
),
|
),
|
||||||
None,
|
None,
|
||||||
@@ -224,7 +224,13 @@ extern "C" fn helper_neg(rhs: JITValue, _env: *const LetEnv) -> JITValue {
|
|||||||
int: -unsafe { rhs.data.int },
|
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 },
|
bool: !unsafe { rhs.data.bool },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
_ => todo!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,14 +323,16 @@ extern "C" fn helper_or(lhs: JITValue, rhs: JITValue) -> JITValue {
|
|||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
extern "C" fn helper_call<'jit, 'vm>(
|
extern "C" fn helper_call<'jit, 'vm>(
|
||||||
func: JITValue,
|
func: JITValue,
|
||||||
arg: JITValue,
|
args: *mut JITValue,
|
||||||
|
arity: usize,
|
||||||
vm: *const VM<'jit>,
|
vm: *const VM<'jit>,
|
||||||
) -> JITValue {
|
) -> JITValue {
|
||||||
use ValueTag::*;
|
use ValueTag::*;
|
||||||
|
let args = unsafe { Vec::from_raw_parts(args, arity, arity) }.into_iter().map(Value::from).collect();
|
||||||
match func.tag {
|
match func.tag {
|
||||||
Function => {
|
Function => {
|
||||||
let func: Value = func.into();
|
let func: Value = func.into();
|
||||||
func.call(unsafe { vm.as_ref() }.unwrap(), vec![arg.into()])
|
func.call(unsafe { vm.as_ref() }.unwrap(), args)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,12 +40,14 @@ pub enum ValueTag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub struct JITValue {
|
pub struct JITValue {
|
||||||
tag: ValueTag,
|
tag: ValueTag,
|
||||||
data: JITValueData,
|
data: JITValueData,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub union JITValueData {
|
pub union JITValueData {
|
||||||
int: i64,
|
int: i64,
|
||||||
float: f64,
|
float: f64,
|
||||||
@@ -365,11 +367,21 @@ impl<'vm, 'ctx: 'vm> JITContext<'ctx> {
|
|||||||
.unwrap(),
|
.unwrap(),
|
||||||
)?,
|
)?,
|
||||||
OpCode::Call { arity } => {
|
OpCode::Call { arity } => {
|
||||||
// TODO:
|
let args = self.builder.build_array_malloc(
|
||||||
assert_eq!(arity, 1);
|
self.helpers.value_type,
|
||||||
let mut args = Vec::with_capacity(arity);
|
self.helpers.int_type.const_int(arity as u64, false),
|
||||||
for _ in 0..arity {
|
"malloc_args",
|
||||||
args.insert(0, stack.pop());
|
)?;
|
||||||
|
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
|
let func = self
|
||||||
.builder
|
.builder
|
||||||
@@ -385,7 +397,15 @@ impl<'vm, 'ctx: 'vm> JITContext<'ctx> {
|
|||||||
.builder
|
.builder
|
||||||
.build_direct_call(
|
.build_direct_call(
|
||||||
self.helpers.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",
|
"call",
|
||||||
)?
|
)?
|
||||||
.try_as_basic_value()
|
.try_as_basic_value()
|
||||||
|
|||||||
Reference in New Issue
Block a user