Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
355 changes: 196 additions & 159 deletions Cargo.lock

Large diffs are not rendered by default.

22 changes: 11 additions & 11 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ name = "uap"
harness = false

[dependencies]
anyhow = "1.0.81"
cap-std = "3.0.0"
env_logger = { version = "0.11", optional = true }
log = "0.4.21"
anyhow = "1.0.97"
cap-std = "3.4.3"
env_logger = { version = "0.11.8", optional = true }
log = "0.4.27"
rayon = "1.10.0"
structopt = { version = "0.3.26", optional = true }
wasm-encoder = "0.202.0"
wasmparser = "0.202.0"
wasm-encoder = "0.228.0"
wasmparser = "0.228.0"
wasmtime = { workspace = true }
wasmtime-wasi = { workspace = true, features = ["preview1"] }

Expand All @@ -45,15 +45,15 @@ workspace = true
optional = true

[workspace.dependencies]
wasmprinter = "0.202.0"
wasmtime = "29"
wasmtime-wasi = "29"
wasmprinter = "0.228.0"
wasmtime = "31"
wasmtime-wasi = "31"

[dev-dependencies]
criterion = "0.5.1"
env_logger = "0.11.3"
env_logger = "0.11.8"
wasmprinter = { workspace = true }
wat = "1.202.0"
wat = "1.228.0"

[workspace]
members = [
Expand Down
5 changes: 4 additions & 1 deletion fuzz/fuzz_targets/same_result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,10 @@ fuzz_target!(|data: &[u8]| {
panic!("divergence between snapshot and non-snapshot memories");
}
}
Extern::SharedMemory(_) | Extern::Func(_) | Extern::Table(_) => continue,
Extern::SharedMemory(_)
| Extern::Func(_)
| Extern::Table(_)
| Extern::Tag(_) => continue,
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/dummy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ pub fn dummy_extern(store: &mut crate::Store, ty: ExternType, name: &str) -> Res
ExternType::Memory(_) => {
anyhow::bail!("Error: attempted to import unknown memory: {}", name)
}
ExternType::Tag(_) => {
anyhow::bail!("Error: attempted to import unknown tag: {}", name)
}
})
}

Expand Down
9 changes: 5 additions & 4 deletions src/info/types_interner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,11 @@ impl TypesInterner {
ty: wasmparser::CompositeType,
_types_space: &[TypeId],
) -> TypeId {
match ty {
wasmparser::CompositeType::Func(func_ty) => self.insert(Type::Func(func_ty)),
wasmparser::CompositeType::Array(_) => todo!(),
wasmparser::CompositeType::Struct(_) => todo!(),
match ty.inner {
wasmparser::CompositeInnerType::Func(func_ty) => self.insert(Type::Func(func_ty)),
wasmparser::CompositeInnerType::Array(_) => todo!(),
wasmparser::CompositeInnerType::Struct(_) => todo!(),
wasmparser::CompositeInnerType::Cont(_) => todo!(),
}
}

Expand Down
83 changes: 31 additions & 52 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ mod snapshot;
mod stack_ext;
mod translate;

use wasmparser::WasmFeatures;
/// Re-export wasmtime so users can align with our version. This is
/// especially useful when providing a custom Linker.
pub use wasmtime;
Expand Down Expand Up @@ -665,6 +666,9 @@ impl Wizer {
.unwrap_or(DEFAULT_WASM_REFERENCE_TYPES),
);

config.wasm_tail_call(true);
config.wasm_extended_const(true);

// Proposals that we should add support for.
config.wasm_threads(false);

Expand All @@ -673,59 +677,34 @@ impl Wizer {

// NB: keep this in sync with the Wasmtime config.
fn wasm_features(&self) -> wasmparser::WasmFeatures {
wasmparser::WasmFeatures {
mutable_global: true,
saturating_float_to_int: true,
sign_extension: true,
floats: true,
component_model_values: false,
component_model_nested_names: false,

// Proposals that we support.
multi_memory: self.wasm_multi_memory.unwrap_or(DEFAULT_WASM_MULTI_MEMORY),
multi_value: self.wasm_multi_value.unwrap_or(DEFAULT_WASM_MULTI_VALUE),

// Proposals that we should add support for.
reference_types: self
.wasm_reference_types
let mut features = WasmFeatures::WASM2;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you verify that this matches the feature set we had before?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See https://github.com/bytecodealliance/wasm-tools/blob/v1.228.0/crates/wasmparser/src/features.rs#L278 it is. I've also enabled tail-call and extended-const since they should be safe for wizer, but if you prefer I can add options to make it possible to disable these two

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems fine


features.set(
WasmFeatures::MULTI_MEMORY,
self.wasm_multi_memory.unwrap_or(DEFAULT_WASM_MULTI_MEMORY),
);
features.set(
WasmFeatures::MULTI_VALUE,
self.wasm_multi_value.unwrap_or(DEFAULT_WASM_MULTI_VALUE),
);
features.set(
WasmFeatures::BULK_MEMORY,
self.wasm_bulk_memory.unwrap_or(DEFAULT_WASM_BULK_MEMORY),
);
features.set(
WasmFeatures::SIMD,
self.wasm_simd.unwrap_or(DEFAULT_WASM_SIMD),
);
features.set(
WasmFeatures::REFERENCE_TYPES,
self.wasm_reference_types
.unwrap_or(DEFAULT_WASM_REFERENCE_TYPES),
simd: self.wasm_simd.unwrap_or(DEFAULT_WASM_SIMD),
threads: false,
tail_call: false,
memory64: false,
exceptions: false,
extended_const: false,
relaxed_simd: false,
component_model: false,
memory_control: false,
function_references: false,
gc: false,

// XXX: Though we don't fully support bulk memory yet, we
// unconditionally turn it on.
//
// Many parsers, notably our own `wasmparser`, assume that which
// Wasm features are enabled or disabled cannot affect parsing, only
// validation. That assumption is incorrect when it comes to data
// segments, the multi-memory proposal, and the bulk memory
// proposal. A `0x01` prefix of a data segment can either mean "this
// is a passive segment" if bulk memory is enabled or "this segment
// is referring to memory index 1" if both bulk memory is disabled
// and multi-memory is enabled. `wasmparser` fails to handle this
// edge case, which means that everything built on top of it, like
// Wasmtime, also fail to handle this edge case. However, because
// bulk memory is merged into the spec proper and is no longer
// technically a "proposal", and because a fix would require
// significant refactoring and API changes to give a
// `wasmparser::Parser` a `wasmparser::WasmFeatures`, we won't ever
// resolve this discrepancy in `wasmparser`.
//
// So we enable bulk memory during parsing, validation, and
// execution, but we add our own custom validation pass to ensure
// that no table-mutating instructions exist in our input modules
// until we *actually* support bulk memory.
bulk_memory: true,
}
);

features.set(WasmFeatures::TAIL_CALL, true);
features.set(WasmFeatures::EXTENDED_CONST, true);

return features;
}

fn wasm_validate(&self, wasm: &[u8]) -> anyhow::Result<()> {
Expand Down
13 changes: 7 additions & 6 deletions src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ pub(crate) fn parse<'a>(full_wasm: &'a [u8]) -> anyhow::Result<ModuleContext<'a>
assert!(stack.is_empty());
return Ok(cx);
}

ComponentTypeSection(_)
| ComponentImportSection(_)
| ComponentExportSection(_)
Expand All @@ -116,6 +115,7 @@ pub(crate) fn parse<'a>(full_wasm: &'a [u8]) -> anyhow::Result<ModuleContext<'a>
| ComponentSection { .. } => {
unreachable!()
}
_ => anyhow::bail!("unsupported wasmparser payload"),
}
}
}
Expand All @@ -133,12 +133,13 @@ fn type_section<'a>(
// instance imports.
for group in types {
for ty in group?.into_types() {
match ty.composite_type {
ty @ wasmparser::CompositeType::Func(_) => {
module.push_type(cx, ty);
match ty.composite_type.inner {
wasmparser::CompositeInnerType::Func(_) => {
module.push_type(cx, ty.composite_type);
}
wasmparser::CompositeType::Array(_) => todo!(),
wasmparser::CompositeType::Struct(_) => todo!(),
wasmparser::CompositeInnerType::Array(_) => todo!(),
wasmparser::CompositeInnerType::Struct(_) => todo!(),
wasmparser::CompositeInnerType::Cont(_) => todo!(),
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/rewrite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ impl Wizer {

fn is_name_section(s: &wasm_encoder::RawSection) -> bool {
s.id == u8::from(SectionId::Custom) && {
let mut reader = wasmparser::BinaryReader::new(s.data);
let mut reader = wasmparser::BinaryReader::new(s.data, 0);
matches!(reader.read_string(), Ok("name"))
}
}
2 changes: 2 additions & 0 deletions src/translate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub(crate) fn global_type(ty: wasmparser::GlobalType) -> wasm_encoder::GlobalTyp
wasm_encoder::GlobalType {
val_type: val_type(ty.content_type),
mutable: ty.mutable,
shared: ty.shared,
}
}

Expand All @@ -27,6 +28,7 @@ pub(crate) fn memory_type(ty: wasmparser::MemoryType) -> wasm_encoder::MemoryTyp
maximum: ty.maximum.map(|val| val.into()),
memory64: ty.memory64,
shared: ty.shared,
page_size_log2: None,
}
}

Expand Down
22 changes: 14 additions & 8 deletions tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,10 @@ fn fails_wizening(wat: &str) -> Result<()> {

let wasm = wat_to_wasm(wat)?;

let mut validator = wasmparser::Validator::new_with_features(wasmparser::WasmFeatures {
multi_memory: true,
..Default::default()
});
let mut features = wasmparser::WasmFeatures::WASM2;
features.set(wasmparser::WasmFeatures::MULTI_MEMORY, true);

let mut validator = wasmparser::Validator::new_with_features(features);
validator
.validate_all(&wasm)
.context("initial Wasm should be valid")?;
Expand Down Expand Up @@ -556,6 +556,8 @@ fn rename_functions() -> Result<()> {
(module
(type (;0;) (func))
(type (;1;) (func (result i32)))
(export "func_a" (func 2))
(export "func_b" (func 3))
(func (;0;) (type 0))
(func (;1;) (type 1) (result i32)
i32.const 1
Expand All @@ -566,8 +568,6 @@ fn rename_functions() -> Result<()> {
(func (;3;) (type 1) (result i32)
i32.const 3
)
(export "func_a" (func 2))
(export "func_b" (func 3))
)
"#;

Expand Down Expand Up @@ -707,8 +707,13 @@ fn accept_bulk_memory_copy() -> Result<()> {
fn accept_bulk_memory_data_count() -> Result<()> {
let mut module = wasm_encoder::Module::new();
let mut types = wasm_encoder::TypeSection::new();
types.function(vec![], vec![wasm_encoder::ValType::I32]);
types.function(vec![], vec![]);
types.ty().func_type(&wasm_encoder::FuncType::new(
vec![],
vec![wasm_encoder::ValType::I32],
));
types
.ty()
.func_type(&wasm_encoder::FuncType::new(vec![], vec![]));
module.section(&types);

let mut functions = wasm_encoder::FunctionSection::new();
Expand All @@ -722,6 +727,7 @@ fn accept_bulk_memory_data_count() -> Result<()> {
maximum: Some(1),
memory64: false,
shared: false,
page_size_log2: None,
});
module.section(&memory);

Expand Down
Loading