feat: lookup at downgrade time
works, but leaks memory
This commit is contained in:
@@ -34,6 +34,8 @@ pub struct Helpers<'ctx> {
|
||||
pub eq: FunctionValue<'ctx>,
|
||||
pub or: FunctionValue<'ctx>,
|
||||
pub call: FunctionValue<'ctx>,
|
||||
pub arg: FunctionValue<'ctx>,
|
||||
pub lookup_let: FunctionValue<'ctx>,
|
||||
pub lookup: FunctionValue<'ctx>,
|
||||
pub force: FunctionValue<'ctx>,
|
||||
}
|
||||
@@ -113,6 +115,16 @@ impl<'ctx> Helpers<'ctx> {
|
||||
),
|
||||
None,
|
||||
);
|
||||
let arg = module.add_function(
|
||||
"arg",
|
||||
value_type.fn_type(&[ptr_int_type.into(), ptr_type.into()], false),
|
||||
None,
|
||||
);
|
||||
let lookup_let = module.add_function(
|
||||
"lookup_let",
|
||||
value_type.fn_type(&[ptr_int_type.into(), ptr_int_type.into(), ptr_type.into()], false),
|
||||
None,
|
||||
);
|
||||
let lookup = module.add_function(
|
||||
"lookup",
|
||||
value_type.fn_type(&[ptr_int_type.into(), ptr_type.into()], false),
|
||||
@@ -142,6 +154,8 @@ impl<'ctx> Helpers<'ctx> {
|
||||
execution_engine.add_global_mapping(&eq, helper_eq as _);
|
||||
execution_engine.add_global_mapping(&or, helper_or as _);
|
||||
execution_engine.add_global_mapping(&call, helper_call as _);
|
||||
execution_engine.add_global_mapping(&arg, helper_arg as _);
|
||||
execution_engine.add_global_mapping(&lookup_let, helper_lookup_let as _);
|
||||
execution_engine.add_global_mapping(&lookup, helper_lookup as _);
|
||||
execution_engine.add_global_mapping(&force, helper_force as _);
|
||||
|
||||
@@ -165,6 +179,8 @@ impl<'ctx> Helpers<'ctx> {
|
||||
eq,
|
||||
or,
|
||||
call,
|
||||
arg,
|
||||
lookup_let,
|
||||
lookup,
|
||||
force,
|
||||
}
|
||||
@@ -348,9 +364,21 @@ extern "C" fn helper_call<'gc>(
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" fn helper_arg(idx: usize, env: *const VmEnv) -> JITValue {
|
||||
let env = unsafe { env.as_ref() }.unwrap();
|
||||
let val: JITValue = env.lookup_arg(idx).into();
|
||||
val
|
||||
}
|
||||
|
||||
extern "C" fn helper_lookup_let(level: usize, idx: usize, env: *const VmEnv) -> JITValue {
|
||||
let env = unsafe { env.as_ref() }.unwrap();
|
||||
let val: JITValue = env.lookup_let(level, idx).into();
|
||||
val
|
||||
}
|
||||
|
||||
extern "C" fn helper_lookup(sym: usize, env: *const VmEnv) -> JITValue {
|
||||
let env = unsafe { env.as_ref() }.unwrap();
|
||||
let val: JITValue = env.lookup_slow(&sym).unwrap().into();
|
||||
let val: JITValue = env.lookup_with(&sym).unwrap().into();
|
||||
val
|
||||
}
|
||||
|
||||
@@ -373,7 +401,7 @@ extern "C" fn helper_force<'gc>(
|
||||
let (opcodes, env) = thunk.suspend(mc).unwrap();
|
||||
let func = unsafe { jit.as_ref() }
|
||||
.unwrap()
|
||||
.compile_seq(opcodes.iter().copied(), vm)
|
||||
.compile_seq(opcodes.iter().copied().rev(), vm)
|
||||
.unwrap();
|
||||
let val = unsafe { func.call(env.as_ref() as *const _, mc as *const _) };
|
||||
thunk.insert_value(val.into(), mc);
|
||||
|
||||
@@ -199,7 +199,7 @@ impl<'gc> JITContext<'gc> {
|
||||
|
||||
pub fn compile_seq(
|
||||
&self,
|
||||
opcodes: impl ExactSizeIterator<Item = OpCode> + DoubleEndedIterator,
|
||||
mut opcodes: impl ExactSizeIterator<Item = OpCode>,
|
||||
vm: &'gc VM<'gc>,
|
||||
) -> Result<JITFunc<'gc>> {
|
||||
let mut stack = Stack::<_, STACK_SIZE>::new();
|
||||
@@ -211,7 +211,7 @@ impl<'gc> JITContext<'gc> {
|
||||
let entry = self.context.append_basic_block(func_, "entry");
|
||||
self.builder.position_at_end(entry);
|
||||
let len = opcodes.len();
|
||||
self.build_expr(&mut opcodes.rev(), vm, env, mc, &mut stack, func_, len)?;
|
||||
self.build_expr(&mut opcodes, vm, env, mc, &mut stack, func_, len)?;
|
||||
|
||||
assert_eq!(stack.len(), 1);
|
||||
let value = stack.pop();
|
||||
@@ -437,6 +437,47 @@ impl<'gc> JITContext<'gc> {
|
||||
_ => todo!("BinOp::{:?} not implemented in JIT", op),
|
||||
}
|
||||
}
|
||||
OpCode::Arg { level } => stack.push(
|
||||
self.builder
|
||||
.build_direct_call(
|
||||
self.helpers.arg,
|
||||
&[
|
||||
self.helpers
|
||||
.ptr_int_type
|
||||
.const_int(level as u64, false)
|
||||
.into(),
|
||||
env.into(),
|
||||
],
|
||||
"call_arg",
|
||||
)
|
||||
.unwrap()
|
||||
.try_as_basic_value()
|
||||
.left()
|
||||
.unwrap(),
|
||||
)?,
|
||||
OpCode::LookUpLet { level, idx } => stack.push(
|
||||
self.builder
|
||||
.build_direct_call(
|
||||
self.helpers.lookup_let,
|
||||
&[
|
||||
self.helpers
|
||||
.ptr_int_type
|
||||
.const_int(level as u64, false)
|
||||
.into(),
|
||||
self.helpers
|
||||
.ptr_int_type
|
||||
.const_int(idx as u64, false)
|
||||
.into(),
|
||||
env.into(),
|
||||
],
|
||||
"call_lookup_let",
|
||||
)
|
||||
.unwrap()
|
||||
.try_as_basic_value()
|
||||
.left()
|
||||
.unwrap(),
|
||||
)?,
|
||||
|
||||
OpCode::LookUp { sym } => stack.push(
|
||||
self.builder
|
||||
.build_direct_call(
|
||||
|
||||
@@ -8,7 +8,6 @@ use hashbrown::{HashMap, HashSet};
|
||||
use inkwell::context::Context;
|
||||
|
||||
use ecow::EcoString;
|
||||
use rpds::vector_sync;
|
||||
|
||||
use crate::builtins::vm_env;
|
||||
use crate::compile::compile;
|
||||
@@ -77,7 +76,7 @@ macro_rules! symbol {
|
||||
|
||||
macro_rules! list {
|
||||
($($x:tt)*) => (
|
||||
Value::List(List::new(vector_sync![$($x)*]))
|
||||
Value::List(List::new(vec![$($x)*]))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user