Exercise building erased function

This commit is contained in:
Ayaz Hafiz 2023-06-25 20:54:49 -05:00
parent a1eb641bb6
commit d17d8c72ad
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
3 changed files with 51 additions and 17 deletions

View file

@ -8219,7 +8219,14 @@ fn specialize_symbol<'a>(
)
}
}
RawFunctionLayout::ErasedFunction(..) => todo_lambda_erasure!(),
RawFunctionLayout::ErasedFunction(..) => erased::build_erased_function(
env,
layout_cache,
original,
captured,
assign_to,
result,
),
RawFunctionLayout::ZeroArgumentThunk(ret_layout) => {
// this is a 0-argument thunk
let top_level = ProcLayout::new(env.arena, &[], Niche::NONE, ret_layout);

View file

@ -283,7 +283,7 @@ pub fn call_erased_function<'a>(
pub fn build_erased_function<'a>(
env: &mut Env<'a, '_>,
layout_cache: &mut LayoutCache<'a>,
lambda_name: LambdaName<'a>,
lambda_symbol: Symbol,
captures: CapturedSymbols<'a>,
assigned: Symbol,
hole: &'a Stmt<'a>,
@ -310,6 +310,35 @@ pub fn build_erased_function<'a>(
env.arena.alloc(result),
);
struct ResolvedCaptures<'a> {
layouts: &'a [InLayout<'a>],
symbols: &'a [Symbol],
}
let resolved_captures;
let lambda_name;
match captures {
CapturedSymbols::None => {
resolved_captures = None;
lambda_name = LambdaName::from_captures(lambda_symbol, &[]);
}
CapturedSymbols::Captured(captures) => {
let layouts = {
let layouts = captures
.iter()
.map(|(_, var)| layout_cache.from_var(env.arena, *var, env.subs).unwrap());
env.arena.alloc_slice_fill_iter(layouts)
};
let symbols = {
let symbols = captures.iter().map(|(sym, _)| *sym);
env.arena.alloc_slice_fill_iter(symbols)
};
resolved_captures = Some(ResolvedCaptures { layouts, symbols });
lambda_name = LambdaName::from_captures(lambda_symbol, layouts);
}
};
// callee = Expr::FunctionPointer(f)
let result = Stmt::Let(
callee,
@ -319,8 +348,8 @@ pub fn build_erased_function<'a>(
);
// value = Expr::Box({s})
match captures {
CapturedSymbols::None => {
match resolved_captures {
None => {
// value = nullptr
// <hole>
Stmt::Let(
@ -330,24 +359,15 @@ pub fn build_erased_function<'a>(
env.arena.alloc(result),
)
}
CapturedSymbols::Captured(captures) => {
Some(ResolvedCaptures { layouts, symbols }) => {
// captures = {...captures}
// captures = Box(captures)
// value = Cast(captures, void*)
// <hole>
let stack_captures = env.unique_symbol();
let stack_captures_layout = {
let layouts = captures
.iter()
.map(|(_, var)| layout_cache.from_var(env.arena, *var, env.subs).unwrap());
let layouts = env.arena.alloc_slice_fill_iter(layouts);
layout_cache.put_in_direct_no_semantic(LayoutRepr::Struct(layouts))
};
let stack_captures_symbols = {
let symbols = captures.iter().map(|(sym, _)| *sym);
env.arena.alloc_slice_fill_iter(symbols)
};
let stack_captures_layout =
layout_cache.put_in_direct_no_semantic(LayoutRepr::Struct(layouts));
let boxed_captures = env.unique_symbol();
let boxed_captures_layout =
@ -355,7 +375,7 @@ pub fn build_erased_function<'a>(
let result = Stmt::Let(
stack_captures,
Expr::Struct(stack_captures_symbols),
Expr::Struct(symbols),
stack_captures_layout,
env.arena.alloc(result),
);

View file

@ -1357,6 +1357,13 @@ pub struct LambdaName<'a> {
}
impl<'a> LambdaName<'a> {
pub(crate) fn from_captures(symbol: Symbol, captures: &'a [InLayout<'a>]) -> Self {
Self {
name: symbol,
niche: Niche(NichePriv::Captures(captures)),
}
}
#[inline(always)]
pub fn name(&self) -> Symbol {
self.name