mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 05:49:08 +00:00
add support for getting a function pointer from a function symbol
This commit is contained in:
parent
5a297248e2
commit
c22f33ec8a
3 changed files with 60 additions and 29 deletions
|
@ -522,6 +522,16 @@ impl Assembler<AArch64GeneralReg, AArch64FloatReg> for AArch64Assembler {
|
||||||
todo!("calling functions literal for AArch64");
|
todo!("calling functions literal for AArch64");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn function_pointer(
|
||||||
|
_buf: &mut Vec<'_, u8>,
|
||||||
|
_relocs: &mut Vec<'_, Relocation>,
|
||||||
|
_fn_name: String,
|
||||||
|
_dst: AArch64GeneralReg,
|
||||||
|
) {
|
||||||
|
todo!("calling functions literal for AArch64");
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn imul_reg64_reg64_reg64(
|
fn imul_reg64_reg64_reg64(
|
||||||
buf: &mut Vec<'_, u8>,
|
buf: &mut Vec<'_, u8>,
|
||||||
|
|
|
@ -216,6 +216,13 @@ pub trait Assembler<GeneralReg: RegTrait, FloatReg: RegTrait>: Sized + Copy {
|
||||||
|
|
||||||
fn call(buf: &mut Vec<'_, u8>, relocs: &mut Vec<'_, Relocation>, fn_name: String);
|
fn call(buf: &mut Vec<'_, u8>, relocs: &mut Vec<'_, Relocation>, fn_name: String);
|
||||||
|
|
||||||
|
fn function_pointer(
|
||||||
|
buf: &mut Vec<'_, u8>,
|
||||||
|
relocs: &mut Vec<'_, Relocation>,
|
||||||
|
fn_name: String,
|
||||||
|
dst: GeneralReg,
|
||||||
|
);
|
||||||
|
|
||||||
/// Jumps by an offset of offset bytes unconditionally.
|
/// Jumps by an offset of offset bytes unconditionally.
|
||||||
/// It should always generate the same number of bytes to enable replacement if offset changes.
|
/// It should always generate the same number of bytes to enable replacement if offset changes.
|
||||||
/// It returns the base offset to calculate the jump from (generally the instruction after the jump).
|
/// It returns the base offset to calculate the jump from (generally the instruction after the jump).
|
||||||
|
@ -738,6 +745,12 @@ impl<
|
||||||
(out.into_bump_slice(), offset)
|
(out.into_bump_slice(), offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn build_fn_pointer(&mut self, dst: &Symbol, fn_name: String) {
|
||||||
|
let reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
|
||||||
|
|
||||||
|
ASM::function_pointer(&mut self.buf, &mut self.relocs, fn_name, reg)
|
||||||
|
}
|
||||||
|
|
||||||
fn build_fn_call(
|
fn build_fn_call(
|
||||||
&mut self,
|
&mut self,
|
||||||
dst: &Symbol,
|
dst: &Symbol,
|
||||||
|
@ -1589,8 +1602,7 @@ impl<
|
||||||
.storage_manager
|
.storage_manager
|
||||||
.claim_stack_area(dst, self.layout_interner.stack_size(*ret_layout));
|
.claim_stack_area(dst, self.layout_interner.stack_size(*ret_layout));
|
||||||
|
|
||||||
let lowlevel_args = bumpalo::vec![
|
let lowlevel_args = [
|
||||||
in self.env.arena;
|
|
||||||
capacity,
|
capacity,
|
||||||
// alignment
|
// alignment
|
||||||
Symbol::DEV_TMP,
|
Symbol::DEV_TMP,
|
||||||
|
@ -1727,13 +1739,12 @@ impl<
|
||||||
.storage_manager
|
.storage_manager
|
||||||
.claim_stack_area(dst, self.layout_interner.stack_size(*ret_layout));
|
.claim_stack_area(dst, self.layout_interner.stack_size(*ret_layout));
|
||||||
|
|
||||||
let lowlevel_args = bumpalo::vec![
|
let lowlevel_args = [
|
||||||
in self.env.arena;
|
|
||||||
list,
|
list,
|
||||||
// element
|
// element
|
||||||
Symbol::DEV_TMP,
|
Symbol::DEV_TMP,
|
||||||
// element_width
|
// element_width
|
||||||
Symbol::DEV_TMP2
|
Symbol::DEV_TMP2,
|
||||||
];
|
];
|
||||||
let lowlevel_arg_layouts = [list_layout, Layout::U64, Layout::U64];
|
let lowlevel_arg_layouts = [list_layout, Layout::U64, Layout::U64];
|
||||||
|
|
||||||
|
@ -2004,8 +2015,7 @@ impl<
|
||||||
.storage_manager
|
.storage_manager
|
||||||
.claim_stack_area(dst, self.layout_interner.stack_size(*ret_layout));
|
.claim_stack_area(dst, self.layout_interner.stack_size(*ret_layout));
|
||||||
|
|
||||||
let lowlevel_args = bumpalo::vec![
|
let lowlevel_args = [
|
||||||
in self.env.arena;
|
|
||||||
list,
|
list,
|
||||||
// alignment
|
// alignment
|
||||||
Symbol::DEV_TMP,
|
Symbol::DEV_TMP,
|
||||||
|
@ -2195,27 +2205,16 @@ impl<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expr_box(&mut self, sym: Symbol, value: Symbol, element_layout: InLayout<'a>) {
|
fn build_ptr_write(
|
||||||
let element_width_symbol = Symbol::DEV_TMP;
|
&mut self,
|
||||||
self.load_layout_stack_size(element_layout, element_width_symbol);
|
sym: Symbol,
|
||||||
|
ptr: Symbol,
|
||||||
// Load allocation alignment (u32)
|
value: Symbol,
|
||||||
let element_alignment_symbol = Symbol::DEV_TMP2;
|
element_layout: InLayout<'a>,
|
||||||
self.load_layout_alignment(Layout::U32, element_alignment_symbol);
|
) {
|
||||||
|
|
||||||
self.allocate_with_refcount(
|
|
||||||
Symbol::DEV_TMP3,
|
|
||||||
element_width_symbol,
|
|
||||||
element_alignment_symbol,
|
|
||||||
);
|
|
||||||
|
|
||||||
self.free_symbol(&element_width_symbol);
|
|
||||||
self.free_symbol(&element_alignment_symbol);
|
|
||||||
|
|
||||||
// Fill pointer with the value
|
|
||||||
let ptr_reg = self
|
let ptr_reg = self
|
||||||
.storage_manager
|
.storage_manager
|
||||||
.load_to_general_reg(&mut self.buf, &Symbol::DEV_TMP3);
|
.load_to_general_reg(&mut self.buf, &ptr);
|
||||||
|
|
||||||
let element_width = self.layout_interner.stack_size(element_layout) as u64;
|
let element_width = self.layout_interner.stack_size(element_layout) as u64;
|
||||||
let element_offset = 0;
|
let element_offset = 0;
|
||||||
|
@ -2237,6 +2236,26 @@ impl<
|
||||||
// box is just a pointer on the stack
|
// box is just a pointer on the stack
|
||||||
let base_offset = self.storage_manager.claim_stack_area(&sym, 8);
|
let base_offset = self.storage_manager.claim_stack_area(&sym, 8);
|
||||||
ASM::mov_base32_reg64(&mut self.buf, base_offset, ptr_reg);
|
ASM::mov_base32_reg64(&mut self.buf, base_offset, ptr_reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expr_box(&mut self, sym: Symbol, value: Symbol, element_layout: InLayout<'a>) {
|
||||||
|
let element_width_symbol = Symbol::DEV_TMP;
|
||||||
|
self.load_layout_stack_size(element_layout, element_width_symbol);
|
||||||
|
|
||||||
|
// Load allocation alignment (u32)
|
||||||
|
let element_alignment_symbol = Symbol::DEV_TMP2;
|
||||||
|
self.load_layout_alignment(Layout::U32, element_alignment_symbol);
|
||||||
|
|
||||||
|
self.allocate_with_refcount(
|
||||||
|
Symbol::DEV_TMP3,
|
||||||
|
element_width_symbol,
|
||||||
|
element_alignment_symbol,
|
||||||
|
);
|
||||||
|
|
||||||
|
self.free_symbol(&element_width_symbol);
|
||||||
|
self.free_symbol(&element_alignment_symbol);
|
||||||
|
|
||||||
|
self.build_ptr_write(sym, Symbol::DEV_TMP3, value, element_layout);
|
||||||
|
|
||||||
self.free_symbol(&Symbol::DEV_TMP3);
|
self.free_symbol(&Symbol::DEV_TMP3);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1184,6 +1184,8 @@ trait Backend<'a> {
|
||||||
ret_layout: &InLayout<'a>,
|
ret_layout: &InLayout<'a>,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
fn build_fn_pointer(&mut self, dst: &Symbol, fn_name: String);
|
||||||
|
|
||||||
/// Move a returned value into `dst`
|
/// Move a returned value into `dst`
|
||||||
fn move_return_value(&mut self, dst: &Symbol, ret_layout: &InLayout<'a>);
|
fn move_return_value(&mut self, dst: &Symbol, ret_layout: &InLayout<'a>);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue