Files
wasmtime/lib/module/src/backend.rs
Dan Gohman 76db9f022d [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.
2018-04-17 10:52:36 -07:00

98 lines
2.9 KiB
Rust

//! 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;
}