[WIP] Module API (#294)
* Initial skeleton. * Add basic faerie support. This adds enough functionality to enable simple .o file writing through faerie. This included adding the functionality to Module to support RelocSink implementations. * Add basic SimpleJIT support. This adds enough functionality to enable a simple program to be jitted and executed. * Make declare_func_in_func take a Function instead of a Context. It only needs the Function, and sometimes it's useful to call it from places that don't have a full Context. * Temporarily disable local and exported global variables in the Faerie backend. Faerie assumes these variables use pc-relative offset instructions, and Cretonne is not yet emitting those instructions. * FaerieBackend depends on PIC. Faerie itself only supports PIC objects for now, so add an assert to Cretonne to check that it's using a PIC target flag. * SimpleJIT support for data objects. * Preliminary faerie support for data objects. * Support for data objects in faerie using the new colocated flag. * Unit tests for DataContext and friends. * Add a Module::consume() function. This consumes the Module and returns the contained Backend, so that users can call Backend-specific functions with it. For example, the Faerie backend has functions to write an object file. * Update the new crates to version 0.4.4. * Make FaerieBackend own its TargetIsa. This simplifies its interface, as it eliminates a lifetime parameter. While we may eventually want to look into allowing multiple clients to share a TargetIsa, it isn't worth the complexity for FaerieBackend right now. * Don't try to protect faerie from multiple declarations. Let faerie decide for itself whether it wants to consider two declarations to be compatible. * Use debug_assert_eq rather than debug_assert with ==. * Fix FaerieRelocSink's reloc_external to handle data object names. * Relax the asserts in get_function_definition and get_data_definition. These functions don't require definable symbols, but they do require that definable symbols be defined. This is needed for the simplejit backend. * Add a function to the faerie backend to retrieve the artifact name. * Sync up with cretonne changes.
This commit is contained in:
97
lib/module/src/backend.rs
Normal file
97
lib/module/src/backend.rs
Normal file
@@ -0,0 +1,97 @@
|
||||
//! Defines the `Backend` trait.
|
||||
|
||||
use DataContext;
|
||||
use Linkage;
|
||||
use ModuleNamespace;
|
||||
use cretonne_codegen::Context;
|
||||
use cretonne_codegen::isa::TargetIsa;
|
||||
use cretonne_codegen::result::CtonError;
|
||||
use cretonne_codegen::{binemit, ir};
|
||||
use std::marker;
|
||||
|
||||
/// A `Backend` implements the functionality needed to support a `Module`.
|
||||
pub trait Backend
|
||||
where
|
||||
Self: marker::Sized,
|
||||
{
|
||||
/// The results of compiling a function.
|
||||
type CompiledFunction;
|
||||
|
||||
/// The results of "compiling" a data object.
|
||||
type CompiledData;
|
||||
|
||||
/// The completed output artifact for a function, if this is meaningful for
|
||||
/// the Backend.
|
||||
type FinalizedFunction;
|
||||
|
||||
/// The completed output artifact for a data object, if this is meaningful for
|
||||
/// the Backend.
|
||||
type FinalizedData;
|
||||
|
||||
/// Return the `TargetIsa` to compile for.
|
||||
fn isa(&self) -> &TargetIsa;
|
||||
|
||||
/// Declare a function.
|
||||
fn declare_function(&mut self, name: &str, linkage: Linkage);
|
||||
|
||||
/// Declare a data object.
|
||||
fn declare_data(&mut self, name: &str, linkage: Linkage, writable: bool);
|
||||
|
||||
/// Define a function, producing the function body from the given `Context`.
|
||||
///
|
||||
/// Functions must be declared before being defined.
|
||||
fn define_function(
|
||||
&mut self,
|
||||
name: &str,
|
||||
ctx: &Context,
|
||||
namespace: &ModuleNamespace<Self>,
|
||||
code_size: u32,
|
||||
) -> Result<Self::CompiledFunction, CtonError>;
|
||||
|
||||
/// Define a zero-initialized data object of the given size.
|
||||
///
|
||||
/// Data objects must be declared before being defined.
|
||||
///
|
||||
/// TODO: Is CtonError the right error code here?
|
||||
fn define_data(
|
||||
&mut self,
|
||||
name: &str,
|
||||
data_ctx: &DataContext,
|
||||
namespace: &ModuleNamespace<Self>,
|
||||
) -> Result<Self::CompiledData, CtonError>;
|
||||
|
||||
/// Write the address of `what` into the data for `data` at `offset`. `data` must refer to a
|
||||
/// defined data object.
|
||||
fn write_data_funcaddr(
|
||||
&mut self,
|
||||
data: &mut Self::CompiledData,
|
||||
offset: usize,
|
||||
what: ir::FuncRef,
|
||||
);
|
||||
|
||||
/// Write the address of `what` plus `addend` into the data for `data` at `offset`. `data` must
|
||||
/// refer to a defined data object.
|
||||
fn write_data_dataaddr(
|
||||
&mut self,
|
||||
data: &mut Self::CompiledData,
|
||||
offset: usize,
|
||||
what: ir::GlobalVar,
|
||||
addend: binemit::Addend,
|
||||
);
|
||||
|
||||
/// Perform all outstanding relocations on the given function. This requires all `Local`
|
||||
/// and `Export` entities referenced to be defined.
|
||||
fn finalize_function(
|
||||
&mut self,
|
||||
func: &Self::CompiledFunction,
|
||||
namespace: &ModuleNamespace<Self>,
|
||||
) -> Self::FinalizedFunction;
|
||||
|
||||
/// Perform all outstanding relocations on the given data object. This requires all
|
||||
/// `Local` and `Export` entities referenced to be defined.
|
||||
fn finalize_data(
|
||||
&mut self,
|
||||
data: &Self::CompiledData,
|
||||
namespace: &ModuleNamespace<Self>,
|
||||
) -> Self::FinalizedData;
|
||||
}
|
||||
Reference in New Issue
Block a user