Remove dependency on TargetIsa from Wasmtime crates (#3178)
This commit started off by deleting the `cranelift_codegen::settings` reexport in the `wasmtime-environ` crate and then basically played whack-a-mole until everything compiled again. The main result of this is that the `wasmtime-*` family of crates have generally less of a dependency on the `TargetIsa` trait and type from Cranelift. While the dependency isn't entirely severed yet this is at least a significant start. This commit is intended to be largely refactorings, no functional changes are intended here. The refactorings are: * A `CompilerBuilder` trait has been added to `wasmtime_environ` which server as an abstraction used to create compilers and configure them in a uniform fashion. The `wasmtime::Config` type now uses this instead of cranelift-specific settings. The `wasmtime-jit` crate exports the ability to create a compiler builder from a `CompilationStrategy`, which only works for Cranelift right now. In a cranelift-less build of Wasmtime this is expected to return a trait object that fails all requests to compile. * The `Compiler` trait in the `wasmtime_environ` crate has been souped up with a number of methods that Wasmtime and other crates needed. * The `wasmtime-debug` crate is now moved entirely behind the `wasmtime-cranelift` crate. * The `wasmtime-cranelift` crate is now only depended on by the `wasmtime-jit` crate. * Wasm types in `cranelift-wasm` no longer contain their IR type, instead they only contain the `WasmType`. This is required to get everything to align correctly but will also be required in a future refactoring where the types used by `cranelift-wasm` will be extracted to a separate crate. * I moved around a fair bit of code in `wasmtime-cranelift`. * Some gdb-specific jit-specific code has moved from `wasmtime-debug` to `wasmtime-jit`.
This commit is contained in:
@@ -13,7 +13,6 @@ edition = "2018"
|
||||
rustdoc-args = ["--cfg", "nightlydoc"]
|
||||
|
||||
[dependencies]
|
||||
cranelift-native = { path = '../../cranelift/native', version = '0.76.0' }
|
||||
wasmtime-runtime = { path = "../runtime", version = "0.29.0" }
|
||||
wasmtime-environ = { path = "../environ", version = "0.29.0" }
|
||||
wasmtime-jit = { path = "../jit", version = "0.29.0" }
|
||||
|
||||
@@ -10,8 +10,7 @@ use std::sync::Arc;
|
||||
use wasmparser::WasmFeatures;
|
||||
#[cfg(feature = "cache")]
|
||||
use wasmtime_cache::CacheConfig;
|
||||
use wasmtime_environ::settings::{self, Configurable, SetError};
|
||||
use wasmtime_environ::{isa, isa::TargetIsa, Tunables};
|
||||
use wasmtime_environ::{CompilerBuilder, Tunables};
|
||||
use wasmtime_jit::{CompilationStrategy, Compiler};
|
||||
use wasmtime_profiling::{JitDumpAgent, NullProfilerAgent, ProfilingAgent, VTuneAgent};
|
||||
use wasmtime_runtime::{
|
||||
@@ -337,12 +336,9 @@ impl Default for InstanceAllocationStrategy {
|
||||
///
|
||||
/// This structure exposed a builder-like interface and is primarily consumed by
|
||||
/// [`Engine::new()`](crate::Engine::new)
|
||||
#[derive(Clone)]
|
||||
pub struct Config {
|
||||
pub(crate) flags: settings::Builder,
|
||||
pub(crate) isa_flags: isa::Builder,
|
||||
pub(crate) compiler: Box<dyn CompilerBuilder>,
|
||||
pub(crate) tunables: Tunables,
|
||||
pub(crate) strategy: CompilationStrategy,
|
||||
#[cfg(feature = "cache")]
|
||||
pub(crate) cache_config: CacheConfig,
|
||||
pub(crate) profiler: Arc<dyn ProfilingAgent>,
|
||||
@@ -362,24 +358,9 @@ impl Config {
|
||||
/// Creates a new configuration object with the default configuration
|
||||
/// specified.
|
||||
pub fn new() -> Self {
|
||||
let mut flags = settings::builder();
|
||||
|
||||
// There are two possible traps for division, and this way
|
||||
// we get the proper one if code traps.
|
||||
flags
|
||||
.enable("avoid_div_traps")
|
||||
.expect("should be valid flag");
|
||||
|
||||
// We don't use probestack as a stack limit mechanism
|
||||
flags
|
||||
.set("enable_probestack", "false")
|
||||
.expect("should be valid flag");
|
||||
|
||||
let mut ret = Self {
|
||||
tunables: Tunables::default(),
|
||||
flags,
|
||||
isa_flags: cranelift_native::builder().expect("host machine is not a supported target"),
|
||||
strategy: CompilationStrategy::Auto,
|
||||
compiler: Compiler::builder(CompilationStrategy::Auto),
|
||||
#[cfg(feature = "cache")]
|
||||
cache_config: CacheConfig::new_cache_disabled(),
|
||||
profiler: Arc::new(NullProfilerAgent),
|
||||
@@ -417,9 +398,8 @@ impl Config {
|
||||
/// This method will error if the given target triple is not supported.
|
||||
pub fn target(&mut self, target: &str) -> Result<&mut Self> {
|
||||
use std::str::FromStr;
|
||||
self.isa_flags = wasmtime_environ::isa::lookup(
|
||||
target_lexicon::Triple::from_str(target).map_err(|e| anyhow::anyhow!(e))?,
|
||||
)?;
|
||||
self.compiler
|
||||
.target(target_lexicon::Triple::from_str(target).map_err(|e| anyhow::anyhow!(e))?)?;
|
||||
|
||||
Ok(self)
|
||||
}
|
||||
@@ -675,7 +655,7 @@ impl Config {
|
||||
pub fn wasm_reference_types(&mut self, enable: bool) -> &mut Self {
|
||||
self.features.reference_types = enable;
|
||||
|
||||
self.flags
|
||||
self.compiler
|
||||
.set("enable_safepoints", if enable { "true" } else { "false" })
|
||||
.unwrap();
|
||||
|
||||
@@ -710,7 +690,7 @@ impl Config {
|
||||
pub fn wasm_simd(&mut self, enable: bool) -> &mut Self {
|
||||
self.features.simd = enable;
|
||||
let val = if enable { "true" } else { "false" };
|
||||
self.flags
|
||||
self.compiler
|
||||
.set("enable_simd", val)
|
||||
.expect("should be valid flag");
|
||||
self
|
||||
@@ -801,7 +781,7 @@ impl Config {
|
||||
/// itself to be set, but if they're not set and the strategy is specified
|
||||
/// here then an error will be returned.
|
||||
pub fn strategy(&mut self, strategy: Strategy) -> Result<&mut Self> {
|
||||
self.strategy = match strategy {
|
||||
let strategy = match strategy {
|
||||
Strategy::Auto => CompilationStrategy::Auto,
|
||||
Strategy::Cranelift => CompilationStrategy::Cranelift,
|
||||
#[cfg(feature = "lightbeam")]
|
||||
@@ -811,6 +791,7 @@ impl Config {
|
||||
anyhow::bail!("lightbeam compilation strategy wasn't enabled at compile time");
|
||||
}
|
||||
};
|
||||
self.compiler = Compiler::builder(strategy);
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
@@ -837,7 +818,7 @@ impl Config {
|
||||
/// The default value for this is `false`
|
||||
pub fn cranelift_debug_verifier(&mut self, enable: bool) -> &mut Self {
|
||||
let val = if enable { "true" } else { "false" };
|
||||
self.flags
|
||||
self.compiler
|
||||
.set("enable_verifier", val)
|
||||
.expect("should be valid flag");
|
||||
self
|
||||
@@ -856,7 +837,7 @@ impl Config {
|
||||
OptLevel::Speed => "speed",
|
||||
OptLevel::SpeedAndSize => "speed_and_size",
|
||||
};
|
||||
self.flags
|
||||
self.compiler
|
||||
.set("opt_level", val)
|
||||
.expect("should be valid flag");
|
||||
self
|
||||
@@ -872,7 +853,7 @@ impl Config {
|
||||
/// The default value for this is `false`
|
||||
pub fn cranelift_nan_canonicalization(&mut self, enable: bool) -> &mut Self {
|
||||
let val = if enable { "true" } else { "false" };
|
||||
self.flags
|
||||
self.compiler
|
||||
.set("enable_nan_canonicalization", val)
|
||||
.expect("should be valid flag");
|
||||
self
|
||||
@@ -893,15 +874,7 @@ impl Config {
|
||||
///
|
||||
/// This method can fail if the flag's name does not exist.
|
||||
pub unsafe fn cranelift_flag_enable(&mut self, flag: &str) -> Result<&mut Self> {
|
||||
if let Err(err) = self.flags.enable(flag) {
|
||||
match err {
|
||||
SetError::BadName(_) => {
|
||||
// Try the target-specific flags.
|
||||
self.isa_flags.enable(flag)?;
|
||||
}
|
||||
_ => bail!(err),
|
||||
}
|
||||
}
|
||||
self.compiler.enable(flag)?;
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
@@ -919,15 +892,7 @@ impl Config {
|
||||
/// This method can fail if the flag's name does not exist, or the value is not appropriate for
|
||||
/// the flag type.
|
||||
pub unsafe fn cranelift_flag_set(&mut self, name: &str, value: &str) -> Result<&mut Self> {
|
||||
if let Err(err) = self.flags.set(name, value) {
|
||||
match err {
|
||||
SetError::BadName(_) => {
|
||||
// Try the target-specific flags.
|
||||
self.isa_flags.set(name, value)?;
|
||||
}
|
||||
_ => bail!(err),
|
||||
}
|
||||
}
|
||||
self.compiler.set(name, value)?;
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
@@ -1238,25 +1203,11 @@ impl Config {
|
||||
self
|
||||
}
|
||||
|
||||
pub(crate) fn target_isa(&self) -> Box<dyn TargetIsa> {
|
||||
self.isa_flags
|
||||
.clone()
|
||||
.finish(settings::Flags::new(self.flags.clone()))
|
||||
}
|
||||
|
||||
pub(crate) fn target_isa_with_reference_types(&self) -> Box<dyn TargetIsa> {
|
||||
let mut flags = self.flags.clone();
|
||||
flags.set("enable_safepoints", "true").unwrap();
|
||||
self.isa_flags.clone().finish(settings::Flags::new(flags))
|
||||
}
|
||||
|
||||
pub(crate) fn build_compiler(&self, allocator: &dyn InstanceAllocator) -> Compiler {
|
||||
let isa = self.target_isa();
|
||||
let mut tunables = self.tunables.clone();
|
||||
allocator.adjust_tunables(&mut tunables);
|
||||
Compiler::new(
|
||||
isa,
|
||||
self.strategy,
|
||||
&*self.compiler,
|
||||
tunables,
|
||||
self.features,
|
||||
self.parallel_compilation,
|
||||
@@ -1304,12 +1255,33 @@ impl Default for Config {
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for Config {
|
||||
fn clone(&self) -> Config {
|
||||
Config {
|
||||
compiler: self.compiler.clone(),
|
||||
tunables: self.tunables.clone(),
|
||||
#[cfg(feature = "cache")]
|
||||
cache_config: self.cache_config.clone(),
|
||||
profiler: self.profiler.clone(),
|
||||
features: self.features.clone(),
|
||||
mem_creator: self.mem_creator.clone(),
|
||||
allocation_strategy: self.allocation_strategy.clone(),
|
||||
max_wasm_stack: self.max_wasm_stack,
|
||||
wasm_backtrace_details_env_used: self.wasm_backtrace_details_env_used,
|
||||
async_support: self.async_support,
|
||||
#[cfg(feature = "async")]
|
||||
async_stack_size: self.async_stack_size,
|
||||
deserialize_check_wasmtime_version: self.deserialize_check_wasmtime_version,
|
||||
parallel_compilation: self.parallel_compilation,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Config {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("Config")
|
||||
.field("debug_info", &self.tunables.generate_native_debuginfo)
|
||||
.field("parse_wasm_debuginfo", &self.tunables.parse_wasm_debuginfo)
|
||||
.field("strategy", &self.strategy)
|
||||
.field("wasm_threads", &self.features.threads)
|
||||
.field("wasm_reference_types", &self.features.reference_types)
|
||||
.field("wasm_bulk_memory", &self.features.bulk_memory)
|
||||
@@ -1333,10 +1305,8 @@ impl fmt::Debug for Config {
|
||||
"guard_before_linear_memory",
|
||||
&self.tunables.guard_before_linear_memory,
|
||||
)
|
||||
.field(
|
||||
"flags",
|
||||
&settings::Flags::new(self.flags.clone()).to_string(),
|
||||
)
|
||||
.field("parallel_compilation", &self.parallel_compilation)
|
||||
.field("compiler", &self.compiler)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,7 +279,7 @@ impl Module {
|
||||
/// ```
|
||||
pub fn from_binary(engine: &Engine, binary: &[u8]) -> Result<Module> {
|
||||
// Check to see that the config's target matches the host
|
||||
let target = engine.config().isa_flags.triple();
|
||||
let target = engine.compiler().compiler().triple();
|
||||
if *target != target_lexicon::Triple::host() {
|
||||
bail!(
|
||||
"target '{}' specified in the configuration does not match the host",
|
||||
@@ -318,9 +318,8 @@ impl Module {
|
||||
|
||||
let modules = CompiledModule::from_artifacts_list(
|
||||
artifacts,
|
||||
engine.compiler().isa(),
|
||||
&*engine.config().profiler,
|
||||
engine.compiler(),
|
||||
&*engine.config().profiler,
|
||||
)?;
|
||||
|
||||
Self::from_parts(engine, modules, main_module, Arc::new(types), &[])
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
//! Implements module serialization.
|
||||
|
||||
use crate::{Engine, Module, OptLevel};
|
||||
use crate::{Engine, Module};
|
||||
use anyhow::{anyhow, bail, Context, Result};
|
||||
use bincode::Options;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::borrow::Cow;
|
||||
use std::fmt;
|
||||
use std::collections::HashMap;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
use std::{collections::HashMap, fmt::Display};
|
||||
use wasmtime_environ::{isa::TargetIsa, settings, Tunables};
|
||||
use wasmtime_jit::{
|
||||
CompilationArtifacts, CompilationStrategy, CompiledModule, Compiler, TypeTables,
|
||||
};
|
||||
use wasmtime_environ::{FlagValue, Tunables};
|
||||
use wasmtime_jit::{CompilationArtifacts, CompiledModule, Compiler, TypeTables};
|
||||
|
||||
const HEADER: &[u8] = b"\0wasmtime-aot";
|
||||
|
||||
@@ -111,16 +107,6 @@ impl<'a, 'b, T: Deserialize<'a>> Deserialize<'a> for MyCow<'b, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<settings::OptLevel> for OptLevel {
|
||||
fn from(level: settings::OptLevel) -> Self {
|
||||
match level {
|
||||
settings::OptLevel::Speed => OptLevel::Speed,
|
||||
settings::OptLevel::SpeedAndSize => OptLevel::SpeedAndSize,
|
||||
settings::OptLevel::None => OptLevel::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A small helper struct for serialized module upvars.
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct SerializedModuleUpvar {
|
||||
@@ -163,40 +149,11 @@ impl SerializedModuleUpvar {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Eq, PartialEq)]
|
||||
enum FlagValue {
|
||||
Enum(Cow<'static, str>),
|
||||
Num(u8),
|
||||
Bool(bool),
|
||||
}
|
||||
|
||||
impl From<settings::Value> for FlagValue {
|
||||
fn from(v: settings::Value) -> Self {
|
||||
match v.kind() {
|
||||
settings::SettingKind::Enum => Self::Enum(v.as_enum().unwrap().into()),
|
||||
settings::SettingKind::Num => Self::Num(v.as_num().unwrap()),
|
||||
settings::SettingKind::Bool => Self::Bool(v.as_bool().unwrap()),
|
||||
settings::SettingKind::Preset => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for FlagValue {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Self::Enum(v) => v.fmt(f),
|
||||
Self::Num(v) => v.fmt(f),
|
||||
Self::Bool(v) => v.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct SerializedModule<'a> {
|
||||
target: String,
|
||||
shared_flags: HashMap<String, FlagValue>,
|
||||
isa_flags: HashMap<String, FlagValue>,
|
||||
strategy: CompilationStrategy,
|
||||
tunables: Tunables,
|
||||
features: WasmFeatures,
|
||||
artifacts: Vec<MyCow<'a, CompilationArtifacts>>,
|
||||
@@ -250,21 +207,10 @@ impl<'a> SerializedModule<'a> {
|
||||
module_upvars: Vec<SerializedModuleUpvar>,
|
||||
types: MyCow<'a, TypeTables>,
|
||||
) -> Self {
|
||||
let isa = compiler.isa();
|
||||
|
||||
Self {
|
||||
target: isa.triple().to_string(),
|
||||
shared_flags: isa
|
||||
.flags()
|
||||
.iter()
|
||||
.map(|v| (v.name.to_owned(), v.into()))
|
||||
.collect(),
|
||||
isa_flags: isa
|
||||
.isa_flags()
|
||||
.into_iter()
|
||||
.map(|v| (v.name.to_owned(), v.into()))
|
||||
.collect(),
|
||||
strategy: compiler.strategy(),
|
||||
target: compiler.triple().to_string(),
|
||||
shared_flags: compiler.compiler().flags(),
|
||||
isa_flags: compiler.compiler().isa_flags(),
|
||||
tunables: compiler.tunables().clone(),
|
||||
features: compiler.features().into(),
|
||||
artifacts,
|
||||
@@ -275,12 +221,10 @@ impl<'a> SerializedModule<'a> {
|
||||
|
||||
pub fn into_module(mut self, engine: &Engine) -> Result<Module> {
|
||||
let compiler = engine.compiler();
|
||||
let isa = compiler.isa();
|
||||
|
||||
self.check_triple(isa)?;
|
||||
self.check_shared_flags(isa)?;
|
||||
self.check_isa_flags(isa)?;
|
||||
self.check_strategy(compiler)?;
|
||||
self.check_triple(compiler)?;
|
||||
self.check_shared_flags(compiler)?;
|
||||
self.check_isa_flags(compiler)?;
|
||||
self.check_tunables(compiler)?;
|
||||
self.check_features(compiler)?;
|
||||
|
||||
@@ -289,9 +233,8 @@ impl<'a> SerializedModule<'a> {
|
||||
.into_iter()
|
||||
.map(|i| i.unwrap_owned())
|
||||
.collect(),
|
||||
engine.compiler().isa(),
|
||||
&*engine.config().profiler,
|
||||
engine.compiler(),
|
||||
&*engine.config().profiler,
|
||||
)?;
|
||||
|
||||
assert!(!modules.is_empty());
|
||||
@@ -361,17 +304,17 @@ impl<'a> SerializedModule<'a> {
|
||||
.context("deserialize compilation artifacts")?)
|
||||
}
|
||||
|
||||
fn check_triple(&self, isa: &dyn TargetIsa) -> Result<()> {
|
||||
fn check_triple(&self, compiler: &Compiler) -> Result<()> {
|
||||
let triple = target_lexicon::Triple::from_str(&self.target).map_err(|e| anyhow!(e))?;
|
||||
|
||||
if triple.architecture != isa.triple().architecture {
|
||||
if triple.architecture != compiler.triple().architecture {
|
||||
bail!(
|
||||
"Module was compiled for architecture '{}'",
|
||||
triple.architecture
|
||||
);
|
||||
}
|
||||
|
||||
if triple.operating_system != isa.triple().operating_system {
|
||||
if triple.operating_system != compiler.triple().operating_system {
|
||||
bail!(
|
||||
"Module was compiled for operating system '{}'",
|
||||
triple.operating_system
|
||||
@@ -381,13 +324,11 @@ impl<'a> SerializedModule<'a> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn check_shared_flags(&mut self, isa: &dyn TargetIsa) -> Result<()> {
|
||||
fn check_shared_flags(&mut self, compiler: &Compiler) -> Result<()> {
|
||||
let mut shared_flags = std::mem::take(&mut self.shared_flags);
|
||||
for value in isa.flags().iter() {
|
||||
let name = value.name;
|
||||
match shared_flags.remove(name) {
|
||||
for (name, host) in compiler.compiler().flags() {
|
||||
match shared_flags.remove(&name) {
|
||||
Some(v) => {
|
||||
let host: FlagValue = value.into();
|
||||
if v != host {
|
||||
bail!("Module was compiled with a different '{}' setting: expected '{}' but host has '{}'", name, v, host);
|
||||
}
|
||||
@@ -406,12 +347,10 @@ impl<'a> SerializedModule<'a> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn check_isa_flags(&mut self, isa: &dyn TargetIsa) -> Result<()> {
|
||||
fn check_isa_flags(&mut self, compiler: &Compiler) -> Result<()> {
|
||||
let mut isa_flags = std::mem::take(&mut self.isa_flags);
|
||||
for value in isa.isa_flags().into_iter() {
|
||||
let name = value.name;
|
||||
let host: FlagValue = value.into();
|
||||
match isa_flags.remove(name) {
|
||||
for (name, host) in compiler.compiler().isa_flags() {
|
||||
match isa_flags.remove(&name) {
|
||||
Some(v) => match (&v, &host) {
|
||||
(FlagValue::Bool(v), FlagValue::Bool(host)) => {
|
||||
// ISA flags represent CPU features; for boolean values, only
|
||||
@@ -441,25 +380,6 @@ impl<'a> SerializedModule<'a> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn check_strategy(&self, compiler: &Compiler) -> Result<()> {
|
||||
#[allow(unreachable_patterns)]
|
||||
let matches = match (self.strategy, compiler.strategy()) {
|
||||
(CompilationStrategy::Auto, CompilationStrategy::Auto)
|
||||
| (CompilationStrategy::Auto, CompilationStrategy::Cranelift)
|
||||
| (CompilationStrategy::Cranelift, CompilationStrategy::Auto)
|
||||
| (CompilationStrategy::Cranelift, CompilationStrategy::Cranelift) => true,
|
||||
#[cfg(feature = "lightbeam")]
|
||||
(CompilationStrategy::Lightbeam, CompilationStrategy::Lightbeam) => true,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
if !matches {
|
||||
bail!("Module was compiled with strategy '{:?}'", self.strategy);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn check_int<T: Eq + std::fmt::Display>(found: T, expected: T, feature: &str) -> Result<()> {
|
||||
if found == expected {
|
||||
return Ok(());
|
||||
@@ -610,6 +530,7 @@ impl<'a> SerializedModule<'a> {
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::Config;
|
||||
use std::borrow::Cow;
|
||||
|
||||
#[test]
|
||||
fn test_architecture_mismatch() -> Result<()> {
|
||||
|
||||
@@ -77,19 +77,14 @@ pub fn create_function(
|
||||
func: Box<dyn Fn(*mut VMContext, *mut u128) -> Result<(), Trap> + Send + Sync>,
|
||||
engine: &Engine,
|
||||
) -> Result<(InstanceHandle, VMTrampoline)> {
|
||||
// Note that we specifically enable reference types here in our ISA because
|
||||
// `Func::new` is intended to be infallible, but our signature may use
|
||||
// reference types which requires safepoints.
|
||||
let isa = &*engine.config().target_isa_with_reference_types();
|
||||
let wasm_trampoline = engine.compiler().compiler().wasm_to_host_trampoline(
|
||||
isa,
|
||||
ft.as_wasm_func_type(),
|
||||
stub_fn as usize,
|
||||
)?;
|
||||
let wasm_trampoline = engine
|
||||
.compiler()
|
||||
.compiler()
|
||||
.wasm_to_host_trampoline(ft.as_wasm_func_type(), stub_fn as usize)?;
|
||||
let host_trampoline = engine
|
||||
.compiler()
|
||||
.compiler()
|
||||
.host_to_wasm_trampoline(isa, ft.as_wasm_func_type())?;
|
||||
.host_to_wasm_trampoline(ft.as_wasm_func_type())?;
|
||||
|
||||
let mut code_memory = CodeMemory::new();
|
||||
let host_trampoline = code_memory
|
||||
@@ -98,7 +93,7 @@ pub fn create_function(
|
||||
let wasm_trampoline =
|
||||
code_memory.allocate_for_function(&wasm_trampoline)? as *mut [VMFunctionBody];
|
||||
|
||||
code_memory.publish(isa);
|
||||
code_memory.publish(engine.compiler());
|
||||
|
||||
let sig = engine.signatures().register(ft.as_wasm_func_type());
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ pub fn create_global(store: &mut StoreOpaque<'_>, gt: &GlobalType, val: Val) ->
|
||||
|
||||
let global = wasm::Global {
|
||||
wasm_ty: gt.content().to_wasm_type(),
|
||||
ty: gt.content().get_wasmtime_type(),
|
||||
mutability: match gt.mutability() {
|
||||
Mutability::Const => false,
|
||||
Mutability::Var => true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::fmt;
|
||||
use wasmtime_environ::wasm;
|
||||
use wasmtime_environ::wasm::{EntityType, WasmFuncType};
|
||||
use wasmtime_environ::{ir, wasm};
|
||||
use wasmtime_jit::TypeTables;
|
||||
|
||||
pub(crate) mod matching;
|
||||
@@ -71,18 +71,6 @@ impl ValType {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_wasmtime_type(&self) -> ir::Type {
|
||||
match self {
|
||||
ValType::I32 => ir::types::I32,
|
||||
ValType::I64 => ir::types::I64,
|
||||
ValType::F32 => ir::types::F32,
|
||||
ValType::F64 => ir::types::F64,
|
||||
ValType::V128 => ir::types::I8X16,
|
||||
ValType::ExternRef => wasmtime_runtime::ref_type(),
|
||||
ValType::FuncRef => wasmtime_runtime::pointer_type(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn to_wasm_type(&self) -> wasm::WasmType {
|
||||
match self {
|
||||
Self::I32 => wasm::WasmType::I32,
|
||||
@@ -334,10 +322,6 @@ impl TableType {
|
||||
pub fn new(element: ValType, min: u32, max: Option<u32>) -> TableType {
|
||||
TableType {
|
||||
ty: wasm::Table {
|
||||
ty: match element {
|
||||
ValType::FuncRef => wasm::TableElementType::Func,
|
||||
_ => wasm::TableElementType::Val(element.get_wasmtime_type()),
|
||||
},
|
||||
wasm_ty: element.to_wasm_type(),
|
||||
minimum: min,
|
||||
maximum: max,
|
||||
|
||||
@@ -22,10 +22,7 @@ impl MatchCx<'_> {
|
||||
}
|
||||
|
||||
fn global_ty(&self, expected: &Global, actual: &Global) -> Result<()> {
|
||||
if expected.ty == actual.ty
|
||||
&& expected.wasm_ty == actual.wasm_ty
|
||||
&& expected.mutability == actual.mutability
|
||||
{
|
||||
if expected.wasm_ty == actual.wasm_ty && expected.mutability == actual.mutability {
|
||||
Ok(())
|
||||
} else {
|
||||
bail!("global types incompatible")
|
||||
@@ -38,7 +35,6 @@ impl MatchCx<'_> {
|
||||
|
||||
fn table_ty(&self, expected: &Table, actual: &Table) -> Result<()> {
|
||||
if expected.wasm_ty == actual.wasm_ty
|
||||
&& expected.ty == actual.ty
|
||||
&& expected.minimum <= actual.minimum
|
||||
&& match expected.maximum {
|
||||
Some(expected) => match actual.maximum {
|
||||
|
||||
Reference in New Issue
Block a user