mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 16:21:11 +00:00
fix llvm build
This commit is contained in:
parent
5a6bd1e187
commit
ca24f1cd38
2 changed files with 110 additions and 111 deletions
|
@ -40,7 +40,7 @@ use roc_collections::all::{ImMap, MutSet};
|
|||
use roc_module::ident::TagName;
|
||||
use roc_module::low_level::LowLevel;
|
||||
use roc_module::symbol::{Interns, ModuleId, Symbol};
|
||||
use roc_mono::ir::{JoinPointId, Wrapped};
|
||||
use roc_mono::ir::{CallType, JoinPointId, Wrapped};
|
||||
use roc_mono::layout::{Builtin, ClosureLayout, Layout, LayoutIds, MemoryMode};
|
||||
use target_lexicon::CallingConvention;
|
||||
|
||||
|
@ -618,18 +618,75 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
|||
layout: &Layout<'a>,
|
||||
expr: &roc_mono::ir::Expr<'a>,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
use roc_mono::ir::CallType::*;
|
||||
use roc_mono::ir::Expr::*;
|
||||
|
||||
match expr {
|
||||
Literal(literal) => build_exp_literal(env, literal),
|
||||
RunLowLevel(op, symbols) => {
|
||||
run_low_level(env, layout_ids, scope, parent, layout, *op, symbols)
|
||||
Call(roc_mono::ir::Call {
|
||||
call_type,
|
||||
arguments,
|
||||
}) => match call_type {
|
||||
CallType::ByName {
|
||||
name, full_layout, ..
|
||||
} => {
|
||||
let mut arg_tuples: Vec<BasicValueEnum> =
|
||||
Vec::with_capacity_in(arguments.len(), env.arena);
|
||||
|
||||
for symbol in arguments.iter() {
|
||||
arg_tuples.push(load_symbol(env, scope, symbol));
|
||||
}
|
||||
|
||||
ForeignCall {
|
||||
call_with_args(
|
||||
env,
|
||||
layout_ids,
|
||||
&full_layout,
|
||||
*name,
|
||||
parent,
|
||||
arg_tuples.into_bump_slice(),
|
||||
)
|
||||
}
|
||||
|
||||
CallType::ByPointer { name, .. } => {
|
||||
let sub_expr = load_symbol(env, scope, name);
|
||||
|
||||
let mut arg_vals: Vec<BasicValueEnum> =
|
||||
Vec::with_capacity_in(arguments.len(), env.arena);
|
||||
|
||||
for arg in arguments.iter() {
|
||||
arg_vals.push(load_symbol(env, scope, arg));
|
||||
}
|
||||
|
||||
let call = match sub_expr {
|
||||
BasicValueEnum::PointerValue(ptr) => {
|
||||
env.builder.build_call(ptr, arg_vals.as_slice(), "tmp")
|
||||
}
|
||||
non_ptr => {
|
||||
panic!(
|
||||
"Tried to call by pointer, but encountered a non-pointer: {:?}",
|
||||
non_ptr
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
if env.exposed_to_host.contains(name) {
|
||||
// If this is an external-facing function, use the C calling convention.
|
||||
call.set_call_convention(C_CALL_CONV);
|
||||
} else {
|
||||
// If it's an internal-only function, use the fast calling convention.
|
||||
call.set_call_convention(FAST_CALL_CONV);
|
||||
}
|
||||
|
||||
call.try_as_basic_value()
|
||||
.left()
|
||||
.unwrap_or_else(|| panic!("LLVM error: Invalid call by pointer."))
|
||||
}
|
||||
|
||||
CallType::LowLevel { op } => {
|
||||
run_low_level(env, layout_ids, scope, parent, layout, *op, arguments)
|
||||
}
|
||||
|
||||
CallType::Foreign {
|
||||
foreign_symbol,
|
||||
arguments,
|
||||
ret_layout,
|
||||
} => {
|
||||
let mut arg_vals: Vec<BasicValueEnum> =
|
||||
|
@ -638,7 +695,8 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
|||
let mut arg_types = Vec::with_capacity_in(arguments.len() + 1, env.arena);
|
||||
|
||||
// crude approximation of the C calling convention
|
||||
let pass_result_by_pointer = ret_layout.stack_size(env.ptr_bytes) > 2 * env.ptr_bytes;
|
||||
let pass_result_by_pointer =
|
||||
ret_layout.stack_size(env.ptr_bytes) > 2 * env.ptr_bytes;
|
||||
|
||||
if pass_result_by_pointer {
|
||||
// the return value is too big to pass through a register, so the caller must
|
||||
|
@ -696,65 +754,7 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
|||
.unwrap_or_else(|| panic!("LLVM error: Invalid call by pointer."))
|
||||
}
|
||||
}
|
||||
FunctionCall {
|
||||
call_type: ByName(name),
|
||||
full_layout,
|
||||
args,
|
||||
..
|
||||
} => {
|
||||
let mut arg_tuples: Vec<BasicValueEnum> = Vec::with_capacity_in(args.len(), env.arena);
|
||||
|
||||
for symbol in args.iter() {
|
||||
arg_tuples.push(load_symbol(env, scope, symbol));
|
||||
}
|
||||
|
||||
call_with_args(
|
||||
env,
|
||||
layout_ids,
|
||||
&full_layout,
|
||||
*name,
|
||||
parent,
|
||||
arg_tuples.into_bump_slice(),
|
||||
)
|
||||
}
|
||||
|
||||
FunctionCall {
|
||||
call_type: ByPointer(name),
|
||||
args,
|
||||
..
|
||||
} => {
|
||||
let sub_expr = load_symbol(env, scope, name);
|
||||
|
||||
let mut arg_vals: Vec<BasicValueEnum> = Vec::with_capacity_in(args.len(), env.arena);
|
||||
|
||||
for arg in args.iter() {
|
||||
arg_vals.push(load_symbol(env, scope, arg));
|
||||
}
|
||||
|
||||
let call = match sub_expr {
|
||||
BasicValueEnum::PointerValue(ptr) => {
|
||||
env.builder.build_call(ptr, arg_vals.as_slice(), "tmp")
|
||||
}
|
||||
non_ptr => {
|
||||
panic!(
|
||||
"Tried to call by pointer, but encountered a non-pointer: {:?}",
|
||||
non_ptr
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
if env.exposed_to_host.contains(name) {
|
||||
// If this is an external-facing function, use the C calling convention.
|
||||
call.set_call_convention(C_CALL_CONV);
|
||||
} else {
|
||||
// If it's an internal-only function, use the fast calling convention.
|
||||
call.set_call_convention(FAST_CALL_CONV);
|
||||
}
|
||||
|
||||
call.try_as_basic_value()
|
||||
.left()
|
||||
.unwrap_or_else(|| panic!("LLVM error: Invalid call by pointer."))
|
||||
}
|
||||
},
|
||||
|
||||
Struct(sorted_fields) => {
|
||||
let ctx = env.context;
|
||||
|
|
|
@ -866,8 +866,7 @@ impl<'a> Call<'a> {
|
|||
.append(alloc.intersperse(it, " "))
|
||||
}
|
||||
Foreign {
|
||||
foreign_symbol: ref foreign_symbol,
|
||||
..
|
||||
ref foreign_symbol, ..
|
||||
} => {
|
||||
let it = arguments.iter().map(|s| symbol_to_doc(alloc, *s));
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue