mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 16:44:33 +00:00
make it actually work
This commit is contained in:
parent
cb28e533b8
commit
0289fe37a5
5 changed files with 63 additions and 38 deletions
|
@ -125,7 +125,7 @@ pub fn gen_from_mono_module(
|
|||
}
|
||||
|
||||
// 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);
|
||||
|
||||
|
|
|
@ -2158,6 +2158,8 @@ pub fn build_closure_caller<'a, 'ctx, 'env>(
|
|||
let context = &env.context;
|
||||
let builder = env.builder;
|
||||
|
||||
// STEP 1: build function header
|
||||
|
||||
let function_name = format!(
|
||||
"{}_{}_caller",
|
||||
def_name,
|
||||
|
@ -2215,7 +2217,7 @@ pub fn build_closure_caller<'a, 'ctx, 'env>(
|
|||
|
||||
function_value.set_call_conventions(C_CALL_CONV);
|
||||
|
||||
// BUILD FUNCTION BODY
|
||||
// STEP 2: build function body
|
||||
|
||||
let entry = context.append_basic_block(function_value, "entry");
|
||||
|
||||
|
@ -2235,18 +2237,36 @@ pub fn build_closure_caller<'a, 'ctx, 'env>(
|
|||
|
||||
let result = call.try_as_basic_value().left().unwrap();
|
||||
|
||||
// TODO here we just assume success (first i64 is 0)
|
||||
unsafe {
|
||||
let tag_ptr = builder.build_struct_gep(output, 0, "gep");
|
||||
// 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);
|
||||
|
||||
// STEP 3: build a {} -> u64 function that gives the size of the return type
|
||||
let size_function_type = env.context.i64_type().fn_type(&[], false);
|
||||
let size_function_name: String = format!(
|
||||
"{}_{}_size",
|
||||
def_name,
|
||||
alias_symbol.ident_string(&env.interns)
|
||||
);
|
||||
|
||||
let size_function = env.module.add_function(
|
||||
size_function_name.as_str(),
|
||||
size_function_type,
|
||||
Some(Linkage::External),
|
||||
);
|
||||
|
||||
let entry = context.append_basic_block(size_function, "entry");
|
||||
|
||||
builder.position_at_end(entry);
|
||||
|
||||
let size: BasicValueEnum = roc_call_result_type.size_of().unwrap().into();
|
||||
builder.build_return(Some(&size));
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
|
|
|
@ -3,6 +3,7 @@ app Closure provides [ makeClosure ] imports []
|
|||
makeClosure : ({} -> Int) as MyClosure
|
||||
makeClosure =
|
||||
x = 42
|
||||
y = 42
|
||||
|
||||
\{} -> x
|
||||
\{} -> x + y
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use roc_std::alloca;
|
||||
use std::alloc::Layout;
|
||||
use std::ffi::CString;
|
||||
use std::mem::MaybeUninit;
|
||||
use std::os::raw::c_char;
|
||||
use std::time::SystemTime;
|
||||
use RocCallResult::*;
|
||||
|
@ -9,40 +9,36 @@ extern "C" {
|
|||
#[link_name = "makeClosure_1_exposed"]
|
||||
fn make_closure(output: *mut u8) -> ();
|
||||
|
||||
#[link_name = "makeClosure_1_MyClosure_caller"]
|
||||
fn call_MyClosure(
|
||||
unit: (),
|
||||
function_pointer: *const u8,
|
||||
closure_data: *const u8,
|
||||
output: *mut u8,
|
||||
) -> ();
|
||||
|
||||
#[link_name = "makeClosure_1_size"]
|
||||
fn closure_size() -> i64;
|
||||
|
||||
#[link_name = "makeClosure_1_MyClosure_caller"]
|
||||
fn call_MyClosure(function_pointer: *const u8, closure_data: *const u8, output: *mut u8) -> ();
|
||||
|
||||
#[link_name = "makeClosure_1_MyClosure_size"]
|
||||
fn size_MyClosure() -> 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;
|
||||
let size = size_MyClosure() as usize;
|
||||
|
||||
call_MyClosure(
|
||||
(),
|
||||
function_pointer,
|
||||
closure_data_ptr as *const u8,
|
||||
buffer as *mut u8,
|
||||
);
|
||||
alloca::with_stack_bytes(size, |buffer| {
|
||||
let buffer: *mut std::ffi::c_void = buffer;
|
||||
let buffer: *mut u8 = buffer as *mut u8;
|
||||
|
||||
dbg!(*buffer);
|
||||
call_MyClosure(
|
||||
function_pointer,
|
||||
closure_data_ptr as *const u8,
|
||||
buffer as *mut u8,
|
||||
);
|
||||
|
||||
let output = &*(buffer as *mut RocCallResult<i64>);
|
||||
let output = &*(buffer as *mut RocCallResult<i64>);
|
||||
|
||||
match output.into() {
|
||||
Ok(v) => v,
|
||||
Err(e) => panic!("failed with {}", e),
|
||||
}
|
||||
match output.into() {
|
||||
Ok(v) => v,
|
||||
Err(e) => panic!("failed with {}", e),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
@ -57,12 +53,19 @@ pub fn rust_main() -> isize {
|
|||
|
||||
make_closure(buffer);
|
||||
|
||||
let output = &*(buffer as *mut RocCallResult<(*const u8, ())>);
|
||||
let output = &*(buffer as *mut RocCallResult<((), ())>);
|
||||
|
||||
match output.into() {
|
||||
Ok((function_pointer, _)) => {
|
||||
Ok((_, _)) => {
|
||||
let function_pointer = {
|
||||
// this is a pointer to the location where the function pointer is stored
|
||||
// we pass just the function pointer
|
||||
let temp = buffer.offset(8) as *const i64;
|
||||
|
||||
(*temp) as *const u8
|
||||
};
|
||||
|
||||
let closure_data_ptr = buffer.offset(16);
|
||||
dbg!(*closure_data_ptr);
|
||||
|
||||
call_the_closure(function_pointer as *const u8, closure_data_ptr as *const u8)
|
||||
}
|
||||
|
|
|
@ -63,7 +63,8 @@ unsafe fn malloc_or_alloca(bytes: usize) -> *mut c_void {
|
|||
#[cfg(not(debug_assertions))]
|
||||
#[inline(always)]
|
||||
unsafe fn malloc_or_alloca(bytes: usize) -> *mut c_void {
|
||||
c_alloca(bytes)
|
||||
// c_alloca(bytes)
|
||||
libc::malloc(bytes)
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue