Update wasmparser to 0.59.0 (#2013)
This commit is intended to update wasmparser to 0.59.0. This primarily includes bytecodealliance/wasm-tools#40 which is a large update to how parsing and validation works. The impact on Wasmtime is pretty small at this time, but over time I'd like to refactor the internals here to lean more heavily on that upstream wasmparser refactoring. For now, though, the intention is to get on the train of wasmparser's latest `main` branch to ensure we get bug fixes and such. As part of this update a few other crates and such were updated. This is primarily to handle the new encoding of `ref.is_null` where the type is not part of the instruction encoding any more.
This commit is contained in:
42
Cargo.lock
generated
42
Cargo.lock
generated
@@ -595,7 +595,7 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"target-lexicon",
|
"target-lexicon",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"wasmparser 0.58.0",
|
"wasmparser 0.59.0",
|
||||||
"wat",
|
"wat",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1124,7 +1124,7 @@ dependencies = [
|
|||||||
"staticvec",
|
"staticvec",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"typemap",
|
"typemap",
|
||||||
"wasmparser 0.58.0",
|
"wasmparser 0.59.0",
|
||||||
"wat",
|
"wat",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2298,12 +2298,6 @@ dependencies = [
|
|||||||
"yanix",
|
"yanix",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasmparser"
|
|
||||||
version = "0.55.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "af931e2e1960c53f4a28b063fec4cacd036f35acbec8ff3a4739125b17382a87"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmparser"
|
name = "wasmparser"
|
||||||
version = "0.57.0"
|
version = "0.57.0"
|
||||||
@@ -2312,18 +2306,18 @@ checksum = "32fddd575d477c6e9702484139cf9f23dcd554b06d185ed0f56c857dd3a47aa6"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmparser"
|
name = "wasmparser"
|
||||||
version = "0.58.0"
|
version = "0.59.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "721a8d79483738d7aef6397edcf8f04cd862640b1ad5973adf5bb50fc10e86db"
|
checksum = "a950e6a618f62147fd514ff445b2a0b53120d382751960797f85f058c7eda9b9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmprinter"
|
name = "wasmprinter"
|
||||||
version = "0.2.5"
|
version = "0.2.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c93ba310101ec5ee980db66b47b3d276577c8310df1570e19994347137650454"
|
checksum = "334551eb8b0b1be16cf366a54ce9b541ac32a96e9b51e67ebbae1696f108f112"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"wasmparser 0.55.0",
|
"wasmparser 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2341,7 +2335,7 @@ dependencies = [
|
|||||||
"smallvec",
|
"smallvec",
|
||||||
"target-lexicon",
|
"target-lexicon",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"wasmparser 0.58.0",
|
"wasmparser 0.59.0",
|
||||||
"wasmtime-environ",
|
"wasmtime-environ",
|
||||||
"wasmtime-jit",
|
"wasmtime-jit",
|
||||||
"wasmtime-profiling",
|
"wasmtime-profiling",
|
||||||
@@ -2415,7 +2409,7 @@ dependencies = [
|
|||||||
"object",
|
"object",
|
||||||
"target-lexicon",
|
"target-lexicon",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"wasmparser 0.58.0",
|
"wasmparser 0.59.0",
|
||||||
"wasmtime-environ",
|
"wasmtime-environ",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2448,7 +2442,7 @@ dependencies = [
|
|||||||
"tempfile",
|
"tempfile",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"toml",
|
"toml",
|
||||||
"wasmparser 0.58.0",
|
"wasmparser 0.59.0",
|
||||||
"winapi",
|
"winapi",
|
||||||
"zstd",
|
"zstd",
|
||||||
]
|
]
|
||||||
@@ -2477,7 +2471,7 @@ dependencies = [
|
|||||||
"env_logger",
|
"env_logger",
|
||||||
"log",
|
"log",
|
||||||
"rayon",
|
"rayon",
|
||||||
"wasmparser 0.58.0",
|
"wasmparser 0.59.0",
|
||||||
"wasmprinter",
|
"wasmprinter",
|
||||||
"wasmtime",
|
"wasmtime",
|
||||||
"wasmtime-wast",
|
"wasmtime-wast",
|
||||||
@@ -2502,7 +2496,7 @@ dependencies = [
|
|||||||
"region",
|
"region",
|
||||||
"target-lexicon",
|
"target-lexicon",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"wasmparser 0.58.0",
|
"wasmparser 0.59.0",
|
||||||
"wasmtime-debug",
|
"wasmtime-debug",
|
||||||
"wasmtime-environ",
|
"wasmtime-environ",
|
||||||
"wasmtime-obj",
|
"wasmtime-obj",
|
||||||
@@ -2599,7 +2593,7 @@ version = "0.18.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"wasmtime",
|
"wasmtime",
|
||||||
"wast 18.0.0",
|
"wast 21.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2643,20 +2637,20 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wast"
|
name = "wast"
|
||||||
version = "18.0.0"
|
version = "21.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "01b1f23531740a81f9300bd2febd397a95c76bfa4aa4bfaf4ca8b1ee3438f337"
|
checksum = "0b1844f66a2bc8526d71690104c0e78a8e59ffa1597b7245769d174ebb91deb5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"leb128",
|
"leb128",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wat"
|
name = "wat"
|
||||||
version = "1.0.19"
|
version = "1.0.22"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4006d418d59293172aebfeeadb7673459dc151874a79135946ea7996b6a98515"
|
checksum = "ce85d72b74242c340e9e3492cfb602652d7bb324c3172dd441b5577e39a2e18c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"wast 18.0.0",
|
"wast 21.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ keywords = ["webassembly", "wasm"]
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wasmparser = { version = "0.58.0", default-features = false }
|
wasmparser = { version = "0.59.0", default-features = false }
|
||||||
cranelift-codegen = { path = "../codegen", version = "0.65.0", default-features = false }
|
cranelift-codegen = { path = "../codegen", version = "0.65.0", default-features = false }
|
||||||
cranelift-entity = { path = "../entity", version = "0.65.0" }
|
cranelift-entity = { path = "../entity", version = "0.65.0" }
|
||||||
cranelift-frontend = { path = "../frontend", version = "0.65.0", default-features = false }
|
cranelift-frontend = { path = "../frontend", version = "0.65.0", default-features = false }
|
||||||
|
|||||||
@@ -1043,7 +1043,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
|||||||
Operator::RefNull { ty } => {
|
Operator::RefNull { ty } => {
|
||||||
state.push1(environ.translate_ref_null(builder.cursor(), (*ty).try_into()?)?)
|
state.push1(environ.translate_ref_null(builder.cursor(), (*ty).try_into()?)?)
|
||||||
}
|
}
|
||||||
Operator::RefIsNull { ty: _ } => {
|
Operator::RefIsNull => {
|
||||||
let value = state.pop1();
|
let value = state.pop1();
|
||||||
state.push1(environ.translate_ref_is_null(builder.cursor(), value)?);
|
state.push1(environ.translate_ref_is_null(builder.cursor(), value)?);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,13 +2,13 @@
|
|||||||
//! to deal with each part of it.
|
//! to deal with each part of it.
|
||||||
use crate::environ::{ModuleEnvironment, WasmResult};
|
use crate::environ::{ModuleEnvironment, WasmResult};
|
||||||
use crate::sections_translator::{
|
use crate::sections_translator::{
|
||||||
parse_code_section, parse_data_section, parse_element_section, parse_export_section,
|
parse_data_section, parse_element_section, parse_export_section, parse_function_section,
|
||||||
parse_function_section, parse_global_section, parse_import_section, parse_memory_section,
|
parse_global_section, parse_import_section, parse_memory_section, parse_name_section,
|
||||||
parse_name_section, parse_start_section, parse_table_section, parse_type_section,
|
parse_start_section, parse_table_section, parse_type_section,
|
||||||
};
|
};
|
||||||
use crate::state::ModuleTranslationState;
|
use crate::state::ModuleTranslationState;
|
||||||
use cranelift_codegen::timing;
|
use cranelift_codegen::timing;
|
||||||
use wasmparser::{CustomSectionContent, ModuleReader, SectionContent};
|
use wasmparser::{NameSectionReader, Parser, Payload};
|
||||||
|
|
||||||
/// Translate a sequence of bytes forming a valid Wasm binary into a list of valid Cranelift IR
|
/// Translate a sequence of bytes forming a valid Wasm binary into a list of valid Cranelift IR
|
||||||
/// [`Function`](cranelift_codegen::ir::Function).
|
/// [`Function`](cranelift_codegen::ir::Function).
|
||||||
@@ -17,80 +17,85 @@ pub fn translate_module<'data>(
|
|||||||
environ: &mut dyn ModuleEnvironment<'data>,
|
environ: &mut dyn ModuleEnvironment<'data>,
|
||||||
) -> WasmResult<ModuleTranslationState> {
|
) -> WasmResult<ModuleTranslationState> {
|
||||||
let _tt = timing::wasm_translate_module();
|
let _tt = timing::wasm_translate_module();
|
||||||
let mut reader = ModuleReader::new(data)?;
|
|
||||||
let mut module_translation_state = ModuleTranslationState::new();
|
let mut module_translation_state = ModuleTranslationState::new();
|
||||||
|
|
||||||
while !reader.eof() {
|
for payload in Parser::new(0).parse_all(data) {
|
||||||
let section = reader.read()?;
|
match payload? {
|
||||||
match section.content()? {
|
Payload::Version { .. } | Payload::End => {}
|
||||||
SectionContent::Type(types) => {
|
|
||||||
|
Payload::TypeSection(types) => {
|
||||||
parse_type_section(types, &mut module_translation_state, environ)?;
|
parse_type_section(types, &mut module_translation_state, environ)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
SectionContent::Import(imports) => {
|
Payload::ImportSection(imports) => {
|
||||||
parse_import_section(imports, environ)?;
|
parse_import_section(imports, environ)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
SectionContent::Function(functions) => {
|
Payload::FunctionSection(functions) => {
|
||||||
parse_function_section(functions, environ)?;
|
parse_function_section(functions, environ)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
SectionContent::Table(tables) => {
|
Payload::TableSection(tables) => {
|
||||||
parse_table_section(tables, environ)?;
|
parse_table_section(tables, environ)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
SectionContent::Memory(memories) => {
|
Payload::MemorySection(memories) => {
|
||||||
parse_memory_section(memories, environ)?;
|
parse_memory_section(memories, environ)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
SectionContent::Global(globals) => {
|
Payload::GlobalSection(globals) => {
|
||||||
parse_global_section(globals, environ)?;
|
parse_global_section(globals, environ)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
SectionContent::Export(exports) => {
|
Payload::ExportSection(exports) => {
|
||||||
parse_export_section(exports, environ)?;
|
parse_export_section(exports, environ)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
SectionContent::Start(start) => {
|
Payload::StartSection { func, .. } => {
|
||||||
parse_start_section(start, environ)?;
|
parse_start_section(func, environ)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
SectionContent::Element(elements) => {
|
Payload::ElementSection(elements) => {
|
||||||
parse_element_section(elements, environ)?;
|
parse_element_section(elements, environ)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
SectionContent::Code(code) => {
|
Payload::CodeSectionStart { .. } => {}
|
||||||
parse_code_section(code, &module_translation_state, environ)?;
|
Payload::CodeSectionEntry(code) => {
|
||||||
|
let mut code = code.get_binary_reader();
|
||||||
|
let size = code.bytes_remaining();
|
||||||
|
let offset = code.original_position();
|
||||||
|
environ.define_function_body(
|
||||||
|
&module_translation_state,
|
||||||
|
code.read_bytes(size)?,
|
||||||
|
offset,
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
SectionContent::Data(data) => {
|
Payload::DataSection(data) => {
|
||||||
parse_data_section(data, environ)?;
|
parse_data_section(data, environ)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
SectionContent::DataCount(count) => {
|
Payload::DataCountSection { count, .. } => {
|
||||||
environ.reserve_passive_data(count)?;
|
environ.reserve_passive_data(count)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
SectionContent::Module(_)
|
Payload::ModuleSection(_)
|
||||||
| SectionContent::ModuleCode(_)
|
| Payload::InstanceSection(_)
|
||||||
| SectionContent::Instance(_)
|
| Payload::AliasSection(_)
|
||||||
| SectionContent::Alias(_) => unimplemented!("module linking not implemented yet"),
|
| Payload::ModuleCodeSectionStart { .. }
|
||||||
|
| Payload::ModuleCodeSectionEntry { .. } => {
|
||||||
|
unimplemented!("module linking not implemented yet")
|
||||||
|
}
|
||||||
|
|
||||||
SectionContent::Custom {
|
Payload::CustomSection {
|
||||||
name,
|
name: "name",
|
||||||
binary,
|
data,
|
||||||
content,
|
data_offset,
|
||||||
} => match content {
|
} => parse_name_section(NameSectionReader::new(data, data_offset)?, environ)?,
|
||||||
Some(CustomSectionContent::Name(names)) => {
|
|
||||||
parse_name_section(names, environ)?;
|
Payload::CustomSection { name, data, .. } => environ.custom_section(name, data)?,
|
||||||
}
|
|
||||||
_ => {
|
Payload::UnknownSection { .. } => unreachable!(),
|
||||||
let mut reader = binary.clone();
|
|
||||||
let len = reader.bytes_remaining();
|
|
||||||
let payload = reader.read_bytes(len)?;
|
|
||||||
environ.custom_section(name, payload)?;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,11 +23,11 @@ use cranelift_entity::EntityRef;
|
|||||||
use std::boxed::Box;
|
use std::boxed::Box;
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
use wasmparser::{
|
use wasmparser::{
|
||||||
self, CodeSectionReader, Data, DataKind, DataSectionReader, Element, ElementItem, ElementItems,
|
self, Data, DataKind, DataSectionReader, Element, ElementItem, ElementItems, ElementKind,
|
||||||
ElementKind, ElementSectionReader, Export, ExportSectionReader, ExternalKind,
|
ElementSectionReader, Export, ExportSectionReader, ExternalKind, FunctionSectionReader,
|
||||||
FunctionSectionReader, GlobalSectionReader, GlobalType, ImportSectionEntryType,
|
GlobalSectionReader, GlobalType, ImportSectionEntryType, ImportSectionReader,
|
||||||
ImportSectionReader, MemorySectionReader, MemoryType, NameSectionReader, Naming, NamingReader,
|
MemorySectionReader, MemoryType, NameSectionReader, Naming, NamingReader, Operator,
|
||||||
Operator, TableSectionReader, Type, TypeDef, TypeSectionReader,
|
TableSectionReader, Type, TypeDef, TypeSectionReader,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Parses the Type section of the wasm module.
|
/// Parses the Type section of the wasm module.
|
||||||
@@ -358,21 +358,6 @@ pub fn parse_element_section<'data>(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses the Code section of the wasm module.
|
|
||||||
pub fn parse_code_section<'data>(
|
|
||||||
code: CodeSectionReader<'data>,
|
|
||||||
module_translation_state: &ModuleTranslationState,
|
|
||||||
environ: &mut dyn ModuleEnvironment<'data>,
|
|
||||||
) -> WasmResult<()> {
|
|
||||||
for body in code {
|
|
||||||
let mut reader = body?.get_binary_reader();
|
|
||||||
let size = reader.bytes_remaining();
|
|
||||||
let offset = reader.original_position();
|
|
||||||
environ.define_function_body(module_translation_state, reader.read_bytes(size)?, offset)?;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Parses the Data section of the wasm module.
|
/// Parses the Data section of the wasm module.
|
||||||
pub fn parse_data_section<'data>(
|
pub fn parse_data_section<'data>(
|
||||||
data: DataSectionReader<'data>,
|
data: DataSectionReader<'data>,
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
gimli = "0.21.0"
|
gimli = "0.21.0"
|
||||||
wasmparser = "0.58.0"
|
wasmparser = "0.59.0"
|
||||||
object = { version = "0.20", default-features = false, features = ["read", "write"] }
|
object = { version = "0.20", default-features = false, features = ["read", "write"] }
|
||||||
wasmtime-environ = { path = "../environ", version = "0.18.0" }
|
wasmtime-environ = { path = "../environ", version = "0.18.0" }
|
||||||
target-lexicon = { version = "0.10.0", default-features = false }
|
target-lexicon = { version = "0.10.0", default-features = false }
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use gimli::{
|
|||||||
};
|
};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use wasmparser::{self, ModuleReader, SectionCode, TypeDef};
|
use wasmparser::{self, NameSectionReader, Parser, Payload, TypeDef};
|
||||||
|
|
||||||
trait Reader: gimli::Reader<Offset = usize, Endian = LittleEndian> {}
|
trait Reader: gimli::Reader<Offset = usize, Endian = LittleEndian> {}
|
||||||
|
|
||||||
@@ -155,7 +155,6 @@ fn read_name_section(reader: wasmparser::NameSectionReader) -> wasmparser::Resul
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_debuginfo(data: &[u8]) -> Result<DebugInfoData> {
|
pub fn read_debuginfo(data: &[u8]) -> Result<DebugInfoData> {
|
||||||
let mut reader = ModuleReader::new(data)?;
|
|
||||||
let mut sections = HashMap::new();
|
let mut sections = HashMap::new();
|
||||||
let mut name_section = None;
|
let mut name_section = None;
|
||||||
let mut code_section_offset = 0;
|
let mut code_section_offset = 0;
|
||||||
@@ -165,26 +164,25 @@ pub fn read_debuginfo(data: &[u8]) -> Result<DebugInfoData> {
|
|||||||
let mut func_params_refs: Vec<usize> = Vec::new();
|
let mut func_params_refs: Vec<usize> = Vec::new();
|
||||||
let mut func_locals: Vec<Box<[(u32, WasmType)]>> = Vec::new();
|
let mut func_locals: Vec<Box<[(u32, WasmType)]>> = Vec::new();
|
||||||
|
|
||||||
while !reader.eof() {
|
for payload in Parser::new(0).parse_all(data) {
|
||||||
let section = reader.read()?;
|
match payload? {
|
||||||
match section.code {
|
Payload::CustomSection {
|
||||||
SectionCode::Custom { name, .. } => {
|
name,
|
||||||
|
data,
|
||||||
|
data_offset,
|
||||||
|
} => {
|
||||||
if name.starts_with(".debug_") {
|
if name.starts_with(".debug_") {
|
||||||
let mut reader = section.get_binary_reader();
|
sections.insert(name, data);
|
||||||
let len = reader.bytes_remaining();
|
} else if name == "name" {
|
||||||
sections.insert(name, reader.read_bytes(len)?);
|
if let Ok(reader) = NameSectionReader::new(data, data_offset) {
|
||||||
}
|
|
||||||
if name == "name" {
|
|
||||||
if let Ok(reader) = section.get_name_section_reader() {
|
|
||||||
if let Ok(section) = read_name_section(reader) {
|
if let Ok(section) = read_name_section(reader) {
|
||||||
name_section = Some(section);
|
name_section = Some(section);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SectionCode::Type => {
|
Payload::TypeSection(s) => {
|
||||||
signatures_params = section
|
signatures_params = s
|
||||||
.get_type_section_reader()?
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|ft| {
|
.map(|ft| {
|
||||||
if let Ok(TypeDef::Func(ft)) = ft {
|
if let Ok(TypeDef::Func(ft)) = ft {
|
||||||
@@ -195,33 +193,29 @@ pub fn read_debuginfo(data: &[u8]) -> Result<DebugInfoData> {
|
|||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>>>()?;
|
.collect::<Result<Vec<_>>>()?;
|
||||||
}
|
}
|
||||||
SectionCode::Import => {
|
Payload::ImportSection(s) => {
|
||||||
for i in section.get_import_section_reader()? {
|
for i in s {
|
||||||
if let wasmparser::ImportSectionEntryType::Function(_) = i?.ty {
|
if let wasmparser::ImportSectionEntryType::Function(_) = i?.ty {
|
||||||
imported_func_count += 1;
|
imported_func_count += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SectionCode::Function => {
|
Payload::FunctionSection(s) => {
|
||||||
func_params_refs = section
|
func_params_refs = s
|
||||||
.get_function_section_reader()?
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|index| Ok(index? as usize))
|
.map(|index| Ok(index? as usize))
|
||||||
.collect::<Result<Vec<_>>>()?;
|
.collect::<Result<Vec<_>>>()?;
|
||||||
}
|
}
|
||||||
SectionCode::Code => {
|
Payload::CodeSectionStart { range, .. } => {
|
||||||
code_section_offset = section.range().start as u64;
|
code_section_offset = range.start as u64;
|
||||||
func_locals = section
|
}
|
||||||
.get_code_section_reader()?
|
Payload::CodeSectionEntry(body) => {
|
||||||
|
let locals = body.get_locals_reader()?;
|
||||||
|
let locals = locals
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|body| {
|
.collect::<Result<Vec<_>, _>>()?
|
||||||
let locals = body?.get_locals_reader()?;
|
.into_boxed_slice();
|
||||||
Ok(locals
|
func_locals.push(locals);
|
||||||
.into_iter()
|
|
||||||
.collect::<Result<Vec<_>, _>>()?
|
|
||||||
.into_boxed_slice())
|
|
||||||
})
|
|
||||||
.collect::<Result<Vec<_>>>()?;
|
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ cranelift-codegen = { path = "../../cranelift/codegen", version = "0.65.0", feat
|
|||||||
cranelift-entity = { path = "../../cranelift/entity", version = "0.65.0", features = ["enable-serde"] }
|
cranelift-entity = { path = "../../cranelift/entity", version = "0.65.0", features = ["enable-serde"] }
|
||||||
cranelift-frontend = { path = "../../cranelift/frontend", version = "0.65.0" }
|
cranelift-frontend = { path = "../../cranelift/frontend", version = "0.65.0" }
|
||||||
cranelift-wasm = { path = "../../cranelift/wasm", version = "0.65.0", features = ["enable-serde"] }
|
cranelift-wasm = { path = "../../cranelift/wasm", version = "0.65.0", features = ["enable-serde"] }
|
||||||
wasmparser = "0.58.0"
|
wasmparser = "0.59.0"
|
||||||
lightbeam = { path = "../lightbeam", optional = true, version = "0.18.0" }
|
lightbeam = { path = "../lightbeam", optional = true, version = "0.18.0" }
|
||||||
indexmap = { version = "1.0.2", features = ["serde-1"] }
|
indexmap = { version = "1.0.2", features = ["serde-1"] }
|
||||||
rayon = { version = "1.2.1", optional = true }
|
rayon = { version = "1.2.1", optional = true }
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ binaryen = { version = "0.10.0", optional = true }
|
|||||||
env_logger = "0.7.1"
|
env_logger = "0.7.1"
|
||||||
log = "0.4.8"
|
log = "0.4.8"
|
||||||
rayon = "1.2.1"
|
rayon = "1.2.1"
|
||||||
wasmparser = "0.58.0"
|
wasmparser = "0.59.0"
|
||||||
wasmprinter = "0.2.5"
|
wasmprinter = "0.2.6"
|
||||||
wasmtime = { path = "../wasmtime" }
|
wasmtime = { path = "../wasmtime" }
|
||||||
wasmtime-wast = { path = "../wast" }
|
wasmtime-wast = { path = "../wast" }
|
||||||
|
|
||||||
|
|||||||
@@ -213,14 +213,12 @@ fn arbitrary_config(
|
|||||||
/// it'll free up new slots to start making new instances.
|
/// it'll free up new slots to start making new instances.
|
||||||
fn predict_rss(wasm: &[u8]) -> Result<usize> {
|
fn predict_rss(wasm: &[u8]) -> Result<usize> {
|
||||||
let mut prediction = 0;
|
let mut prediction = 0;
|
||||||
let mut reader = ModuleReader::new(wasm)?;
|
for payload in Parser::new(0).parse_all(wasm) {
|
||||||
while !reader.eof() {
|
match payload? {
|
||||||
let section = reader.read()?;
|
|
||||||
match section.code {
|
|
||||||
// For each declared memory we'll have to map that all in, so add in
|
// For each declared memory we'll have to map that all in, so add in
|
||||||
// the minimum amount of memory to our predicted rss.
|
// the minimum amount of memory to our predicted rss.
|
||||||
SectionCode::Memory => {
|
Payload::MemorySection(s) => {
|
||||||
for entry in section.get_memory_section_reader()? {
|
for entry in s {
|
||||||
let initial = entry?.limits.initial as usize;
|
let initial = entry?.limits.initial as usize;
|
||||||
prediction += initial * 64 * 1024;
|
prediction += initial * 64 * 1024;
|
||||||
}
|
}
|
||||||
@@ -228,8 +226,8 @@ fn predict_rss(wasm: &[u8]) -> Result<usize> {
|
|||||||
|
|
||||||
// We'll need to allocate tables and space for table elements, and
|
// We'll need to allocate tables and space for table elements, and
|
||||||
// currently this is 3 pointers per table entry.
|
// currently this is 3 pointers per table entry.
|
||||||
SectionCode::Table => {
|
Payload::TableSection(s) => {
|
||||||
for entry in section.get_table_section_reader()? {
|
for entry in s {
|
||||||
let initial = entry?.limits.initial as usize;
|
let initial = entry?.limits.initial as usize;
|
||||||
prediction += initial * 3 * mem::size_of::<usize>();
|
prediction += initial * 3 * mem::size_of::<usize>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ wasmtime-obj = { path = "../obj", version = "0.18.0" }
|
|||||||
region = "2.1.0"
|
region = "2.1.0"
|
||||||
thiserror = "1.0.4"
|
thiserror = "1.0.4"
|
||||||
target-lexicon = { version = "0.10.0", default-features = false }
|
target-lexicon = { version = "0.10.0", default-features = false }
|
||||||
wasmparser = "0.58.0"
|
wasmparser = "0.59.0"
|
||||||
more-asserts = "0.2.1"
|
more-asserts = "0.2.1"
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
cfg-if = "0.1.9"
|
cfg-if = "0.1.9"
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ smallvec = "1.0.0"
|
|||||||
staticvec = "0.10"
|
staticvec = "0.10"
|
||||||
thiserror = "1.0.9"
|
thiserror = "1.0.9"
|
||||||
typemap = "0.3"
|
typemap = "0.3"
|
||||||
wasmparser = "0.58.0"
|
wasmparser = "0.59.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
lazy_static = "1.2"
|
lazy_static = "1.2"
|
||||||
|
|||||||
@@ -2130,7 +2130,7 @@ where
|
|||||||
WasmOperator::RefNull { ty: _ } => {
|
WasmOperator::RefNull { ty: _ } => {
|
||||||
return Err(Error::Microwasm("RefNull unimplemented".into()))
|
return Err(Error::Microwasm("RefNull unimplemented".into()))
|
||||||
}
|
}
|
||||||
WasmOperator::RefIsNull { ty: _ } => {
|
WasmOperator::RefIsNull => {
|
||||||
return Err(Error::Microwasm("RefIsNull unimplemented".into()))
|
return Err(Error::Microwasm("RefIsNull unimplemented".into()))
|
||||||
}
|
}
|
||||||
WasmOperator::I32Eqz => one(Operator::Eqz(Size::_32)),
|
WasmOperator::I32Eqz => one(Operator::Eqz(Size::_32)),
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use memoffset::offset_of;
|
|||||||
|
|
||||||
use std::{convert::TryInto, mem};
|
use std::{convert::TryInto, mem};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use wasmparser::{FuncType, MemoryType, ModuleReader, SectionCode, Type};
|
use wasmparser::{FuncType, MemoryType, Parser, Payload, Type};
|
||||||
|
|
||||||
pub trait AsValueType {
|
pub trait AsValueType {
|
||||||
const TYPE: Type;
|
const TYPE: Type;
|
||||||
@@ -512,150 +512,58 @@ pub fn translate(data: &[u8]) -> Result<ExecutableModule, Error> {
|
|||||||
|
|
||||||
/// Translate from a slice of bytes holding a wasm module.
|
/// Translate from a slice of bytes holding a wasm module.
|
||||||
pub fn translate_only(data: &[u8]) -> Result<TranslatedModule, Error> {
|
pub fn translate_only(data: &[u8]) -> Result<TranslatedModule, Error> {
|
||||||
let mut reader = ModuleReader::new(data)?;
|
|
||||||
let mut output = TranslatedModule::default();
|
let mut output = TranslatedModule::default();
|
||||||
|
|
||||||
reader.skip_custom_sections()?;
|
for payload in Parser::new(0).parse_all(data) {
|
||||||
if reader.eof() {
|
match payload? {
|
||||||
return Ok(output);
|
Payload::TypeSection(s) => output.ctx.types = translate_sections::type_(s)?,
|
||||||
}
|
Payload::ImportSection(s) => translate_sections::import(s)?,
|
||||||
let mut section = reader.read()?;
|
Payload::FunctionSection(s) => {
|
||||||
|
output.ctx.func_ty_indices = translate_sections::function(s)?;
|
||||||
if let SectionCode::Type = section.code {
|
|
||||||
let types_reader = section.get_type_section_reader()?;
|
|
||||||
output.ctx.types = translate_sections::type_(types_reader)?;
|
|
||||||
|
|
||||||
reader.skip_custom_sections()?;
|
|
||||||
if reader.eof() {
|
|
||||||
return Ok(output);
|
|
||||||
}
|
|
||||||
section = reader.read()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let SectionCode::Import = section.code {
|
|
||||||
let imports = section.get_import_section_reader()?;
|
|
||||||
translate_sections::import(imports)?;
|
|
||||||
|
|
||||||
reader.skip_custom_sections()?;
|
|
||||||
if reader.eof() {
|
|
||||||
return Ok(output);
|
|
||||||
}
|
|
||||||
section = reader.read()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let SectionCode::Function = section.code {
|
|
||||||
let functions = section.get_function_section_reader()?;
|
|
||||||
output.ctx.func_ty_indices = translate_sections::function(functions)?;
|
|
||||||
|
|
||||||
reader.skip_custom_sections()?;
|
|
||||||
if reader.eof() {
|
|
||||||
return Ok(output);
|
|
||||||
}
|
|
||||||
section = reader.read()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let SectionCode::Table = section.code {
|
|
||||||
let tables = section.get_table_section_reader()?;
|
|
||||||
translate_sections::table(tables)?;
|
|
||||||
|
|
||||||
reader.skip_custom_sections()?;
|
|
||||||
if reader.eof() {
|
|
||||||
return Ok(output);
|
|
||||||
}
|
|
||||||
section = reader.read()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let SectionCode::Memory = section.code {
|
|
||||||
let memories = section.get_memory_section_reader()?;
|
|
||||||
let mem = translate_sections::memory(memories)?;
|
|
||||||
|
|
||||||
if mem.len() > 1 {
|
|
||||||
return Err(Error::Input(
|
|
||||||
"Multiple memory sections not yet implemented".to_string(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
if !mem.is_empty() {
|
|
||||||
let mem = mem[0];
|
|
||||||
if Some(mem.limits.initial) != mem.limits.maximum {
|
|
||||||
return Err(Error::Input(
|
|
||||||
"Custom memory limits not supported in lightbeam".to_string(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
output.memory = Some(mem);
|
Payload::TableSection(s) => {
|
||||||
|
translate_sections::table(s)?;
|
||||||
|
}
|
||||||
|
Payload::MemorySection(s) => {
|
||||||
|
let mem = translate_sections::memory(s)?;
|
||||||
|
|
||||||
|
if mem.len() > 1 {
|
||||||
|
return Err(Error::Input(
|
||||||
|
"Multiple memory sections not yet implemented".to_string(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if !mem.is_empty() {
|
||||||
|
let mem = mem[0];
|
||||||
|
if Some(mem.limits.initial) != mem.limits.maximum {
|
||||||
|
return Err(Error::Input(
|
||||||
|
"Custom memory limits not supported in lightbeam".to_string(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
output.memory = Some(mem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Payload::GlobalSection(s) => {
|
||||||
|
translate_sections::global(s)?;
|
||||||
|
}
|
||||||
|
Payload::ExportSection(s) => {
|
||||||
|
translate_sections::export(s)?;
|
||||||
|
}
|
||||||
|
Payload::StartSection { func, .. } => {
|
||||||
|
translate_sections::start(func)?;
|
||||||
|
}
|
||||||
|
Payload::ElementSection(s) => {
|
||||||
|
translate_sections::element(s)?;
|
||||||
|
}
|
||||||
|
Payload::DataSection(s) => {
|
||||||
|
translate_sections::data(s)?;
|
||||||
|
}
|
||||||
|
Payload::CodeSectionStart { .. }
|
||||||
|
| Payload::CustomSection { .. }
|
||||||
|
| Payload::Version { .. } => {}
|
||||||
|
|
||||||
|
other => unimplemented!("can't translate {:?}", other),
|
||||||
}
|
}
|
||||||
|
|
||||||
reader.skip_custom_sections()?;
|
|
||||||
if reader.eof() {
|
|
||||||
return Ok(output);
|
|
||||||
}
|
|
||||||
section = reader.read()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let SectionCode::Global = section.code {
|
|
||||||
let globals = section.get_global_section_reader()?;
|
|
||||||
translate_sections::global(globals)?;
|
|
||||||
|
|
||||||
reader.skip_custom_sections()?;
|
|
||||||
if reader.eof() {
|
|
||||||
return Ok(output);
|
|
||||||
}
|
|
||||||
section = reader.read()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let SectionCode::Export = section.code {
|
|
||||||
let exports = section.get_export_section_reader()?;
|
|
||||||
translate_sections::export(exports)?;
|
|
||||||
|
|
||||||
reader.skip_custom_sections()?;
|
|
||||||
if reader.eof() {
|
|
||||||
return Ok(output);
|
|
||||||
}
|
|
||||||
section = reader.read()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let SectionCode::Start = section.code {
|
|
||||||
let start = section.get_start_section_content()?;
|
|
||||||
translate_sections::start(start)?;
|
|
||||||
|
|
||||||
reader.skip_custom_sections()?;
|
|
||||||
if reader.eof() {
|
|
||||||
return Ok(output);
|
|
||||||
}
|
|
||||||
section = reader.read()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let SectionCode::Element = section.code {
|
|
||||||
let elements = section.get_element_section_reader()?;
|
|
||||||
translate_sections::element(elements)?;
|
|
||||||
|
|
||||||
reader.skip_custom_sections()?;
|
|
||||||
if reader.eof() {
|
|
||||||
return Ok(output);
|
|
||||||
}
|
|
||||||
section = reader.read()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let SectionCode::Code = section.code {
|
|
||||||
let code = section.get_code_section_reader()?;
|
|
||||||
output.translated_code_section = Some(translate_sections::code(code, &output.ctx)?);
|
|
||||||
|
|
||||||
reader.skip_custom_sections()?;
|
|
||||||
if reader.eof() {
|
|
||||||
return Ok(output);
|
|
||||||
}
|
|
||||||
section = reader.read()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let SectionCode::Data = section.code {
|
|
||||||
let data = section.get_data_section_reader()?;
|
|
||||||
translate_sections::data(data)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if !reader.eof() {
|
|
||||||
return Err(Error::Input(
|
|
||||||
"Unexpected data found after the end of the module".to_string(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(output)
|
Ok(output)
|
||||||
|
|||||||
@@ -108,6 +108,7 @@ impl binemit::RelocSink for UnimplementedRelocSink {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Parses the Code section of the wasm module.
|
/// Parses the Code section of the wasm module.
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn code(
|
pub fn code(
|
||||||
_code: CodeSectionReader,
|
_code: CodeSectionReader,
|
||||||
_translation_ctx: &SimpleContext,
|
_translation_ctx: &SimpleContext,
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ wasmtime-runtime = { path = "../runtime", version = "0.18.0" }
|
|||||||
wasmtime-environ = { path = "../environ", version = "0.18.0" }
|
wasmtime-environ = { path = "../environ", version = "0.18.0" }
|
||||||
wasmtime-jit = { path = "../jit", version = "0.18.0" }
|
wasmtime-jit = { path = "../jit", version = "0.18.0" }
|
||||||
wasmtime-profiling = { path = "../profiling", version = "0.18.0" }
|
wasmtime-profiling = { path = "../profiling", version = "0.18.0" }
|
||||||
wasmparser = "0.58.0"
|
wasmparser = "0.59.0"
|
||||||
target-lexicon = { version = "0.10.0", default-features = false }
|
target-lexicon = { version = "0.10.0", default-features = false }
|
||||||
anyhow = "1.0.19"
|
anyhow = "1.0.19"
|
||||||
region = "2.2.0"
|
region = "2.2.0"
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ fn instantiate(
|
|||||||
let instance = store.add_instance(instance);
|
let instance = store.add_instance(instance);
|
||||||
instance
|
instance
|
||||||
.initialize(
|
.initialize(
|
||||||
config.validating_config.operator_config.enable_bulk_memory,
|
config.wasm_bulk_memory,
|
||||||
&compiled_module.data_initializers(),
|
&compiled_module.data_initializers(),
|
||||||
)
|
)
|
||||||
.map_err(|e| -> Error {
|
.map_err(|e| -> Error {
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
use crate::frame_info::GlobalFrameInfoRegistration;
|
use crate::frame_info::GlobalFrameInfoRegistration;
|
||||||
use crate::runtime::Engine;
|
use crate::runtime::Engine;
|
||||||
use crate::types::{EntityType, ExportType, ExternType, ImportType};
|
use crate::types::{EntityType, ExportType, ExternType, ImportType};
|
||||||
use anyhow::{Error, Result};
|
use anyhow::Result;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use wasmparser::validate;
|
|
||||||
use wasmtime_jit::CompiledModule;
|
use wasmtime_jit::CompiledModule;
|
||||||
|
|
||||||
/// A compiled WebAssembly module, ready to be instantiated.
|
/// A compiled WebAssembly module, ready to be instantiated.
|
||||||
@@ -296,8 +295,8 @@ impl Module {
|
|||||||
///
|
///
|
||||||
/// [binary]: https://webassembly.github.io/spec/core/binary/index.html
|
/// [binary]: https://webassembly.github.io/spec/core/binary/index.html
|
||||||
pub fn validate(engine: &Engine, binary: &[u8]) -> Result<()> {
|
pub fn validate(engine: &Engine, binary: &[u8]) -> Result<()> {
|
||||||
let config = engine.config().validating_config.clone();
|
engine.config().validator().validate_all(binary)?;
|
||||||
validate(binary, Some(config)).map_err(Error::new)
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn compile(engine: &Engine, binary: &[u8]) -> Result<Self> {
|
unsafe fn compile(engine: &Engine, binary: &[u8]) -> Result<Self> {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use std::hash::{Hash, Hasher};
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::rc::{Rc, Weak};
|
use std::rc::{Rc, Weak};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use wasmparser::{OperatorValidatorConfig, ValidatingParserConfig};
|
use wasmparser::Validator;
|
||||||
use wasmtime_environ::settings::{self, Configurable, SetError};
|
use wasmtime_environ::settings::{self, Configurable, SetError};
|
||||||
use wasmtime_environ::{ir, isa, isa::TargetIsa, wasm, CacheConfig, Tunables};
|
use wasmtime_environ::{ir, isa, isa::TargetIsa, wasm, CacheConfig, Tunables};
|
||||||
use wasmtime_jit::{native, CompilationStrategy, Compiler};
|
use wasmtime_jit::{native, CompilationStrategy, Compiler};
|
||||||
@@ -34,13 +34,17 @@ use wasmtime_runtime::{
|
|||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub(crate) flags: settings::Builder,
|
pub(crate) flags: settings::Builder,
|
||||||
pub(crate) isa_flags: isa::Builder,
|
pub(crate) isa_flags: isa::Builder,
|
||||||
pub(crate) validating_config: ValidatingParserConfig,
|
|
||||||
pub(crate) tunables: Tunables,
|
pub(crate) tunables: Tunables,
|
||||||
pub(crate) strategy: CompilationStrategy,
|
pub(crate) strategy: CompilationStrategy,
|
||||||
pub(crate) cache_config: CacheConfig,
|
pub(crate) cache_config: CacheConfig,
|
||||||
pub(crate) profiler: Arc<dyn ProfilingAgent>,
|
pub(crate) profiler: Arc<dyn ProfilingAgent>,
|
||||||
pub(crate) memory_creator: Option<MemoryCreatorProxy>,
|
pub(crate) memory_creator: Option<MemoryCreatorProxy>,
|
||||||
pub(crate) max_wasm_stack: usize,
|
pub(crate) max_wasm_stack: usize,
|
||||||
|
wasm_threads: bool,
|
||||||
|
wasm_reference_types: bool,
|
||||||
|
pub(crate) wasm_bulk_memory: bool,
|
||||||
|
wasm_simd: bool,
|
||||||
|
wasm_multi_value: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
@@ -81,17 +85,6 @@ impl Config {
|
|||||||
|
|
||||||
Config {
|
Config {
|
||||||
tunables,
|
tunables,
|
||||||
validating_config: ValidatingParserConfig {
|
|
||||||
operator_config: OperatorValidatorConfig {
|
|
||||||
enable_threads: false,
|
|
||||||
enable_reference_types: false,
|
|
||||||
enable_bulk_memory: false,
|
|
||||||
enable_simd: false,
|
|
||||||
enable_multi_value: true,
|
|
||||||
enable_tail_call: false,
|
|
||||||
enable_module_linking: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
flags,
|
flags,
|
||||||
isa_flags: native::builder(),
|
isa_flags: native::builder(),
|
||||||
strategy: CompilationStrategy::Auto,
|
strategy: CompilationStrategy::Auto,
|
||||||
@@ -99,6 +92,11 @@ impl Config {
|
|||||||
profiler: Arc::new(NullProfilerAgent),
|
profiler: Arc::new(NullProfilerAgent),
|
||||||
memory_creator: None,
|
memory_creator: None,
|
||||||
max_wasm_stack: 1 << 20,
|
max_wasm_stack: 1 << 20,
|
||||||
|
wasm_threads: false,
|
||||||
|
wasm_reference_types: false,
|
||||||
|
wasm_bulk_memory: false,
|
||||||
|
wasm_simd: false,
|
||||||
|
wasm_multi_value: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,7 +161,7 @@ impl Config {
|
|||||||
///
|
///
|
||||||
/// [threads]: https://github.com/webassembly/threads
|
/// [threads]: https://github.com/webassembly/threads
|
||||||
pub fn wasm_threads(&mut self, enable: bool) -> &mut Self {
|
pub fn wasm_threads(&mut self, enable: bool) -> &mut Self {
|
||||||
self.validating_config.operator_config.enable_threads = enable;
|
self.wasm_threads = enable;
|
||||||
// The threads proposal depends on the bulk memory proposal
|
// The threads proposal depends on the bulk memory proposal
|
||||||
if enable {
|
if enable {
|
||||||
self.wasm_bulk_memory(true);
|
self.wasm_bulk_memory(true);
|
||||||
@@ -193,9 +191,7 @@ impl Config {
|
|||||||
///
|
///
|
||||||
/// [proposal]: https://github.com/webassembly/reference-types
|
/// [proposal]: https://github.com/webassembly/reference-types
|
||||||
pub fn wasm_reference_types(&mut self, enable: bool) -> &mut Self {
|
pub fn wasm_reference_types(&mut self, enable: bool) -> &mut Self {
|
||||||
self.validating_config
|
self.wasm_reference_types = enable;
|
||||||
.operator_config
|
|
||||||
.enable_reference_types = enable;
|
|
||||||
|
|
||||||
self.flags
|
self.flags
|
||||||
.set("enable_safepoints", if enable { "true" } else { "false" })
|
.set("enable_safepoints", if enable { "true" } else { "false" })
|
||||||
@@ -230,7 +226,7 @@ impl Config {
|
|||||||
///
|
///
|
||||||
/// [proposal]: https://github.com/webassembly/simd
|
/// [proposal]: https://github.com/webassembly/simd
|
||||||
pub fn wasm_simd(&mut self, enable: bool) -> &mut Self {
|
pub fn wasm_simd(&mut self, enable: bool) -> &mut Self {
|
||||||
self.validating_config.operator_config.enable_simd = enable;
|
self.wasm_simd = enable;
|
||||||
let val = if enable { "true" } else { "false" };
|
let val = if enable { "true" } else { "false" };
|
||||||
self.flags
|
self.flags
|
||||||
.set("enable_simd", val)
|
.set("enable_simd", val)
|
||||||
@@ -254,7 +250,7 @@ impl Config {
|
|||||||
///
|
///
|
||||||
/// [proposal]: https://github.com/webassembly/bulk-memory-operations
|
/// [proposal]: https://github.com/webassembly/bulk-memory-operations
|
||||||
pub fn wasm_bulk_memory(&mut self, enable: bool) -> &mut Self {
|
pub fn wasm_bulk_memory(&mut self, enable: bool) -> &mut Self {
|
||||||
self.validating_config.operator_config.enable_bulk_memory = enable;
|
self.wasm_bulk_memory = enable;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,7 +264,7 @@ impl Config {
|
|||||||
///
|
///
|
||||||
/// [proposal]: https://github.com/webassembly/multi-value
|
/// [proposal]: https://github.com/webassembly/multi-value
|
||||||
pub fn wasm_multi_value(&mut self, enable: bool) -> &mut Self {
|
pub fn wasm_multi_value(&mut self, enable: bool) -> &mut Self {
|
||||||
self.validating_config.operator_config.enable_multi_value = enable;
|
self.wasm_multi_value = enable;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -613,6 +609,16 @@ impl Config {
|
|||||||
.finish(settings::Flags::new(self.flags.clone()))
|
.finish(settings::Flags::new(self.flags.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn validator(&self) -> Validator {
|
||||||
|
let mut ret = Validator::new();
|
||||||
|
ret.wasm_threads(self.wasm_threads)
|
||||||
|
.wasm_bulk_memory(self.wasm_bulk_memory)
|
||||||
|
.wasm_multi_value(self.wasm_multi_value)
|
||||||
|
.wasm_reference_types(self.wasm_reference_types)
|
||||||
|
.wasm_simd(self.wasm_simd);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
fn build_compiler(&self) -> Compiler {
|
fn build_compiler(&self) -> Compiler {
|
||||||
let isa = self.target_isa();
|
let isa = self.target_isa();
|
||||||
Compiler::new(
|
Compiler::new(
|
||||||
@@ -640,15 +646,14 @@ impl Default for Config {
|
|||||||
|
|
||||||
impl fmt::Debug for Config {
|
impl fmt::Debug for Config {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let features = &self.validating_config.operator_config;
|
|
||||||
f.debug_struct("Config")
|
f.debug_struct("Config")
|
||||||
.field("debug_info", &self.tunables.debug_info)
|
.field("debug_info", &self.tunables.debug_info)
|
||||||
.field("strategy", &self.strategy)
|
.field("strategy", &self.strategy)
|
||||||
.field("wasm_threads", &features.enable_threads)
|
.field("wasm_threads", &self.wasm_threads)
|
||||||
.field("wasm_reference_types", &features.enable_reference_types)
|
.field("wasm_reference_types", &self.wasm_reference_types)
|
||||||
.field("wasm_bulk_memory", &features.enable_bulk_memory)
|
.field("wasm_bulk_memory", &self.wasm_bulk_memory)
|
||||||
.field("wasm_simd", &features.enable_simd)
|
.field("wasm_simd", &self.wasm_simd)
|
||||||
.field("wasm_multi_value", &features.enable_multi_value)
|
.field("wasm_multi_value", &self.wasm_multi_value)
|
||||||
.field(
|
.field(
|
||||||
"flags",
|
"flags",
|
||||||
&settings::Flags::new(self.flags.clone()).to_string(),
|
&settings::Flags::new(self.flags.clone()).to_string(),
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ edition = "2018"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.19"
|
anyhow = "1.0.19"
|
||||||
wasmtime = { path = "../wasmtime", version = "0.18.0", default-features = false }
|
wasmtime = { path = "../wasmtime", version = "0.18.0", default-features = false }
|
||||||
wast = "18.0.0"
|
wast = "21.0.0"
|
||||||
|
|
||||||
[badges]
|
[badges]
|
||||||
maintenance = { status = "actively-developed" }
|
maintenance = { status = "actively-developed" }
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use wasmtime::*;
|
|||||||
use wast::Wat;
|
use wast::Wat;
|
||||||
use wast::{
|
use wast::{
|
||||||
parser::{self, ParseBuffer},
|
parser::{self, ParseBuffer},
|
||||||
RefType,
|
HeapType,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Translate from a `script::Value` to a `RuntimeValue`.
|
/// Translate from a `script::Value` to a `RuntimeValue`.
|
||||||
@@ -22,8 +22,8 @@ fn runtime_value(v: &wast::Expression<'_>) -> Result<Val> {
|
|||||||
F32Const(x) => Val::F32(x.bits),
|
F32Const(x) => Val::F32(x.bits),
|
||||||
F64Const(x) => Val::F64(x.bits),
|
F64Const(x) => Val::F64(x.bits),
|
||||||
V128Const(x) => Val::V128(u128::from_le_bytes(x.to_le_bytes())),
|
V128Const(x) => Val::V128(u128::from_le_bytes(x.to_le_bytes())),
|
||||||
RefNull(RefType::Extern) => Val::ExternRef(None),
|
RefNull(HeapType::Extern) => Val::ExternRef(None),
|
||||||
RefNull(RefType::Func) => Val::FuncRef(None),
|
RefNull(HeapType::Func) => Val::FuncRef(None),
|
||||||
RefExtern(x) => Val::ExternRef(Some(ExternRef::new(*x))),
|
RefExtern(x) => Val::ExternRef(Some(ExternRef::new(*x))),
|
||||||
other => bail!("couldn't convert {:?} to a runtime value", other),
|
other => bail!("couldn't convert {:?} to a runtime value", other),
|
||||||
})
|
})
|
||||||
@@ -409,7 +409,7 @@ fn val_matches(actual: &Val, expected: &wast::AssertExpression) -> Result<bool>
|
|||||||
(Val::F32(a), wast::AssertExpression::F32(b)) => f32_matches(*a, b),
|
(Val::F32(a), wast::AssertExpression::F32(b)) => f32_matches(*a, b),
|
||||||
(Val::F64(a), wast::AssertExpression::F64(b)) => f64_matches(*a, b),
|
(Val::F64(a), wast::AssertExpression::F64(b)) => f64_matches(*a, b),
|
||||||
(Val::V128(a), wast::AssertExpression::V128(b)) => v128_matches(*a, b),
|
(Val::V128(a), wast::AssertExpression::V128(b)) => v128_matches(*a, b),
|
||||||
(Val::ExternRef(x), wast::AssertExpression::RefNull(wast::RefType::Extern)) => x.is_none(),
|
(Val::ExternRef(x), wast::AssertExpression::RefNull(HeapType::Extern)) => x.is_none(),
|
||||||
(Val::ExternRef(x), wast::AssertExpression::RefExtern(y)) => {
|
(Val::ExternRef(x), wast::AssertExpression::RefExtern(y)) => {
|
||||||
if let Some(x) = x {
|
if let Some(x) = x {
|
||||||
let x = x
|
let x = x
|
||||||
@@ -421,7 +421,7 @@ fn val_matches(actual: &Val, expected: &wast::AssertExpression) -> Result<bool>
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Val::FuncRef(x), wast::AssertExpression::RefNull(wast::RefType::Func)) => x.is_none(),
|
(Val::FuncRef(x), wast::AssertExpression::RefNull(HeapType::Func)) => x.is_none(),
|
||||||
_ => bail!(
|
_ => bail!(
|
||||||
"don't know how to compare {:?} and {:?} yet",
|
"don't know how to compare {:?} and {:?} yet",
|
||||||
actual,
|
actual,
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
(module
|
(module
|
||||||
(func (export "func_is_null") (param funcref) (result i32)
|
(func (export "func_is_null") (param funcref) (result i32)
|
||||||
(ref.is_null func (local.get 0))
|
(ref.is_null (local.get 0))
|
||||||
)
|
)
|
||||||
(func (export "func_is_null_with_non_null_funcref") (result i32)
|
(func (export "func_is_null_with_non_null_funcref") (result i32)
|
||||||
(call 0 (ref.func 0))
|
(call 0 (ref.func 0))
|
||||||
)
|
)
|
||||||
(func (export "extern_is_null") (param externref) (result i32)
|
(func (export "extern_is_null") (param externref) (result i32)
|
||||||
(ref.is_null extern (local.get 0))
|
(ref.is_null (local.get 0))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Submodule tests/spec_testsuite updated: 21a10bc594...d2163dace0
Reference in New Issue
Block a user