This commit extracts the two implementations of `Compiler` into two separate crates, `wasmtime-cranelfit` and `wasmtime-lightbeam`. The `wasmtime-jit` crate then depends on these two and instantiates them appropriately. The goal here is to start reducing the weight of the `wasmtime-environ` crate, which currently serves as a common set of types between all `wasmtime-*` crates. Long-term I'd like to remove the dependency on Cranelift from `wasmtime-environ`, but that's going to take a lot more work. In the meantime I figure it's a good way to get started by separating out the lightbeam/cranelift function compilers from the `wasmtime-environ` crate. We can continue to iterate on moving things out in the future, too.
69 lines
2.3 KiB
Rust
69 lines
2.3 KiB
Rust
use anyhow::{bail, Context as _, Result};
|
|
use object::write::Object;
|
|
use target_lexicon::Triple;
|
|
use wasmtime::Strategy;
|
|
use wasmtime_environ::{settings, settings::Configurable, ModuleEnvironment, Tunables};
|
|
use wasmtime_jit::{native, Compiler};
|
|
|
|
/// Creates object file from binary wasm data.
|
|
pub fn compile_to_obj(
|
|
wasm: &[u8],
|
|
target: Option<&Triple>,
|
|
strategy: Strategy,
|
|
enable_simd: bool,
|
|
opt_level: wasmtime::OptLevel,
|
|
debug_info: bool,
|
|
) -> Result<Object> {
|
|
let isa_builder = match target {
|
|
Some(target) => native::lookup(target.clone())?,
|
|
None => native::builder(),
|
|
};
|
|
let mut flag_builder = settings::builder();
|
|
|
|
// There are two possible traps for division, and this way
|
|
// we get the proper one if code traps.
|
|
flag_builder.enable("avoid_div_traps").unwrap();
|
|
|
|
if enable_simd {
|
|
flag_builder.enable("enable_simd").unwrap();
|
|
}
|
|
|
|
match opt_level {
|
|
wasmtime::OptLevel::None => {}
|
|
wasmtime::OptLevel::Speed => {
|
|
flag_builder.set("opt_level", "speed").unwrap();
|
|
}
|
|
wasmtime::OptLevel::SpeedAndSize => {
|
|
flag_builder.set("opt_level", "speed_and_size").unwrap();
|
|
}
|
|
other => bail!("unknown optimization level {:?}", other),
|
|
}
|
|
|
|
let isa = isa_builder.finish(settings::Flags::new(flag_builder));
|
|
|
|
// TODO: Expose the tunables as command-line flags.
|
|
let mut tunables = Tunables::default();
|
|
tunables.debug_info = debug_info;
|
|
|
|
let compiler = Compiler::new(
|
|
isa,
|
|
match strategy {
|
|
Strategy::Auto => wasmtime_jit::CompilationStrategy::Auto,
|
|
Strategy::Cranelift => wasmtime_jit::CompilationStrategy::Cranelift,
|
|
#[cfg(feature = "lightbeam")]
|
|
Strategy::Lightbeam => wasmtime_jit::CompilationStrategy::Lightbeam,
|
|
#[cfg(not(feature = "lightbeam"))]
|
|
Strategy::Lightbeam => bail!("lightbeam support not enabled"),
|
|
s => bail!("unknown compilation strategy {:?}", s),
|
|
},
|
|
tunables.clone(),
|
|
);
|
|
|
|
let environ = ModuleEnvironment::new(compiler.isa().frontend_config(), &tunables);
|
|
let translation = environ
|
|
.translate(wasm)
|
|
.context("failed to translate module")?;
|
|
let compilation = compiler.compile(&translation)?;
|
|
Ok(compilation.obj)
|
|
}
|