mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 14:54:47 +00:00
Generate roc_alloc etc in dev_num tests
This commit is contained in:
parent
0b3715ebee
commit
595c704e88
4 changed files with 90 additions and 0 deletions
|
@ -341,6 +341,16 @@ impl<
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Used for generating wrappers for malloc/realloc/free
|
||||
fn build_wrapped_jmp(&mut self) -> Result<(&'a [u8], u64), String> {
|
||||
let mut out = bumpalo::vec![in self.env.arena];
|
||||
|
||||
ASM::jmp_imm32(&mut out, 0);
|
||||
|
||||
let offset = out.len() as u64 - 4;
|
||||
Ok((out.into_bump_slice(), offset))
|
||||
}
|
||||
|
||||
fn build_fn_call(
|
||||
&mut self,
|
||||
dst: &Symbol,
|
||||
|
|
|
@ -22,6 +22,7 @@ pub struct Env<'a> {
|
|||
pub interns: Interns,
|
||||
pub exposed_to_host: MutSet<Symbol>,
|
||||
pub lazy_literals: bool,
|
||||
pub generate_allocators: bool,
|
||||
}
|
||||
|
||||
// These relocations likely will need a length.
|
||||
|
@ -67,6 +68,9 @@ where
|
|||
// The backend should track these args so it can use them as needed.
|
||||
fn load_args(&mut self, args: &'a [(Layout<'a>, Symbol)]) -> Result<(), String>;
|
||||
|
||||
/// Used for generating wrappers for malloc/realloc/free
|
||||
fn build_wrapped_jmp(&mut self) -> Result<(&'a [u8], u64), String>;
|
||||
|
||||
/// build_proc creates a procedure and outputs it to the wrapped object writer.
|
||||
fn build_proc(&mut self, proc: Proc<'a>) -> Result<(&'a [u8], &[Relocation]), String> {
|
||||
self.reset();
|
||||
|
|
|
@ -89,6 +89,60 @@ pub fn build_module<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
fn generate_wrapper<'a, B: Backend<'a>>(
|
||||
backend: &mut B,
|
||||
output: &mut Object,
|
||||
wrapper_name: String,
|
||||
wraps: String,
|
||||
) -> Result<(), String> {
|
||||
let text_section = output.section_id(StandardSection::Text);
|
||||
let proc_symbol = Symbol {
|
||||
name: wrapper_name.as_bytes().to_vec(),
|
||||
value: 0,
|
||||
size: 0,
|
||||
kind: SymbolKind::Text,
|
||||
scope: SymbolScope::Dynamic,
|
||||
weak: false,
|
||||
section: SymbolSection::Section(text_section),
|
||||
flags: SymbolFlags::None,
|
||||
};
|
||||
let proc_id = output.add_symbol(proc_symbol);
|
||||
let (proc_data, offset) = backend.build_wrapped_jmp()?;
|
||||
let proc_offset = output.add_symbol_data(proc_id, text_section, proc_data, 16);
|
||||
|
||||
let name = wraps.as_str().as_bytes();
|
||||
// If the symbol is an undefined zig builtin, we need to add it here.
|
||||
let symbol = Symbol {
|
||||
name: name.to_vec(),
|
||||
value: 0,
|
||||
size: 0,
|
||||
kind: SymbolKind::Text,
|
||||
scope: SymbolScope::Linkage,
|
||||
weak: false,
|
||||
section: SymbolSection::Undefined,
|
||||
flags: SymbolFlags::None,
|
||||
};
|
||||
output.add_symbol(symbol);
|
||||
if let Some(sym_id) = output.symbol_id(name) {
|
||||
let reloc = write::Relocation {
|
||||
offset: offset + proc_offset,
|
||||
size: 32,
|
||||
kind: RelocationKind::PltRelative,
|
||||
encoding: RelocationEncoding::X86Branch,
|
||||
symbol: sym_id,
|
||||
addend: -4,
|
||||
};
|
||||
|
||||
output
|
||||
.add_relocation(text_section, reloc)
|
||||
.map_err(|e| format!("{:?}", e))?;
|
||||
|
||||
Ok(())
|
||||
} else {
|
||||
Err(format!("failed to find fn symbol for {:?}", wraps))
|
||||
}
|
||||
}
|
||||
|
||||
fn build_object<'a, B: Backend<'a>>(
|
||||
env: &'a Env,
|
||||
procedures: MutMap<(symbol::Symbol, Layout<'a>), Proc<'a>>,
|
||||
|
@ -107,6 +161,27 @@ fn build_object<'a, B: Backend<'a>>(
|
|||
);
|
||||
*/
|
||||
|
||||
if env.generate_allocators {
|
||||
generate_wrapper(
|
||||
&mut backend,
|
||||
&mut output,
|
||||
"roc_alloc".into(),
|
||||
"malloc".into(),
|
||||
)?;
|
||||
generate_wrapper(
|
||||
&mut backend,
|
||||
&mut output,
|
||||
"roc_realloc".into(),
|
||||
"realloc".into(),
|
||||
)?;
|
||||
generate_wrapper(
|
||||
&mut backend,
|
||||
&mut output,
|
||||
"roc_dealloc".into(),
|
||||
"free".into(),
|
||||
)?;
|
||||
}
|
||||
|
||||
// Setup layout_ids for procedure calls.
|
||||
let mut layout_ids = roc_mono::layout::LayoutIds::default();
|
||||
let mut procs = Vec::with_capacity_in(procedures.len(), env.arena);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue