mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 21:39:07 +00:00
Make sure to stacksave on x86
This commit is contained in:
parent
94f1e399e3
commit
dad10af0f9
1 changed files with 22 additions and 1 deletions
|
@ -546,6 +546,13 @@ fn add_intrinsics<'ctx>(ctx: &'ctx Context, module: &Module<'ctx>) {
|
||||||
i8_ptr_type.fn_type(&[i32_type.into()], false),
|
i8_ptr_type.fn_type(&[i32_type.into()], false),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
add_intrinsic(
|
||||||
|
ctx,
|
||||||
|
module,
|
||||||
|
LLVM_STACK_SAVE,
|
||||||
|
i8_ptr_type.fn_type(&[], false),
|
||||||
|
);
|
||||||
|
|
||||||
add_float_intrinsic(ctx, module, &LLVM_LOG, |t| t.fn_type(&[t.into()], false));
|
add_float_intrinsic(ctx, module, &LLVM_LOG, |t| t.fn_type(&[t.into()], false));
|
||||||
add_float_intrinsic(ctx, module, &LLVM_POW, |t| {
|
add_float_intrinsic(ctx, module, &LLVM_POW, |t| {
|
||||||
t.fn_type(&[t.into(), t.into()], false)
|
t.fn_type(&[t.into(), t.into()], false)
|
||||||
|
@ -599,6 +606,7 @@ static LLVM_MEMSET_I64: &str = "llvm.memset.p0i8.i64";
|
||||||
static LLVM_MEMSET_I32: &str = "llvm.memset.p0i8.i32";
|
static LLVM_MEMSET_I32: &str = "llvm.memset.p0i8.i32";
|
||||||
|
|
||||||
static LLVM_FRAME_ADDRESS: &str = "llvm.frameaddress.p0i8";
|
static LLVM_FRAME_ADDRESS: &str = "llvm.frameaddress.p0i8";
|
||||||
|
static LLVM_STACK_SAVE: &str = "llvm.stacksave";
|
||||||
|
|
||||||
static LLVM_SETJMP: &str = "llvm.eh.sjlj.setjmp";
|
static LLVM_SETJMP: &str = "llvm.eh.sjlj.setjmp";
|
||||||
pub static LLVM_LONGJMP: &str = "llvm.eh.sjlj.longjmp";
|
pub static LLVM_LONGJMP: &str = "llvm.eh.sjlj.longjmp";
|
||||||
|
@ -3689,6 +3697,8 @@ pub fn build_setjmp_call<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> BasicValu
|
||||||
call_bitcode_fn(env, &[jmp_buf.into()], bitcode::UTILS_SETJMP)
|
call_bitcode_fn(env, &[jmp_buf.into()], bitcode::UTILS_SETJMP)
|
||||||
} else {
|
} else {
|
||||||
// Anywhere else, use the LLVM intrinsic.
|
// Anywhere else, use the LLVM intrinsic.
|
||||||
|
// https://llvm.org/docs/ExceptionHandling.html#llvm-eh-sjlj-setjmp
|
||||||
|
|
||||||
let jmp_buf_i8p_arr = env
|
let jmp_buf_i8p_arr = env
|
||||||
.builder
|
.builder
|
||||||
.build_bitcast(
|
.build_bitcast(
|
||||||
|
@ -3701,6 +3711,7 @@ pub fn build_setjmp_call<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> BasicValu
|
||||||
"jmp_buf [5 x i8*]",
|
"jmp_buf [5 x i8*]",
|
||||||
)
|
)
|
||||||
.into_pointer_value();
|
.into_pointer_value();
|
||||||
|
|
||||||
// LLVM asks us to please store the frame pointer in the first word.
|
// LLVM asks us to please store the frame pointer in the first word.
|
||||||
let frame_address = env.call_intrinsic(
|
let frame_address = env.call_intrinsic(
|
||||||
LLVM_FRAME_ADDRESS,
|
LLVM_FRAME_ADDRESS,
|
||||||
|
@ -3716,9 +3727,19 @@ pub fn build_setjmp_call<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> BasicValu
|
||||||
"frame address index",
|
"frame address index",
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
env.builder.build_store(fa, frame_address);
|
env.builder.build_store(fa, frame_address);
|
||||||
|
|
||||||
|
// LLVM says that the target implementation of the setjmp intrinsic will put the
|
||||||
|
// destination address at index 1, and that the remaining three words are for ad-hoc target
|
||||||
|
// usage. But for whatever reason, on x86, it appears we need a stacksave in those words.
|
||||||
|
let ss_index = env.context.i32_type().const_int(2, false);
|
||||||
|
let ss = unsafe {
|
||||||
|
env.builder
|
||||||
|
.build_in_bounds_gep(jmp_buf_i8p_arr, &[zero, ss_index], "name")
|
||||||
|
};
|
||||||
|
let stack_save = env.call_intrinsic(LLVM_STACK_SAVE, &[]);
|
||||||
|
env.builder.build_store(ss, stack_save);
|
||||||
|
|
||||||
let jmp_buf_i8p = env.builder.build_bitcast(
|
let jmp_buf_i8p = env.builder.build_bitcast(
|
||||||
jmp_buf,
|
jmp_buf,
|
||||||
env.context.i8_type().ptr_type(AddressSpace::Generic),
|
env.context.i8_type().ptr_type(AddressSpace::Generic),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue