Remove wasmtime-environ's dependency on cranelift-codegen (#3199)
* Move `CompiledFunction` into wasmtime-cranelift This commit moves the `wasmtime_environ::CompiledFunction` type into the `wasmtime-cranelift` crate. This type has lots of Cranelift-specific pieces of compilation and doesn't need to be generated by all Wasmtime compilers. This replaces the usage in the `Compiler` trait with a `Box<Any>` type that each compiler can select. Each compiler must still produce a `FunctionInfo`, however, which is shared information we'll deserialize for each module. The `wasmtime-debug` crate is also folded into the `wasmtime-cranelift` crate as a result of this commit. One possibility was to move the `CompiledFunction` commit into its own crate and have `wasmtime-debug` depend on that, but since `wasmtime-debug` is Cranelift-specific at this time it didn't seem like it was too too necessary to keep it separate. If `wasmtime-debug` supports other backends in the future we can recreate a new crate, perhaps with it refactored to not depend on Cranelift. * Move wasmtime_environ::reference_type This now belongs in wasmtime-cranelift and nowhere else * Remove `Type` reexport in wasmtime-environ One less dependency on `cranelift-codegen`! * Remove `types` reexport from `wasmtime-environ` Less cranelift! * Remove `SourceLoc` from wasmtime-environ Change the `srcloc`, `start_srcloc`, and `end_srcloc` fields to a custom `FilePos` type instead of `ir::SourceLoc`. These are only used in a few places so there's not much to lose from an extra abstraction for these leaf use cases outside of cranelift. * Remove wasmtime-environ's dep on cranelift's `StackMap` This commit "clones" the `StackMap` data structure in to `wasmtime-environ` to have an independent representation that that chosen by Cranelift. This allows Wasmtime to decouple this runtime dependency of stack map information and let the two evolve independently, if necessary. An alternative would be to refactor cranelift's implementation into a separate crate and have wasmtime depend on that but it seemed a bit like overkill to do so and easier to clone just a few lines for this. * Define code offsets in wasmtime-environ with `u32` Don't use Cranelift's `binemit::CodeOffset` alias to define this field type since the `wasmtime-environ` crate will be losing the `cranelift-codegen` dependency soon. * Commit to using `cranelift-entity` in Wasmtime This commit removes the reexport of `cranelift-entity` from the `wasmtime-environ` crate and instead directly depends on the `cranelift-entity` crate in all referencing crates. The original reason for the reexport was to make cranelift version bumps easier since it's less versions to change, but nowadays we have a script to do that. Otherwise this encourages crates to use whatever they want from `cranelift-entity` since we'll always depend on the whole crate. It's expected that the `cranelift-entity` crate will continue to be a lean crate in dependencies and suitable for use at both runtime and compile time. Consequently there's no need to avoid its usage in Wasmtime at runtime, since "remove Cranelift at compile time" is primarily about the `cranelift-codegen` crate. * Remove most uses of `cranelift-codegen` in `wasmtime-environ` There's only one final use remaining, which is the reexport of `TrapCode`, which will get handled later. * Limit the glob-reexport of `cranelift_wasm` This commit removes the glob reexport of `cranelift-wasm` from the `wasmtime-environ` crate. This is intended to explicitly define what we're reexporting and is a transitionary step to curtail the amount of dependencies taken on `cranelift-wasm` throughout the codebase. For example some functions used by debuginfo mapping are better imported directly from the crate since they're Cranelift-specific. Note that this is intended to be a temporary state affairs, soon this reexport will be gone entirely. Additionally this commit reduces imports from `cranelift_wasm` and also primarily imports from `crate::wasm` within `wasmtime-environ` to get a better sense of what's imported from where and what will need to be shared. * Extract types from cranelift-wasm to cranelift-wasm-types This commit creates a new crate called `cranelift-wasm-types` and extracts type definitions from the `cranelift-wasm` crate into this new crate. The purpose of this crate is to be a shared definition of wasm types that can be shared both by compilers (like Cranelift) as well as wasm runtimes (e.g. Wasmtime). This new `cranelift-wasm-types` crate doesn't depend on `cranelift-codegen` and is the final step in severing the unconditional dependency from Wasmtime to `cranelift-codegen`. The final refactoring in this commit is to then reexport this crate from `wasmtime-environ`, delete the `cranelift-codegen` dependency, and then update all `use` paths to point to these new types. The main change of substance here is that the `TrapCode` enum is mirrored from Cranelift into this `cranelift-wasm-types` crate. While this unfortunately results in three definitions (one more which is non-exhaustive in Wasmtime itself) it's hopefully not too onerous and ideally something we can patch up in the future. * Get lightbeam compiling * Remove unnecessary dependency * Fix compile with uffd * Update publish script * Fix more uffd tests * Rename cranelift-wasm-types to wasmtime-types This reflects the purpose a bit more where it's types specifically intended for Wasmtime and its support. * Fix publish script
This commit is contained in:
31
Cargo.lock
generated
31
Cargo.lock
generated
@@ -805,8 +805,8 @@ dependencies = [
|
||||
"serde",
|
||||
"smallvec",
|
||||
"target-lexicon",
|
||||
"thiserror",
|
||||
"wasmparser",
|
||||
"wasmtime-types",
|
||||
"wat",
|
||||
]
|
||||
|
||||
@@ -3645,7 +3645,6 @@ name = "wasmtime-cli"
|
||||
version = "0.29.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-native",
|
||||
"criterion",
|
||||
"env_logger 0.8.3",
|
||||
"file-per-thread-logger",
|
||||
@@ -3668,7 +3667,6 @@ dependencies = [
|
||||
"wasmparser",
|
||||
"wasmtime",
|
||||
"wasmtime-cache",
|
||||
"wasmtime-debug",
|
||||
"wasmtime-environ",
|
||||
"wasmtime-fuzzing",
|
||||
"wasmtime-jit",
|
||||
@@ -3693,20 +3691,6 @@ dependencies = [
|
||||
"cranelift-native",
|
||||
"cranelift-wasm",
|
||||
"gimli",
|
||||
"object",
|
||||
"target-lexicon",
|
||||
"wasmparser",
|
||||
"wasmtime-debug",
|
||||
"wasmtime-environ",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime-debug"
|
||||
version = "0.29.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-codegen",
|
||||
"gimli",
|
||||
"more-asserts",
|
||||
"object",
|
||||
"target-lexicon",
|
||||
@@ -3721,9 +3705,7 @@ version = "0.29.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cfg-if 1.0.0",
|
||||
"cranelift-codegen",
|
||||
"cranelift-entity",
|
||||
"cranelift-wasm",
|
||||
"gimli",
|
||||
"indexmap",
|
||||
"log",
|
||||
@@ -3732,6 +3714,7 @@ dependencies = [
|
||||
"target-lexicon",
|
||||
"thiserror",
|
||||
"wasmparser",
|
||||
"wasmtime-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3862,6 +3845,16 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime-types"
|
||||
version = "0.29.0"
|
||||
dependencies = [
|
||||
"cranelift-entity",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"wasmparser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime-wasi"
|
||||
version = "0.29.0"
|
||||
|
||||
@@ -23,7 +23,6 @@ doc = false
|
||||
[dependencies]
|
||||
wasmtime = { path = "crates/wasmtime", version = "0.29.0", default-features = false, features = ['cache'] }
|
||||
wasmtime-cache = { path = "crates/cache", version = "0.29.0" }
|
||||
wasmtime-debug = { path = "crates/debug", version = "0.29.0" }
|
||||
wasmtime-environ = { path = "crates/environ", version = "0.29.0" }
|
||||
wasmtime-jit = { path = "crates/jit", version = "0.29.0" }
|
||||
wasmtime-wast = { path = "crates/wast", version = "0.29.0" }
|
||||
@@ -43,7 +42,6 @@ rayon = "1.5.0"
|
||||
humantime = "2.0.0"
|
||||
wasmparser = "0.80.0"
|
||||
lazy_static = "1.4.0"
|
||||
cranelift-native = { path = 'cranelift/native', version = '0.76.0' }
|
||||
|
||||
[dev-dependencies]
|
||||
env_logger = "0.8.1"
|
||||
|
||||
@@ -16,12 +16,12 @@ wasmparser = { version = "0.80", default-features = false }
|
||||
cranelift-codegen = { path = "../codegen", version = "0.76.0", default-features = false }
|
||||
cranelift-entity = { path = "../entity", version = "0.76.0" }
|
||||
cranelift-frontend = { path = "../frontend", version = "0.76.0", default-features = false }
|
||||
wasmtime-types = { path = "../../crates/types", version = "0.29.0" }
|
||||
hashbrown = { version = "0.9.1", optional = true }
|
||||
itertools = "0.10.0"
|
||||
log = { version = "0.4.6", default-features = false }
|
||||
serde = { version = "1.0.94", features = ["derive"], optional = true }
|
||||
smallvec = "1.6.1"
|
||||
thiserror = "1.0.4"
|
||||
|
||||
[dev-dependencies]
|
||||
wat = "1.0.37"
|
||||
|
||||
@@ -72,13 +72,13 @@
|
||||
//! ("Relax verification to allow I8X16 to act as a default vector type")
|
||||
|
||||
use super::{hash_map, HashMap};
|
||||
use crate::environ::{FuncEnvironment, GlobalVariable, ReturnMode, WasmResult};
|
||||
use crate::environ::{FuncEnvironment, GlobalVariable, ReturnMode};
|
||||
use crate::state::{ControlStackFrame, ElseData, FuncTranslationState};
|
||||
use crate::translation_utils::{
|
||||
block_with_params, blocktype_params_results, f32_translation, f64_translation,
|
||||
};
|
||||
use crate::translation_utils::{FuncIndex, GlobalIndex, MemoryIndex, TableIndex, TypeIndex};
|
||||
use crate::wasm_unsupported;
|
||||
use crate::{FuncIndex, GlobalIndex, MemoryIndex, TableIndex, TypeIndex, WasmResult};
|
||||
use core::convert::TryInto;
|
||||
use core::{i32, u32};
|
||||
use cranelift_codegen::ir::condcodes::{FloatCC, IntCC};
|
||||
|
||||
@@ -7,15 +7,14 @@
|
||||
|
||||
use crate::environ::{
|
||||
FuncEnvironment, GlobalVariable, ModuleEnvironment, ReturnMode, TargetEnvironment,
|
||||
WasmFuncType, WasmResult,
|
||||
};
|
||||
use crate::func_translator::FuncTranslator;
|
||||
use crate::state::FuncTranslationState;
|
||||
use crate::translation_utils::{
|
||||
DataIndex, DefinedFuncIndex, ElemIndex, FuncIndex, Global, GlobalIndex, Memory, MemoryIndex,
|
||||
Table, TableIndex, TypeIndex,
|
||||
};
|
||||
use crate::WasmType;
|
||||
use crate::{
|
||||
DataIndex, DefinedFuncIndex, ElemIndex, FuncIndex, Global, GlobalIndex, Memory, MemoryIndex,
|
||||
Table, TableIndex, TypeIndex, WasmFuncType, WasmResult,
|
||||
};
|
||||
use core::convert::TryFrom;
|
||||
use cranelift_codegen::cursor::FuncCursor;
|
||||
use cranelift_codegen::ir::immediates::{Offset32, Uimm64};
|
||||
|
||||
@@ -7,5 +7,4 @@ mod spec;
|
||||
pub use crate::environ::dummy::DummyEnvironment;
|
||||
pub use crate::environ::spec::{
|
||||
Alias, FuncEnvironment, GlobalVariable, ModuleEnvironment, ReturnMode, TargetEnvironment,
|
||||
WasmError, WasmFuncType, WasmResult, WasmType,
|
||||
};
|
||||
|
||||
@@ -7,114 +7,21 @@
|
||||
//! [Wasmtime]: https://github.com/bytecodealliance/wasmtime
|
||||
|
||||
use crate::state::FuncTranslationState;
|
||||
use crate::translation_utils::{
|
||||
use crate::{
|
||||
DataIndex, ElemIndex, EntityIndex, EntityType, FuncIndex, Global, GlobalIndex, InstanceIndex,
|
||||
InstanceTypeIndex, Memory, MemoryIndex, ModuleIndex, ModuleTypeIndex, SignatureIndex, Table,
|
||||
TableIndex, Tag, TagIndex, TypeIndex,
|
||||
TableIndex, Tag, TagIndex, TypeIndex, WasmError, WasmFuncType, WasmResult, WasmType,
|
||||
};
|
||||
use core::convert::From;
|
||||
use core::convert::TryFrom;
|
||||
use cranelift_codegen::cursor::FuncCursor;
|
||||
use cranelift_codegen::ir::immediates::Offset32;
|
||||
use cranelift_codegen::ir::{self, InstBuilder};
|
||||
use cranelift_codegen::isa::TargetFrontendConfig;
|
||||
use cranelift_frontend::FunctionBuilder;
|
||||
#[cfg(feature = "enable-serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::boxed::Box;
|
||||
use std::string::ToString;
|
||||
use std::vec::Vec;
|
||||
use thiserror::Error;
|
||||
use wasmparser::ValidatorResources;
|
||||
use wasmparser::{BinaryReaderError, FuncValidator, FunctionBody, Operator, WasmFeatures};
|
||||
|
||||
/// WebAssembly value type -- equivalent of `wasmparser`'s Type.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub enum WasmType {
|
||||
/// I32 type
|
||||
I32,
|
||||
/// I64 type
|
||||
I64,
|
||||
/// F32 type
|
||||
F32,
|
||||
/// F64 type
|
||||
F64,
|
||||
/// V128 type
|
||||
V128,
|
||||
/// FuncRef type
|
||||
FuncRef,
|
||||
/// ExternRef type
|
||||
ExternRef,
|
||||
/// ExnRef type
|
||||
ExnRef,
|
||||
}
|
||||
|
||||
impl TryFrom<wasmparser::Type> for WasmType {
|
||||
type Error = WasmError;
|
||||
fn try_from(ty: wasmparser::Type) -> Result<Self, Self::Error> {
|
||||
use wasmparser::Type::*;
|
||||
match ty {
|
||||
I32 => Ok(WasmType::I32),
|
||||
I64 => Ok(WasmType::I64),
|
||||
F32 => Ok(WasmType::F32),
|
||||
F64 => Ok(WasmType::F64),
|
||||
V128 => Ok(WasmType::V128),
|
||||
FuncRef => Ok(WasmType::FuncRef),
|
||||
ExternRef => Ok(WasmType::ExternRef),
|
||||
ExnRef => Ok(WasmType::ExnRef),
|
||||
EmptyBlockType | Func => Err(WasmError::InvalidWebAssembly {
|
||||
message: "unexpected value type".to_string(),
|
||||
offset: 0,
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<WasmType> for wasmparser::Type {
|
||||
fn from(ty: WasmType) -> wasmparser::Type {
|
||||
match ty {
|
||||
WasmType::I32 => wasmparser::Type::I32,
|
||||
WasmType::I64 => wasmparser::Type::I64,
|
||||
WasmType::F32 => wasmparser::Type::F32,
|
||||
WasmType::F64 => wasmparser::Type::F64,
|
||||
WasmType::V128 => wasmparser::Type::V128,
|
||||
WasmType::FuncRef => wasmparser::Type::FuncRef,
|
||||
WasmType::ExternRef => wasmparser::Type::ExternRef,
|
||||
WasmType::ExnRef => wasmparser::Type::ExnRef,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// WebAssembly function type -- equivalent of `wasmparser`'s FuncType.
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub struct WasmFuncType {
|
||||
/// Function params types.
|
||||
pub params: Box<[WasmType]>,
|
||||
/// Returns params types.
|
||||
pub returns: Box<[WasmType]>,
|
||||
}
|
||||
|
||||
impl TryFrom<wasmparser::FuncType> for WasmFuncType {
|
||||
type Error = WasmError;
|
||||
fn try_from(ty: wasmparser::FuncType) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
params: ty
|
||||
.params
|
||||
.into_vec()
|
||||
.into_iter()
|
||||
.map(WasmType::try_from)
|
||||
.collect::<Result<_, Self::Error>>()?,
|
||||
returns: ty
|
||||
.returns
|
||||
.into_vec()
|
||||
.into_iter()
|
||||
.map(WasmType::try_from)
|
||||
.collect::<Result<_, Self::Error>>()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
use wasmparser::{FuncValidator, FunctionBody, Operator, ValidatorResources, WasmFeatures};
|
||||
|
||||
/// The value of a WebAssembly global variable.
|
||||
#[derive(Clone, Copy)]
|
||||
@@ -136,64 +43,6 @@ pub enum GlobalVariable {
|
||||
Custom,
|
||||
}
|
||||
|
||||
/// A WebAssembly translation error.
|
||||
///
|
||||
/// When a WebAssembly function can't be translated, one of these error codes will be returned
|
||||
/// to describe the failure.
|
||||
#[derive(Error, Debug)]
|
||||
pub enum WasmError {
|
||||
/// The input WebAssembly code is invalid.
|
||||
///
|
||||
/// This error code is used by a WebAssembly translator when it encounters invalid WebAssembly
|
||||
/// code. This should never happen for validated WebAssembly code.
|
||||
#[error("Invalid input WebAssembly code at offset {offset}: {message}")]
|
||||
InvalidWebAssembly {
|
||||
/// A string describing the validation error.
|
||||
message: std::string::String,
|
||||
/// The bytecode offset where the error occurred.
|
||||
offset: usize,
|
||||
},
|
||||
|
||||
/// A feature used by the WebAssembly code is not supported by the embedding environment.
|
||||
///
|
||||
/// Embedding environments may have their own limitations and feature restrictions.
|
||||
#[error("Unsupported feature: {0}")]
|
||||
Unsupported(std::string::String),
|
||||
|
||||
/// An implementation limit was exceeded.
|
||||
///
|
||||
/// Cranelift can compile very large and complicated functions, but the [implementation has
|
||||
/// limits][limits] that cause compilation to fail when they are exceeded.
|
||||
///
|
||||
/// [limits]: https://github.com/bytecodealliance/wasmtime/blob/main/cranelift/docs/ir.md#implementation-limits
|
||||
#[error("Implementation limit exceeded")]
|
||||
ImplLimitExceeded,
|
||||
|
||||
/// Any user-defined error.
|
||||
#[error("User error: {0}")]
|
||||
User(std::string::String),
|
||||
}
|
||||
|
||||
/// Return an `Err(WasmError::Unsupported(msg))` where `msg` the string built by calling `format!`
|
||||
/// on the arguments to this macro.
|
||||
#[macro_export]
|
||||
macro_rules! wasm_unsupported {
|
||||
($($arg:tt)*) => { $crate::environ::WasmError::Unsupported(format!($($arg)*)) }
|
||||
}
|
||||
|
||||
impl From<BinaryReaderError> for WasmError {
|
||||
/// Convert from a `BinaryReaderError` to a `WasmError`.
|
||||
fn from(e: BinaryReaderError) -> Self {
|
||||
Self::InvalidWebAssembly {
|
||||
message: e.message().into(),
|
||||
offset: e.offset(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A convenient alias for a `Result` that uses `WasmError` as the error type.
|
||||
pub type WasmResult<T> = Result<T, WasmError>;
|
||||
|
||||
/// How to return from functions.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub enum ReturnMode {
|
||||
|
||||
@@ -5,10 +5,11 @@
|
||||
//! WebAssembly module and the runtime environment.
|
||||
|
||||
use crate::code_translator::{bitcast_arguments, translate_operator, wasm_param_types};
|
||||
use crate::environ::{FuncEnvironment, ReturnMode, WasmResult};
|
||||
use crate::environ::{FuncEnvironment, ReturnMode};
|
||||
use crate::state::FuncTranslationState;
|
||||
use crate::translation_utils::get_vmctx_value_label;
|
||||
use crate::wasm_unsupported;
|
||||
use crate::WasmResult;
|
||||
use core::convert::TryInto;
|
||||
use cranelift_codegen::entity::EntityRef;
|
||||
use cranelift_codegen::ir::{self, Block, InstBuilder, ValueLabel};
|
||||
|
||||
@@ -58,7 +58,7 @@ mod translation_utils;
|
||||
|
||||
pub use crate::environ::{
|
||||
Alias, DummyEnvironment, FuncEnvironment, GlobalVariable, ModuleEnvironment, ReturnMode,
|
||||
TargetEnvironment, WasmError, WasmFuncType, WasmResult, WasmType,
|
||||
TargetEnvironment,
|
||||
};
|
||||
pub use crate::func_translator::FuncTranslator;
|
||||
pub use crate::module_translator::translate_module;
|
||||
@@ -66,6 +66,7 @@ pub use crate::state::func_state::FuncTranslationState;
|
||||
pub use crate::state::module_state::ModuleTranslationState;
|
||||
pub use crate::translation_utils::*;
|
||||
pub use cranelift_frontend::FunctionBuilder;
|
||||
pub use wasmtime_types::*;
|
||||
|
||||
// Convenience reexport of the wasmparser crate that we're linking against,
|
||||
// since a number of types in `wasmparser` show up in the public API of
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! Translation skeleton that traverses the whole WebAssembly module and call helper functions
|
||||
//! to deal with each part of it.
|
||||
use crate::environ::{ModuleEnvironment, WasmResult};
|
||||
use crate::environ::ModuleEnvironment;
|
||||
use crate::sections_translator::{
|
||||
parse_alias_section, parse_data_section, parse_element_section, parse_export_section,
|
||||
parse_function_section, parse_global_section, parse_import_section, parse_instance_section,
|
||||
@@ -8,6 +8,7 @@ use crate::sections_translator::{
|
||||
parse_tag_section, parse_type_section,
|
||||
};
|
||||
use crate::state::ModuleTranslationState;
|
||||
use crate::WasmResult;
|
||||
use cranelift_codegen::timing;
|
||||
use std::prelude::v1::*;
|
||||
use wasmparser::{NameSectionReader, Parser, Payload, Validator};
|
||||
|
||||
@@ -7,16 +7,16 @@
|
||||
//! The special case of the initialize expressions for table elements offsets or global variables
|
||||
//! is handled, according to the semantics of WebAssembly, to only specific expressions that are
|
||||
//! interpreted on the fly.
|
||||
use crate::environ::{Alias, ModuleEnvironment, WasmError, WasmResult};
|
||||
use crate::environ::{Alias, ModuleEnvironment};
|
||||
use crate::state::ModuleTranslationState;
|
||||
use crate::translation_utils::{
|
||||
use crate::wasm_unsupported;
|
||||
use crate::{
|
||||
DataIndex, ElemIndex, EntityIndex, EntityType, FuncIndex, Global, GlobalIndex, GlobalInit,
|
||||
InstanceIndex, Memory, MemoryIndex, ModuleIndex, Table, TableIndex, Tag, TagIndex, TypeIndex,
|
||||
WasmError, WasmResult,
|
||||
};
|
||||
use crate::wasm_unsupported;
|
||||
use core::convert::TryFrom;
|
||||
use core::convert::TryInto;
|
||||
use cranelift_codegen::ir::immediates::V128Imm;
|
||||
use cranelift_entity::packed_option::ReservedValue;
|
||||
use cranelift_entity::EntityRef;
|
||||
use std::boxed::Box;
|
||||
@@ -259,7 +259,7 @@ pub fn parse_global_section(
|
||||
Operator::F32Const { value } => GlobalInit::F32Const(value.bits()),
|
||||
Operator::F64Const { value } => GlobalInit::F64Const(value.bits()),
|
||||
Operator::V128Const { value } => {
|
||||
GlobalInit::V128Const(V128Imm::from(value.bytes().to_vec().as_slice()))
|
||||
GlobalInit::V128Const(u128::from_le_bytes(*value.bytes()))
|
||||
}
|
||||
Operator::RefNull { ty: _ } => GlobalInit::RefNullConst,
|
||||
Operator::RefFunc { function_index } => {
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
//! The `FuncTranslationState` struct defined in this module is used to keep track of the WebAssembly
|
||||
//! value and control stacks during the translation of a single function.
|
||||
|
||||
use crate::environ::{FuncEnvironment, GlobalVariable, WasmResult};
|
||||
use crate::translation_utils::{FuncIndex, GlobalIndex, MemoryIndex, TableIndex, TypeIndex};
|
||||
use crate::environ::{FuncEnvironment, GlobalVariable};
|
||||
use crate::{FuncIndex, GlobalIndex, MemoryIndex, TableIndex, TypeIndex, WasmResult};
|
||||
use crate::{HashMap, Occupied, Vacant};
|
||||
use cranelift_codegen::ir::{self, Block, Inst, Value};
|
||||
use std::vec::Vec;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use crate::environ::{WasmError, WasmResult};
|
||||
use crate::translation_utils::SignatureIndex;
|
||||
use crate::{SignatureIndex, WasmError, WasmResult};
|
||||
use cranelift_codegen::ir::{types, Type};
|
||||
use cranelift_entity::PrimaryMap;
|
||||
use std::boxed::Box;
|
||||
|
||||
@@ -1,235 +1,15 @@
|
||||
//! Helper functions and structures for the translation.
|
||||
use crate::environ::{TargetEnvironment, WasmResult, WasmType};
|
||||
use crate::{wasm_unsupported, WasmError};
|
||||
use core::convert::{TryFrom, TryInto};
|
||||
use crate::environ::TargetEnvironment;
|
||||
use crate::wasm_unsupported;
|
||||
use crate::WasmResult;
|
||||
use core::convert::TryInto;
|
||||
use core::u32;
|
||||
use cranelift_codegen::entity::entity_impl;
|
||||
use cranelift_codegen::ir;
|
||||
use cranelift_codegen::ir::immediates::V128Imm;
|
||||
use cranelift_frontend::FunctionBuilder;
|
||||
#[cfg(feature = "enable-serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
use wasmparser::{FuncValidator, WasmFuncType, WasmModuleResources};
|
||||
|
||||
/// Index type of a function (imported or defined) inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub struct FuncIndex(u32);
|
||||
entity_impl!(FuncIndex);
|
||||
|
||||
/// Index type of a defined function inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub struct DefinedFuncIndex(u32);
|
||||
entity_impl!(DefinedFuncIndex);
|
||||
|
||||
/// Index type of a defined table inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
|
||||
pub struct DefinedTableIndex(u32);
|
||||
entity_impl!(DefinedTableIndex);
|
||||
|
||||
/// Index type of a defined memory inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
|
||||
pub struct DefinedMemoryIndex(u32);
|
||||
entity_impl!(DefinedMemoryIndex);
|
||||
|
||||
/// Index type of a defined global inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
|
||||
pub struct DefinedGlobalIndex(u32);
|
||||
entity_impl!(DefinedGlobalIndex);
|
||||
|
||||
/// Index type of a table (imported or defined) inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub struct TableIndex(u32);
|
||||
entity_impl!(TableIndex);
|
||||
|
||||
/// Index type of a global variable (imported or defined) inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub struct GlobalIndex(u32);
|
||||
entity_impl!(GlobalIndex);
|
||||
|
||||
/// Index type of a linear memory (imported or defined) inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub struct MemoryIndex(u32);
|
||||
entity_impl!(MemoryIndex);
|
||||
|
||||
/// Index type of a signature (imported or defined) inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub struct SignatureIndex(u32);
|
||||
entity_impl!(SignatureIndex);
|
||||
|
||||
/// Index type of a passive data segment inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub struct DataIndex(u32);
|
||||
entity_impl!(DataIndex);
|
||||
|
||||
/// Index type of a passive element segment inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub struct ElemIndex(u32);
|
||||
entity_impl!(ElemIndex);
|
||||
|
||||
/// Index type of a type inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub struct TypeIndex(u32);
|
||||
entity_impl!(TypeIndex);
|
||||
|
||||
/// Index type of a module inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub struct ModuleIndex(u32);
|
||||
entity_impl!(ModuleIndex);
|
||||
|
||||
/// Index type of an instance inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub struct InstanceIndex(u32);
|
||||
entity_impl!(InstanceIndex);
|
||||
|
||||
/// Index type of an event inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub struct TagIndex(u32);
|
||||
entity_impl!(TagIndex);
|
||||
|
||||
/// Specialized index for just module types.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub struct ModuleTypeIndex(u32);
|
||||
entity_impl!(ModuleTypeIndex);
|
||||
|
||||
/// Specialized index for just instance types.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub struct InstanceTypeIndex(u32);
|
||||
entity_impl!(InstanceTypeIndex);
|
||||
|
||||
/// An index of an entity.
|
||||
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub enum EntityIndex {
|
||||
/// Function index.
|
||||
Function(FuncIndex),
|
||||
/// Table index.
|
||||
Table(TableIndex),
|
||||
/// Memory index.
|
||||
Memory(MemoryIndex),
|
||||
/// Global index.
|
||||
Global(GlobalIndex),
|
||||
/// Module index.
|
||||
Module(ModuleIndex),
|
||||
/// Instance index.
|
||||
Instance(InstanceIndex),
|
||||
}
|
||||
|
||||
/// A type of an item in a wasm module where an item is typically something that
|
||||
/// can be exported.
|
||||
#[allow(missing_docs)]
|
||||
#[derive(Clone, Debug)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub enum EntityType {
|
||||
/// A global variable with the specified content type
|
||||
Global(Global),
|
||||
/// A linear memory with the specified limits
|
||||
Memory(Memory),
|
||||
/// An event definition.
|
||||
Tag(Tag),
|
||||
/// A table with the specified element type and limits
|
||||
Table(Table),
|
||||
/// A function type where the index points to the type section and records a
|
||||
/// function signature.
|
||||
Function(SignatureIndex),
|
||||
/// An instance where the index points to the type section and records a
|
||||
/// instance's exports.
|
||||
Instance(InstanceTypeIndex),
|
||||
/// A module where the index points to the type section and records a
|
||||
/// module's imports and exports.
|
||||
Module(ModuleTypeIndex),
|
||||
}
|
||||
|
||||
/// A WebAssembly global.
|
||||
///
|
||||
/// Note that we record both the original Wasm type and the Cranelift IR type
|
||||
/// used to represent it. This is because multiple different kinds of Wasm types
|
||||
/// might be represented with the same Cranelift IR type. For example, both a
|
||||
/// Wasm `i64` and a `funcref` might be represented with a Cranelift `i64` on
|
||||
/// 64-bit architectures, and when GC is not required for func refs.
|
||||
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub struct Global {
|
||||
/// The Wasm type of the value stored in the global.
|
||||
pub wasm_ty: crate::WasmType,
|
||||
/// A flag indicating whether the value may change at runtime.
|
||||
pub mutability: bool,
|
||||
/// The source of the initial value.
|
||||
pub initializer: GlobalInit,
|
||||
}
|
||||
|
||||
/// Globals are initialized via the `const` operators or by referring to another import.
|
||||
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub enum GlobalInit {
|
||||
/// An `i32.const`.
|
||||
I32Const(i32),
|
||||
/// An `i64.const`.
|
||||
I64Const(i64),
|
||||
/// An `f32.const`.
|
||||
F32Const(u32),
|
||||
/// An `f64.const`.
|
||||
F64Const(u64),
|
||||
/// A `vconst`.
|
||||
V128Const(V128Imm),
|
||||
/// A `global.get` of another global.
|
||||
GetGlobal(GlobalIndex),
|
||||
/// A `ref.null`.
|
||||
RefNullConst,
|
||||
/// A `ref.func <index>`.
|
||||
RefFunc(FuncIndex),
|
||||
///< The global is imported from, and thus initialized by, a different module.
|
||||
Import,
|
||||
}
|
||||
|
||||
impl Global {
|
||||
/// Creates a new `Global` type from wasmparser's representation.
|
||||
pub fn new(ty: wasmparser::GlobalType, initializer: GlobalInit) -> WasmResult<Global> {
|
||||
Ok(Global {
|
||||
wasm_ty: ty.content_type.try_into()?,
|
||||
mutability: ty.mutable,
|
||||
initializer,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// WebAssembly table.
|
||||
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub struct Table {
|
||||
/// The table elements' Wasm type.
|
||||
pub wasm_ty: WasmType,
|
||||
/// The minimum number of elements in the table.
|
||||
pub minimum: u32,
|
||||
/// The maximum number of elements in the table.
|
||||
pub maximum: Option<u32>,
|
||||
}
|
||||
|
||||
impl TryFrom<wasmparser::TableType> for Table {
|
||||
type Error = WasmError;
|
||||
|
||||
fn try_from(ty: wasmparser::TableType) -> WasmResult<Table> {
|
||||
Ok(Table {
|
||||
wasm_ty: ty.element_type.try_into()?,
|
||||
minimum: ty.initial,
|
||||
maximum: ty.maximum,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// WebAssembly table element. Can be a function or a scalar type.
|
||||
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
@@ -240,47 +20,6 @@ pub enum TableElementType {
|
||||
Func,
|
||||
}
|
||||
|
||||
/// WebAssembly linear memory.
|
||||
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub struct Memory {
|
||||
/// The minimum number of pages in the memory.
|
||||
pub minimum: u64,
|
||||
/// The maximum number of pages in the memory.
|
||||
pub maximum: Option<u64>,
|
||||
/// Whether the memory may be shared between multiple threads.
|
||||
pub shared: bool,
|
||||
/// Whether or not this is a 64-bit memory
|
||||
pub memory64: bool,
|
||||
}
|
||||
|
||||
impl From<wasmparser::MemoryType> for Memory {
|
||||
fn from(ty: wasmparser::MemoryType) -> Memory {
|
||||
Memory {
|
||||
minimum: ty.initial,
|
||||
maximum: ty.maximum,
|
||||
shared: ty.shared,
|
||||
memory64: ty.memory64,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// WebAssembly event.
|
||||
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub struct Tag {
|
||||
/// The event signature type.
|
||||
pub ty: TypeIndex,
|
||||
}
|
||||
|
||||
impl From<wasmparser::TagType> for Tag {
|
||||
fn from(ty: wasmparser::TagType) -> Tag {
|
||||
Tag {
|
||||
ty: TypeIndex::from_u32(ty.type_index),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper function translating wasmparser types to Cranelift types when possible.
|
||||
pub fn type_to_type<PE: TargetEnvironment + ?Sized>(
|
||||
ty: wasmparser::Type,
|
||||
|
||||
@@ -18,11 +18,12 @@ cranelift-codegen = { path = "../../cranelift/codegen", version = "0.76.0" }
|
||||
cranelift-frontend = { path = "../../cranelift/frontend", version = "0.76.0" }
|
||||
cranelift-entity = { path = "../../cranelift/entity", version = "0.76.0" }
|
||||
cranelift-native = { path = '../../cranelift/native', version = '0.76.0' }
|
||||
wasmtime-debug = { path = '../debug', version = '0.29.0' }
|
||||
wasmparser = "0.80.0"
|
||||
target-lexicon = "0.12"
|
||||
gimli = "0.25.0"
|
||||
object = { version = "0.26.0", default-features = false, features = ['write'] }
|
||||
more-asserts = "0.2.1"
|
||||
thiserror = "1.0.4"
|
||||
|
||||
[features]
|
||||
all-arch = ["cranelift-codegen/all-arch"]
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
use crate::func_environ::{get_func_name, FuncEnvironment};
|
||||
use crate::obj::{ObjectBuilder, ObjectBuilderTarget};
|
||||
use crate::{blank_sig, func_signature, indirect_signature, value_type, wasmtime_call_conv};
|
||||
use crate::{
|
||||
blank_sig, func_signature, indirect_signature, value_type, wasmtime_call_conv,
|
||||
CompiledFunction, Relocation, RelocationTarget,
|
||||
};
|
||||
use anyhow::{Context as _, Result};
|
||||
use cranelift_codegen::ir::{self, ExternalName, InstBuilder, MemFlags};
|
||||
use cranelift_codegen::isa::TargetIsa;
|
||||
@@ -8,22 +11,22 @@ use cranelift_codegen::print_errors::pretty_error;
|
||||
use cranelift_codegen::settings;
|
||||
use cranelift_codegen::MachSrcLoc;
|
||||
use cranelift_codegen::{binemit, Context};
|
||||
use cranelift_entity::EntityRef;
|
||||
use cranelift_entity::{EntityRef, PrimaryMap};
|
||||
use cranelift_frontend::FunctionBuilder;
|
||||
use cranelift_wasm::{
|
||||
DefinedFuncIndex, DefinedMemoryIndex, FuncIndex, FuncTranslator, MemoryIndex, SignatureIndex,
|
||||
WasmFuncType,
|
||||
};
|
||||
use std::any::Any;
|
||||
use std::cmp;
|
||||
use std::collections::{BTreeSet, HashMap};
|
||||
use std::convert::TryFrom;
|
||||
use std::mem;
|
||||
use std::sync::Mutex;
|
||||
use wasmtime_environ::{
|
||||
CompileError, CompiledFunction, CompiledFunctions, FlagValue, FunctionAddressMap,
|
||||
FunctionBodyData, InstructionAddressMap, Module, ModuleMemoryOffset, ModuleTranslation,
|
||||
Relocation, RelocationTarget, StackMapInformation, TrapInformation, Tunables, TypeTables,
|
||||
VMOffsets,
|
||||
CompileError, FilePos, FlagValue, FunctionAddressMap, FunctionBodyData, FunctionInfo,
|
||||
InstructionAddressMap, Module, ModuleMemoryOffset, ModuleTranslation, StackMapInformation,
|
||||
TrapCode, TrapInformation, Tunables, TypeTables, VMOffsets,
|
||||
};
|
||||
|
||||
/// A compiler that compiles a WebAssembly module with Compiler, translating
|
||||
@@ -62,8 +65,8 @@ impl Compiler {
|
||||
let offset = data.original_position();
|
||||
let len = data.bytes_remaining();
|
||||
assert!((offset + len) <= u32::max_value() as usize);
|
||||
let start_srcloc = ir::SourceLoc::new(offset as u32);
|
||||
let end_srcloc = ir::SourceLoc::new((offset + len) as u32);
|
||||
let start_srcloc = FilePos::new(offset as u32);
|
||||
let end_srcloc = FilePos::new((offset + len) as u32);
|
||||
|
||||
let instructions = if let Some(ref mcr) = &context.mach_compile_result {
|
||||
// New-style backend: we have a `MachCompileResult` that will give us `MachSrcLoc` mapping
|
||||
@@ -109,7 +112,7 @@ impl wasmtime_environ::Compiler for Compiler {
|
||||
mut input: FunctionBodyData<'_>,
|
||||
tunables: &Tunables,
|
||||
types: &TypeTables,
|
||||
) -> Result<CompiledFunction, CompileError> {
|
||||
) -> Result<Box<dyn Any + Send>, CompileError> {
|
||||
let isa = &*self.isa;
|
||||
let module = &translation.module;
|
||||
let func_index = module.func_index(func_index);
|
||||
@@ -196,27 +199,33 @@ impl wasmtime_environ::Compiler for Compiler {
|
||||
None
|
||||
};
|
||||
|
||||
Ok(CompiledFunction {
|
||||
Ok(Box::new(CompiledFunction {
|
||||
body: code_buf,
|
||||
jt_offsets: context.func.jt_offsets,
|
||||
relocations: reloc_sink.func_relocs,
|
||||
address_map: address_transform,
|
||||
value_labels_ranges: ranges.unwrap_or(Default::default()),
|
||||
stack_slots: context.func.stack_slots,
|
||||
traps: trap_sink.traps,
|
||||
unwind_info,
|
||||
stack_maps: stack_map_sink.finish(),
|
||||
})
|
||||
info: FunctionInfo {
|
||||
address_map: address_transform,
|
||||
traps: trap_sink.traps,
|
||||
stack_maps: stack_map_sink.finish(),
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
||||
fn emit_obj(
|
||||
&self,
|
||||
translation: &ModuleTranslation,
|
||||
types: &TypeTables,
|
||||
funcs: &CompiledFunctions,
|
||||
funcs: PrimaryMap<DefinedFuncIndex, Box<dyn Any + Send>>,
|
||||
emit_dwarf: bool,
|
||||
) -> Result<Vec<u8>> {
|
||||
) -> Result<(Vec<u8>, PrimaryMap<DefinedFuncIndex, FunctionInfo>)> {
|
||||
const CODE_SECTION_ALIGNMENT: u64 = 0x1000;
|
||||
let funcs: crate::CompiledFunctions = funcs
|
||||
.into_iter()
|
||||
.map(|(_i, f)| *f.downcast().unwrap())
|
||||
.collect();
|
||||
|
||||
// Build trampolines for every signature that can be used by this module.
|
||||
let signatures = translation
|
||||
@@ -265,17 +274,20 @@ impl wasmtime_environ::Compiler for Compiler {
|
||||
} else {
|
||||
ModuleMemoryOffset::None
|
||||
};
|
||||
let dwarf_sections = wasmtime_debug::emit_dwarf(
|
||||
let dwarf_sections = crate::debug::emit_dwarf(
|
||||
&*self.isa,
|
||||
&translation.debuginfo,
|
||||
funcs,
|
||||
&funcs,
|
||||
&memory_offset,
|
||||
)
|
||||
.with_context(|| "failed to emit DWARF debug information")?;
|
||||
builder.dwarf_sections(&dwarf_sections)?;
|
||||
}
|
||||
|
||||
Ok(builder.finish(&*self.isa)?)
|
||||
Ok((
|
||||
builder.finish(&*self.isa)?,
|
||||
funcs.into_iter().map(|(_, f)| f.info).collect(),
|
||||
))
|
||||
}
|
||||
|
||||
fn emit_trampoline_obj(&self, ty: &WasmFuncType, host_fn: usize) -> Result<Vec<u8>> {
|
||||
@@ -507,11 +519,9 @@ impl Compiler {
|
||||
jt_offsets: context.func.jt_offsets,
|
||||
unwind_info,
|
||||
relocations: reloc_sink.relocs,
|
||||
stack_maps: Default::default(),
|
||||
stack_slots: Default::default(),
|
||||
traps: Default::default(),
|
||||
value_labels_ranges: Default::default(),
|
||||
address_map: Default::default(),
|
||||
info: Default::default(),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -540,14 +550,14 @@ fn collect_address_maps(
|
||||
|
||||
// Push an entry for the previous source item.
|
||||
ret.push(InstructionAddressMap {
|
||||
srcloc: cur_loc,
|
||||
srcloc: cvt(cur_loc),
|
||||
code_offset: cur_offset,
|
||||
});
|
||||
// And push a "dummy" entry if necessary to cover the span of ranges,
|
||||
// if any, between the previous source offset and this one.
|
||||
if cur_offset + cur_len != offset {
|
||||
ret.push(InstructionAddressMap {
|
||||
srcloc: ir::SourceLoc::default(),
|
||||
srcloc: FilePos::default(),
|
||||
code_offset: cur_offset + cur_len,
|
||||
});
|
||||
}
|
||||
@@ -558,17 +568,25 @@ fn collect_address_maps(
|
||||
cur_len = len;
|
||||
}
|
||||
ret.push(InstructionAddressMap {
|
||||
srcloc: cur_loc,
|
||||
srcloc: cvt(cur_loc),
|
||||
code_offset: cur_offset,
|
||||
});
|
||||
if cur_offset + cur_len != code_size {
|
||||
ret.push(InstructionAddressMap {
|
||||
srcloc: ir::SourceLoc::default(),
|
||||
srcloc: FilePos::default(),
|
||||
code_offset: cur_offset + cur_len,
|
||||
});
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
fn cvt(loc: ir::SourceLoc) -> FilePos {
|
||||
if loc.is_default() {
|
||||
FilePos::default()
|
||||
} else {
|
||||
FilePos::new(loc.bits())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Implementation of a relocation sink that just saves all the information for later
|
||||
@@ -658,7 +676,22 @@ impl binemit::TrapSink for TrapSink {
|
||||
) {
|
||||
self.traps.push(TrapInformation {
|
||||
code_offset,
|
||||
trap_code,
|
||||
trap_code: match trap_code {
|
||||
ir::TrapCode::StackOverflow => TrapCode::StackOverflow,
|
||||
ir::TrapCode::HeapOutOfBounds => TrapCode::HeapOutOfBounds,
|
||||
ir::TrapCode::HeapMisaligned => TrapCode::HeapMisaligned,
|
||||
ir::TrapCode::TableOutOfBounds => TrapCode::TableOutOfBounds,
|
||||
ir::TrapCode::IndirectCallToNull => TrapCode::IndirectCallToNull,
|
||||
ir::TrapCode::BadSignature => TrapCode::BadSignature,
|
||||
ir::TrapCode::IntegerOverflow => TrapCode::IntegerOverflow,
|
||||
ir::TrapCode::IntegerDivisionByZero => TrapCode::IntegerDivisionByZero,
|
||||
ir::TrapCode::BadConversionToInteger => TrapCode::BadConversionToInteger,
|
||||
ir::TrapCode::UnreachableCodeReached => TrapCode::UnreachableCodeReached,
|
||||
ir::TrapCode::Interrupt => TrapCode::Interrupt,
|
||||
|
||||
// these should never be emitted by wasmtime-cranelift
|
||||
ir::TrapCode::User(_) => unreachable!(),
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -670,6 +703,13 @@ struct StackMapSink {
|
||||
|
||||
impl binemit::StackMapSink for StackMapSink {
|
||||
fn add_stack_map(&mut self, code_offset: binemit::CodeOffset, stack_map: binemit::StackMap) {
|
||||
// This is converting from Cranelift's representation of a stack map to
|
||||
// Wasmtime's representation. They happen to align today but that may
|
||||
// not always be true in the future.
|
||||
let stack_map = wasmtime_environ::StackMap::new(
|
||||
stack_map.mapped_words(),
|
||||
stack_map.as_slice().iter().map(|a| a.0),
|
||||
);
|
||||
self.infos.push(StackMapInformation {
|
||||
code_offset,
|
||||
stack_map,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#![allow(clippy::cast_ptr_alignment)]
|
||||
|
||||
pub use crate::write_debuginfo::{emit_dwarf, DwarfSection, DwarfSectionRelocTarget};
|
||||
pub use write_debuginfo::{emit_dwarf, DwarfSection, DwarfSectionRelocTarget};
|
||||
|
||||
mod gc;
|
||||
mod transform;
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::transform::AddressTransform;
|
||||
use crate::debug::transform::AddressTransform;
|
||||
use gimli::constants;
|
||||
use gimli::read;
|
||||
use gimli::{Reader, UnitSectionOffset};
|
||||
@@ -1,11 +1,11 @@
|
||||
use cranelift_codegen::ir::SourceLoc;
|
||||
use crate::CompiledFunctions;
|
||||
use gimli::write;
|
||||
use more_asserts::assert_le;
|
||||
use std::collections::BTreeMap;
|
||||
use std::iter::FromIterator;
|
||||
use wasmtime_environ::entity::{EntityRef, PrimaryMap};
|
||||
use wasmtime_environ::wasm::DefinedFuncIndex;
|
||||
use wasmtime_environ::{CompiledFunctions, FunctionAddressMap, WasmFileInfo};
|
||||
use wasmtime_environ::{
|
||||
DefinedFuncIndex, EntityRef, FilePos, FunctionAddressMap, PrimaryMap, WasmFileInfo,
|
||||
};
|
||||
|
||||
pub type GeneratedAddress = usize;
|
||||
pub type WasmAddress = u64;
|
||||
@@ -78,16 +78,21 @@ pub struct AddressTransform {
|
||||
}
|
||||
|
||||
/// Returns a wasm bytecode offset in the code section from SourceLoc.
|
||||
pub fn get_wasm_code_offset(loc: SourceLoc, code_section_offset: u64) -> WasmAddress {
|
||||
fn get_wasm_code_offset(loc: FilePos, code_section_offset: u64) -> WasmAddress {
|
||||
// Code section size <= 4GB, allow wrapped SourceLoc to recover the overflow.
|
||||
loc.bits().wrapping_sub(code_section_offset as u32) as WasmAddress
|
||||
loc.file_offset()
|
||||
.unwrap()
|
||||
.wrapping_sub(code_section_offset as u32) as WasmAddress
|
||||
}
|
||||
|
||||
fn build_function_lookup(
|
||||
ft: &FunctionAddressMap,
|
||||
code_section_offset: u64,
|
||||
) -> (WasmAddress, WasmAddress, FuncLookup) {
|
||||
assert_le!(code_section_offset, ft.start_srcloc.bits() as u64);
|
||||
assert_le!(
|
||||
code_section_offset,
|
||||
ft.start_srcloc.file_offset().unwrap().into()
|
||||
);
|
||||
let fn_start = get_wasm_code_offset(ft.start_srcloc, code_section_offset);
|
||||
let fn_end = get_wasm_code_offset(ft.end_srcloc, code_section_offset);
|
||||
assert_le!(fn_start, fn_end);
|
||||
@@ -103,7 +108,7 @@ fn build_function_lookup(
|
||||
let mut current_range = Vec::new();
|
||||
let mut last_gen_inst_empty = false;
|
||||
for (i, t) in ft.instructions.iter().enumerate() {
|
||||
if t.srcloc.is_default() {
|
||||
if t.srcloc.file_offset().is_none() {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -194,10 +199,10 @@ fn build_function_addr_map(
|
||||
) -> PrimaryMap<DefinedFuncIndex, FunctionMap> {
|
||||
let mut map = PrimaryMap::new();
|
||||
for (_, f) in funcs {
|
||||
let ft = &f.address_map;
|
||||
let ft = &f.info.address_map;
|
||||
let mut fn_map = Vec::new();
|
||||
for t in ft.instructions.iter() {
|
||||
if t.srcloc.is_default() {
|
||||
if t.srcloc.file_offset().is_none() {
|
||||
continue;
|
||||
}
|
||||
let offset = get_wasm_code_offset(t.srcloc, code_section_offset);
|
||||
@@ -455,7 +460,7 @@ impl AddressTransform {
|
||||
|
||||
let mut func = BTreeMap::new();
|
||||
for (i, f) in funcs {
|
||||
let ft = &f.address_map;
|
||||
let ft = &f.info.address_map;
|
||||
let (fn_start, fn_end, lookup) = build_function_lookup(ft, code_section_offset);
|
||||
|
||||
func.insert(
|
||||
@@ -606,21 +611,22 @@ impl AddressTransform {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{build_function_lookup, get_wasm_code_offset, AddressTransform};
|
||||
use crate::{CompiledFunction, CompiledFunctions};
|
||||
use cranelift_entity::PrimaryMap;
|
||||
use gimli::write::Address;
|
||||
use std::iter::FromIterator;
|
||||
use std::mem;
|
||||
use wasmtime_environ::entity::PrimaryMap;
|
||||
use wasmtime_environ::ir::SourceLoc;
|
||||
use wasmtime_environ::{CompiledFunction, WasmFileInfo};
|
||||
use wasmtime_environ::{CompiledFunctions, FunctionAddressMap, InstructionAddressMap};
|
||||
use wasmtime_environ::{
|
||||
FilePos, FunctionAddressMap, FunctionInfo, InstructionAddressMap, WasmFileInfo,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn test_get_wasm_code_offset() {
|
||||
let offset = get_wasm_code_offset(SourceLoc::new(3), 1);
|
||||
let offset = get_wasm_code_offset(FilePos::new(3), 1);
|
||||
assert_eq!(2, offset);
|
||||
let offset = get_wasm_code_offset(SourceLoc::new(16), 0xF000_0000);
|
||||
let offset = get_wasm_code_offset(FilePos::new(16), 0xF000_0000);
|
||||
assert_eq!(0x1000_0010, offset);
|
||||
let offset = get_wasm_code_offset(SourceLoc::new(1), 0x20_8000_0000);
|
||||
let offset = get_wasm_code_offset(FilePos::new(1), 0x20_8000_0000);
|
||||
assert_eq!(0x8000_0001, offset);
|
||||
}
|
||||
|
||||
@@ -628,25 +634,25 @@ mod tests {
|
||||
FunctionAddressMap {
|
||||
instructions: vec![
|
||||
InstructionAddressMap {
|
||||
srcloc: SourceLoc::new(wasm_offset + 2),
|
||||
srcloc: FilePos::new(wasm_offset + 2),
|
||||
code_offset: 5,
|
||||
},
|
||||
InstructionAddressMap {
|
||||
srcloc: SourceLoc::default(),
|
||||
srcloc: FilePos::default(),
|
||||
code_offset: 8,
|
||||
},
|
||||
InstructionAddressMap {
|
||||
srcloc: SourceLoc::new(wasm_offset + 7),
|
||||
srcloc: FilePos::new(wasm_offset + 7),
|
||||
code_offset: 15,
|
||||
},
|
||||
InstructionAddressMap {
|
||||
srcloc: SourceLoc::default(),
|
||||
srcloc: FilePos::default(),
|
||||
code_offset: 23,
|
||||
},
|
||||
]
|
||||
.into(),
|
||||
start_srcloc: SourceLoc::new(wasm_offset),
|
||||
end_srcloc: SourceLoc::new(wasm_offset + 10),
|
||||
start_srcloc: FilePos::new(wasm_offset),
|
||||
end_srcloc: FilePos::new(wasm_offset + 10),
|
||||
body_offset: 0,
|
||||
body_len: 30,
|
||||
}
|
||||
@@ -654,7 +660,10 @@ mod tests {
|
||||
|
||||
fn create_simple_module(address_map: FunctionAddressMap) -> CompiledFunctions {
|
||||
PrimaryMap::from_iter(vec![CompiledFunction {
|
||||
address_map,
|
||||
info: FunctionInfo {
|
||||
address_map,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
}])
|
||||
}
|
||||
@@ -691,11 +700,11 @@ mod tests {
|
||||
// append instruction with same srcloc as input.instructions[0]
|
||||
let mut list = Vec::from(mem::take(&mut input.instructions));
|
||||
list.push(InstructionAddressMap {
|
||||
srcloc: SourceLoc::new(11 + 2),
|
||||
srcloc: FilePos::new(11 + 2),
|
||||
code_offset: 23,
|
||||
});
|
||||
list.push(InstructionAddressMap {
|
||||
srcloc: SourceLoc::default(),
|
||||
srcloc: FilePos::default(),
|
||||
code_offset: 26,
|
||||
});
|
||||
input.instructions = list.into();
|
||||
@@ -3,15 +3,14 @@ use anyhow::{Context, Error, Result};
|
||||
use cranelift_codegen::ir::{LabelValueLoc, StackSlots, ValueLabel, ValueLoc};
|
||||
use cranelift_codegen::isa::TargetIsa;
|
||||
use cranelift_codegen::ValueLabelsRanges;
|
||||
use cranelift_wasm::get_vmctx_value_label;
|
||||
use gimli::{self, write, Expression, Operation, Reader, ReaderOffset, X86_64};
|
||||
use more_asserts::{assert_le, assert_lt};
|
||||
use std::cmp::PartialEq;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::rc::Rc;
|
||||
use wasmtime_environ::entity::EntityRef;
|
||||
use wasmtime_environ::wasm::{get_vmctx_value_label, DefinedFuncIndex};
|
||||
use wasmtime_environ::ModuleMemoryOffset;
|
||||
use wasmtime_environ::{DefinedFuncIndex, EntityRef, ModuleMemoryOffset};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FunctionFrameInfo<'a> {
|
||||
@@ -847,8 +846,9 @@ mod tests {
|
||||
compile_expression, AddressTransform, CompiledExpression, CompiledExpressionPart,
|
||||
FunctionFrameInfo, JumpTargetMarker, ValueLabel, ValueLabelsRanges,
|
||||
};
|
||||
use crate::CompiledFunction;
|
||||
use gimli::{self, constants, Encoding, EndianSlice, Expression, RunTimeEndian};
|
||||
use wasmtime_environ::CompiledFunction;
|
||||
use wasmtime_environ::{FilePos, FunctionInfo};
|
||||
|
||||
macro_rules! dw_op {
|
||||
(DW_OP_WASM_location) => {
|
||||
@@ -906,7 +906,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_debug_parse_expressions() {
|
||||
use wasmtime_environ::entity::EntityRef;
|
||||
use cranelift_entity::EntityRef;
|
||||
|
||||
let (val1, val3, val20) = (ValueLabel::new(1), ValueLabel::new(3), ValueLabel::new(20));
|
||||
|
||||
@@ -1176,37 +1176,39 @@ mod tests {
|
||||
}
|
||||
|
||||
fn create_mock_address_transform() -> AddressTransform {
|
||||
use wasmtime_environ::entity::PrimaryMap;
|
||||
use wasmtime_environ::ir::SourceLoc;
|
||||
use cranelift_entity::PrimaryMap;
|
||||
use wasmtime_environ::WasmFileInfo;
|
||||
use wasmtime_environ::{FunctionAddressMap, InstructionAddressMap};
|
||||
let mut module_map = PrimaryMap::new();
|
||||
let code_section_offset: u32 = 100;
|
||||
module_map.push(CompiledFunction {
|
||||
address_map: FunctionAddressMap {
|
||||
instructions: vec![
|
||||
InstructionAddressMap {
|
||||
srcloc: SourceLoc::new(code_section_offset + 12),
|
||||
code_offset: 5,
|
||||
},
|
||||
InstructionAddressMap {
|
||||
srcloc: SourceLoc::default(),
|
||||
code_offset: 8,
|
||||
},
|
||||
InstructionAddressMap {
|
||||
srcloc: SourceLoc::new(code_section_offset + 17),
|
||||
code_offset: 15,
|
||||
},
|
||||
InstructionAddressMap {
|
||||
srcloc: SourceLoc::default(),
|
||||
code_offset: 23,
|
||||
},
|
||||
]
|
||||
.into(),
|
||||
start_srcloc: SourceLoc::new(code_section_offset + 10),
|
||||
end_srcloc: SourceLoc::new(code_section_offset + 20),
|
||||
body_offset: 0,
|
||||
body_len: 30,
|
||||
info: FunctionInfo {
|
||||
address_map: FunctionAddressMap {
|
||||
instructions: vec![
|
||||
InstructionAddressMap {
|
||||
srcloc: FilePos::new(code_section_offset + 12),
|
||||
code_offset: 5,
|
||||
},
|
||||
InstructionAddressMap {
|
||||
srcloc: FilePos::default(),
|
||||
code_offset: 8,
|
||||
},
|
||||
InstructionAddressMap {
|
||||
srcloc: FilePos::new(code_section_offset + 17),
|
||||
code_offset: 15,
|
||||
},
|
||||
InstructionAddressMap {
|
||||
srcloc: FilePos::default(),
|
||||
code_offset: 23,
|
||||
},
|
||||
]
|
||||
.into(),
|
||||
start_srcloc: FilePos::new(code_section_offset + 10),
|
||||
end_srcloc: FilePos::new(code_section_offset + 20),
|
||||
body_offset: 0,
|
||||
body_len: 30,
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
});
|
||||
@@ -1222,8 +1224,8 @@ mod tests {
|
||||
fn create_mock_value_ranges() -> (ValueLabelsRanges, (ValueLabel, ValueLabel, ValueLabel)) {
|
||||
use cranelift_codegen::ir::{LabelValueLoc, ValueLoc};
|
||||
use cranelift_codegen::ValueLocRange;
|
||||
use cranelift_entity::EntityRef;
|
||||
use std::collections::HashMap;
|
||||
use wasmtime_environ::entity::EntityRef;
|
||||
let mut value_ranges = HashMap::new();
|
||||
let value_0 = ValueLabel::new(0);
|
||||
let value_1 = ValueLabel::new(1);
|
||||
@@ -1266,9 +1268,7 @@ mod tests {
|
||||
fn test_debug_value_range_builder() {
|
||||
use super::ValueLabelRangesBuilder;
|
||||
use cranelift_codegen::ir::StackSlots;
|
||||
use wasmtime_environ::entity::EntityRef;
|
||||
use wasmtime_environ::wasm::DefinedFuncIndex;
|
||||
use wasmtime_environ::ModuleMemoryOffset;
|
||||
use wasmtime_environ::{DefinedFuncIndex, EntityRef, ModuleMemoryOffset};
|
||||
|
||||
let addr_tr = create_mock_address_transform();
|
||||
let stack_slots = StackSlots::new();
|
||||
@@ -7,8 +7,7 @@ use gimli::{
|
||||
DebuggingInformationEntry, LineEncoding, Unit,
|
||||
};
|
||||
use more_asserts::assert_le;
|
||||
use wasmtime_environ::entity::EntityRef;
|
||||
use wasmtime_environ::wasm::DefinedFuncIndex;
|
||||
use wasmtime_environ::{DefinedFuncIndex, EntityRef};
|
||||
|
||||
#[derive(Debug)]
|
||||
enum SavedLineProgramRow {
|
||||
@@ -1,7 +1,8 @@
|
||||
use self::refs::DebugInfoRefsMap;
|
||||
use self::simulate::generate_simulated_dwarf;
|
||||
use self::unit::clone_unit;
|
||||
use crate::gc::build_dependencies;
|
||||
use crate::debug::gc::build_dependencies;
|
||||
use crate::CompiledFunctions;
|
||||
use anyhow::Error;
|
||||
use cranelift_codegen::isa::TargetIsa;
|
||||
use gimli::{
|
||||
@@ -10,7 +11,7 @@ use gimli::{
|
||||
};
|
||||
use std::collections::HashSet;
|
||||
use thiserror::Error;
|
||||
use wasmtime_environ::{CompiledFunctions, DebugInfoData, ModuleMemoryOffset};
|
||||
use wasmtime_environ::{DebugInfoData, ModuleMemoryOffset};
|
||||
|
||||
pub use address_transform::AddressTransform;
|
||||
|
||||
@@ -3,8 +3,7 @@ use super::{DebugInputContext, Reader};
|
||||
use anyhow::Error;
|
||||
use gimli::{write, AttributeValue, DebuggingInformationEntry, RangeListsOffset, Unit};
|
||||
use more_asserts::assert_lt;
|
||||
use wasmtime_environ::entity::EntityRef;
|
||||
use wasmtime_environ::wasm::DefinedFuncIndex;
|
||||
use wasmtime_environ::{DefinedFuncIndex, EntityRef};
|
||||
|
||||
pub(crate) enum RangeInfoBuilder {
|
||||
Undefined,
|
||||
@@ -1,18 +1,18 @@
|
||||
use super::expression::{CompiledExpression, FunctionFrameInfo};
|
||||
use super::utils::{add_internal_types, append_vmctx_info, get_function_frame_info};
|
||||
use super::AddressTransform;
|
||||
use crate::CompiledFunctions;
|
||||
use anyhow::{Context, Error};
|
||||
use cranelift_codegen::isa::TargetIsa;
|
||||
use cranelift_wasm::get_vmctx_value_label;
|
||||
use gimli::write;
|
||||
use gimli::{self, LineEncoding};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
|
||||
use wasmparser::Type as WasmType;
|
||||
use wasmtime_environ::entity::EntityRef;
|
||||
use wasmtime_environ::wasm::{get_vmctx_value_label, DefinedFuncIndex};
|
||||
use wasmtime_environ::{
|
||||
CompiledFunctions, DebugInfoData, FunctionMetadata, ModuleMemoryOffset, WasmFileInfo,
|
||||
DebugInfoData, DefinedFuncIndex, EntityRef, FunctionMetadata, ModuleMemoryOffset, WasmFileInfo,
|
||||
};
|
||||
|
||||
const PRODUCER_NAME: &str = "wasmtime";
|
||||
@@ -6,14 +6,14 @@ use super::range_info_builder::RangeInfoBuilder;
|
||||
use super::refs::{PendingDebugInfoRefs, PendingUnitRefs, UnitRefsMap};
|
||||
use super::utils::{add_internal_types, append_vmctx_info, get_function_frame_info};
|
||||
use super::{DebugInputContext, Reader, TransformError};
|
||||
use crate::CompiledFunctions;
|
||||
use anyhow::{Context, Error};
|
||||
use cranelift_codegen::ir::Endianness;
|
||||
use cranelift_codegen::isa::TargetIsa;
|
||||
use gimli::write;
|
||||
use gimli::{AttributeValue, DebuggingInformationEntry, Unit};
|
||||
use std::collections::HashSet;
|
||||
use wasmtime_environ::wasm::DefinedFuncIndex;
|
||||
use wasmtime_environ::{CompiledFunctions, ModuleMemoryOffset};
|
||||
use wasmtime_environ::{DefinedFuncIndex, ModuleMemoryOffset};
|
||||
|
||||
struct InheritedAttr<T> {
|
||||
stack: Vec<(usize, T)>,
|
||||
@@ -1,10 +1,10 @@
|
||||
use super::address_transform::AddressTransform;
|
||||
use super::expression::{CompiledExpression, FunctionFrameInfo};
|
||||
use crate::CompiledFunctions;
|
||||
use anyhow::Error;
|
||||
use cranelift_codegen::isa::TargetIsa;
|
||||
use gimli::write;
|
||||
use wasmtime_environ::wasm::DefinedFuncIndex;
|
||||
use wasmtime_environ::{CompiledFunctions, ModuleMemoryOffset};
|
||||
use wasmtime_environ::{DefinedFuncIndex, ModuleMemoryOffset};
|
||||
|
||||
/// Adds internal Wasm utility types DIEs such as WebAssemblyPtr and
|
||||
/// WasmtimeVMContext.
|
||||
@@ -1,10 +1,11 @@
|
||||
pub use crate::transform::transform_dwarf;
|
||||
pub use crate::debug::transform::transform_dwarf;
|
||||
use crate::CompiledFunctions;
|
||||
use cranelift_codegen::ir::Endianness;
|
||||
use cranelift_codegen::isa::{unwind::UnwindInfo, TargetIsa};
|
||||
use cranelift_entity::EntityRef;
|
||||
use gimli::write::{Address, Dwarf, EndianVec, FrameTable, Result, Sections, Writer};
|
||||
use gimli::{RunTimeEndian, SectionId};
|
||||
use wasmtime_environ::entity::EntityRef;
|
||||
use wasmtime_environ::{CompiledFunctions, DebugInfoData, ModuleMemoryOffset};
|
||||
use wasmtime_environ::{DebugInfoData, ModuleMemoryOffset};
|
||||
|
||||
#[allow(missing_docs)]
|
||||
pub struct DwarfSection {
|
||||
@@ -617,7 +617,7 @@ impl<'module_environment> TargetEnvironment for FuncEnvironment<'module_environm
|
||||
}
|
||||
|
||||
fn reference_type(&self, ty: WasmType) -> ir::Type {
|
||||
wasmtime_environ::reference_type(ty, self.pointer_type())
|
||||
crate::reference_type(ty, self.pointer_type())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -671,7 +671,10 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m
|
||||
let bound_gv = func.create_global_value(ir::GlobalValueData::Load {
|
||||
base: ptr,
|
||||
offset: Offset32::new(current_elements_offset),
|
||||
global_type: self.offsets.type_of_vmtable_definition_current_elements(),
|
||||
global_type: ir::Type::int(
|
||||
u16::from(self.offsets.size_of_vmtable_definition_current_elements()) * 8,
|
||||
)
|
||||
.unwrap(),
|
||||
readonly: false,
|
||||
});
|
||||
|
||||
|
||||
@@ -88,19 +88,67 @@
|
||||
// also need to actually catch stack overflow, so for now 32k is chosen and it's
|
||||
// assume no valid stack pointer will ever be `usize::max_value() - 32k`.
|
||||
|
||||
use cranelift_codegen::binemit;
|
||||
use cranelift_codegen::ir;
|
||||
use cranelift_codegen::isa::{CallConv, TargetIsa};
|
||||
use cranelift_wasm::{FuncIndex, WasmFuncType, WasmType};
|
||||
use cranelift_codegen::isa::{unwind::UnwindInfo, CallConv, TargetIsa};
|
||||
use cranelift_entity::PrimaryMap;
|
||||
use cranelift_wasm::{DefinedFuncIndex, FuncIndex, WasmFuncType, WasmType};
|
||||
use target_lexicon::CallingConvention;
|
||||
use wasmtime_environ::{Module, TypeTables};
|
||||
use wasmtime_environ::{FunctionInfo, Module, TypeTables};
|
||||
|
||||
pub use builder::builder;
|
||||
|
||||
mod builder;
|
||||
mod compiler;
|
||||
mod debug;
|
||||
mod func_environ;
|
||||
mod obj;
|
||||
|
||||
type CompiledFunctions = PrimaryMap<DefinedFuncIndex, CompiledFunction>;
|
||||
|
||||
/// Compiled function: machine code body, jump table offsets, and unwind information.
|
||||
#[derive(Default)]
|
||||
pub struct CompiledFunction {
|
||||
/// The machine code for this function.
|
||||
body: Vec<u8>,
|
||||
|
||||
/// The jump tables offsets (in the body).
|
||||
jt_offsets: ir::JumpTableOffsets,
|
||||
|
||||
/// The unwind information.
|
||||
unwind_info: Option<UnwindInfo>,
|
||||
|
||||
relocations: Vec<Relocation>,
|
||||
value_labels_ranges: cranelift_codegen::ValueLabelsRanges,
|
||||
stack_slots: ir::StackSlots,
|
||||
|
||||
info: FunctionInfo,
|
||||
}
|
||||
|
||||
/// A record of a relocation to perform.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
struct Relocation {
|
||||
/// The relocation code.
|
||||
reloc: binemit::Reloc,
|
||||
/// Relocation target.
|
||||
reloc_target: RelocationTarget,
|
||||
/// The offset where to apply the relocation.
|
||||
offset: binemit::CodeOffset,
|
||||
/// The addend to add to the relocation value.
|
||||
addend: binemit::Addend,
|
||||
}
|
||||
|
||||
/// Destination function. Can be either user function or some special one, like `memory.grow`.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
enum RelocationTarget {
|
||||
/// The user function index.
|
||||
UserFunc(FuncIndex),
|
||||
/// A compiler-generated libcall.
|
||||
LibCall(ir::LibCall),
|
||||
/// Jump table index.
|
||||
JumpTable(FuncIndex, ir::JumpTable),
|
||||
}
|
||||
|
||||
/// Creates a new cranelift `Signature` with no wasm params/results for the
|
||||
/// given calling convention.
|
||||
///
|
||||
@@ -148,9 +196,7 @@ fn value_type(isa: &dyn TargetIsa, ty: WasmType) -> ir::types::Type {
|
||||
WasmType::F32 => ir::types::F32,
|
||||
WasmType::F64 => ir::types::F64,
|
||||
WasmType::V128 => ir::types::I8X16,
|
||||
WasmType::FuncRef | WasmType::ExternRef => {
|
||||
wasmtime_environ::reference_type(ty, isa.pointer_type())
|
||||
}
|
||||
WasmType::FuncRef | WasmType::ExternRef => reference_type(ty, isa.pointer_type()),
|
||||
WasmType::ExnRef => unimplemented!(),
|
||||
}
|
||||
}
|
||||
@@ -199,3 +245,16 @@ fn func_signature(
|
||||
);
|
||||
return sig;
|
||||
}
|
||||
|
||||
/// Returns the reference type to use for the provided wasm type.
|
||||
fn reference_type(wasm_ty: cranelift_wasm::WasmType, pointer_type: ir::Type) -> ir::Type {
|
||||
match wasm_ty {
|
||||
cranelift_wasm::WasmType::FuncRef => pointer_type,
|
||||
cranelift_wasm::WasmType::ExternRef => match pointer_type {
|
||||
ir::types::I32 => ir::types::R32,
|
||||
ir::types::I64 => ir::types::R64,
|
||||
_ => panic!("unsupported pointer type"),
|
||||
},
|
||||
_ => panic!("unsupported Wasm reference type"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
//! function body, the imported wasm function do not. The trampolines symbol
|
||||
//! names have format "_trampoline_N", where N is `SignatureIndex`.
|
||||
|
||||
#![allow(missing_docs)]
|
||||
|
||||
use crate::debug::{DwarfSection, DwarfSectionRelocTarget};
|
||||
use crate::{CompiledFunction, Relocation, RelocationTarget};
|
||||
use anyhow::Result;
|
||||
use cranelift_codegen::binemit::Reloc;
|
||||
use cranelift_codegen::ir::{JumpTableOffsets, LibCall};
|
||||
@@ -34,11 +34,10 @@ use object::{
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use std::convert::TryFrom;
|
||||
use wasmtime_debug::{DwarfSection, DwarfSectionRelocTarget};
|
||||
use wasmtime_environ::entity::{EntityRef, PrimaryMap};
|
||||
use wasmtime_environ::obj;
|
||||
use wasmtime_environ::wasm::{DefinedFuncIndex, FuncIndex, SignatureIndex};
|
||||
use wasmtime_environ::{CompiledFunction, Module, Relocation, RelocationTarget};
|
||||
use wasmtime_environ::{
|
||||
DefinedFuncIndex, EntityRef, FuncIndex, Module, PrimaryMap, SignatureIndex,
|
||||
};
|
||||
|
||||
fn to_object_architecture(
|
||||
arch: target_lexicon::Architecture,
|
||||
|
||||
3
crates/debug/.gitignore
vendored
3
crates/debug/.gitignore
vendored
@@ -1,3 +0,0 @@
|
||||
target/
|
||||
**/*.rs.bk
|
||||
Cargo.lock
|
||||
@@ -1,25 +0,0 @@
|
||||
[package]
|
||||
name = "wasmtime-debug"
|
||||
version = "0.29.0"
|
||||
authors = ["The Wasmtime Project Developers"]
|
||||
description = "Debug utils for WebAsssembly code in Cranelift"
|
||||
license = "Apache-2.0 WITH LLVM-exception"
|
||||
repository = "https://github.com/bytecodealliance/wasmtime"
|
||||
documentation = "https://docs.rs/wasmtime-debug/"
|
||||
categories = ["wasm"]
|
||||
keywords = ["webassembly", "wasm", "debuginfo"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
gimli = "0.25.0"
|
||||
wasmparser = "0.80"
|
||||
object = { version = "0.26.0", default-features = false, features = ["read_core", "elf", "write"] }
|
||||
wasmtime-environ = { path = "../environ", version = "0.29.0" }
|
||||
target-lexicon = { version = "0.12.0", default-features = false }
|
||||
anyhow = "1.0"
|
||||
thiserror = "1.0.4"
|
||||
more-asserts = "0.2.1"
|
||||
cranelift-codegen = { path = "../../cranelift/codegen", version = "0.76.0" }
|
||||
|
||||
[badges]
|
||||
maintenance = { status = "actively-developed" }
|
||||
@@ -1,220 +0,0 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
|
||||
--- LLVM Exceptions to the Apache 2.0 License ----
|
||||
|
||||
As an exception, if, as a result of your compiling your source code, portions
|
||||
of this Software are embedded into an Object form of such source code, you
|
||||
may redistribute such embedded portions in such Object form without complying
|
||||
with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
|
||||
|
||||
In addition, if you combine or link compiled forms of this Software with
|
||||
software that is licensed under the GPLv2 ("Combined Software") and if a
|
||||
court of competent jurisdiction determines that the patent provision (Section
|
||||
3), the indemnity provision (Section 9) or other Section of the License
|
||||
conflicts with the conditions of the GPLv2, you may retroactively and
|
||||
prospectively choose to deem waived or otherwise exclude such Section(s) of
|
||||
the License, but only in their entirety and only with respect to the Combined
|
||||
Software.
|
||||
|
||||
@@ -12,9 +12,8 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
cranelift-codegen = { path = "../../cranelift/codegen", version = "0.76.0", features = ["enable-serde"] }
|
||||
cranelift-entity = { path = "../../cranelift/entity", version = "0.76.0", features = ["enable-serde"] }
|
||||
cranelift-wasm = { path = "../../cranelift/wasm", version = "0.76.0", features = ["enable-serde"] }
|
||||
cranelift-entity = { path = "../../cranelift/entity", version = "0.76.0" }
|
||||
wasmtime-types = { path = "../types", version = "0.29.0" }
|
||||
wasmparser = "0.80"
|
||||
indexmap = { version = "1.0.2", features = ["serde-1"] }
|
||||
thiserror = "1.0.4"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
//! Data structures to provide transformation of the source
|
||||
// addresses of a WebAssembly module into the native code.
|
||||
|
||||
use cranelift_codegen::ir;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Single source location to generated address mapping.
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
|
||||
pub struct InstructionAddressMap {
|
||||
/// Where in the source this instruction comes from.
|
||||
pub srcloc: ir::SourceLoc,
|
||||
/// Where in the source wasm binary this instruction comes from, specified
|
||||
/// in an offset of bytes from the front of the file.
|
||||
pub srcloc: FilePos,
|
||||
|
||||
/// Offset from the start of the function's compiled code to where this
|
||||
/// instruction is located, or the region where it starts.
|
||||
@@ -26,11 +26,13 @@ pub struct FunctionAddressMap {
|
||||
/// gap between it and the next item in the array.
|
||||
pub instructions: Box<[InstructionAddressMap]>,
|
||||
|
||||
/// Function start source location (normally declaration).
|
||||
pub start_srcloc: ir::SourceLoc,
|
||||
/// Function's initial offset in the source file, specified in bytes from
|
||||
/// the front of the file.
|
||||
pub start_srcloc: FilePos,
|
||||
|
||||
/// Function end source location.
|
||||
pub end_srcloc: ir::SourceLoc,
|
||||
/// Function's end offset in the source file, specified in bytes from
|
||||
/// the front of the file.
|
||||
pub end_srcloc: FilePos,
|
||||
|
||||
/// Generated function body offset if applicable, otherwise 0.
|
||||
pub body_offset: usize,
|
||||
@@ -39,6 +41,40 @@ pub struct FunctionAddressMap {
|
||||
pub body_len: u32,
|
||||
}
|
||||
|
||||
/// A position within an original source file,
|
||||
///
|
||||
/// This structure is used as a newtype wrapper around a 32-bit integer which
|
||||
/// represents an offset within a file where a wasm instruction or function is
|
||||
/// to be originally found.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct FilePos(u32);
|
||||
|
||||
impl FilePos {
|
||||
/// Create a new file position with the given offset.
|
||||
pub fn new(pos: u32) -> FilePos {
|
||||
assert!(pos != u32::MAX);
|
||||
FilePos(pos)
|
||||
}
|
||||
|
||||
/// Returns the offset that this offset was created with.
|
||||
///
|
||||
/// Note that the `Default` implementation will return `None` here, whereas
|
||||
/// positions created with `FilePos::new` will return `Some`.
|
||||
pub fn file_offset(self) -> Option<u32> {
|
||||
if self.0 == u32::MAX {
|
||||
None
|
||||
} else {
|
||||
Some(self.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for FilePos {
|
||||
fn default() -> FilePos {
|
||||
FilePos(u32::MAX)
|
||||
}
|
||||
}
|
||||
|
||||
/// Memory definition offset in the VMContext structure.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ModuleMemoryOffset {
|
||||
|
||||
@@ -1,72 +1,79 @@
|
||||
//! A `Compilation` contains the compiled function bodies for a WebAssembly
|
||||
//! module.
|
||||
|
||||
use crate::{FunctionAddressMap, FunctionBodyData, ModuleTranslation, Tunables, TypeTables};
|
||||
use crate::{
|
||||
DefinedFuncIndex, FunctionAddressMap, FunctionBodyData, ModuleTranslation, PrimaryMap,
|
||||
StackMap, Tunables, TypeTables, WasmError, WasmFuncType,
|
||||
};
|
||||
use anyhow::Result;
|
||||
use cranelift_codegen::{binemit, ir, isa::unwind::UnwindInfo};
|
||||
use cranelift_entity::PrimaryMap;
|
||||
use cranelift_wasm::{DefinedFuncIndex, FuncIndex, WasmError, WasmFuncType};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::any::Any;
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use thiserror::Error;
|
||||
|
||||
/// Information about a function, such as trap information, address map,
|
||||
/// and stack maps.
|
||||
#[derive(Serialize, Deserialize, Clone, Default)]
|
||||
#[allow(missing_docs)]
|
||||
pub type CompiledFunctions = PrimaryMap<DefinedFuncIndex, CompiledFunction>;
|
||||
|
||||
/// Compiled function: machine code body, jump table offsets, and unwind information.
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Default)]
|
||||
#[allow(missing_docs)]
|
||||
pub struct CompiledFunction {
|
||||
/// The machine code for this function.
|
||||
pub body: Vec<u8>,
|
||||
|
||||
/// The jump tables offsets (in the body).
|
||||
pub jt_offsets: ir::JumpTableOffsets,
|
||||
|
||||
/// The unwind information.
|
||||
pub unwind_info: Option<UnwindInfo>,
|
||||
|
||||
pub relocations: Vec<Relocation>,
|
||||
pub address_map: FunctionAddressMap,
|
||||
pub value_labels_ranges: cranelift_codegen::ValueLabelsRanges,
|
||||
pub stack_slots: ir::StackSlots,
|
||||
pub struct FunctionInfo {
|
||||
pub traps: Vec<TrapInformation>,
|
||||
pub address_map: FunctionAddressMap,
|
||||
pub stack_maps: Vec<StackMapInformation>,
|
||||
}
|
||||
|
||||
/// A record of a relocation to perform.
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Relocation {
|
||||
/// The relocation code.
|
||||
pub reloc: binemit::Reloc,
|
||||
/// Relocation target.
|
||||
pub reloc_target: RelocationTarget,
|
||||
/// The offset where to apply the relocation.
|
||||
pub offset: binemit::CodeOffset,
|
||||
/// The addend to add to the relocation value.
|
||||
pub addend: binemit::Addend,
|
||||
}
|
||||
|
||||
/// Destination function. Can be either user function or some special one, like `memory.grow`.
|
||||
#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum RelocationTarget {
|
||||
/// The user function index.
|
||||
UserFunc(FuncIndex),
|
||||
/// A compiler-generated libcall.
|
||||
LibCall(ir::LibCall),
|
||||
/// Jump table index.
|
||||
JumpTable(FuncIndex, ir::JumpTable),
|
||||
}
|
||||
|
||||
/// Information about trap.
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct TrapInformation {
|
||||
/// The offset of the trapping instruction in native code. It is relative to the beginning of the function.
|
||||
pub code_offset: binemit::CodeOffset,
|
||||
pub code_offset: u32,
|
||||
/// Code of the trap.
|
||||
pub trap_code: ir::TrapCode,
|
||||
pub trap_code: TrapCode,
|
||||
}
|
||||
|
||||
/// A trap code describing the reason for a trap.
|
||||
///
|
||||
/// All trap instructions have an explicit trap code.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize, Deserialize)]
|
||||
pub enum TrapCode {
|
||||
/// The current stack space was exhausted.
|
||||
StackOverflow,
|
||||
|
||||
/// A `heap_addr` instruction detected an out-of-bounds error.
|
||||
///
|
||||
/// Note that not all out-of-bounds heap accesses are reported this way;
|
||||
/// some are detected by a segmentation fault on the heap unmapped or
|
||||
/// offset-guard pages.
|
||||
HeapOutOfBounds,
|
||||
|
||||
/// A wasm atomic operation was presented with a not-naturally-aligned linear-memory address.
|
||||
HeapMisaligned,
|
||||
|
||||
/// A `table_addr` instruction detected an out-of-bounds error.
|
||||
TableOutOfBounds,
|
||||
|
||||
/// Indirect call to a null table entry.
|
||||
IndirectCallToNull,
|
||||
|
||||
/// Signature mismatch on indirect call.
|
||||
BadSignature,
|
||||
|
||||
/// An integer arithmetic operation caused an overflow.
|
||||
IntegerOverflow,
|
||||
|
||||
/// An integer division by zero.
|
||||
IntegerDivisionByZero,
|
||||
|
||||
/// Failed float-to-int conversion.
|
||||
BadConversionToInteger,
|
||||
|
||||
/// Code that was supposed to have been unreachable was reached.
|
||||
UnreachableCodeReached,
|
||||
|
||||
/// Execution has potentially run too long and may be interrupted.
|
||||
/// This trap is resumable.
|
||||
Interrupt,
|
||||
}
|
||||
|
||||
/// The offset within a function of a GC safepoint, and its associated stack
|
||||
@@ -75,10 +82,10 @@ pub struct TrapInformation {
|
||||
pub struct StackMapInformation {
|
||||
/// The offset of the GC safepoint within the function's native code. It is
|
||||
/// relative to the beginning of the function.
|
||||
pub code_offset: binemit::CodeOffset,
|
||||
pub code_offset: u32,
|
||||
|
||||
/// The stack map for identifying live GC refs at the GC safepoint.
|
||||
pub stack_map: binemit::StackMap,
|
||||
pub stack_map: StackMap,
|
||||
}
|
||||
|
||||
/// An error while compiling WebAssembly to machine code.
|
||||
@@ -175,7 +182,7 @@ pub trait Compiler: Send + Sync {
|
||||
data: FunctionBodyData<'_>,
|
||||
tunables: &Tunables,
|
||||
types: &TypeTables,
|
||||
) -> Result<CompiledFunction, CompileError>;
|
||||
) -> Result<Box<dyn Any + Send>, CompileError>;
|
||||
|
||||
/// Collects the results of compilation and emits an in-memory ELF object
|
||||
/// which is the serialized representation of all compiler artifacts.
|
||||
@@ -185,9 +192,9 @@ pub trait Compiler: Send + Sync {
|
||||
&self,
|
||||
module: &ModuleTranslation,
|
||||
types: &TypeTables,
|
||||
funcs: &CompiledFunctions,
|
||||
funcs: PrimaryMap<DefinedFuncIndex, Box<dyn Any + Send>>,
|
||||
emit_dwarf: bool,
|
||||
) -> Result<Vec<u8>>;
|
||||
) -> Result<(Vec<u8>, PrimaryMap<DefinedFuncIndex, FunctionInfo>)>;
|
||||
|
||||
/// Emits a small ELF object file in-memory which has two functions for the
|
||||
/// host-to-wasm and wasm-to-host trampolines for the wasm type given.
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#![doc(hidden)]
|
||||
|
||||
pub mod ir {
|
||||
pub use cranelift_codegen::binemit::StackMap;
|
||||
pub use cranelift_codegen::ir::{types, SourceLoc, TrapCode, Type};
|
||||
}
|
||||
|
||||
pub mod entity {
|
||||
pub use cranelift_entity::{packed_option, BoxedSlice, EntityRef, EntitySet, PrimaryMap};
|
||||
}
|
||||
|
||||
pub mod wasm {
|
||||
pub use cranelift_wasm::*;
|
||||
}
|
||||
@@ -26,22 +26,28 @@
|
||||
mod address_map;
|
||||
mod builtin;
|
||||
mod compilation;
|
||||
mod data_structures;
|
||||
mod module;
|
||||
mod module_environ;
|
||||
pub mod obj;
|
||||
mod stack_map;
|
||||
mod tunables;
|
||||
mod vmoffsets;
|
||||
|
||||
pub use crate::address_map::*;
|
||||
pub use crate::builtin::*;
|
||||
pub use crate::compilation::*;
|
||||
pub use crate::data_structures::*;
|
||||
pub use crate::module::*;
|
||||
pub use crate::module_environ::*;
|
||||
pub use crate::stack_map::StackMap;
|
||||
pub use crate::tunables::Tunables;
|
||||
pub use crate::vmoffsets::*;
|
||||
|
||||
// Reexport all of these type-level since they're quite commonly used and it's
|
||||
// much easier to refer to everything through one crate rather than importing
|
||||
// one of three and making sure you're using the right one.
|
||||
pub use cranelift_entity::*;
|
||||
pub use wasmtime_types::*;
|
||||
|
||||
/// WebAssembly page sizes are defined to be 64KiB.
|
||||
pub const WASM_PAGE_SIZE: u32 = 0x10000;
|
||||
|
||||
@@ -55,19 +61,6 @@ pub const WASM64_MAX_PAGES: u64 = 1 << 48;
|
||||
/// Version number of this crate.
|
||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
|
||||
/// Returns the reference type to use for the provided wasm type.
|
||||
pub fn reference_type(wasm_ty: cranelift_wasm::WasmType, pointer_type: ir::Type) -> ir::Type {
|
||||
match wasm_ty {
|
||||
cranelift_wasm::WasmType::FuncRef => pointer_type,
|
||||
cranelift_wasm::WasmType::ExternRef => match pointer_type {
|
||||
ir::types::I32 => ir::types::R32,
|
||||
ir::types::I64 => ir::types::R64,
|
||||
_ => panic!("unsupported pointer type"),
|
||||
},
|
||||
_ => panic!("unsupported Wasm reference type"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterates through all `LibCall` members and all runtime exported functions.
|
||||
#[macro_export]
|
||||
macro_rules! for_each_libcall {
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
//! Data structures for representing decoded wasm modules.
|
||||
|
||||
use crate::tunables::Tunables;
|
||||
use cranelift_entity::{EntityRef, PrimaryMap};
|
||||
use cranelift_wasm::*;
|
||||
use crate::{EntityRef, PrimaryMap, Tunables};
|
||||
use indexmap::IndexMap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::convert::TryFrom;
|
||||
use std::sync::Arc;
|
||||
use wasmtime_types::*;
|
||||
|
||||
/// Implemenation styles for WebAssembly linear memory.
|
||||
#[derive(Debug, Clone, Hash, Serialize, Deserialize)]
|
||||
@@ -267,7 +266,7 @@ impl TableStyle {
|
||||
#[derive(Debug, Clone, Hash, Serialize, Deserialize)]
|
||||
pub struct TablePlan {
|
||||
/// The WebAssembly table description.
|
||||
pub table: cranelift_wasm::Table,
|
||||
pub table: Table,
|
||||
/// Our chosen implementation style.
|
||||
pub style: TableStyle,
|
||||
}
|
||||
|
||||
@@ -2,15 +2,13 @@ use crate::module::{
|
||||
Initializer, InstanceSignature, MemoryInitialization, MemoryInitializer, MemoryPlan, Module,
|
||||
ModuleSignature, ModuleType, ModuleUpvar, TableInitializer, TablePlan, TypeTables,
|
||||
};
|
||||
use crate::tunables::Tunables;
|
||||
use cranelift_codegen::ir::immediates::V128Imm;
|
||||
use cranelift_codegen::packed_option::ReservedValue;
|
||||
use cranelift_entity::PrimaryMap;
|
||||
use cranelift_wasm::{
|
||||
self, DataIndex, DefinedFuncIndex, ElemIndex, EntityIndex, EntityType, FuncIndex, Global,
|
||||
use crate::{
|
||||
DataIndex, DefinedFuncIndex, ElemIndex, EntityIndex, EntityType, FuncIndex, Global,
|
||||
GlobalIndex, GlobalInit, InstanceIndex, InstanceTypeIndex, MemoryIndex, ModuleIndex,
|
||||
ModuleTypeIndex, SignatureIndex, TableIndex, TypeIndex, WasmError, WasmFuncType, WasmResult,
|
||||
ModuleTypeIndex, PrimaryMap, SignatureIndex, TableIndex, Tunables, TypeIndex, WasmError,
|
||||
WasmFuncType, WasmResult,
|
||||
};
|
||||
use cranelift_entity::packed_option::ReservedValue;
|
||||
use std::collections::{hash_map::Entry, HashMap};
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use std::mem;
|
||||
@@ -396,7 +394,7 @@ impl<'data> ModuleEnvironment<'data> {
|
||||
Operator::F32Const { value } => GlobalInit::F32Const(value.bits()),
|
||||
Operator::F64Const { value } => GlobalInit::F64Const(value.bits()),
|
||||
Operator::V128Const { value } => {
|
||||
GlobalInit::V128Const(V128Imm::from(value.bytes().to_vec().as_slice()))
|
||||
GlobalInit::V128Const(u128::from_le_bytes(*value.bytes()))
|
||||
}
|
||||
Operator::RefNull { ty: _ } => GlobalInit::RefNullConst,
|
||||
Operator::RefFunc { function_index } => {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
//! Utilities for working with object files that operate as Wasmtime's
|
||||
//! serialization and intermediate format for compiled modules.
|
||||
|
||||
use cranelift_entity::EntityRef;
|
||||
use cranelift_wasm::{FuncIndex, SignatureIndex};
|
||||
use crate::{EntityRef, FuncIndex, SignatureIndex};
|
||||
|
||||
const FUNCTION_PREFIX: &str = "_wasm_function_";
|
||||
const TRAMPOLINE_PREFIX: &str = "_trampoline_";
|
||||
|
||||
36
crates/environ/src/stack_map.rs
Normal file
36
crates/environ/src/stack_map.rs
Normal file
@@ -0,0 +1,36 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// A map for determining where live GC references live in a stack frame.
|
||||
///
|
||||
/// Note that this is currently primarily documented as cranelift's
|
||||
/// `binemit::StackMap`, so for detailed documentation about this please read
|
||||
/// the docs over there.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct StackMap {
|
||||
bits: Box<[u32]>,
|
||||
mapped_words: u32,
|
||||
}
|
||||
|
||||
impl StackMap {
|
||||
/// Creates a new `StackMap`, typically from a preexisting
|
||||
/// `binemit::StackMap`.
|
||||
pub fn new(mapped_words: u32, bits: impl Iterator<Item = u32>) -> StackMap {
|
||||
StackMap {
|
||||
bits: bits.collect(),
|
||||
mapped_words,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a specified bit.
|
||||
pub fn get_bit(&self, bit_index: usize) -> bool {
|
||||
assert!(bit_index < 32 * self.bits.len());
|
||||
let word_index = bit_index / 32;
|
||||
let word_offset = bit_index % 32;
|
||||
(self.bits[word_index] & (1 << word_offset)) != 0
|
||||
}
|
||||
|
||||
/// Returns the number of words represented by this stack map.
|
||||
pub fn mapped_words(&self) -> u32 {
|
||||
self.mapped_words
|
||||
}
|
||||
}
|
||||
@@ -19,12 +19,9 @@
|
||||
// builtins: VMBuiltinFunctionsArray,
|
||||
// }
|
||||
|
||||
use crate::module::Module;
|
||||
use crate::BuiltinFunctionIndex;
|
||||
use cranelift_codegen::ir;
|
||||
use cranelift_wasm::{
|
||||
DefinedGlobalIndex, DefinedMemoryIndex, DefinedTableIndex, FuncIndex, GlobalIndex, MemoryIndex,
|
||||
TableIndex, TypeIndex,
|
||||
use crate::{
|
||||
BuiltinFunctionIndex, DefinedGlobalIndex, DefinedMemoryIndex, DefinedTableIndex, FuncIndex,
|
||||
GlobalIndex, MemoryIndex, Module, TableIndex, TypeIndex,
|
||||
};
|
||||
use more_asserts::assert_lt;
|
||||
use std::convert::TryFrom;
|
||||
@@ -375,12 +372,6 @@ impl<P: PtrSize> VMOffsets<P> {
|
||||
pub fn size_of_vmtable_definition(&self) -> u8 {
|
||||
2 * self.pointer_size()
|
||||
}
|
||||
|
||||
/// The type of the `current_elements` field.
|
||||
#[inline]
|
||||
pub fn type_of_vmtable_definition_current_elements(&self) -> ir::Type {
|
||||
ir::Type::int(u16::from(self.size_of_vmtable_definition_current_elements()) * 8).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
/// Offsets for `VMMemoryImport`.
|
||||
|
||||
@@ -6,7 +6,7 @@ use object::read::{File as ObjectFile, Object, ObjectSection, ObjectSymbol};
|
||||
use std::collections::BTreeMap;
|
||||
use std::mem::ManuallyDrop;
|
||||
use wasmtime_environ::obj::{try_parse_func_name, try_parse_trampoline_name};
|
||||
use wasmtime_environ::wasm::{FuncIndex, SignatureIndex};
|
||||
use wasmtime_environ::{FuncIndex, SignatureIndex};
|
||||
use wasmtime_runtime::{Mmap, VMFunctionBody};
|
||||
|
||||
struct CodeMemoryEntry {
|
||||
|
||||
@@ -9,8 +9,8 @@ use std::hash::{Hash, Hasher};
|
||||
use std::mem;
|
||||
use wasmparser::WasmFeatures;
|
||||
use wasmtime_environ::{
|
||||
CompiledFunctions, Compiler as EnvCompiler, CompilerBuilder, ModuleTranslation, Tunables,
|
||||
TypeTables,
|
||||
Compiler as EnvCompiler, CompilerBuilder, DefinedFuncIndex, FunctionInfo, ModuleTranslation,
|
||||
PrimaryMap, Tunables, TypeTables,
|
||||
};
|
||||
|
||||
/// Select which kind of compilation to use.
|
||||
@@ -72,7 +72,7 @@ fn _assert_compiler_send_sync() {
|
||||
#[allow(missing_docs)]
|
||||
pub struct Compilation {
|
||||
pub obj: Vec<u8>,
|
||||
pub funcs: CompiledFunctions,
|
||||
pub funcs: PrimaryMap<DefinedFuncIndex, FunctionInfo>,
|
||||
}
|
||||
|
||||
impl Compiler {
|
||||
@@ -111,12 +111,12 @@ impl Compiler {
|
||||
.compile_function(translation, index, func, &self.tunables, types)
|
||||
})?
|
||||
.into_iter()
|
||||
.collect::<CompiledFunctions>();
|
||||
.collect();
|
||||
|
||||
let obj = self.compiler.emit_obj(
|
||||
let (obj, funcs) = self.compiler.emit_obj(
|
||||
&translation,
|
||||
types,
|
||||
&funcs,
|
||||
funcs,
|
||||
self.tunables.generate_native_debuginfo,
|
||||
)?;
|
||||
|
||||
|
||||
@@ -12,13 +12,10 @@ use serde::{Deserialize, Serialize};
|
||||
use std::ops::Range;
|
||||
use std::sync::Arc;
|
||||
use thiserror::Error;
|
||||
use wasmtime_environ::entity::PrimaryMap;
|
||||
use wasmtime_environ::wasm::{
|
||||
DefinedFuncIndex, InstanceTypeIndex, ModuleTypeIndex, SignatureIndex, WasmFuncType,
|
||||
};
|
||||
use wasmtime_environ::{
|
||||
CompileError, DebugInfoData, FunctionAddressMap, InstanceSignature, Module, ModuleEnvironment,
|
||||
ModuleSignature, ModuleTranslation, StackMapInformation, TrapInformation,
|
||||
CompileError, DebugInfoData, DefinedFuncIndex, FunctionInfo, InstanceSignature,
|
||||
InstanceTypeIndex, Module, ModuleEnvironment, ModuleSignature, ModuleTranslation,
|
||||
ModuleTypeIndex, PrimaryMap, SignatureIndex, StackMapInformation, WasmFuncType,
|
||||
};
|
||||
use wasmtime_profiling::ProfilingAgent;
|
||||
use wasmtime_runtime::{GdbJitImageRegistration, InstantiationError, VMFunctionBody, VMTrampoline};
|
||||
@@ -158,15 +155,6 @@ struct FinishedFunctions(PrimaryMap<DefinedFuncIndex, *mut [VMFunctionBody]>);
|
||||
unsafe impl Send for FinishedFunctions {}
|
||||
unsafe impl Sync for FinishedFunctions {}
|
||||
|
||||
/// Information about a function, such as trap information, address map,
|
||||
/// and stack maps.
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct FunctionInfo {
|
||||
pub traps: Vec<TrapInformation>,
|
||||
pub address_map: FunctionAddressMap,
|
||||
pub stack_maps: Vec<StackMapInformation>,
|
||||
}
|
||||
|
||||
/// This is intended to mirror the type tables in `wasmtime_environ`, except that
|
||||
/// it doesn't store the native signatures which are no longer needed past compilation.
|
||||
#[derive(Serialize, Deserialize)]
|
||||
|
||||
@@ -3,10 +3,8 @@
|
||||
use object::read::{Object, ObjectSection, Relocation, RelocationTarget};
|
||||
use object::{elf, File, ObjectSymbol, RelocationEncoding, RelocationKind};
|
||||
use std::ptr::{read_unaligned, write_unaligned};
|
||||
use wasmtime_environ::entity::PrimaryMap;
|
||||
use wasmtime_environ::obj::try_parse_func_name;
|
||||
use wasmtime_environ::wasm::DefinedFuncIndex;
|
||||
use wasmtime_environ::Module;
|
||||
use wasmtime_environ::{DefinedFuncIndex, Module, PrimaryMap};
|
||||
use wasmtime_runtime::libcalls;
|
||||
use wasmtime_runtime::VMFunctionBody;
|
||||
|
||||
|
||||
@@ -8,15 +8,15 @@
|
||||
use anyhow::Result;
|
||||
use cranelift_codegen::binemit;
|
||||
use cranelift_codegen::ir::{self, ExternalName};
|
||||
use std::any::Any;
|
||||
use std::collections::HashMap;
|
||||
use wasmtime_environ::wasm::{
|
||||
DefinedFuncIndex, DefinedGlobalIndex, DefinedMemoryIndex, DefinedTableIndex, FuncIndex,
|
||||
GlobalIndex, MemoryIndex, TableIndex, TypeIndex, WasmFuncType,
|
||||
use wasmtime_environ::{
|
||||
BuiltinFunctionIndex, CompileError, Compiler, FlagValue, FunctionBodyData, FunctionInfo,
|
||||
Module, ModuleTranslation, PrimaryMap, TrapInformation, Tunables, TypeTables, VMOffsets,
|
||||
};
|
||||
use wasmtime_environ::{
|
||||
BuiltinFunctionIndex, CompileError, CompiledFunction, CompiledFunctions, Compiler, FlagValue,
|
||||
FunctionBodyData, Module, ModuleTranslation, Relocation, RelocationTarget, TrapInformation,
|
||||
Tunables, TypeTables, VMOffsets,
|
||||
DefinedFuncIndex, DefinedGlobalIndex, DefinedMemoryIndex, DefinedTableIndex, FuncIndex,
|
||||
GlobalIndex, MemoryIndex, TableIndex, TypeIndex, WasmFuncType,
|
||||
};
|
||||
|
||||
/// A compiler that compiles a WebAssembly module with Lightbeam, directly translating the Wasm file.
|
||||
@@ -30,7 +30,7 @@ impl Compiler for Lightbeam {
|
||||
_function_body: FunctionBodyData<'_>,
|
||||
_tunables: &Tunables,
|
||||
_types: &TypeTables,
|
||||
) -> Result<CompiledFunction, CompileError> {
|
||||
) -> Result<Box<dyn Any + Send>, CompileError> {
|
||||
unimplemented!()
|
||||
// if tunables.generate_native_debuginfo {
|
||||
// return Err(CompileError::DebugInfoNotSupported);
|
||||
@@ -82,9 +82,9 @@ impl Compiler for Lightbeam {
|
||||
&self,
|
||||
_module: &ModuleTranslation,
|
||||
_types: &TypeTables,
|
||||
_funcs: &CompiledFunctions,
|
||||
_funcs: PrimaryMap<DefinedFuncIndex, Box<dyn Any + Send>>,
|
||||
_emit_dwarf: bool,
|
||||
) -> Result<Vec<u8>> {
|
||||
) -> Result<(Vec<u8>, PrimaryMap<DefinedFuncIndex, FunctionInfo>)> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
@@ -109,34 +109,34 @@ impl Compiler for Lightbeam {
|
||||
struct RelocSink {
|
||||
/// Current function index.
|
||||
func_index: FuncIndex,
|
||||
|
||||
/// Relocations recorded for the function.
|
||||
func_relocs: Vec<Relocation>,
|
||||
// /// Relocations recorded for the function.
|
||||
// func_relocs: Vec<Relocation>,
|
||||
}
|
||||
|
||||
impl binemit::RelocSink for RelocSink {
|
||||
fn reloc_external(
|
||||
&mut self,
|
||||
offset: binemit::CodeOffset,
|
||||
_offset: binemit::CodeOffset,
|
||||
_srcloc: ir::SourceLoc,
|
||||
reloc: binemit::Reloc,
|
||||
name: &ExternalName,
|
||||
addend: binemit::Addend,
|
||||
_reloc: binemit::Reloc,
|
||||
_name: &ExternalName,
|
||||
_addend: binemit::Addend,
|
||||
) {
|
||||
let reloc_target = if let ExternalName::User { namespace, index } = *name {
|
||||
debug_assert_eq!(namespace, 0);
|
||||
RelocationTarget::UserFunc(FuncIndex::from_u32(index))
|
||||
} else if let ExternalName::LibCall(libcall) = *name {
|
||||
RelocationTarget::LibCall(libcall)
|
||||
} else {
|
||||
panic!("unrecognized external name")
|
||||
};
|
||||
self.func_relocs.push(Relocation {
|
||||
reloc,
|
||||
reloc_target,
|
||||
offset,
|
||||
addend,
|
||||
});
|
||||
unimplemented!()
|
||||
// let reloc_target = if let ExternalName::User { namespace, index } = *name {
|
||||
// debug_assert_eq!(namespace, 0);
|
||||
// RelocationTarget::UserFunc(FuncIndex::from_u32(index))
|
||||
// } else if let ExternalName::LibCall(libcall) = *name {
|
||||
// RelocationTarget::LibCall(libcall)
|
||||
// } else {
|
||||
// panic!("unrecognized external name")
|
||||
// };
|
||||
// self.func_relocs.push(Relocation {
|
||||
// reloc,
|
||||
// reloc_target,
|
||||
// offset,
|
||||
// addend,
|
||||
// });
|
||||
}
|
||||
|
||||
fn reloc_constant(
|
||||
@@ -149,13 +149,19 @@ impl binemit::RelocSink for RelocSink {
|
||||
// function code with correct relative offsets to the constant data.
|
||||
}
|
||||
|
||||
fn reloc_jt(&mut self, offset: binemit::CodeOffset, reloc: binemit::Reloc, jt: ir::JumpTable) {
|
||||
self.func_relocs.push(Relocation {
|
||||
reloc,
|
||||
reloc_target: RelocationTarget::JumpTable(self.func_index, jt),
|
||||
offset,
|
||||
addend: 0,
|
||||
});
|
||||
fn reloc_jt(
|
||||
&mut self,
|
||||
_offset: binemit::CodeOffset,
|
||||
_reloc: binemit::Reloc,
|
||||
_jt: ir::JumpTable,
|
||||
) {
|
||||
unimplemented!()
|
||||
// self.func_relocs.push(Relocation {
|
||||
// reloc,
|
||||
// reloc_target: RelocationTarget::JumpTable(self.func_index, jt),
|
||||
// offset,
|
||||
// addend: 0,
|
||||
// });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,7 +170,7 @@ impl RelocSink {
|
||||
fn new(func_index: FuncIndex) -> Self {
|
||||
Self {
|
||||
func_index,
|
||||
func_relocs: Vec::new(),
|
||||
// func_relocs: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -186,14 +192,15 @@ impl TrapSink {
|
||||
impl binemit::TrapSink for TrapSink {
|
||||
fn trap(
|
||||
&mut self,
|
||||
code_offset: binemit::CodeOffset,
|
||||
_code_offset: binemit::CodeOffset,
|
||||
_source_loc: ir::SourceLoc,
|
||||
trap_code: ir::TrapCode,
|
||||
_trap_code: ir::TrapCode,
|
||||
) {
|
||||
self.traps.push(TrapInformation {
|
||||
code_offset,
|
||||
trap_code,
|
||||
});
|
||||
unimplemented!()
|
||||
// self.traps.push(TrapInformation {
|
||||
// code_offset,
|
||||
// trap_code,
|
||||
// });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
use crate::ProfilingAgent;
|
||||
use anyhow::{bail, Result};
|
||||
use wasmtime_environ::entity::PrimaryMap;
|
||||
use wasmtime_environ::wasm::DefinedFuncIndex;
|
||||
use wasmtime_environ::Module;
|
||||
use wasmtime_environ::{DefinedFuncIndex, Module, PrimaryMap};
|
||||
use wasmtime_runtime::VMFunctionBody;
|
||||
|
||||
/// Interface for driving the creation of jitdump files
|
||||
|
||||
@@ -25,9 +25,7 @@ use std::ptr;
|
||||
use std::sync::Mutex;
|
||||
use std::{borrow, mem, process};
|
||||
use target_lexicon::Architecture;
|
||||
use wasmtime_environ::entity::PrimaryMap;
|
||||
use wasmtime_environ::wasm::DefinedFuncIndex;
|
||||
use wasmtime_environ::Module;
|
||||
use wasmtime_environ::{DefinedFuncIndex, Module, PrimaryMap};
|
||||
use wasmtime_runtime::VMFunctionBody;
|
||||
|
||||
use object::elf;
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
use wasmtime_environ::entity::{EntityRef, PrimaryMap};
|
||||
use wasmtime_environ::wasm::DefinedFuncIndex;
|
||||
use wasmtime_environ::Module;
|
||||
use wasmtime_environ::{DefinedFuncIndex, EntityRef, Module, PrimaryMap};
|
||||
use wasmtime_runtime::VMFunctionBody;
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
use crate::ProfilingAgent;
|
||||
use anyhow::{bail, Result};
|
||||
use wasmtime_environ::entity::PrimaryMap;
|
||||
use wasmtime_environ::wasm::DefinedFuncIndex;
|
||||
use wasmtime_environ::Module;
|
||||
use wasmtime_environ::{DefinedFuncIndex, Module, PrimaryMap};
|
||||
use wasmtime_runtime::VMFunctionBody;
|
||||
|
||||
/// Interface for driving vtune support
|
||||
|
||||
@@ -10,12 +10,12 @@
|
||||
use crate::ProfilingAgent;
|
||||
use anyhow::Result;
|
||||
use core::ptr;
|
||||
use cranelift_entity::PrimaryMap;
|
||||
use cranelift_wasm_types::DefinedFuncIndex;
|
||||
use ittapi_rs::*;
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::CString;
|
||||
use std::sync::Mutex;
|
||||
use wasmtime_environ::entity::PrimaryMap;
|
||||
use wasmtime_environ::wasm::DefinedFuncIndex;
|
||||
use wasmtime_environ::Module;
|
||||
use wasmtime_runtime::VMFunctionBody;
|
||||
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
use crate::instance::InstanceHandle;
|
||||
use crate::vmcontext::VMContext;
|
||||
use wasmtime_environ::entity::EntityRef;
|
||||
use wasmtime_environ::wasm::MemoryIndex;
|
||||
use wasmtime_environ::{EntityRef, MemoryIndex};
|
||||
|
||||
static mut VMCTX_AND_MEMORY: (*mut VMContext, usize) = (std::ptr::null_mut(), 0);
|
||||
|
||||
|
||||
@@ -2,8 +2,7 @@ use crate::vmcontext::{
|
||||
VMCallerCheckedAnyfunc, VMContext, VMGlobalDefinition, VMMemoryDefinition, VMTableDefinition,
|
||||
};
|
||||
use std::ptr::NonNull;
|
||||
use wasmtime_environ::wasm::Global;
|
||||
use wasmtime_environ::{MemoryPlan, TablePlan};
|
||||
use wasmtime_environ::{Global, MemoryPlan, TablePlan};
|
||||
|
||||
/// The value of an export passed from one instance to another.
|
||||
pub enum Export {
|
||||
|
||||
@@ -109,7 +109,7 @@ use std::ops::Deref;
|
||||
use std::ptr::{self, NonNull};
|
||||
use std::sync::atomic::{self, AtomicUsize, Ordering};
|
||||
use std::{alloc::Layout, sync::Arc};
|
||||
use wasmtime_environ::ir::StackMap;
|
||||
use wasmtime_environ::StackMap;
|
||||
|
||||
/// An external reference to some opaque data.
|
||||
///
|
||||
|
||||
@@ -22,12 +22,11 @@ use std::hash::Hash;
|
||||
use std::ptr::NonNull;
|
||||
use std::sync::Arc;
|
||||
use std::{mem, ptr, slice};
|
||||
use wasmtime_environ::entity::{packed_option::ReservedValue, EntityRef, EntitySet, PrimaryMap};
|
||||
use wasmtime_environ::wasm::{
|
||||
DataIndex, DefinedGlobalIndex, DefinedMemoryIndex, DefinedTableIndex, ElemIndex, EntityIndex,
|
||||
FuncIndex, GlobalIndex, MemoryIndex, TableIndex, WasmType,
|
||||
use wasmtime_environ::{
|
||||
packed_option::ReservedValue, DataIndex, DefinedGlobalIndex, DefinedMemoryIndex,
|
||||
DefinedTableIndex, ElemIndex, EntityIndex, EntityRef, EntitySet, FuncIndex, GlobalIndex,
|
||||
HostPtr, MemoryIndex, Module, PrimaryMap, TableIndex, TrapCode, VMOffsets, WasmType,
|
||||
};
|
||||
use wasmtime_environ::{ir, HostPtr, Module, VMOffsets};
|
||||
|
||||
mod allocator;
|
||||
|
||||
@@ -571,7 +570,7 @@ impl Instance {
|
||||
.and_then(|s| s.get(..usize::try_from(len).unwrap()))
|
||||
{
|
||||
Some(elements) => elements,
|
||||
None => return Err(Trap::wasm(ir::TrapCode::TableOutOfBounds)),
|
||||
None => return Err(Trap::wasm(TrapCode::TableOutOfBounds)),
|
||||
};
|
||||
|
||||
match table.element_type() {
|
||||
@@ -649,7 +648,7 @@ impl Instance {
|
||||
}
|
||||
|
||||
fn validate_inbounds(&self, max: usize, ptr: u64, len: u64) -> Result<usize, Trap> {
|
||||
let oob = || Trap::wasm(ir::TrapCode::HeapOutOfBounds);
|
||||
let oob = || Trap::wasm(TrapCode::HeapOutOfBounds);
|
||||
let end = ptr
|
||||
.checked_add(len)
|
||||
.and_then(|i| usize::try_from(i).ok())
|
||||
|
||||
@@ -17,13 +17,10 @@ use std::ptr::{self, NonNull};
|
||||
use std::slice;
|
||||
use std::sync::Arc;
|
||||
use thiserror::Error;
|
||||
use wasmtime_environ::entity::{EntityRef, EntitySet, PrimaryMap};
|
||||
use wasmtime_environ::wasm::{
|
||||
DefinedFuncIndex, DefinedMemoryIndex, DefinedTableIndex, GlobalInit, SignatureIndex, WasmType,
|
||||
};
|
||||
use wasmtime_environ::{
|
||||
ir, HostPtr, MemoryInitialization, MemoryInitializer, Module, ModuleType, TableInitializer,
|
||||
VMOffsets, WASM_PAGE_SIZE,
|
||||
DefinedFuncIndex, DefinedMemoryIndex, DefinedTableIndex, EntityRef, EntitySet, GlobalInit,
|
||||
HostPtr, MemoryInitialization, MemoryInitializer, Module, ModuleType, PrimaryMap,
|
||||
SignatureIndex, TableInitializer, TrapCode, VMOffsets, WasmType, WASM_PAGE_SIZE,
|
||||
};
|
||||
|
||||
mod pooling;
|
||||
@@ -408,7 +405,7 @@ fn initialize_instance(
|
||||
// the expected behavior of the bulk memory spec.
|
||||
if *out_of_bounds {
|
||||
return Err(InstantiationError::Trap(Trap::wasm(
|
||||
ir::TrapCode::HeapOutOfBounds,
|
||||
TrapCode::HeapOutOfBounds,
|
||||
)));
|
||||
}
|
||||
}
|
||||
@@ -533,7 +530,7 @@ unsafe fn initialize_vmcontext_globals(instance: &Instance) {
|
||||
GlobalInit::I64Const(x) => *(*to).as_i64_mut() = x,
|
||||
GlobalInit::F32Const(x) => *(*to).as_f32_bits_mut() = x,
|
||||
GlobalInit::F64Const(x) => *(*to).as_f64_bits_mut() = x,
|
||||
GlobalInit::V128Const(x) => *(*to).as_u128_bits_mut() = x.0,
|
||||
GlobalInit::V128Const(x) => *(*to).as_u128_mut() = x,
|
||||
GlobalInit::GetGlobal(x) => {
|
||||
let from = if let Some(def_x) = module.defined_global_index(x) {
|
||||
instance.global(def_x)
|
||||
|
||||
@@ -20,8 +20,8 @@ use std::marker;
|
||||
use std::mem;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use wasmtime_environ::{
|
||||
entity::{EntitySet, PrimaryMap},
|
||||
HostPtr, MemoryStyle, Module, Tunables, VMOffsets, VMOffsetsFields, WASM_PAGE_SIZE,
|
||||
EntitySet, HostPtr, MemoryStyle, Module, PrimaryMap, Tunables, VMOffsets, VMOffsetsFields,
|
||||
WASM_PAGE_SIZE,
|
||||
};
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
@@ -1000,7 +1000,7 @@ unsafe impl InstanceAllocator for PoolingInstanceAllocator {
|
||||
// If there was an out of bounds access observed in initialization, return a trap
|
||||
if *out_of_bounds {
|
||||
return Err(InstantiationError::Trap(crate::traphandlers::Trap::wasm(
|
||||
wasmtime_environ::ir::TrapCode::HeapOutOfBounds,
|
||||
wasmtime_environ::TrapCode::HeapOutOfBounds,
|
||||
)));
|
||||
}
|
||||
|
||||
@@ -1050,9 +1050,8 @@ mod test {
|
||||
use super::*;
|
||||
use crate::{Imports, VMSharedSignatureIndex};
|
||||
use wasmtime_environ::{
|
||||
entity::EntityRef,
|
||||
wasm::{Global, GlobalInit, Memory, SignatureIndex, Table, WasmType},
|
||||
MemoryPlan, ModuleType, TablePlan, TableStyle,
|
||||
EntityRef, Global, GlobalInit, Memory, MemoryPlan, ModuleType, SignatureIndex, Table,
|
||||
TablePlan, TableStyle, WasmType,
|
||||
};
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -35,7 +35,7 @@ use crate::instance::Instance;
|
||||
use anyhow::{bail, Context, Result};
|
||||
use std::thread;
|
||||
use userfaultfd::{Event, FeatureFlags, IoctlFlags, Uffd, UffdBuilder};
|
||||
use wasmtime_environ::{entity::EntityRef, wasm::DefinedMemoryIndex, MemoryInitialization};
|
||||
use wasmtime_environ::{DefinedMemoryIndex, EntityRef, MemoryInitialization};
|
||||
|
||||
const WASM_PAGE_SIZE: usize = wasmtime_environ::WASM_PAGE_SIZE as usize;
|
||||
|
||||
@@ -441,9 +441,7 @@ mod test {
|
||||
PoolingAllocationStrategy, VMSharedSignatureIndex,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
use wasmtime_environ::{
|
||||
entity::PrimaryMap, wasm::Memory, MemoryPlan, MemoryStyle, Module, Tunables,
|
||||
};
|
||||
use wasmtime_environ::{Memory, MemoryPlan, MemoryStyle, Module, PrimaryMap, Tunables};
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
#[test]
|
||||
|
||||
@@ -62,28 +62,6 @@ pub use crate::vmcontext::{
|
||||
/// Version number of this crate.
|
||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
|
||||
/// The Cranelift IR type used for reference types for this target architecture.
|
||||
pub fn ref_type() -> wasmtime_environ::ir::Type {
|
||||
if cfg!(target_pointer_width = "32") {
|
||||
wasmtime_environ::ir::types::R32
|
||||
} else if cfg!(target_pointer_width = "64") {
|
||||
wasmtime_environ::ir::types::R64
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
/// The Cranelift IR type used for pointer types for this target architecture.
|
||||
pub fn pointer_type() -> wasmtime_environ::ir::Type {
|
||||
if cfg!(target_pointer_width = "32") {
|
||||
wasmtime_environ::ir::types::I32
|
||||
} else if cfg!(target_pointer_width = "64") {
|
||||
wasmtime_environ::ir::types::I64
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
/// Dynamic runtime functionality needed by this crate throughout the execution
|
||||
/// of a wasm instance.
|
||||
///
|
||||
|
||||
@@ -64,8 +64,7 @@ use crate::vmcontext::{VMCallerCheckedAnyfunc, VMContext};
|
||||
use backtrace::Backtrace;
|
||||
use std::mem;
|
||||
use std::ptr::{self, NonNull};
|
||||
use wasmtime_environ::ir::TrapCode;
|
||||
use wasmtime_environ::wasm::{DataIndex, ElemIndex, GlobalIndex, MemoryIndex, TableIndex};
|
||||
use wasmtime_environ::{DataIndex, ElemIndex, GlobalIndex, MemoryIndex, TableIndex, TrapCode};
|
||||
|
||||
const TOINT_32: f32 = 1.0 / f32::EPSILON;
|
||||
const TOINT_64: f64 = 1.0 / f64::EPSILON;
|
||||
|
||||
@@ -8,8 +8,7 @@ use anyhow::{bail, Result};
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use std::ops::Range;
|
||||
use std::ptr;
|
||||
use wasmtime_environ::wasm::WasmType;
|
||||
use wasmtime_environ::{ir, TablePlan};
|
||||
use wasmtime_environ::{TablePlan, TrapCode, WasmType};
|
||||
|
||||
/// An element going into or coming out of a table.
|
||||
///
|
||||
@@ -237,7 +236,7 @@ impl Table {
|
||||
.and_then(|s| s.get_mut(..items.len()))
|
||||
{
|
||||
Some(elements) => elements,
|
||||
None => return Err(Trap::wasm(ir::TrapCode::TableOutOfBounds)),
|
||||
None => return Err(Trap::wasm(TrapCode::TableOutOfBounds)),
|
||||
};
|
||||
|
||||
for (item, slot) in items.zip(elements) {
|
||||
@@ -253,10 +252,10 @@ impl Table {
|
||||
let start = dst as usize;
|
||||
let end = start
|
||||
.checked_add(len as usize)
|
||||
.ok_or_else(|| Trap::wasm(ir::TrapCode::TableOutOfBounds))?;
|
||||
.ok_or_else(|| Trap::wasm(TrapCode::TableOutOfBounds))?;
|
||||
|
||||
if end > self.size() as usize {
|
||||
return Err(Trap::wasm(ir::TrapCode::TableOutOfBounds));
|
||||
return Err(Trap::wasm(TrapCode::TableOutOfBounds));
|
||||
}
|
||||
|
||||
debug_assert!(self.type_matches(&val));
|
||||
@@ -379,7 +378,7 @@ impl Table {
|
||||
.checked_add(len)
|
||||
.map_or(true, |m| m > (*dst_table).size())
|
||||
{
|
||||
return Err(Trap::wasm(ir::TrapCode::TableOutOfBounds));
|
||||
return Err(Trap::wasm(TrapCode::TableOutOfBounds));
|
||||
}
|
||||
|
||||
debug_assert!(
|
||||
|
||||
@@ -10,7 +10,7 @@ use std::mem::MaybeUninit;
|
||||
use std::ptr;
|
||||
use std::sync::atomic::Ordering::SeqCst;
|
||||
use std::sync::Once;
|
||||
use wasmtime_environ::ir;
|
||||
use wasmtime_environ::TrapCode;
|
||||
|
||||
pub use self::tls::{tls_eager_initialize, TlsRestore};
|
||||
|
||||
@@ -131,7 +131,7 @@ pub enum Trap {
|
||||
/// A trap raised from a wasm libcall
|
||||
Wasm {
|
||||
/// Code of the trap.
|
||||
trap_code: ir::TrapCode,
|
||||
trap_code: TrapCode,
|
||||
/// Native stack backtrace at the time the trap occurred
|
||||
backtrace: Backtrace,
|
||||
},
|
||||
@@ -147,7 +147,7 @@ impl Trap {
|
||||
/// Construct a new Wasm trap with the given source location and trap code.
|
||||
///
|
||||
/// Internally saves a backtrace when constructed.
|
||||
pub fn wasm(trap_code: ir::TrapCode) -> Self {
|
||||
pub fn wasm(trap_code: TrapCode) -> Self {
|
||||
let backtrace = Backtrace::new_unresolved();
|
||||
Trap::Wasm {
|
||||
trap_code,
|
||||
|
||||
15
crates/types/Cargo.toml
Normal file
15
crates/types/Cargo.toml
Normal file
@@ -0,0 +1,15 @@
|
||||
[package]
|
||||
name = "wasmtime-types"
|
||||
version = "0.29.0"
|
||||
authors = ["The Wasmtime Project Developers"]
|
||||
description = "WebAssembly type definitions for Cranelift"
|
||||
license = "Apache-2.0 WITH LLVM-exception"
|
||||
repository = "https://github.com/bytecodealliance/wasmtime"
|
||||
documentation = "https://docs.rs/wasmtime-types"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
cranelift-entity = { path = "../../cranelift/entity", version = "0.76.0", features = ['enable-serde'] }
|
||||
serde = { version = "1.0.94", features = ["derive"] }
|
||||
thiserror = "1.0.4"
|
||||
wasmparser = { version = "0.80", default-features = false }
|
||||
59
crates/types/src/error.rs
Normal file
59
crates/types/src/error.rs
Normal file
@@ -0,0 +1,59 @@
|
||||
use thiserror::Error;
|
||||
|
||||
/// A WebAssembly translation error.
|
||||
///
|
||||
/// When a WebAssembly function can't be translated, one of these error codes will be returned
|
||||
/// to describe the failure.
|
||||
#[derive(Error, Debug)]
|
||||
pub enum WasmError {
|
||||
/// The input WebAssembly code is invalid.
|
||||
///
|
||||
/// This error code is used by a WebAssembly translator when it encounters invalid WebAssembly
|
||||
/// code. This should never happen for validated WebAssembly code.
|
||||
#[error("Invalid input WebAssembly code at offset {offset}: {message}")]
|
||||
InvalidWebAssembly {
|
||||
/// A string describing the validation error.
|
||||
message: String,
|
||||
/// The bytecode offset where the error occurred.
|
||||
offset: usize,
|
||||
},
|
||||
|
||||
/// A feature used by the WebAssembly code is not supported by the embedding environment.
|
||||
///
|
||||
/// Embedding environments may have their own limitations and feature restrictions.
|
||||
#[error("Unsupported feature: {0}")]
|
||||
Unsupported(String),
|
||||
|
||||
/// An implementation limit was exceeded.
|
||||
///
|
||||
/// Cranelift can compile very large and complicated functions, but the [implementation has
|
||||
/// limits][limits] that cause compilation to fail when they are exceeded.
|
||||
///
|
||||
/// [limits]: https://github.com/bytecodealliance/wasmtime/blob/main/cranelift/docs/ir.md#implementation-limits
|
||||
#[error("Implementation limit exceeded")]
|
||||
ImplLimitExceeded,
|
||||
|
||||
/// Any user-defined error.
|
||||
#[error("User error: {0}")]
|
||||
User(String),
|
||||
}
|
||||
|
||||
/// Return an `Err(WasmError::Unsupported(msg))` where `msg` the string built by calling `format!`
|
||||
/// on the arguments to this macro.
|
||||
#[macro_export]
|
||||
macro_rules! wasm_unsupported {
|
||||
($($arg:tt)*) => { $crate::WasmError::Unsupported(format!($($arg)*)) }
|
||||
}
|
||||
|
||||
impl From<wasmparser::BinaryReaderError> for WasmError {
|
||||
/// Convert from a `BinaryReaderError` to a `WasmError`.
|
||||
fn from(e: wasmparser::BinaryReaderError) -> Self {
|
||||
Self::InvalidWebAssembly {
|
||||
message: e.message().into(),
|
||||
offset: e.offset(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A convenient alias for a `Result` that uses `WasmError` as the error type.
|
||||
pub type WasmResult<T> = Result<T, WasmError>;
|
||||
337
crates/types/src/lib.rs
Normal file
337
crates/types/src/lib.rs
Normal file
@@ -0,0 +1,337 @@
|
||||
//! Internal dependency of Wasmtime and Cranelift that defines types for
|
||||
//! WebAssembly.
|
||||
|
||||
pub use wasmparser;
|
||||
|
||||
use cranelift_entity::entity_impl;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
|
||||
mod error;
|
||||
pub use error::*;
|
||||
|
||||
/// WebAssembly value type -- equivalent of `wasmparser`'s Type.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum WasmType {
|
||||
/// I32 type
|
||||
I32,
|
||||
/// I64 type
|
||||
I64,
|
||||
/// F32 type
|
||||
F32,
|
||||
/// F64 type
|
||||
F64,
|
||||
/// V128 type
|
||||
V128,
|
||||
/// FuncRef type
|
||||
FuncRef,
|
||||
/// ExternRef type
|
||||
ExternRef,
|
||||
/// ExnRef type
|
||||
ExnRef,
|
||||
}
|
||||
|
||||
impl TryFrom<wasmparser::Type> for WasmType {
|
||||
type Error = WasmError;
|
||||
fn try_from(ty: wasmparser::Type) -> Result<Self, Self::Error> {
|
||||
use wasmparser::Type::*;
|
||||
match ty {
|
||||
I32 => Ok(WasmType::I32),
|
||||
I64 => Ok(WasmType::I64),
|
||||
F32 => Ok(WasmType::F32),
|
||||
F64 => Ok(WasmType::F64),
|
||||
V128 => Ok(WasmType::V128),
|
||||
FuncRef => Ok(WasmType::FuncRef),
|
||||
ExternRef => Ok(WasmType::ExternRef),
|
||||
ExnRef => Ok(WasmType::ExnRef),
|
||||
EmptyBlockType | Func => Err(WasmError::InvalidWebAssembly {
|
||||
message: "unexpected value type".to_string(),
|
||||
offset: 0,
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<WasmType> for wasmparser::Type {
|
||||
fn from(ty: WasmType) -> wasmparser::Type {
|
||||
match ty {
|
||||
WasmType::I32 => wasmparser::Type::I32,
|
||||
WasmType::I64 => wasmparser::Type::I64,
|
||||
WasmType::F32 => wasmparser::Type::F32,
|
||||
WasmType::F64 => wasmparser::Type::F64,
|
||||
WasmType::V128 => wasmparser::Type::V128,
|
||||
WasmType::FuncRef => wasmparser::Type::FuncRef,
|
||||
WasmType::ExternRef => wasmparser::Type::ExternRef,
|
||||
WasmType::ExnRef => wasmparser::Type::ExnRef,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// WebAssembly function type -- equivalent of `wasmparser`'s FuncType.
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
|
||||
pub struct WasmFuncType {
|
||||
/// Function params types.
|
||||
pub params: Box<[WasmType]>,
|
||||
/// Returns params types.
|
||||
pub returns: Box<[WasmType]>,
|
||||
}
|
||||
|
||||
impl TryFrom<wasmparser::FuncType> for WasmFuncType {
|
||||
type Error = WasmError;
|
||||
fn try_from(ty: wasmparser::FuncType) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
params: ty
|
||||
.params
|
||||
.into_vec()
|
||||
.into_iter()
|
||||
.map(WasmType::try_from)
|
||||
.collect::<Result<_, Self::Error>>()?,
|
||||
returns: ty
|
||||
.returns
|
||||
.into_vec()
|
||||
.into_iter()
|
||||
.map(WasmType::try_from)
|
||||
.collect::<Result<_, Self::Error>>()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Index type of a function (imported or defined) inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
|
||||
pub struct FuncIndex(u32);
|
||||
entity_impl!(FuncIndex);
|
||||
|
||||
/// Index type of a defined function inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
|
||||
pub struct DefinedFuncIndex(u32);
|
||||
entity_impl!(DefinedFuncIndex);
|
||||
|
||||
/// Index type of a defined table inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
|
||||
pub struct DefinedTableIndex(u32);
|
||||
entity_impl!(DefinedTableIndex);
|
||||
|
||||
/// Index type of a defined memory inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
|
||||
pub struct DefinedMemoryIndex(u32);
|
||||
entity_impl!(DefinedMemoryIndex);
|
||||
|
||||
/// Index type of a defined global inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
|
||||
pub struct DefinedGlobalIndex(u32);
|
||||
entity_impl!(DefinedGlobalIndex);
|
||||
|
||||
/// Index type of a table (imported or defined) inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
|
||||
pub struct TableIndex(u32);
|
||||
entity_impl!(TableIndex);
|
||||
|
||||
/// Index type of a global variable (imported or defined) inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
|
||||
pub struct GlobalIndex(u32);
|
||||
entity_impl!(GlobalIndex);
|
||||
|
||||
/// Index type of a linear memory (imported or defined) inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
|
||||
pub struct MemoryIndex(u32);
|
||||
entity_impl!(MemoryIndex);
|
||||
|
||||
/// Index type of a signature (imported or defined) inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
|
||||
pub struct SignatureIndex(u32);
|
||||
entity_impl!(SignatureIndex);
|
||||
|
||||
/// Index type of a passive data segment inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
|
||||
pub struct DataIndex(u32);
|
||||
entity_impl!(DataIndex);
|
||||
|
||||
/// Index type of a passive element segment inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
|
||||
pub struct ElemIndex(u32);
|
||||
entity_impl!(ElemIndex);
|
||||
|
||||
/// Index type of a type inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
|
||||
pub struct TypeIndex(u32);
|
||||
entity_impl!(TypeIndex);
|
||||
|
||||
/// Index type of a module inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
|
||||
pub struct ModuleIndex(u32);
|
||||
entity_impl!(ModuleIndex);
|
||||
|
||||
/// Index type of an instance inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
|
||||
pub struct InstanceIndex(u32);
|
||||
entity_impl!(InstanceIndex);
|
||||
|
||||
/// Index type of an event inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
|
||||
pub struct TagIndex(u32);
|
||||
entity_impl!(TagIndex);
|
||||
|
||||
/// Specialized index for just module types.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
|
||||
pub struct ModuleTypeIndex(u32);
|
||||
entity_impl!(ModuleTypeIndex);
|
||||
|
||||
/// Specialized index for just instance types.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
|
||||
pub struct InstanceTypeIndex(u32);
|
||||
entity_impl!(InstanceTypeIndex);
|
||||
|
||||
/// An index of an entity.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
|
||||
pub enum EntityIndex {
|
||||
/// Function index.
|
||||
Function(FuncIndex),
|
||||
/// Table index.
|
||||
Table(TableIndex),
|
||||
/// Memory index.
|
||||
Memory(MemoryIndex),
|
||||
/// Global index.
|
||||
Global(GlobalIndex),
|
||||
/// Module index.
|
||||
Module(ModuleIndex),
|
||||
/// Instance index.
|
||||
Instance(InstanceIndex),
|
||||
}
|
||||
|
||||
/// A type of an item in a wasm module where an item is typically something that
|
||||
/// can be exported.
|
||||
#[allow(missing_docs)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub enum EntityType {
|
||||
/// A global variable with the specified content type
|
||||
Global(Global),
|
||||
/// A linear memory with the specified limits
|
||||
Memory(Memory),
|
||||
/// An event definition.
|
||||
Tag(Tag),
|
||||
/// A table with the specified element type and limits
|
||||
Table(Table),
|
||||
/// A function type where the index points to the type section and records a
|
||||
/// function signature.
|
||||
Function(SignatureIndex),
|
||||
/// An instance where the index points to the type section and records a
|
||||
/// instance's exports.
|
||||
Instance(InstanceTypeIndex),
|
||||
/// A module where the index points to the type section and records a
|
||||
/// module's imports and exports.
|
||||
Module(ModuleTypeIndex),
|
||||
}
|
||||
|
||||
/// A WebAssembly global.
|
||||
///
|
||||
/// Note that we record both the original Wasm type and the Cranelift IR type
|
||||
/// used to represent it. This is because multiple different kinds of Wasm types
|
||||
/// might be represented with the same Cranelift IR type. For example, both a
|
||||
/// Wasm `i64` and a `funcref` might be represented with a Cranelift `i64` on
|
||||
/// 64-bit architectures, and when GC is not required for func refs.
|
||||
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Global {
|
||||
/// The Wasm type of the value stored in the global.
|
||||
pub wasm_ty: crate::WasmType,
|
||||
/// A flag indicating whether the value may change at runtime.
|
||||
pub mutability: bool,
|
||||
/// The source of the initial value.
|
||||
pub initializer: GlobalInit,
|
||||
}
|
||||
|
||||
/// Globals are initialized via the `const` operators or by referring to another import.
|
||||
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Serialize, Deserialize)]
|
||||
pub enum GlobalInit {
|
||||
/// An `i32.const`.
|
||||
I32Const(i32),
|
||||
/// An `i64.const`.
|
||||
I64Const(i64),
|
||||
/// An `f32.const`.
|
||||
F32Const(u32),
|
||||
/// An `f64.const`.
|
||||
F64Const(u64),
|
||||
/// A `vconst`.
|
||||
V128Const(u128),
|
||||
/// A `global.get` of another global.
|
||||
GetGlobal(GlobalIndex),
|
||||
/// A `ref.null`.
|
||||
RefNullConst,
|
||||
/// A `ref.func <index>`.
|
||||
RefFunc(FuncIndex),
|
||||
///< The global is imported from, and thus initialized by, a different module.
|
||||
Import,
|
||||
}
|
||||
|
||||
impl Global {
|
||||
/// Creates a new `Global` type from wasmparser's representation.
|
||||
pub fn new(ty: wasmparser::GlobalType, initializer: GlobalInit) -> WasmResult<Global> {
|
||||
Ok(Global {
|
||||
wasm_ty: ty.content_type.try_into()?,
|
||||
mutability: ty.mutable,
|
||||
initializer,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// WebAssembly table.
|
||||
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Table {
|
||||
/// The table elements' Wasm type.
|
||||
pub wasm_ty: WasmType,
|
||||
/// The minimum number of elements in the table.
|
||||
pub minimum: u32,
|
||||
/// The maximum number of elements in the table.
|
||||
pub maximum: Option<u32>,
|
||||
}
|
||||
|
||||
impl TryFrom<wasmparser::TableType> for Table {
|
||||
type Error = WasmError;
|
||||
|
||||
fn try_from(ty: wasmparser::TableType) -> WasmResult<Table> {
|
||||
Ok(Table {
|
||||
wasm_ty: ty.element_type.try_into()?,
|
||||
minimum: ty.initial,
|
||||
maximum: ty.maximum,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// WebAssembly linear memory.
|
||||
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Memory {
|
||||
/// The minimum number of pages in the memory.
|
||||
pub minimum: u64,
|
||||
/// The maximum number of pages in the memory.
|
||||
pub maximum: Option<u64>,
|
||||
/// Whether the memory may be shared between multiple threads.
|
||||
pub shared: bool,
|
||||
/// Whether or not this is a 64-bit memory
|
||||
pub memory64: bool,
|
||||
}
|
||||
|
||||
impl From<wasmparser::MemoryType> for Memory {
|
||||
fn from(ty: wasmparser::MemoryType) -> Memory {
|
||||
Memory {
|
||||
minimum: ty.initial,
|
||||
maximum: ty.maximum,
|
||||
shared: ty.shared,
|
||||
memory64: ty.memory64,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// WebAssembly event.
|
||||
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Tag {
|
||||
/// The event signature type.
|
||||
pub ty: TypeIndex,
|
||||
}
|
||||
|
||||
impl From<wasmparser::TagType> for Tag {
|
||||
fn from(ty: wasmparser::TagType) -> Tag {
|
||||
Tag {
|
||||
ty: TypeIndex::from_u32(ty.type_index),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -368,10 +368,7 @@ impl Global {
|
||||
Global(store.store_data_mut().insert(wasmtime_export))
|
||||
}
|
||||
|
||||
pub(crate) fn wasmtime_ty<'a>(
|
||||
&self,
|
||||
data: &'a StoreData,
|
||||
) -> &'a wasmtime_environ::wasm::Global {
|
||||
pub(crate) fn wasmtime_ty<'a>(&self, data: &'a StoreData) -> &'a wasmtime_environ::Global {
|
||||
&data[self.0].global
|
||||
}
|
||||
|
||||
@@ -651,7 +648,7 @@ impl Table {
|
||||
Table(store.store_data_mut().insert(wasmtime_export))
|
||||
}
|
||||
|
||||
pub(crate) fn wasmtime_ty<'a>(&self, data: &'a StoreData) -> &'a wasmtime_environ::wasm::Table {
|
||||
pub(crate) fn wasmtime_ty<'a>(&self, data: &'a StoreData) -> &'a wasmtime_environ::Table {
|
||||
&data[self.0].table.table
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ use std::pin::Pin;
|
||||
use std::ptr::NonNull;
|
||||
use std::sync::atomic::Ordering::Relaxed;
|
||||
use std::sync::Arc;
|
||||
use wasmtime_environ::wasm::{EntityIndex, FuncIndex};
|
||||
use wasmtime_environ::{EntityIndex, FuncIndex};
|
||||
use wasmtime_runtime::{
|
||||
raise_user_trap, ExportFunction, InstanceAllocator, InstanceHandle, OnDemandInstanceAllocator,
|
||||
VMCallerCheckedAnyfunc, VMContext, VMFunctionBody, VMFunctionImport, VMSharedSignatureIndex,
|
||||
@@ -1135,7 +1135,7 @@ fn enter_wasm<T>(store: &mut StoreContextMut<'_, T>) -> Result<Option<usize>, Tr
|
||||
interrupts.stack_limit.store(usize::max_value(), Relaxed);
|
||||
return Err(Trap::new_wasm(
|
||||
None,
|
||||
wasmtime_environ::ir::TrapCode::Interrupt,
|
||||
wasmtime_environ::TrapCode::Interrupt,
|
||||
backtrace::Backtrace::new_unresolved(),
|
||||
));
|
||||
}
|
||||
|
||||
@@ -9,12 +9,10 @@ use crate::{
|
||||
use anyhow::{anyhow, bail, Context, Error, Result};
|
||||
use std::mem;
|
||||
use std::sync::Arc;
|
||||
use wasmtime_environ::entity::PrimaryMap;
|
||||
use wasmtime_environ::wasm::{
|
||||
EntityIndex, EntityType, FuncIndex, GlobalIndex, InstanceIndex, MemoryIndex, ModuleIndex,
|
||||
TableIndex,
|
||||
use wasmtime_environ::{
|
||||
EntityIndex, EntityType, FuncIndex, GlobalIndex, Initializer, InstanceIndex, MemoryIndex,
|
||||
ModuleIndex, PrimaryMap, TableIndex,
|
||||
};
|
||||
use wasmtime_environ::Initializer;
|
||||
use wasmtime_jit::TypeTables;
|
||||
use wasmtime_runtime::{
|
||||
Imports, InstanceAllocationRequest, InstantiationError, VMContext, VMFunctionBody,
|
||||
|
||||
@@ -480,10 +480,7 @@ impl Memory {
|
||||
Memory(store.store_data_mut().insert(wasmtime_export))
|
||||
}
|
||||
|
||||
pub(crate) fn wasmtime_ty<'a>(
|
||||
&self,
|
||||
store: &'a StoreData,
|
||||
) -> &'a wasmtime_environ::wasm::Memory {
|
||||
pub(crate) fn wasmtime_ty<'a>(&self, store: &'a StoreData) -> &'a wasmtime_environ::Memory {
|
||||
&store[self.0].memory.memory
|
||||
}
|
||||
|
||||
|
||||
@@ -10,8 +10,7 @@ use std::sync::Arc;
|
||||
use wasmparser::Validator;
|
||||
#[cfg(feature = "cache")]
|
||||
use wasmtime_cache::ModuleCacheEntry;
|
||||
use wasmtime_environ::entity::PrimaryMap;
|
||||
use wasmtime_environ::wasm::ModuleIndex;
|
||||
use wasmtime_environ::{ModuleIndex, PrimaryMap};
|
||||
use wasmtime_jit::{CompilationArtifacts, CompiledModule, TypeTables};
|
||||
|
||||
mod registry;
|
||||
|
||||
@@ -6,10 +6,7 @@ use std::{
|
||||
sync::{Arc, RwLock},
|
||||
};
|
||||
use wasmtime_environ::{
|
||||
entity::EntityRef,
|
||||
ir::{self, StackMap},
|
||||
wasm::DefinedFuncIndex,
|
||||
FunctionAddressMap, TrapInformation,
|
||||
DefinedFuncIndex, EntityRef, FilePos, FunctionAddressMap, StackMap, TrapInformation,
|
||||
};
|
||||
use wasmtime_jit::CompiledModule;
|
||||
use wasmtime_runtime::{ModuleInfo, VMCallerCheckedAnyfunc, VMTrampoline};
|
||||
@@ -339,10 +336,9 @@ impl GlobalRegisteredModule {
|
||||
// though so we can omit this check in release mode.
|
||||
debug_assert!(pos.is_some(), "failed to find instruction for {:x}", pc);
|
||||
|
||||
let instr = match pos {
|
||||
Some(pos) => info.address_map.instructions[pos].srcloc,
|
||||
None => info.address_map.start_srcloc,
|
||||
};
|
||||
let instr = pos
|
||||
.map(|i| info.address_map.instructions[i].srcloc)
|
||||
.unwrap_or(info.address_map.start_srcloc);
|
||||
|
||||
// Use our wasm-relative pc to symbolize this frame. If there's a
|
||||
// symbolication context (dwarf debug info) available then we can try to
|
||||
@@ -355,23 +351,25 @@ impl GlobalRegisteredModule {
|
||||
let mut symbols = Vec::new();
|
||||
|
||||
if let Some(s) = &self.module.symbolize_context().ok().and_then(|c| c) {
|
||||
let to_lookup = (instr.bits() as u64) - s.code_section_offset();
|
||||
if let Ok(mut frames) = s.addr2line().find_frames(to_lookup) {
|
||||
while let Ok(Some(frame)) = frames.next() {
|
||||
symbols.push(FrameSymbol {
|
||||
name: frame
|
||||
.function
|
||||
.as_ref()
|
||||
.and_then(|l| l.raw_name().ok())
|
||||
.map(|s| s.to_string()),
|
||||
file: frame
|
||||
.location
|
||||
.as_ref()
|
||||
.and_then(|l| l.file)
|
||||
.map(|s| s.to_string()),
|
||||
line: frame.location.as_ref().and_then(|l| l.line),
|
||||
column: frame.location.as_ref().and_then(|l| l.column),
|
||||
});
|
||||
if let Some(offset) = instr.file_offset() {
|
||||
let to_lookup = u64::from(offset) - s.code_section_offset();
|
||||
if let Ok(mut frames) = s.addr2line().find_frames(to_lookup) {
|
||||
while let Ok(Some(frame)) = frames.next() {
|
||||
symbols.push(FrameSymbol {
|
||||
name: frame
|
||||
.function
|
||||
.as_ref()
|
||||
.and_then(|l| l.raw_name().ok())
|
||||
.map(|s| s.to_string()),
|
||||
file: frame
|
||||
.location
|
||||
.as_ref()
|
||||
.and_then(|l| l.file)
|
||||
.map(|s| s.to_string()),
|
||||
line: frame.location.as_ref().and_then(|l| l.line),
|
||||
column: frame.location.as_ref().and_then(|l| l.column),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -413,8 +411,8 @@ pub struct FrameInfo {
|
||||
module_name: Option<String>,
|
||||
func_index: u32,
|
||||
func_name: Option<String>,
|
||||
func_start: ir::SourceLoc,
|
||||
instr: ir::SourceLoc,
|
||||
func_start: FilePos,
|
||||
instr: FilePos,
|
||||
symbols: Vec<FrameSymbol>,
|
||||
}
|
||||
|
||||
@@ -464,7 +462,7 @@ impl FrameInfo {
|
||||
/// The offset here is the offset from the beginning of the original wasm
|
||||
/// module to the instruction that this frame points to.
|
||||
pub fn module_offset(&self) -> usize {
|
||||
self.instr.bits() as usize
|
||||
self.instr.file_offset().unwrap_or(u32::MAX) as usize
|
||||
}
|
||||
|
||||
/// Returns the offset from the original wasm module's function to this
|
||||
@@ -474,7 +472,10 @@ impl FrameInfo {
|
||||
/// function of this frame (within the wasm module) to the instruction this
|
||||
/// frame points to.
|
||||
pub fn func_offset(&self) -> usize {
|
||||
(self.instr.bits() - self.func_start.bits()) as usize
|
||||
match self.instr.file_offset() {
|
||||
Some(i) => (i - self.func_start.file_offset().unwrap()) as usize,
|
||||
None => u32::MAX as usize,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the debug symbols found, if any, for this function frame.
|
||||
|
||||
@@ -6,8 +6,7 @@ use std::{
|
||||
sync::RwLock,
|
||||
};
|
||||
use std::{convert::TryFrom, sync::Arc};
|
||||
use wasmtime_environ::entity::PrimaryMap;
|
||||
use wasmtime_environ::wasm::{SignatureIndex, WasmFuncType};
|
||||
use wasmtime_environ::{PrimaryMap, SignatureIndex, WasmFuncType};
|
||||
use wasmtime_runtime::{VMSharedSignatureIndex, VMTrampoline};
|
||||
|
||||
/// Represents a collection of shared signatures.
|
||||
|
||||
@@ -16,7 +16,9 @@ use crate::{GlobalType, MemoryType, TableType, Val};
|
||||
use anyhow::Result;
|
||||
use std::any::Any;
|
||||
use std::sync::Arc;
|
||||
use wasmtime_environ::{entity::PrimaryMap, wasm, Module};
|
||||
use wasmtime_environ::{
|
||||
DefinedFuncIndex, EntityIndex, GlobalIndex, MemoryIndex, Module, PrimaryMap, TableIndex,
|
||||
};
|
||||
use wasmtime_runtime::{
|
||||
Imports, InstanceAllocationRequest, InstanceAllocator, OnDemandInstanceAllocator,
|
||||
VMFunctionBody, VMFunctionImport, VMSharedSignatureIndex,
|
||||
@@ -25,7 +27,7 @@ use wasmtime_runtime::{
|
||||
fn create_handle(
|
||||
module: Module,
|
||||
store: &mut StoreOpaque<'_>,
|
||||
finished_functions: PrimaryMap<wasm::DefinedFuncIndex, *mut [VMFunctionBody]>,
|
||||
finished_functions: PrimaryMap<DefinedFuncIndex, *mut [VMFunctionBody]>,
|
||||
host_state: Box<dyn Any + Send + Sync>,
|
||||
func_imports: &[VMFunctionImport],
|
||||
shared_signature_id: Option<VMSharedSignatureIndex>,
|
||||
@@ -59,7 +61,7 @@ pub fn generate_global_export(
|
||||
val: Val,
|
||||
) -> Result<wasmtime_runtime::ExportGlobal> {
|
||||
let instance = create_global(store, gt, val)?;
|
||||
let idx = wasm::EntityIndex::Global(wasm::GlobalIndex::from_u32(0));
|
||||
let idx = EntityIndex::Global(GlobalIndex::from_u32(0));
|
||||
match store.instance(instance).lookup_by_declaration(&idx) {
|
||||
wasmtime_runtime::Export::Global(g) => Ok(g),
|
||||
_ => unreachable!(),
|
||||
@@ -71,7 +73,7 @@ pub fn generate_memory_export(
|
||||
m: &MemoryType,
|
||||
) -> Result<wasmtime_runtime::ExportMemory> {
|
||||
let instance = create_memory(store, m)?;
|
||||
let idx = wasm::EntityIndex::Memory(wasm::MemoryIndex::from_u32(0));
|
||||
let idx = EntityIndex::Memory(MemoryIndex::from_u32(0));
|
||||
match store.instance(instance).lookup_by_declaration(&idx) {
|
||||
wasmtime_runtime::Export::Memory(m) => Ok(m),
|
||||
_ => unreachable!(),
|
||||
@@ -83,7 +85,7 @@ pub fn generate_table_export(
|
||||
t: &TableType,
|
||||
) -> Result<wasmtime_runtime::ExportTable> {
|
||||
let instance = create_table(store, t)?;
|
||||
let idx = wasm::EntityIndex::Table(wasm::TableIndex::from_u32(0));
|
||||
let idx = EntityIndex::Table(TableIndex::from_u32(0));
|
||||
match store.instance(instance).lookup_by_declaration(&idx) {
|
||||
wasmtime_runtime::Export::Table(t) => Ok(t),
|
||||
_ => unreachable!(),
|
||||
|
||||
@@ -5,9 +5,7 @@ use anyhow::Result;
|
||||
use std::any::Any;
|
||||
use std::panic::{self, AssertUnwindSafe};
|
||||
use std::sync::Arc;
|
||||
use wasmtime_environ::entity::PrimaryMap;
|
||||
use wasmtime_environ::wasm::SignatureIndex;
|
||||
use wasmtime_environ::{wasm, Module, ModuleType};
|
||||
use wasmtime_environ::{EntityIndex, Module, ModuleType, PrimaryMap, SignatureIndex};
|
||||
use wasmtime_jit::CodeMemory;
|
||||
use wasmtime_runtime::{
|
||||
Imports, InstanceAllocationRequest, InstanceAllocator, InstanceHandle,
|
||||
@@ -123,7 +121,7 @@ pub unsafe fn create_raw_function(
|
||||
let func_id = module.functions.push(sig_id);
|
||||
module
|
||||
.exports
|
||||
.insert(String::new(), wasm::EntityIndex::Function(func_id));
|
||||
.insert(String::new(), EntityIndex::Function(func_id));
|
||||
finished_functions.push(func);
|
||||
|
||||
Ok(
|
||||
|
||||
@@ -2,10 +2,8 @@ use crate::store::{InstanceId, StoreOpaque};
|
||||
use crate::trampoline::create_handle;
|
||||
use crate::{GlobalType, Mutability, Val};
|
||||
use anyhow::Result;
|
||||
use wasmtime_environ::entity::PrimaryMap;
|
||||
use wasmtime_environ::{
|
||||
wasm::{self, SignatureIndex},
|
||||
Module, ModuleType,
|
||||
EntityIndex, Global, GlobalInit, Module, ModuleType, PrimaryMap, SignatureIndex,
|
||||
};
|
||||
use wasmtime_runtime::VMFunctionImport;
|
||||
|
||||
@@ -15,26 +13,26 @@ pub fn create_global(store: &mut StoreOpaque<'_>, gt: &GlobalType, val: Val) ->
|
||||
let mut externref_init = None;
|
||||
let mut shared_signature_id = None;
|
||||
|
||||
let global = wasm::Global {
|
||||
let global = Global {
|
||||
wasm_ty: gt.content().to_wasm_type(),
|
||||
mutability: match gt.mutability() {
|
||||
Mutability::Const => false,
|
||||
Mutability::Var => true,
|
||||
},
|
||||
initializer: match val {
|
||||
Val::I32(i) => wasm::GlobalInit::I32Const(i),
|
||||
Val::I64(i) => wasm::GlobalInit::I64Const(i),
|
||||
Val::F32(f) => wasm::GlobalInit::F32Const(f),
|
||||
Val::F64(f) => wasm::GlobalInit::F64Const(f),
|
||||
Val::V128(i) => wasm::GlobalInit::V128Const(i.into()),
|
||||
Val::ExternRef(None) | Val::FuncRef(None) => wasm::GlobalInit::RefNullConst,
|
||||
Val::I32(i) => GlobalInit::I32Const(i),
|
||||
Val::I64(i) => GlobalInit::I64Const(i),
|
||||
Val::F32(f) => GlobalInit::F32Const(f),
|
||||
Val::F64(f) => GlobalInit::F64Const(f),
|
||||
Val::V128(i) => GlobalInit::V128Const(i.into()),
|
||||
Val::ExternRef(None) | Val::FuncRef(None) => GlobalInit::RefNullConst,
|
||||
Val::ExternRef(Some(x)) => {
|
||||
// There is no `GlobalInit` variant for using an existing
|
||||
// `externref` that isn't an import (because Wasm can't create
|
||||
// an `externref` by itself). Therefore, initialize the global
|
||||
// as null, and then monkey patch it after instantiation below.
|
||||
externref_init = Some(x);
|
||||
wasm::GlobalInit::RefNullConst
|
||||
GlobalInit::RefNullConst
|
||||
}
|
||||
Val::FuncRef(Some(f)) => {
|
||||
// Add a function import to the stub module, and then initialize
|
||||
@@ -51,7 +49,7 @@ pub fn create_global(store: &mut StoreOpaque<'_>, gt: &GlobalType, val: Val) ->
|
||||
.push(wasmtime_environ::Initializer::Import {
|
||||
name: "".into(),
|
||||
field: None,
|
||||
index: wasm::EntityIndex::Function(func_index),
|
||||
index: EntityIndex::Function(func_index),
|
||||
});
|
||||
|
||||
func_imports.push(VMFunctionImport {
|
||||
@@ -59,7 +57,7 @@ pub fn create_global(store: &mut StoreOpaque<'_>, gt: &GlobalType, val: Val) ->
|
||||
vmctx: f.vmctx,
|
||||
});
|
||||
|
||||
wasm::GlobalInit::RefFunc(func_index)
|
||||
GlobalInit::RefFunc(func_index)
|
||||
}
|
||||
},
|
||||
};
|
||||
@@ -67,7 +65,7 @@ pub fn create_global(store: &mut StoreOpaque<'_>, gt: &GlobalType, val: Val) ->
|
||||
let global_id = module.globals.push(global);
|
||||
module
|
||||
.exports
|
||||
.insert(String::new(), wasm::EntityIndex::Global(global_id));
|
||||
.insert(String::new(), EntityIndex::Global(global_id));
|
||||
let id = create_handle(
|
||||
module,
|
||||
store,
|
||||
@@ -79,7 +77,7 @@ pub fn create_global(store: &mut StoreOpaque<'_>, gt: &GlobalType, val: Val) ->
|
||||
|
||||
if let Some(x) = externref_init {
|
||||
let instance = store.instance(id);
|
||||
match instance.lookup_by_declaration(&wasm::EntityIndex::Global(global_id)) {
|
||||
match instance.lookup_by_declaration(&EntityIndex::Global(global_id)) {
|
||||
wasmtime_runtime::Export::Global(g) => unsafe {
|
||||
*(*g.definition).as_externref_mut() = Some(x.inner);
|
||||
},
|
||||
|
||||
@@ -5,8 +5,7 @@ use crate::MemoryType;
|
||||
use anyhow::{anyhow, Result};
|
||||
use std::convert::TryFrom;
|
||||
use std::sync::Arc;
|
||||
use wasmtime_environ::entity::PrimaryMap;
|
||||
use wasmtime_environ::{wasm, MemoryPlan, MemoryStyle, Module, WASM_PAGE_SIZE};
|
||||
use wasmtime_environ::{EntityIndex, MemoryPlan, MemoryStyle, Module, PrimaryMap, WASM_PAGE_SIZE};
|
||||
use wasmtime_runtime::{RuntimeLinearMemory, RuntimeMemoryCreator, VMMemoryDefinition};
|
||||
|
||||
pub fn create_memory(store: &mut StoreOpaque<'_>, memory: &MemoryType) -> Result<InstanceId> {
|
||||
@@ -19,7 +18,7 @@ pub fn create_memory(store: &mut StoreOpaque<'_>, memory: &MemoryType) -> Result
|
||||
let memory_id = module.memory_plans.push(memory_plan);
|
||||
module
|
||||
.exports
|
||||
.insert(String::new(), wasm::EntityIndex::Memory(memory_id));
|
||||
.insert(String::new(), EntityIndex::Memory(memory_id));
|
||||
|
||||
create_handle(module, store, PrimaryMap::new(), Box::new(()), &[], None)
|
||||
}
|
||||
|
||||
@@ -2,8 +2,7 @@ use crate::store::{InstanceId, StoreOpaque};
|
||||
use crate::trampoline::create_handle;
|
||||
use crate::TableType;
|
||||
use anyhow::Result;
|
||||
use wasmtime_environ::entity::PrimaryMap;
|
||||
use wasmtime_environ::{wasm, Module};
|
||||
use wasmtime_environ::{EntityIndex, Module, PrimaryMap};
|
||||
|
||||
pub fn create_table(store: &mut StoreOpaque<'_>, table: &TableType) -> Result<InstanceId> {
|
||||
let mut module = Module::new();
|
||||
@@ -15,7 +14,7 @@ pub fn create_table(store: &mut StoreOpaque<'_>, table: &TableType) -> Result<In
|
||||
// TODO: can this `exports.insert` get removed?
|
||||
module
|
||||
.exports
|
||||
.insert(String::new(), wasm::EntityIndex::Table(table_id));
|
||||
.insert(String::new(), EntityIndex::Table(table_id));
|
||||
|
||||
create_handle(module, store, PrimaryMap::new(), Box::new(()), &[], None)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ use crate::FrameInfo;
|
||||
use backtrace::Backtrace;
|
||||
use std::fmt;
|
||||
use std::sync::Arc;
|
||||
use wasmtime_environ::ir;
|
||||
use wasmtime_environ::TrapCode as EnvTrapCode;
|
||||
|
||||
/// A struct representing an aborted instruction execution, with a message
|
||||
/// indicating the cause.
|
||||
@@ -88,21 +88,20 @@ pub enum TrapCode {
|
||||
}
|
||||
|
||||
impl TrapCode {
|
||||
/// Panics if `code` is `ir::TrapCode::User`.
|
||||
fn from_non_user(code: ir::TrapCode) -> Self {
|
||||
/// Panics if `code` is `EnvTrapCode::User`.
|
||||
fn from_non_user(code: EnvTrapCode) -> Self {
|
||||
match code {
|
||||
ir::TrapCode::StackOverflow => TrapCode::StackOverflow,
|
||||
ir::TrapCode::HeapOutOfBounds => TrapCode::MemoryOutOfBounds,
|
||||
ir::TrapCode::HeapMisaligned => TrapCode::HeapMisaligned,
|
||||
ir::TrapCode::TableOutOfBounds => TrapCode::TableOutOfBounds,
|
||||
ir::TrapCode::IndirectCallToNull => TrapCode::IndirectCallToNull,
|
||||
ir::TrapCode::BadSignature => TrapCode::BadSignature,
|
||||
ir::TrapCode::IntegerOverflow => TrapCode::IntegerOverflow,
|
||||
ir::TrapCode::IntegerDivisionByZero => TrapCode::IntegerDivisionByZero,
|
||||
ir::TrapCode::BadConversionToInteger => TrapCode::BadConversionToInteger,
|
||||
ir::TrapCode::UnreachableCodeReached => TrapCode::UnreachableCodeReached,
|
||||
ir::TrapCode::Interrupt => TrapCode::Interrupt,
|
||||
ir::TrapCode::User(_) => panic!("Called `TrapCode::from_non_user` with user code"),
|
||||
EnvTrapCode::StackOverflow => TrapCode::StackOverflow,
|
||||
EnvTrapCode::HeapOutOfBounds => TrapCode::MemoryOutOfBounds,
|
||||
EnvTrapCode::HeapMisaligned => TrapCode::HeapMisaligned,
|
||||
EnvTrapCode::TableOutOfBounds => TrapCode::TableOutOfBounds,
|
||||
EnvTrapCode::IndirectCallToNull => TrapCode::IndirectCallToNull,
|
||||
EnvTrapCode::BadSignature => TrapCode::BadSignature,
|
||||
EnvTrapCode::IntegerOverflow => TrapCode::IntegerOverflow,
|
||||
EnvTrapCode::IntegerDivisionByZero => TrapCode::IntegerDivisionByZero,
|
||||
EnvTrapCode::BadConversionToInteger => TrapCode::BadConversionToInteger,
|
||||
EnvTrapCode::UnreachableCodeReached => TrapCode::UnreachableCodeReached,
|
||||
EnvTrapCode::Interrupt => TrapCode::Interrupt,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -175,10 +174,10 @@ impl Trap {
|
||||
modules
|
||||
.lookup_trap_info(pc)
|
||||
.map(|info| info.trap_code)
|
||||
.unwrap_or(ir::TrapCode::StackOverflow)
|
||||
.unwrap_or(EnvTrapCode::StackOverflow)
|
||||
});
|
||||
if maybe_interrupted && code == ir::TrapCode::StackOverflow {
|
||||
code = ir::TrapCode::Interrupt;
|
||||
if maybe_interrupted && code == EnvTrapCode::StackOverflow {
|
||||
code = EnvTrapCode::Interrupt;
|
||||
}
|
||||
Trap::new_wasm(Some(pc), code, backtrace)
|
||||
}
|
||||
@@ -196,7 +195,7 @@ impl Trap {
|
||||
#[cold] // see Trap::new
|
||||
pub(crate) fn new_wasm(
|
||||
trap_pc: Option<usize>,
|
||||
code: ir::TrapCode,
|
||||
code: EnvTrapCode,
|
||||
backtrace: Backtrace,
|
||||
) -> Self {
|
||||
let code = TrapCode::from_non_user(code);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use std::fmt;
|
||||
use wasmtime_environ::wasm;
|
||||
use wasmtime_environ::wasm::{EntityType, WasmFuncType};
|
||||
use wasmtime_environ::{EntityType, Global, Memory, Table, WasmFuncType, WasmType};
|
||||
use wasmtime_jit::TypeTables;
|
||||
|
||||
pub(crate) mod matching;
|
||||
@@ -71,28 +70,28 @@ impl ValType {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn to_wasm_type(&self) -> wasm::WasmType {
|
||||
pub(crate) fn to_wasm_type(&self) -> WasmType {
|
||||
match self {
|
||||
Self::I32 => wasm::WasmType::I32,
|
||||
Self::I64 => wasm::WasmType::I64,
|
||||
Self::F32 => wasm::WasmType::F32,
|
||||
Self::F64 => wasm::WasmType::F64,
|
||||
Self::V128 => wasm::WasmType::V128,
|
||||
Self::FuncRef => wasm::WasmType::FuncRef,
|
||||
Self::ExternRef => wasm::WasmType::ExternRef,
|
||||
Self::I32 => WasmType::I32,
|
||||
Self::I64 => WasmType::I64,
|
||||
Self::F32 => WasmType::F32,
|
||||
Self::F64 => WasmType::F64,
|
||||
Self::V128 => WasmType::V128,
|
||||
Self::FuncRef => WasmType::FuncRef,
|
||||
Self::ExternRef => WasmType::ExternRef,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn from_wasm_type(ty: &wasm::WasmType) -> Self {
|
||||
pub(crate) fn from_wasm_type(ty: &WasmType) -> Self {
|
||||
match ty {
|
||||
wasm::WasmType::I32 => Self::I32,
|
||||
wasm::WasmType::I64 => Self::I64,
|
||||
wasm::WasmType::F32 => Self::F32,
|
||||
wasm::WasmType::F64 => Self::F64,
|
||||
wasm::WasmType::V128 => Self::V128,
|
||||
wasm::WasmType::FuncRef => Self::FuncRef,
|
||||
wasm::WasmType::ExternRef => Self::ExternRef,
|
||||
wasm::WasmType::ExnRef => unimplemented!(),
|
||||
WasmType::I32 => Self::I32,
|
||||
WasmType::I64 => Self::I64,
|
||||
WasmType::F32 => Self::F32,
|
||||
WasmType::F64 => Self::F64,
|
||||
WasmType::V128 => Self::V128,
|
||||
WasmType::FuncRef => Self::FuncRef,
|
||||
WasmType::ExternRef => Self::ExternRef,
|
||||
WasmType::ExnRef => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -154,10 +153,7 @@ impl ExternType {
|
||||
(Instance(InstanceType) instance unwrap_instance)
|
||||
}
|
||||
|
||||
pub(crate) fn from_wasmtime(
|
||||
types: &TypeTables,
|
||||
ty: &wasmtime_environ::wasm::EntityType,
|
||||
) -> ExternType {
|
||||
pub(crate) fn from_wasmtime(types: &TypeTables, ty: &EntityType) -> ExternType {
|
||||
match ty {
|
||||
EntityType::Function(idx) => {
|
||||
FuncType::from_wasm_func_type(types.wasm_signatures[*idx].clone()).into()
|
||||
@@ -249,11 +245,11 @@ impl FuncType {
|
||||
self.sig.returns.iter().map(ValType::from_wasm_type)
|
||||
}
|
||||
|
||||
pub(crate) fn as_wasm_func_type(&self) -> &wasm::WasmFuncType {
|
||||
pub(crate) fn as_wasm_func_type(&self) -> &WasmFuncType {
|
||||
&self.sig
|
||||
}
|
||||
|
||||
pub(crate) fn from_wasm_func_type(sig: wasm::WasmFuncType) -> FuncType {
|
||||
pub(crate) fn from_wasm_func_type(sig: WasmFuncType) -> FuncType {
|
||||
Self { sig }
|
||||
}
|
||||
}
|
||||
@@ -293,7 +289,7 @@ impl GlobalType {
|
||||
|
||||
/// Returns `None` if the wasmtime global has a type that we can't
|
||||
/// represent, but that should only very rarely happen and indicate a bug.
|
||||
pub(crate) fn from_wasmtime_global(global: &wasm::Global) -> GlobalType {
|
||||
pub(crate) fn from_wasmtime_global(global: &Global) -> GlobalType {
|
||||
let ty = ValType::from_wasm_type(&global.wasm_ty);
|
||||
let mutability = if global.mutability {
|
||||
Mutability::Var
|
||||
@@ -313,7 +309,7 @@ impl GlobalType {
|
||||
/// which `call_indirect` can invoke other functions.
|
||||
#[derive(Debug, Clone, Hash, Eq, PartialEq)]
|
||||
pub struct TableType {
|
||||
ty: wasm::Table,
|
||||
ty: Table,
|
||||
}
|
||||
|
||||
impl TableType {
|
||||
@@ -321,7 +317,7 @@ impl TableType {
|
||||
/// `element` and have the `limits` applied to its length.
|
||||
pub fn new(element: ValType, min: u32, max: Option<u32>) -> TableType {
|
||||
TableType {
|
||||
ty: wasm::Table {
|
||||
ty: Table {
|
||||
wasm_ty: element.to_wasm_type(),
|
||||
minimum: min,
|
||||
maximum: max,
|
||||
@@ -347,11 +343,11 @@ impl TableType {
|
||||
self.ty.maximum
|
||||
}
|
||||
|
||||
pub(crate) fn from_wasmtime_table(table: &wasm::Table) -> TableType {
|
||||
pub(crate) fn from_wasmtime_table(table: &Table) -> TableType {
|
||||
TableType { ty: table.clone() }
|
||||
}
|
||||
|
||||
pub(crate) fn wasmtime_table(&self) -> &wasm::Table {
|
||||
pub(crate) fn wasmtime_table(&self) -> &Table {
|
||||
&self.ty
|
||||
}
|
||||
}
|
||||
@@ -364,7 +360,7 @@ impl TableType {
|
||||
/// chunks of addressable memory.
|
||||
#[derive(Debug, Clone, Hash, Eq, PartialEq)]
|
||||
pub struct MemoryType {
|
||||
ty: wasm::Memory,
|
||||
ty: Memory,
|
||||
}
|
||||
|
||||
impl MemoryType {
|
||||
@@ -375,7 +371,7 @@ impl MemoryType {
|
||||
/// WebAssembly pages, which are 64k.
|
||||
pub fn new(minimum: u32, maximum: Option<u32>) -> MemoryType {
|
||||
MemoryType {
|
||||
ty: wasm::Memory {
|
||||
ty: Memory {
|
||||
memory64: false,
|
||||
shared: false,
|
||||
minimum: minimum.into(),
|
||||
@@ -394,7 +390,7 @@ impl MemoryType {
|
||||
/// WebAssembly which is not standardized yet.
|
||||
pub fn new64(minimum: u64, maximum: Option<u64>) -> MemoryType {
|
||||
MemoryType {
|
||||
ty: wasm::Memory {
|
||||
ty: Memory {
|
||||
memory64: true,
|
||||
shared: false,
|
||||
minimum,
|
||||
@@ -430,11 +426,11 @@ impl MemoryType {
|
||||
self.ty.maximum
|
||||
}
|
||||
|
||||
pub(crate) fn from_wasmtime_memory(memory: &wasm::Memory) -> MemoryType {
|
||||
pub(crate) fn from_wasmtime_memory(memory: &Memory) -> MemoryType {
|
||||
MemoryType { ty: memory.clone() }
|
||||
}
|
||||
|
||||
pub(crate) fn wasmtime_memory(&self) -> &wasm::Memory {
|
||||
pub(crate) fn wasmtime_memory(&self) -> &Memory {
|
||||
&self.ty
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ use crate::linker::Definition;
|
||||
use crate::store::StoreInnermost;
|
||||
use crate::{signatures::SignatureCollection, Engine, Extern};
|
||||
use anyhow::{bail, Context, Result};
|
||||
use wasmtime_environ::wasm::{
|
||||
use wasmtime_environ::{
|
||||
EntityType, Global, InstanceTypeIndex, Memory, ModuleTypeIndex, SignatureIndex, Table,
|
||||
};
|
||||
use wasmtime_jit::TypeTables;
|
||||
|
||||
@@ -25,6 +25,7 @@ const CRATES_TO_PUBLISH: &[&str] = &[
|
||||
"peepmatic-souper",
|
||||
// cranelift
|
||||
"cranelift-entity",
|
||||
"wasmtime-types",
|
||||
"cranelift-bforest",
|
||||
"cranelift-codegen-shared",
|
||||
"cranelift-codegen-meta",
|
||||
@@ -48,9 +49,7 @@ const CRATES_TO_PUBLISH: &[&str] = &[
|
||||
"wasmtime-fiber",
|
||||
"wasmtime-environ",
|
||||
"wasmtime-runtime",
|
||||
"wasmtime-debug",
|
||||
"wasmtime-profiling",
|
||||
"wasmtime-obj",
|
||||
"wasmtime-cranelift",
|
||||
"wasmtime-lightbeam",
|
||||
"wasmtime-jit",
|
||||
|
||||
Reference in New Issue
Block a user