mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 22:34:45 +00:00
so close
This commit is contained in:
parent
4c5a5dc6a2
commit
cb28e533b8
6 changed files with 234 additions and 50 deletions
|
@ -125,7 +125,7 @@ pub fn gen_from_mono_module(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uncomment this to see the module's optimized LLVM instruction output:
|
// Uncomment this to see the module's optimized LLVM instruction output:
|
||||||
// env.module.print_to_stderr();
|
env.module.print_to_stderr();
|
||||||
|
|
||||||
mpm.run_on(module);
|
mpm.run_on(module);
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ use roc_collections::all::{ImMap, MutSet};
|
||||||
use roc_module::low_level::LowLevel;
|
use roc_module::low_level::LowLevel;
|
||||||
use roc_module::symbol::{Interns, ModuleId, Symbol};
|
use roc_module::symbol::{Interns, ModuleId, Symbol};
|
||||||
use roc_mono::ir::{JoinPointId, Wrapped};
|
use roc_mono::ir::{JoinPointId, Wrapped};
|
||||||
use roc_mono::layout::{Builtin, Layout, MemoryMode};
|
use roc_mono::layout::{Builtin, ClosureLayout, Layout, MemoryMode};
|
||||||
use target_lexicon::CallingConvention;
|
use target_lexicon::CallingConvention;
|
||||||
|
|
||||||
/// This is for Inkwell's FunctionValue::verify - we want to know the verification
|
/// This is for Inkwell's FunctionValue::verify - we want to know the verification
|
||||||
|
@ -2099,6 +2099,27 @@ pub fn build_proc_header<'a, 'ctx, 'env>(
|
||||||
let arena = env.arena;
|
let arena = env.arena;
|
||||||
let context = &env.context;
|
let context = &env.context;
|
||||||
|
|
||||||
|
let fn_name = layout_ids
|
||||||
|
.get(symbol, layout)
|
||||||
|
.to_symbol_string(symbol, &env.interns);
|
||||||
|
|
||||||
|
use roc_mono::ir::HostExposedLayouts;
|
||||||
|
match &proc.host_exposed_layouts {
|
||||||
|
HostExposedLayouts::NotHostExposed => {}
|
||||||
|
HostExposedLayouts::HostExposed { rigids: _, aliases } => {
|
||||||
|
for (name, layout) in aliases {
|
||||||
|
match layout {
|
||||||
|
Layout::Closure(arguments, closure, result) => {
|
||||||
|
build_closure_caller(env, &fn_name, *name, arguments, closure, result)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let ret_type = basic_type_from_layout(arena, context, &proc.ret_layout, env.ptr_bytes);
|
let ret_type = basic_type_from_layout(arena, context, &proc.ret_layout, env.ptr_bytes);
|
||||||
let mut arg_basic_types = Vec::with_capacity_in(args.len(), arena);
|
let mut arg_basic_types = Vec::with_capacity_in(args.len(), arena);
|
||||||
|
|
||||||
|
@ -2110,9 +2131,6 @@ pub fn build_proc_header<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
let fn_type = get_fn_type(&ret_type, &arg_basic_types);
|
let fn_type = get_fn_type(&ret_type, &arg_basic_types);
|
||||||
|
|
||||||
let fn_name = layout_ids
|
|
||||||
.get(symbol, layout)
|
|
||||||
.to_symbol_string(symbol, &env.interns);
|
|
||||||
let fn_val = env
|
let fn_val = env
|
||||||
.module
|
.module
|
||||||
.add_function(fn_name.as_str(), fn_type, Some(Linkage::Private));
|
.add_function(fn_name.as_str(), fn_type, Some(Linkage::Private));
|
||||||
|
@ -2126,8 +2144,113 @@ pub fn build_proc_header<'a, 'ctx, 'env>(
|
||||||
fn_val
|
fn_val
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn build_closure_caller<'a, 'ctx, 'env>(
|
pub fn build_closure_caller<'a, 'ctx, 'env>(
|
||||||
|
env: &'a Env<'a, 'ctx, 'env>,
|
||||||
|
def_name: &str,
|
||||||
|
alias_symbol: Symbol,
|
||||||
|
arguments: &[Layout<'a>],
|
||||||
|
closure: &ClosureLayout<'a>,
|
||||||
|
result: &Layout<'a>,
|
||||||
|
) {
|
||||||
|
use inkwell::types::BasicType;
|
||||||
|
|
||||||
|
let arena = env.arena;
|
||||||
|
let context = &env.context;
|
||||||
|
let builder = env.builder;
|
||||||
|
|
||||||
|
let function_name = format!(
|
||||||
|
"{}_{}_caller",
|
||||||
|
def_name,
|
||||||
|
alias_symbol.ident_string(&env.interns)
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut argument_types = Vec::with_capacity_in(arguments.len() + 3, env.arena);
|
||||||
|
|
||||||
|
for layout in arguments {
|
||||||
|
argument_types.push(basic_type_from_layout(
|
||||||
|
arena,
|
||||||
|
context,
|
||||||
|
layout,
|
||||||
|
env.ptr_bytes,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let function_pointer_type = {
|
||||||
|
let function_layout =
|
||||||
|
ClosureLayout::extend_function_layout(arena, arguments, closure.clone(), result);
|
||||||
|
let basic_type = basic_type_from_layout(arena, context, &function_layout, env.ptr_bytes);
|
||||||
|
|
||||||
|
// this is already a (function) pointer type
|
||||||
|
basic_type
|
||||||
|
};
|
||||||
|
argument_types.push(function_pointer_type.into());
|
||||||
|
|
||||||
|
let closure_argument_type = {
|
||||||
|
let basic_type = basic_type_from_layout(
|
||||||
|
arena,
|
||||||
|
context,
|
||||||
|
&closure.as_block_of_memory_layout(),
|
||||||
|
env.ptr_bytes,
|
||||||
|
);
|
||||||
|
|
||||||
|
basic_type.ptr_type(AddressSpace::Generic)
|
||||||
|
};
|
||||||
|
argument_types.push(closure_argument_type.into());
|
||||||
|
|
||||||
|
let result_type = basic_type_from_layout(arena, context, result, env.ptr_bytes);
|
||||||
|
|
||||||
|
let roc_call_result_type =
|
||||||
|
context.struct_type(&[context.i64_type().into(), result_type], false);
|
||||||
|
|
||||||
|
let output_type = { roc_call_result_type.ptr_type(AddressSpace::Generic) };
|
||||||
|
argument_types.push(output_type.into());
|
||||||
|
|
||||||
|
let function_type = context.void_type().fn_type(&argument_types, false);
|
||||||
|
|
||||||
|
let function_value = env.module.add_function(
|
||||||
|
function_name.as_str(),
|
||||||
|
function_type,
|
||||||
|
Some(Linkage::External),
|
||||||
|
);
|
||||||
|
|
||||||
|
function_value.set_call_conventions(C_CALL_CONV);
|
||||||
|
|
||||||
|
// BUILD FUNCTION BODY
|
||||||
|
|
||||||
|
let entry = context.append_basic_block(function_value, "entry");
|
||||||
|
|
||||||
|
builder.position_at_end(entry);
|
||||||
|
|
||||||
|
let mut parameters = function_value.get_params();
|
||||||
|
let output = parameters.pop().unwrap().into_pointer_value();
|
||||||
|
let closure_data_ptr = parameters.pop().unwrap().into_pointer_value();
|
||||||
|
let function_ptr = parameters.pop().unwrap().into_pointer_value();
|
||||||
|
|
||||||
|
let closure_data = builder.build_load(closure_data_ptr, "load_closure_data");
|
||||||
|
|
||||||
|
let mut arguments = parameters;
|
||||||
|
arguments.push(closure_data);
|
||||||
|
let call = builder.build_call(function_ptr, &arguments, "call_closure");
|
||||||
|
call.set_call_convention(FAST_CALL_CONV);
|
||||||
|
|
||||||
|
let result = call.try_as_basic_value().left().unwrap();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let tag_ptr = builder.build_struct_gep(output, 0, "gep");
|
||||||
|
let result_ptr = builder.build_struct_gep(output, 1, "gep");
|
||||||
|
|
||||||
|
// let v33 = context.i64_type().const_int(33, false);
|
||||||
|
// builder.build_store(tag_ptr, v33);
|
||||||
|
builder.build_store(result_ptr, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
//builder.build_store(output, roc_call_result);
|
||||||
|
|
||||||
|
builder.build_return(None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn build_closure_caller_old<'a, 'ctx, 'env>(
|
||||||
env: &'a Env<'a, 'ctx, 'env>,
|
env: &'a Env<'a, 'ctx, 'env>,
|
||||||
closure_function: FunctionValue<'ctx>,
|
closure_function: FunctionValue<'ctx>,
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -2331,7 +2331,6 @@ fn add_def_to_module<'a>(
|
||||||
) {
|
) {
|
||||||
use roc_can::expr::Expr::*;
|
use roc_can::expr::Expr::*;
|
||||||
use roc_can::pattern::Pattern::*;
|
use roc_can::pattern::Pattern::*;
|
||||||
use roc_mono::ir::HostExposedVariables;
|
|
||||||
|
|
||||||
match def.loc_pattern.value {
|
match def.loc_pattern.value {
|
||||||
Identifier(symbol) => {
|
Identifier(symbol) => {
|
||||||
|
@ -2425,7 +2424,6 @@ fn add_def_to_module<'a>(
|
||||||
body,
|
body,
|
||||||
// This is a 0-arity thunk, so it cannot be recursive
|
// This is a 0-arity thunk, so it cannot be recursive
|
||||||
is_self_recursive: false,
|
is_self_recursive: false,
|
||||||
host_exposed_variables: HostExposedVariables::default(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
procs.partial_procs.insert(symbol, proc);
|
procs.partial_procs.insert(symbol, proc);
|
||||||
|
|
|
@ -26,7 +26,6 @@ pub struct PartialProc<'a> {
|
||||||
pub captured_symbols: CapturedSymbols<'a>,
|
pub captured_symbols: CapturedSymbols<'a>,
|
||||||
pub body: roc_can::expr::Expr,
|
pub body: roc_can::expr::Expr,
|
||||||
pub is_self_recursive: bool,
|
pub is_self_recursive: bool,
|
||||||
pub host_exposed_variables: HostExposedVariables,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Default)]
|
#[derive(Clone, Debug, PartialEq, Default)]
|
||||||
|
@ -382,7 +381,6 @@ impl<'a> Procs<'a> {
|
||||||
captured_symbols,
|
captured_symbols,
|
||||||
body: body.value,
|
body: body.value,
|
||||||
is_self_recursive,
|
is_self_recursive,
|
||||||
host_exposed_variables: HostExposedVariables::default(),
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -456,7 +454,6 @@ impl<'a> Procs<'a> {
|
||||||
captured_symbols,
|
captured_symbols,
|
||||||
body: body.value,
|
body: body.value,
|
||||||
is_self_recursive,
|
is_self_recursive,
|
||||||
host_exposed_variables: HostExposedVariables::default(),
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -468,7 +465,6 @@ impl<'a> Procs<'a> {
|
||||||
captured_symbols,
|
captured_symbols,
|
||||||
body: body.value,
|
body: body.value,
|
||||||
is_self_recursive,
|
is_self_recursive,
|
||||||
host_exposed_variables: HostExposedVariables::default(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Mark this proc as in-progress, so if we're dealing with
|
// Mark this proc as in-progress, so if we're dealing with
|
||||||
|
@ -1351,6 +1347,7 @@ pub fn specialize_all<'a>(
|
||||||
name,
|
name,
|
||||||
layout_cache,
|
layout_cache,
|
||||||
solved_type,
|
solved_type,
|
||||||
|
MutMap::default(),
|
||||||
partial_proc,
|
partial_proc,
|
||||||
) {
|
) {
|
||||||
Ok((proc, layout)) => {
|
Ok((proc, layout)) => {
|
||||||
|
@ -1436,6 +1433,7 @@ fn specialize_external<'a>(
|
||||||
proc_name: Symbol,
|
proc_name: Symbol,
|
||||||
layout_cache: &mut LayoutCache<'a>,
|
layout_cache: &mut LayoutCache<'a>,
|
||||||
fn_var: Variable,
|
fn_var: Variable,
|
||||||
|
host_exposed_variables: &[(Symbol, Variable)],
|
||||||
partial_proc: PartialProc<'a>,
|
partial_proc: PartialProc<'a>,
|
||||||
) -> Result<Proc<'a>, LayoutProblem> {
|
) -> Result<Proc<'a>, LayoutProblem> {
|
||||||
let PartialProc {
|
let PartialProc {
|
||||||
|
@ -1444,7 +1442,6 @@ fn specialize_external<'a>(
|
||||||
captured_symbols,
|
captured_symbols,
|
||||||
body,
|
body,
|
||||||
is_self_recursive,
|
is_self_recursive,
|
||||||
host_exposed_variables,
|
|
||||||
} = partial_proc;
|
} = partial_proc;
|
||||||
|
|
||||||
// unify the called function with the specialized signature, then specialize the function body
|
// unify the called function with the specialized signature, then specialize the function body
|
||||||
|
@ -1501,12 +1498,23 @@ fn specialize_external<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
// TODO host exposed thngs
|
||||||
let host_exposed_layouts = {
|
// host_exposed_variables: &[(Symbol, Variable)],
|
||||||
if host_exposed_variables == HostExposedVariables::default() {
|
let host_exposed_layouts = if host_exposed_variables.is_empty() {
|
||||||
HostExposedLayouts::NotHostExposed
|
HostExposedLayouts::NotHostExposed
|
||||||
} else {
|
} else {
|
||||||
todo!()
|
let mut aliases = MutMap::default();
|
||||||
|
|
||||||
|
for (symbol, variable) in host_exposed_variables {
|
||||||
|
let layout = layout_cache
|
||||||
|
.from_var(env.arena, *variable, env.subs)
|
||||||
|
.unwrap();
|
||||||
|
aliases.insert(*symbol, layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
HostExposedLayouts::HostExposed {
|
||||||
|
rigids: MutMap::default(),
|
||||||
|
aliases,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1764,44 +1772,71 @@ fn specialize<'a>(
|
||||||
proc_name,
|
proc_name,
|
||||||
layout_cache,
|
layout_cache,
|
||||||
solved_type,
|
solved_type,
|
||||||
|
host_exposed_aliases,
|
||||||
partial_proc,
|
partial_proc,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn introduce_solved_type_to_subs<'a>(env: &mut Env<'a, '_>, solved_type: &SolvedType) -> Variable {
|
||||||
|
use roc_solve::solve::insert_type_into_subs;
|
||||||
|
use roc_types::solved_types::{to_type, FreeVars};
|
||||||
|
use roc_types::subs::VarStore;
|
||||||
|
let mut free_vars = FreeVars::default();
|
||||||
|
let mut var_store = VarStore::new_from_subs(env.subs);
|
||||||
|
|
||||||
|
let before = var_store.peek();
|
||||||
|
|
||||||
|
let normal_type = to_type(solved_type, &mut free_vars, &mut var_store);
|
||||||
|
|
||||||
|
let after = var_store.peek();
|
||||||
|
let variables_introduced = after - before;
|
||||||
|
|
||||||
|
env.subs.extend_by(variables_introduced as usize);
|
||||||
|
|
||||||
|
let result = insert_type_into_subs(env.subs, &normal_type);
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
fn specialize_solved_type<'a>(
|
fn specialize_solved_type<'a>(
|
||||||
env: &mut Env<'a, '_>,
|
env: &mut Env<'a, '_>,
|
||||||
procs: &mut Procs<'a>,
|
procs: &mut Procs<'a>,
|
||||||
proc_name: Symbol,
|
proc_name: Symbol,
|
||||||
layout_cache: &mut LayoutCache<'a>,
|
layout_cache: &mut LayoutCache<'a>,
|
||||||
solved_type: SolvedType,
|
solved_type: SolvedType,
|
||||||
|
host_exposed_aliases: MutMap<Symbol, SolvedType>,
|
||||||
partial_proc: PartialProc<'a>,
|
partial_proc: PartialProc<'a>,
|
||||||
) -> Result<(Proc<'a>, Layout<'a>), LayoutProblem> {
|
) -> Result<(Proc<'a>, Layout<'a>), LayoutProblem> {
|
||||||
// add the specializations that other modules require of us
|
// add the specializations that other modules require of us
|
||||||
use roc_solve::solve::{insert_type_into_subs, instantiate_rigids};
|
use roc_solve::solve::instantiate_rigids;
|
||||||
use roc_types::solved_types::{to_type, FreeVars};
|
|
||||||
use roc_types::subs::VarStore;
|
|
||||||
|
|
||||||
let snapshot = env.subs.snapshot();
|
let snapshot = env.subs.snapshot();
|
||||||
let cache_snapshot = layout_cache.snapshot();
|
let cache_snapshot = layout_cache.snapshot();
|
||||||
|
|
||||||
let mut free_vars = FreeVars::default();
|
let fn_var = introduce_solved_type_to_subs(env, &solved_type);
|
||||||
let mut var_store = VarStore::new_from_subs(env.subs);
|
|
||||||
|
|
||||||
let before = var_store.peek();
|
|
||||||
|
|
||||||
let normal_type = to_type(&solved_type, &mut free_vars, &mut var_store);
|
|
||||||
|
|
||||||
let after = var_store.peek();
|
|
||||||
let variables_introduced = after - before;
|
|
||||||
|
|
||||||
env.subs.extend_by(variables_introduced as usize);
|
|
||||||
|
|
||||||
let fn_var = insert_type_into_subs(env.subs, &normal_type);
|
|
||||||
|
|
||||||
// make sure rigid variables in the annotation are converted to flex variables
|
// make sure rigid variables in the annotation are converted to flex variables
|
||||||
instantiate_rigids(env.subs, partial_proc.annotation);
|
instantiate_rigids(env.subs, partial_proc.annotation);
|
||||||
|
|
||||||
match specialize_external(env, procs, proc_name, layout_cache, fn_var, partial_proc) {
|
let mut host_exposed_variables = Vec::with_capacity_in(host_exposed_aliases.len(), env.arena);
|
||||||
|
|
||||||
|
for (symbol, solved_type) in host_exposed_aliases {
|
||||||
|
let alias_var = introduce_solved_type_to_subs(env, &solved_type);
|
||||||
|
|
||||||
|
host_exposed_variables.push((symbol, alias_var));
|
||||||
|
}
|
||||||
|
|
||||||
|
let specialized = specialize_external(
|
||||||
|
env,
|
||||||
|
procs,
|
||||||
|
proc_name,
|
||||||
|
layout_cache,
|
||||||
|
fn_var,
|
||||||
|
&host_exposed_variables,
|
||||||
|
partial_proc,
|
||||||
|
);
|
||||||
|
|
||||||
|
match specialized {
|
||||||
Ok(proc) => {
|
Ok(proc) => {
|
||||||
let layout = layout_cache
|
let layout = layout_cache
|
||||||
.from_var(&env.arena, fn_var, env.subs)
|
.from_var(&env.arena, fn_var, env.subs)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
app Closure provides [ closure ] imports []
|
app Closure provides [ makeClosure ] imports []
|
||||||
|
|
||||||
closure : ({} -> Int) as MyClosure
|
makeClosure : ({} -> Int) as MyClosure
|
||||||
closure =
|
makeClosure =
|
||||||
x = 42
|
x = 42
|
||||||
|
|
||||||
\{} -> x
|
\{} -> x
|
||||||
|
|
|
@ -6,16 +6,45 @@ use std::time::SystemTime;
|
||||||
use RocCallResult::*;
|
use RocCallResult::*;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#[link_name = "closure_1_exposed"]
|
#[link_name = "makeClosure_1_exposed"]
|
||||||
fn make_closure(output: *mut u8) -> ();
|
fn make_closure(output: *mut u8) -> ();
|
||||||
|
|
||||||
// #[link_name = "0_1_caller"]
|
#[link_name = "makeClosure_1_MyClosure_caller"]
|
||||||
// fn call_closure_0(unit: (), closure_data: *const u8, output: *mut u8) -> ();
|
fn call_MyClosure(
|
||||||
|
unit: (),
|
||||||
|
function_pointer: *const u8,
|
||||||
|
closure_data: *const u8,
|
||||||
|
output: *mut u8,
|
||||||
|
) -> ();
|
||||||
|
|
||||||
#[link_name = "closure_1_size"]
|
#[link_name = "makeClosure_1_size"]
|
||||||
fn closure_size() -> i64;
|
fn closure_size() -> i64;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe fn call_the_closure(function_pointer: *const u8, closure_data_ptr: *const u8) -> i64 {
|
||||||
|
// wow
|
||||||
|
let layout = Layout::array::<u8>(100).unwrap();
|
||||||
|
// let buffer = std::alloc::alloc(layout);
|
||||||
|
let mut foo = (0, 0);
|
||||||
|
let buffer: *mut (i64, i64) = &mut foo;
|
||||||
|
|
||||||
|
call_MyClosure(
|
||||||
|
(),
|
||||||
|
function_pointer,
|
||||||
|
closure_data_ptr as *const u8,
|
||||||
|
buffer as *mut u8,
|
||||||
|
);
|
||||||
|
|
||||||
|
dbg!(*buffer);
|
||||||
|
|
||||||
|
let output = &*(buffer as *mut RocCallResult<i64>);
|
||||||
|
|
||||||
|
match output.into() {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(e) => panic!("failed with {}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn rust_main() -> isize {
|
pub fn rust_main() -> isize {
|
||||||
println!("Running Roc closure");
|
println!("Running Roc closure");
|
||||||
|
@ -23,19 +52,19 @@ pub fn rust_main() -> isize {
|
||||||
|
|
||||||
let size = unsafe { closure_size() } as usize;
|
let size = unsafe { closure_size() } as usize;
|
||||||
let layout = Layout::array::<u8>(size).unwrap();
|
let layout = Layout::array::<u8>(size).unwrap();
|
||||||
let roc_closure = unsafe {
|
let answer = unsafe {
|
||||||
let buffer = std::alloc::alloc(layout);
|
let buffer = std::alloc::alloc(layout);
|
||||||
|
|
||||||
make_closure(buffer);
|
make_closure(buffer);
|
||||||
|
|
||||||
type CLOSURE_DATA = i64;
|
let output = &*(buffer as *mut RocCallResult<(*const u8, ())>);
|
||||||
let output = &*(buffer as *mut RocCallResult<(fn(CLOSURE_DATA) -> i64, CLOSURE_DATA)>);
|
|
||||||
|
|
||||||
match output.into() {
|
match output.into() {
|
||||||
Ok((function_pointer, closure_data)) => {
|
Ok((function_pointer, _)) => {
|
||||||
std::alloc::dealloc(buffer, layout);
|
let closure_data_ptr = buffer.offset(16);
|
||||||
|
dbg!(*closure_data_ptr);
|
||||||
|
|
||||||
move || function_pointer(closure_data)
|
call_the_closure(function_pointer as *const u8, closure_data_ptr as *const u8)
|
||||||
}
|
}
|
||||||
Err(msg) => {
|
Err(msg) => {
|
||||||
std::alloc::dealloc(buffer, layout);
|
std::alloc::dealloc(buffer, layout);
|
||||||
|
@ -44,7 +73,6 @@ pub fn rust_main() -> isize {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let answer = roc_closure();
|
|
||||||
let end_time = SystemTime::now();
|
let end_time = SystemTime::now();
|
||||||
let duration = end_time.duration_since(start_time).unwrap();
|
let duration = end_time.duration_since(start_time).unwrap();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue