mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 21:39:07 +00:00
Erased functions do not take a func spec
This commit is contained in:
parent
7c8e7bbea3
commit
13d1232f7d
9 changed files with 185 additions and 28 deletions
|
@ -444,6 +444,7 @@ fn build_exposed_proc<'a, B: Backend<'a>>(backend: &mut B, proc: &Proc<'a>) -> P
|
||||||
ret_layout: proc.ret_layout,
|
ret_layout: proc.ret_layout,
|
||||||
is_self_recursive: roc_mono::ir::SelfRecursive::NotSelfRecursive,
|
is_self_recursive: roc_mono::ir::SelfRecursive::NotSelfRecursive,
|
||||||
host_exposed_layouts: roc_mono::ir::HostExposedLayouts::NotHostExposed,
|
host_exposed_layouts: roc_mono::ir::HostExposedLayouts::NotHostExposed,
|
||||||
|
is_erased: proc.is_erased,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -525,6 +526,7 @@ fn build_exposed_generic_proc<'a, B: Backend<'a>>(backend: &mut B, proc: &Proc<'
|
||||||
ret_layout: roc_mono::layout::Layout::UNIT,
|
ret_layout: roc_mono::layout::Layout::UNIT,
|
||||||
is_self_recursive: roc_mono::ir::SelfRecursive::NotSelfRecursive,
|
is_self_recursive: roc_mono::ir::SelfRecursive::NotSelfRecursive,
|
||||||
host_exposed_layouts: roc_mono::ir::HostExposedLayouts::NotHostExposed,
|
host_exposed_layouts: roc_mono::ir::HostExposedLayouts::NotHostExposed,
|
||||||
|
is_erased: proc.is_erased,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ use crate::llvm::convert::{
|
||||||
argument_type_from_layout, basic_type_from_builtin, basic_type_from_layout, zig_str_type,
|
argument_type_from_layout, basic_type_from_builtin, basic_type_from_layout, zig_str_type,
|
||||||
};
|
};
|
||||||
use crate::llvm::expect::{clone_to_shared_memory, SharedMemoryPointer};
|
use crate::llvm::expect::{clone_to_shared_memory, SharedMemoryPointer};
|
||||||
|
use crate::llvm::fn_ptr;
|
||||||
use crate::llvm::memcpy::build_memcpy;
|
use crate::llvm::memcpy::build_memcpy;
|
||||||
use crate::llvm::refcounting::{
|
use crate::llvm::refcounting::{
|
||||||
build_reset, decrement_refcount_layout, increment_refcount_layout, PointerToRefcount,
|
build_reset, decrement_refcount_layout, increment_refcount_layout, PointerToRefcount,
|
||||||
|
@ -605,8 +606,14 @@ fn promote_to_main_function<'a, 'ctx>(
|
||||||
);
|
);
|
||||||
|
|
||||||
// NOTE fake layout; it is only used for debug prints
|
// NOTE fake layout; it is only used for debug prints
|
||||||
let roc_main_fn =
|
let roc_main_fn = function_value_by_func_spec(
|
||||||
function_value_by_func_spec(env, *func_spec, symbol, &[], Niche::NONE, Layout::UNIT);
|
env,
|
||||||
|
FuncBorrowSpec::Some(*func_spec),
|
||||||
|
symbol,
|
||||||
|
&[],
|
||||||
|
Niche::NONE,
|
||||||
|
Layout::UNIT,
|
||||||
|
);
|
||||||
|
|
||||||
let main_fn_name = "$Test.main";
|
let main_fn_name = "$Test.main";
|
||||||
|
|
||||||
|
@ -655,8 +662,14 @@ fn promote_to_wasm_test_wrapper<'a, 'ctx>(
|
||||||
);
|
);
|
||||||
|
|
||||||
// NOTE fake layout; it is only used for debug prints
|
// NOTE fake layout; it is only used for debug prints
|
||||||
let roc_main_fn =
|
let roc_main_fn = function_value_by_func_spec(
|
||||||
function_value_by_func_spec(env, *func_spec, symbol, &[], Niche::NONE, Layout::UNIT);
|
env,
|
||||||
|
FuncBorrowSpec::Some(*func_spec),
|
||||||
|
symbol,
|
||||||
|
&[],
|
||||||
|
Niche::NONE,
|
||||||
|
Layout::UNIT,
|
||||||
|
);
|
||||||
|
|
||||||
let output_type = match roc_main_fn.get_type().get_return_type() {
|
let output_type = match roc_main_fn.get_type().get_return_type() {
|
||||||
Some(return_type) => {
|
Some(return_type) => {
|
||||||
|
@ -934,7 +947,7 @@ pub(crate) fn build_exp_call<'a, 'ctx>(
|
||||||
arg_layouts,
|
arg_layouts,
|
||||||
*ret_layout,
|
*ret_layout,
|
||||||
*name,
|
*name,
|
||||||
func_spec,
|
FuncBorrowSpec::Some(func_spec),
|
||||||
arg_tuples.into_bump_slice(),
|
arg_tuples.into_bump_slice(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1126,7 +1139,12 @@ pub(crate) fn build_exp_expr<'a, 'ctx>(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionPointer { .. } => todo_lambda_erasure!(),
|
FunctionPointer { lambda_name } => {
|
||||||
|
let function_ptr_type =
|
||||||
|
fn_ptr::pointer_type_expecting_layout(env, layout_interner, layout);
|
||||||
|
let alloca = fn_ptr::build(env, layout_interner, *lambda_name, function_ptr_type);
|
||||||
|
alloca.into()
|
||||||
|
}
|
||||||
ErasedMake { .. } => todo_lambda_erasure!(),
|
ErasedMake { .. } => todo_lambda_erasure!(),
|
||||||
ErasedLoad { .. } => todo_lambda_erasure!(),
|
ErasedLoad { .. } => todo_lambda_erasure!(),
|
||||||
|
|
||||||
|
@ -4871,15 +4889,19 @@ pub(crate) fn build_proc_headers<'a, 'r, 'ctx>(
|
||||||
|
|
||||||
let it = func_solutions.specs();
|
let it = func_solutions.specs();
|
||||||
let mut function_values = std::vec::Vec::with_capacity(it.size_hint().0);
|
let mut function_values = std::vec::Vec::with_capacity(it.size_hint().0);
|
||||||
|
|
||||||
|
let is_erased = proc.is_erased;
|
||||||
|
debug_assert!(!is_erased || func_solutions.specs().count() == 1);
|
||||||
|
|
||||||
for specialization in it {
|
for specialization in it {
|
||||||
let fn_val = build_proc_header(
|
let func_spec = if is_erased {
|
||||||
env,
|
FuncBorrowSpec::Erased
|
||||||
layout_interner,
|
} else {
|
||||||
*specialization,
|
FuncBorrowSpec::Some(*specialization)
|
||||||
symbol,
|
};
|
||||||
&proc,
|
|
||||||
layout_ids,
|
let fn_val =
|
||||||
);
|
build_proc_header(env, layout_interner, func_spec, symbol, &proc, layout_ids);
|
||||||
|
|
||||||
if proc.args.is_empty() {
|
if proc.args.is_empty() {
|
||||||
// this is a 0-argument thunk, i.e. a top-level constant definition
|
// this is a 0-argument thunk, i.e. a top-level constant definition
|
||||||
|
@ -4934,8 +4956,14 @@ pub fn build_procedures<'a>(
|
||||||
);
|
);
|
||||||
|
|
||||||
// NOTE fake layout; it is only used for debug prints
|
// NOTE fake layout; it is only used for debug prints
|
||||||
let getter_fn =
|
let getter_fn = function_value_by_func_spec(
|
||||||
function_value_by_func_spec(env, *func_spec, symbol, &[], niche, Layout::UNIT);
|
env,
|
||||||
|
FuncBorrowSpec::Some(*func_spec),
|
||||||
|
symbol,
|
||||||
|
&[],
|
||||||
|
niche,
|
||||||
|
Layout::UNIT,
|
||||||
|
);
|
||||||
|
|
||||||
let name = getter_fn.get_name().to_str().unwrap();
|
let name = getter_fn.get_name().to_str().unwrap();
|
||||||
let getter_name = symbol.as_str(&env.interns);
|
let getter_name = symbol.as_str(&env.interns);
|
||||||
|
@ -5050,8 +5078,14 @@ pub fn build_procedures_expose_expects<'a>(
|
||||||
);
|
);
|
||||||
|
|
||||||
// NOTE fake layout; it is only used for debug prints
|
// NOTE fake layout; it is only used for debug prints
|
||||||
let roc_main_fn =
|
let roc_main_fn = function_value_by_func_spec(
|
||||||
function_value_by_func_spec(env, *func_spec, symbol, &[], captures_niche, Layout::UNIT);
|
env,
|
||||||
|
FuncBorrowSpec::Some(*func_spec),
|
||||||
|
symbol,
|
||||||
|
&[],
|
||||||
|
captures_niche,
|
||||||
|
Layout::UNIT,
|
||||||
|
);
|
||||||
|
|
||||||
let name = roc_main_fn.get_name().to_str().unwrap();
|
let name = roc_main_fn.get_name().to_str().unwrap();
|
||||||
|
|
||||||
|
@ -5178,11 +5212,19 @@ fn build_procedures_help<'a>(
|
||||||
mod_solutions
|
mod_solutions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum FuncBorrowSpec {
|
||||||
|
/// This function has an specialization due to alias analysis.
|
||||||
|
Some(FuncSpec),
|
||||||
|
/// This function does not have a specialization due to alias analysis,
|
||||||
|
/// because it is type-erased, and thus has no statically determined AA specialization.
|
||||||
|
Erased,
|
||||||
|
}
|
||||||
|
|
||||||
fn func_spec_name<'a>(
|
fn func_spec_name<'a>(
|
||||||
arena: &'a Bump,
|
arena: &'a Bump,
|
||||||
interns: &Interns,
|
interns: &Interns,
|
||||||
symbol: Symbol,
|
symbol: Symbol,
|
||||||
func_spec: FuncSpec,
|
func_spec: FuncBorrowSpec,
|
||||||
) -> bumpalo::collections::String<'a> {
|
) -> bumpalo::collections::String<'a> {
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
|
||||||
|
@ -5192,8 +5234,13 @@ fn func_spec_name<'a>(
|
||||||
let module_string = interns.module_ids.get_name(symbol.module_id()).unwrap();
|
let module_string = interns.module_ids.get_name(symbol.module_id()).unwrap();
|
||||||
write!(buf, "{module_string}_{ident_string}_").unwrap();
|
write!(buf, "{module_string}_{ident_string}_").unwrap();
|
||||||
|
|
||||||
for byte in func_spec.0.iter() {
|
match func_spec {
|
||||||
write!(buf, "{byte:x?}").unwrap();
|
FuncBorrowSpec::Some(func_spec) => {
|
||||||
|
for byte in func_spec.0.iter() {
|
||||||
|
write!(buf, "{byte:x?}").unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FuncBorrowSpec::Erased => write!(buf, "erased").unwrap(),
|
||||||
}
|
}
|
||||||
|
|
||||||
buf
|
buf
|
||||||
|
@ -5202,7 +5249,7 @@ fn func_spec_name<'a>(
|
||||||
fn build_proc_header<'a, 'ctx>(
|
fn build_proc_header<'a, 'ctx>(
|
||||||
env: &Env<'a, 'ctx, '_>,
|
env: &Env<'a, 'ctx, '_>,
|
||||||
layout_interner: &STLayoutInterner<'a>,
|
layout_interner: &STLayoutInterner<'a>,
|
||||||
func_spec: FuncSpec,
|
func_spec: FuncBorrowSpec,
|
||||||
symbol: Symbol,
|
symbol: Symbol,
|
||||||
proc: &roc_mono::ir::Proc<'a>,
|
proc: &roc_mono::ir::Proc<'a>,
|
||||||
layout_ids: &mut LayoutIds<'a>,
|
layout_ids: &mut LayoutIds<'a>,
|
||||||
|
@ -5307,7 +5354,7 @@ fn expose_alias_to_host<'a>(
|
||||||
|
|
||||||
function_value_by_func_spec(
|
function_value_by_func_spec(
|
||||||
env,
|
env,
|
||||||
*func_spec,
|
FuncBorrowSpec::Some(*func_spec),
|
||||||
hels.symbol,
|
hels.symbol,
|
||||||
hels.proc_layout.arguments,
|
hels.proc_layout.arguments,
|
||||||
Niche::NONE,
|
Niche::NONE,
|
||||||
|
@ -5619,7 +5666,7 @@ pub fn verify_fn(fn_val: FunctionValue<'_>) {
|
||||||
|
|
||||||
pub(crate) fn function_value_by_func_spec<'a, 'ctx>(
|
pub(crate) fn function_value_by_func_spec<'a, 'ctx>(
|
||||||
env: &Env<'a, 'ctx, '_>,
|
env: &Env<'a, 'ctx, '_>,
|
||||||
func_spec: FuncSpec,
|
func_spec: FuncBorrowSpec,
|
||||||
symbol: Symbol,
|
symbol: Symbol,
|
||||||
arguments: &[InLayout<'a>],
|
arguments: &[InLayout<'a>],
|
||||||
niche: Niche<'a>,
|
niche: Niche<'a>,
|
||||||
|
@ -5671,7 +5718,7 @@ fn roc_call_with_args<'a, 'ctx>(
|
||||||
argument_layouts: &[InLayout<'a>],
|
argument_layouts: &[InLayout<'a>],
|
||||||
result_layout: InLayout<'a>,
|
result_layout: InLayout<'a>,
|
||||||
name: LambdaName<'a>,
|
name: LambdaName<'a>,
|
||||||
func_spec: FuncSpec,
|
func_spec: FuncBorrowSpec,
|
||||||
arguments: &[BasicValueEnum<'ctx>],
|
arguments: &[BasicValueEnum<'ctx>],
|
||||||
) -> BasicValueEnum<'ctx> {
|
) -> BasicValueEnum<'ctx> {
|
||||||
let fn_val = function_value_by_func_spec(
|
let fn_val = function_value_by_func_spec(
|
||||||
|
@ -6412,7 +6459,7 @@ fn get_foreign_symbol<'ctx>(
|
||||||
/// Add a function to a module, after asserting that the function is unique.
|
/// Add a function to a module, after asserting that the function is unique.
|
||||||
/// We never want to define the same function twice in the same module!
|
/// We never want to define the same function twice in the same module!
|
||||||
/// The result can be bugs that are difficult to track down.
|
/// The result can be bugs that are difficult to track down.
|
||||||
pub fn add_func<'ctx>(
|
pub(crate) fn add_func<'ctx>(
|
||||||
ctx: &Context,
|
ctx: &Context,
|
||||||
module: &Module<'ctx>,
|
module: &Module<'ctx>,
|
||||||
name: &str,
|
name: &str,
|
||||||
|
|
80
crates/compiler/gen_llvm/src/llvm/fn_ptr.rs
Normal file
80
crates/compiler/gen_llvm/src/llvm/fn_ptr.rs
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
use bumpalo::collections::CollectIn;
|
||||||
|
use inkwell::{
|
||||||
|
types::{FunctionType, PointerType},
|
||||||
|
values::{BasicValueEnum, FunctionValue},
|
||||||
|
AddressSpace,
|
||||||
|
};
|
||||||
|
use roc_error_macros::internal_error;
|
||||||
|
use roc_mono::layout::{
|
||||||
|
FunctionPointer, InLayout, LambdaName, LayoutInterner, LayoutRepr, STLayoutInterner,
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
build::{function_value_by_func_spec, Env, FuncBorrowSpec, FunctionSpec, RocReturn},
|
||||||
|
convert::basic_type_from_layout,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn function_type<'a, 'ctx>(
|
||||||
|
env: &Env<'a, 'ctx, '_>,
|
||||||
|
layout_interner: &STLayoutInterner<'a>,
|
||||||
|
function_pointer: FunctionPointer<'a>,
|
||||||
|
) -> FunctionType<'ctx> {
|
||||||
|
let FunctionPointer { args, ret } = function_pointer;
|
||||||
|
|
||||||
|
let args = args
|
||||||
|
.iter()
|
||||||
|
.map(|arg| basic_type_from_layout(env, layout_interner, layout_interner.get_repr(*arg)));
|
||||||
|
|
||||||
|
let ret_repr = layout_interner.get_repr(ret);
|
||||||
|
let ret = basic_type_from_layout(env, layout_interner, ret_repr);
|
||||||
|
|
||||||
|
let roc_return = RocReturn::from_layout(layout_interner, ret_repr);
|
||||||
|
|
||||||
|
let fn_spec = FunctionSpec::fastcc(env, roc_return, ret, args.collect_in(env.arena));
|
||||||
|
|
||||||
|
fn_spec.typ
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pointer_type<'a, 'ctx>(
|
||||||
|
env: &Env<'a, 'ctx, '_>,
|
||||||
|
layout_interner: &STLayoutInterner<'a>,
|
||||||
|
function_pointer: FunctionPointer<'a>,
|
||||||
|
) -> PointerType<'ctx> {
|
||||||
|
let function_type = function_type(env, layout_interner, function_pointer);
|
||||||
|
|
||||||
|
function_type.ptr_type(AddressSpace::default())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
pub fn pointer_type_expecting_layout<'a, 'ctx>(
|
||||||
|
env: &Env<'a, 'ctx, '_>,
|
||||||
|
layout_interner: &STLayoutInterner<'a>,
|
||||||
|
layout: InLayout<'a>,
|
||||||
|
) -> PointerType<'ctx> {
|
||||||
|
let function_pointer = match layout_interner.get_repr(layout) {
|
||||||
|
LayoutRepr::FunctionPointer(function_pointer) => function_pointer,
|
||||||
|
_ => internal_error!("expected function pointer"),
|
||||||
|
};
|
||||||
|
|
||||||
|
pointer_type(env, layout_interner, function_pointer)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build<'a, 'ctx>(
|
||||||
|
env: &Env<'a, 'ctx, '_>,
|
||||||
|
layout_interner: &STLayoutInterner<'a>,
|
||||||
|
lambda_name: LambdaName<'a>,
|
||||||
|
function_ptr_type: PointerType<'ctx>,
|
||||||
|
) -> BasicValueEnum<'ctx> {
|
||||||
|
let alloca = env
|
||||||
|
.builder
|
||||||
|
.build_alloca(function_ptr_type, "function_pointer_alloca");
|
||||||
|
let func_value: FunctionValue<'ctx> = function_value_by_func_spec(
|
||||||
|
env,
|
||||||
|
FuncBorrowSpec::Erased,
|
||||||
|
lambda_name.name(),
|
||||||
|
lambda_name.niche(),
|
||||||
|
);
|
||||||
|
env.builder
|
||||||
|
.build_store(alloca, func_value.as_global_value().as_pointer_value());
|
||||||
|
alloca.into()
|
||||||
|
}
|
|
@ -31,7 +31,7 @@ use crate::llvm::{
|
||||||
build::{
|
build::{
|
||||||
cast_basic_basic, complex_bitcast_check_size, create_entry_block_alloca,
|
cast_basic_basic, complex_bitcast_check_size, create_entry_block_alloca,
|
||||||
entry_block_alloca_zerofill, function_value_by_func_spec, load_roc_value,
|
entry_block_alloca_zerofill, function_value_by_func_spec, load_roc_value,
|
||||||
roc_function_call, tag_pointer_clear_tag_id, BuilderExt, RocReturn,
|
roc_function_call, tag_pointer_clear_tag_id, BuilderExt, FuncBorrowSpec, RocReturn,
|
||||||
},
|
},
|
||||||
build_list::{
|
build_list::{
|
||||||
list_append_unsafe, list_concat, list_drop_at, list_get_unsafe, list_len, list_map,
|
list_append_unsafe, list_concat, list_drop_at, list_get_unsafe, list_len, list_map,
|
||||||
|
@ -2624,7 +2624,7 @@ pub(crate) fn run_higher_order_low_level<'a, 'ctx>(
|
||||||
() => {{
|
() => {{
|
||||||
let function = function_value_by_func_spec(
|
let function = function_value_by_func_spec(
|
||||||
env,
|
env,
|
||||||
func_spec,
|
FuncBorrowSpec::Some(func_spec),
|
||||||
function_name.name(),
|
function_name.name(),
|
||||||
argument_layouts,
|
argument_layouts,
|
||||||
function_name.niche(),
|
function_name.niche(),
|
||||||
|
|
|
@ -12,6 +12,7 @@ pub mod refcounting;
|
||||||
|
|
||||||
mod align;
|
mod align;
|
||||||
mod erased;
|
mod erased;
|
||||||
|
mod fn_ptr;
|
||||||
mod memcpy;
|
mod memcpy;
|
||||||
mod scope;
|
mod scope;
|
||||||
mod struct_;
|
mod struct_;
|
||||||
|
|
|
@ -453,6 +453,7 @@ impl<'a> CodeGenHelp<'a> {
|
||||||
ret_layout,
|
ret_layout,
|
||||||
is_self_recursive: SelfRecursive::NotSelfRecursive,
|
is_self_recursive: SelfRecursive::NotSelfRecursive,
|
||||||
host_exposed_layouts: HostExposedLayouts::NotHostExposed,
|
host_exposed_layouts: HostExposedLayouts::NotHostExposed,
|
||||||
|
is_erased: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
proc_symbol
|
proc_symbol
|
||||||
|
@ -772,6 +773,7 @@ impl<'a> CallerProc<'a> {
|
||||||
ret_layout: Layout::UNIT,
|
ret_layout: Layout::UNIT,
|
||||||
is_self_recursive: SelfRecursive::NotSelfRecursive,
|
is_self_recursive: SelfRecursive::NotSelfRecursive,
|
||||||
host_exposed_layouts: HostExposedLayouts::NotHostExposed,
|
host_exposed_layouts: HostExposedLayouts::NotHostExposed,
|
||||||
|
is_erased: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
if false {
|
if false {
|
||||||
|
|
|
@ -308,6 +308,7 @@ pub struct Proc<'a> {
|
||||||
pub ret_layout: InLayout<'a>,
|
pub ret_layout: InLayout<'a>,
|
||||||
pub is_self_recursive: SelfRecursive,
|
pub is_self_recursive: SelfRecursive,
|
||||||
pub host_exposed_layouts: HostExposedLayouts<'a>,
|
pub host_exposed_layouts: HostExposedLayouts<'a>,
|
||||||
|
pub is_erased: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
@ -3269,6 +3270,7 @@ fn generate_runtime_error_function<'a>(
|
||||||
|
|
||||||
let runtime_error = runtime_error(env, msg.into_bump_str());
|
let runtime_error = runtime_error(env, msg.into_bump_str());
|
||||||
|
|
||||||
|
let is_erased = layout.is_erased_function();
|
||||||
let (args, ret_layout) = match layout {
|
let (args, ret_layout) = match layout {
|
||||||
RawFunctionLayout::Function(arg_layouts, lambda_set, ret_layout) => {
|
RawFunctionLayout::Function(arg_layouts, lambda_set, ret_layout) => {
|
||||||
let real_arg_layouts =
|
let real_arg_layouts =
|
||||||
|
@ -3299,6 +3301,7 @@ fn generate_runtime_error_function<'a>(
|
||||||
ret_layout,
|
ret_layout,
|
||||||
is_self_recursive: SelfRecursive::NotSelfRecursive,
|
is_self_recursive: SelfRecursive::NotSelfRecursive,
|
||||||
host_exposed_layouts: HostExposedLayouts::NotHostExposed,
|
host_exposed_layouts: HostExposedLayouts::NotHostExposed,
|
||||||
|
is_erased,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3394,6 +3397,7 @@ fn generate_host_exposed_function<'a>(
|
||||||
ret_layout: result,
|
ret_layout: result,
|
||||||
is_self_recursive: SelfRecursive::NotSelfRecursive,
|
is_self_recursive: SelfRecursive::NotSelfRecursive,
|
||||||
host_exposed_layouts: HostExposedLayouts::NotHostExposed,
|
host_exposed_layouts: HostExposedLayouts::NotHostExposed,
|
||||||
|
is_erased: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let top_level = ProcLayout::from_raw_named(env.arena, lambda_name, layout);
|
let top_level = ProcLayout::from_raw_named(env.arena, lambda_name, layout);
|
||||||
|
@ -3458,6 +3462,7 @@ fn generate_host_exposed_lambda_set<'a>(
|
||||||
ret_layout: return_layout,
|
ret_layout: return_layout,
|
||||||
is_self_recursive: SelfRecursive::NotSelfRecursive,
|
is_self_recursive: SelfRecursive::NotSelfRecursive,
|
||||||
host_exposed_layouts: HostExposedLayouts::NotHostExposed,
|
host_exposed_layouts: HostExposedLayouts::NotHostExposed,
|
||||||
|
is_erased: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let top_level = ProcLayout::new(
|
let top_level = ProcLayout::new(
|
||||||
|
@ -3529,6 +3534,7 @@ fn specialize_proc_help<'a>(
|
||||||
SpecializedLayout::FunctionPointerBody {
|
SpecializedLayout::FunctionPointerBody {
|
||||||
ret_layout,
|
ret_layout,
|
||||||
closure: opt_closure_layout,
|
closure: opt_closure_layout,
|
||||||
|
is_erased,
|
||||||
} => {
|
} => {
|
||||||
// this is a function body like
|
// this is a function body like
|
||||||
//
|
//
|
||||||
|
@ -3554,12 +3560,14 @@ fn specialize_proc_help<'a>(
|
||||||
ret_layout,
|
ret_layout,
|
||||||
is_self_recursive: recursivity,
|
is_self_recursive: recursivity,
|
||||||
host_exposed_layouts,
|
host_exposed_layouts,
|
||||||
|
is_erased,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SpecializedLayout::FunctionBody {
|
SpecializedLayout::FunctionBody {
|
||||||
arguments: proc_args,
|
arguments: proc_args,
|
||||||
closure: opt_closure_layout,
|
closure: opt_closure_layout,
|
||||||
ret_layout,
|
ret_layout,
|
||||||
|
is_erased,
|
||||||
} => {
|
} => {
|
||||||
let mut proc_args = Vec::from_iter_in(proc_args.iter().copied(), env.arena);
|
let mut proc_args = Vec::from_iter_in(proc_args.iter().copied(), env.arena);
|
||||||
|
|
||||||
|
@ -3755,6 +3763,7 @@ fn specialize_proc_help<'a>(
|
||||||
ret_layout,
|
ret_layout,
|
||||||
is_self_recursive: recursivity,
|
is_self_recursive: recursivity,
|
||||||
host_exposed_layouts,
|
host_exposed_layouts,
|
||||||
|
is_erased,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -3769,11 +3778,13 @@ enum SpecializedLayout<'a> {
|
||||||
arguments: &'a [(InLayout<'a>, Symbol)],
|
arguments: &'a [(InLayout<'a>, Symbol)],
|
||||||
closure: Option<ClosureDataKind<'a>>,
|
closure: Option<ClosureDataKind<'a>>,
|
||||||
ret_layout: InLayout<'a>,
|
ret_layout: InLayout<'a>,
|
||||||
|
is_erased: bool,
|
||||||
},
|
},
|
||||||
/// A body like `foo = Num.add`
|
/// A body like `foo = Num.add`
|
||||||
FunctionPointerBody {
|
FunctionPointerBody {
|
||||||
closure: Option<LambdaSet<'a>>,
|
closure: Option<LambdaSet<'a>>,
|
||||||
ret_layout: InLayout<'a>,
|
ret_layout: InLayout<'a>,
|
||||||
|
is_erased: bool,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3845,6 +3856,8 @@ fn build_specialized_proc<'a>(
|
||||||
proc_args.push((arg_layout, *arg_name));
|
proc_args.push((arg_layout, *arg_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let is_erased = matches!(closure_data, Some(ClosureDataKind::Erased));
|
||||||
|
|
||||||
// Given
|
// Given
|
||||||
//
|
//
|
||||||
// foo =
|
// foo =
|
||||||
|
@ -3883,6 +3896,7 @@ fn build_specialized_proc<'a>(
|
||||||
arguments: proc_args,
|
arguments: proc_args,
|
||||||
closure: Some(closure_data),
|
closure: Some(closure_data),
|
||||||
ret_layout,
|
ret_layout,
|
||||||
|
is_erased,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Some(closure_data) => {
|
Some(closure_data) => {
|
||||||
|
@ -3901,6 +3915,7 @@ fn build_specialized_proc<'a>(
|
||||||
arguments: proc_args,
|
arguments: proc_args,
|
||||||
closure: None,
|
closure: None,
|
||||||
ret_layout,
|
ret_layout,
|
||||||
|
is_erased,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Ordering::Greater => {
|
Ordering::Greater => {
|
||||||
|
@ -3909,6 +3924,7 @@ fn build_specialized_proc<'a>(
|
||||||
Ok(FunctionPointerBody {
|
Ok(FunctionPointerBody {
|
||||||
closure: None,
|
closure: None,
|
||||||
ret_layout,
|
ret_layout,
|
||||||
|
is_erased,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// so far, the problem when hitting this branch was always somewhere else
|
// so far, the problem when hitting this branch was always somewhere else
|
||||||
|
@ -3939,6 +3955,7 @@ fn build_specialized_proc<'a>(
|
||||||
arguments: proc_args,
|
arguments: proc_args,
|
||||||
closure: None,
|
closure: None,
|
||||||
ret_layout,
|
ret_layout,
|
||||||
|
is_erased,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Ordering::Greater => {
|
Ordering::Greater => {
|
||||||
|
@ -3946,6 +3963,7 @@ fn build_specialized_proc<'a>(
|
||||||
Ok(FunctionPointerBody {
|
Ok(FunctionPointerBody {
|
||||||
closure: None,
|
closure: None,
|
||||||
ret_layout,
|
ret_layout,
|
||||||
|
is_erased,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// so far, the problem when hitting this branch was always somewhere else
|
// so far, the problem when hitting this branch was always somewhere else
|
||||||
|
@ -10316,6 +10334,7 @@ where
|
||||||
ret_layout: *field,
|
ret_layout: *field,
|
||||||
is_self_recursive: SelfRecursive::NotSelfRecursive,
|
is_self_recursive: SelfRecursive::NotSelfRecursive,
|
||||||
host_exposed_layouts: HostExposedLayouts::NotHostExposed,
|
host_exposed_layouts: HostExposedLayouts::NotHostExposed,
|
||||||
|
is_erased: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
answer.push(GlueProc {
|
answer.push(GlueProc {
|
||||||
|
@ -10411,6 +10430,7 @@ where
|
||||||
ret_layout: *field,
|
ret_layout: *field,
|
||||||
is_self_recursive: SelfRecursive::NotSelfRecursive,
|
is_self_recursive: SelfRecursive::NotSelfRecursive,
|
||||||
host_exposed_layouts: HostExposedLayouts::NotHostExposed,
|
host_exposed_layouts: HostExposedLayouts::NotHostExposed,
|
||||||
|
is_erased: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
answer.push(GlueProc {
|
answer.push(GlueProc {
|
||||||
|
|
|
@ -496,6 +496,10 @@ impl<'a> RawFunctionLayout<'a> {
|
||||||
matches!(self, RawFunctionLayout::ZeroArgumentThunk(_))
|
matches!(self, RawFunctionLayout::ZeroArgumentThunk(_))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_erased_function(&self) -> bool {
|
||||||
|
matches!(self, RawFunctionLayout::ErasedFunction(_, _))
|
||||||
|
}
|
||||||
|
|
||||||
fn new_help<'b>(
|
fn new_help<'b>(
|
||||||
env: &mut Env<'a, 'b>,
|
env: &mut Env<'a, 'b>,
|
||||||
var: Variable,
|
var: Variable,
|
||||||
|
|
|
@ -813,6 +813,7 @@ impl<'a> TrmcEnv<'a> {
|
||||||
ret_layout: proc.ret_layout,
|
ret_layout: proc.ret_layout,
|
||||||
is_self_recursive: SelfRecursive::NotSelfRecursive,
|
is_self_recursive: SelfRecursive::NotSelfRecursive,
|
||||||
host_exposed_layouts: proc.host_exposed_layouts.clone(),
|
host_exposed_layouts: proc.host_exposed_layouts.clone(),
|
||||||
|
is_erased: proc.is_erased,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue