mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 07:41:12 +00:00
get foreign call compiling (but not working)
This commit is contained in:
parent
2f42463a97
commit
4c3f0a5002
3 changed files with 69 additions and 4 deletions
|
@ -810,6 +810,24 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
Literal(literal) => build_exp_literal(env, literal),
|
Literal(literal) => build_exp_literal(env, literal),
|
||||||
RunLowLevel(op, symbols) => run_low_level(env, scope, parent, layout, *op, symbols),
|
RunLowLevel(op, symbols) => run_low_level(env, scope, parent, layout, *op, symbols),
|
||||||
|
|
||||||
|
ForeignCall(foreign_symbol, symbols) => {
|
||||||
|
let function = get_foreign_symbol(env, foreign_symbol.clone());
|
||||||
|
|
||||||
|
let mut arg_vals: Vec<BasicValueEnum> = Vec::with_capacity_in(symbols.len(), env.arena);
|
||||||
|
|
||||||
|
for arg in symbols.iter() {
|
||||||
|
arg_vals.push(load_symbol(env, scope, arg));
|
||||||
|
}
|
||||||
|
|
||||||
|
let call = env.builder.build_call(function, arg_vals.as_slice(), "tmp");
|
||||||
|
|
||||||
|
// this is a foreign function, use c calling convention
|
||||||
|
call.set_call_convention(C_CALL_CONV);
|
||||||
|
|
||||||
|
call.try_as_basic_value()
|
||||||
|
.left()
|
||||||
|
.unwrap_or_else(|| panic!("LLVM error: Invalid call by pointer."))
|
||||||
|
}
|
||||||
FunctionCall {
|
FunctionCall {
|
||||||
call_type: ByName(name),
|
call_type: ByName(name),
|
||||||
full_layout,
|
full_layout,
|
||||||
|
@ -3402,6 +3420,28 @@ fn cxa_rethrow_exception<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> BasicValu
|
||||||
call.try_as_basic_value().left().unwrap()
|
call.try_as_basic_value().left().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_foreign_symbol<'a, 'ctx, 'env>(
|
||||||
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
|
foreign_symbol: roc_module::ident::ForeignSymbol,
|
||||||
|
) -> FunctionValue<'ctx> {
|
||||||
|
let module = env.module;
|
||||||
|
let context = env.context;
|
||||||
|
|
||||||
|
match module.get_function(foreign_symbol.as_str()) {
|
||||||
|
Some(gvalue) => gvalue,
|
||||||
|
None => {
|
||||||
|
let foreign_function = module.add_function(
|
||||||
|
foreign_symbol.as_str(),
|
||||||
|
context.i64_type().fn_type(&[], false),
|
||||||
|
Some(Linkage::External),
|
||||||
|
);
|
||||||
|
foreign_function.set_call_conventions(C_CALL_CONV);
|
||||||
|
|
||||||
|
foreign_function
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn get_gxx_personality_v0<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> FunctionValue<'ctx> {
|
fn get_gxx_personality_v0<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> FunctionValue<'ctx> {
|
||||||
let name = "__gxx_personality_v0";
|
let name = "__gxx_personality_v0";
|
||||||
|
|
||||||
|
|
|
@ -2146,9 +2146,8 @@ fn fabricate_host_exposed_def<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO figure out something better for run lowlevel
|
// TODO figure out something better for run lowlevel
|
||||||
use roc_module::low_level::LowLevel;
|
let low_level_call = Expr::ForeignCall {
|
||||||
let low_level_call = Expr::RunLowLevel {
|
foreign_symbol: "roc_fx_put_char".into(),
|
||||||
op: LowLevel::Not,
|
|
||||||
args: linked_symbol_arguments,
|
args: linked_symbol_arguments,
|
||||||
ret_var: var_store.fresh(),
|
ret_var: var_store.fresh(),
|
||||||
};
|
};
|
||||||
|
|
|
@ -3264,7 +3264,33 @@ pub fn with_hole<'a>(
|
||||||
foreign_symbol,
|
foreign_symbol,
|
||||||
args,
|
args,
|
||||||
ret_var,
|
ret_var,
|
||||||
} => todo!(),
|
} => {
|
||||||
|
let mut arg_symbols = Vec::with_capacity_in(args.len(), env.arena);
|
||||||
|
|
||||||
|
for (_, arg_expr) in args.iter() {
|
||||||
|
arg_symbols.push(possible_reuse_symbol(env, procs, &arg_expr));
|
||||||
|
}
|
||||||
|
let arg_symbols = arg_symbols.into_bump_slice();
|
||||||
|
|
||||||
|
// layout of the return type
|
||||||
|
let layout = layout_cache
|
||||||
|
.from_var(env.arena, ret_var, env.subs)
|
||||||
|
.unwrap_or_else(|err| todo!("TODO turn fn_var into a RuntimeError {:?}", err));
|
||||||
|
|
||||||
|
let result = Stmt::Let(
|
||||||
|
assigned,
|
||||||
|
Expr::ForeignCall(foreign_symbol.clone(), arg_symbols),
|
||||||
|
layout,
|
||||||
|
hole,
|
||||||
|
);
|
||||||
|
|
||||||
|
let iter = args
|
||||||
|
.into_iter()
|
||||||
|
.rev()
|
||||||
|
.map(|(a, b)| (a, Located::at_zero(b)))
|
||||||
|
.zip(arg_symbols.iter().rev());
|
||||||
|
assign_to_symbols(env, procs, layout_cache, iter, result)
|
||||||
|
}
|
||||||
|
|
||||||
RunLowLevel { op, args, ret_var } => {
|
RunLowLevel { op, args, ret_var } => {
|
||||||
let op = optimize_low_level(env.subs, op, &args);
|
let op = optimize_low_level(env.subs, op, &args);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue