Skip to content

Commit

Permalink
Merge pull request #41 from dhil/wasmfx-merge
Browse files Browse the repository at this point in the history
Merge with upstream
  • Loading branch information
dhil authored Dec 14, 2023
2 parents 7102709 + 544b1f0 commit ac769cf
Show file tree
Hide file tree
Showing 216 changed files with 4,004 additions and 941 deletions.
2 changes: 1 addition & 1 deletion crates/wasm-compose/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ description = "A library for composing WebAssembly components."

[dependencies]
wat = { workspace = true }
wasm-encoder = { workspace = true }
wasm-encoder = { workspace = true, features = ['wasmparser'] }
wasmparser = { workspace = true }
indexmap = { workspace = true, features = ["serde"] }
anyhow = { workspace = true }
Expand Down
83 changes: 6 additions & 77 deletions crates/wasm-compose/src/encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,9 +362,9 @@ impl<'a> TypeEncoder<'a> {
};
EntityType::Function(idx)
}
wasmparser::types::EntityType::Table(ty) => EntityType::Table(Self::table_type(ty)),
wasmparser::types::EntityType::Memory(ty) => EntityType::Memory(Self::memory_type(ty)),
wasmparser::types::EntityType::Global(ty) => EntityType::Global(Self::global_type(ty)),
wasmparser::types::EntityType::Table(ty) => EntityType::Table(ty.try_into().unwrap()),
wasmparser::types::EntityType::Memory(ty) => EntityType::Memory(ty.try_into().unwrap()),
wasmparser::types::EntityType::Global(ty) => EntityType::Global(ty.try_into().unwrap()),
wasmparser::types::EntityType::Tag(id) => {
let ty = &self.0.types[id];
let idx = match types.entry(ComponentCoreTypeId::Sub(id).into()) {
Expand Down Expand Up @@ -427,78 +427,7 @@ impl<'a> TypeEncoder<'a> {
}

fn val_type(ty: wasmparser::ValType) -> ValType {
match ty {
wasmparser::ValType::I32 => ValType::I32,
wasmparser::ValType::I64 => ValType::I64,
wasmparser::ValType::F32 => ValType::F32,
wasmparser::ValType::F64 => ValType::F64,
wasmparser::ValType::V128 => ValType::V128,
wasmparser::ValType::Ref(ty) => ValType::Ref(Self::ref_type(ty)),
}
}

fn ref_type(ty: wasmparser::RefType) -> RefType {
RefType {
nullable: ty.is_nullable(),
heap_type: match ty.heap_type() {
wasmparser::HeapType::Func => HeapType::Func,
wasmparser::HeapType::Extern => HeapType::Extern,
wasmparser::HeapType::Any => HeapType::Any,
wasmparser::HeapType::None => HeapType::None,
wasmparser::HeapType::NoExtern => HeapType::NoExtern,
wasmparser::HeapType::NoFunc => HeapType::NoFunc,
wasmparser::HeapType::Eq => HeapType::Eq,
wasmparser::HeapType::Struct => HeapType::Struct,
wasmparser::HeapType::Array => HeapType::Array,
wasmparser::HeapType::I31 => HeapType::I31,
wasmparser::HeapType::Cont | wasmparser::HeapType::NoCont => todo!(), // TODO(dhil): Some day.
wasmparser::HeapType::Concrete(i) => {
HeapType::Concrete(i.as_module_index().unwrap())
}
},
}
}

fn table_type(ty: wasmparser::TableType) -> TableType {
TableType {
element_type: Self::ref_type(ty.element_type),
minimum: ty.initial,
maximum: ty.maximum,
}
}

fn memory_type(ty: wasmparser::MemoryType) -> MemoryType {
MemoryType {
minimum: ty.initial,
maximum: ty.maximum,
memory64: ty.memory64,
shared: ty.shared,
}
}

fn global_type(ty: wasmparser::GlobalType) -> GlobalType {
GlobalType {
val_type: Self::val_type(ty.content_type),
mutable: ty.mutable,
}
}

fn primitive(ty: wasmparser::PrimitiveValType) -> PrimitiveValType {
match ty {
wasmparser::PrimitiveValType::Bool => PrimitiveValType::Bool,
wasmparser::PrimitiveValType::S8 => PrimitiveValType::S8,
wasmparser::PrimitiveValType::U8 => PrimitiveValType::U8,
wasmparser::PrimitiveValType::S16 => PrimitiveValType::S16,
wasmparser::PrimitiveValType::U16 => PrimitiveValType::U16,
wasmparser::PrimitiveValType::S32 => PrimitiveValType::S32,
wasmparser::PrimitiveValType::U32 => PrimitiveValType::U32,
wasmparser::PrimitiveValType::S64 => PrimitiveValType::S64,
wasmparser::PrimitiveValType::U64 => PrimitiveValType::U64,
wasmparser::PrimitiveValType::Float32 => PrimitiveValType::Float32,
wasmparser::PrimitiveValType::Float64 => PrimitiveValType::Float64,
wasmparser::PrimitiveValType::Char => PrimitiveValType::Char,
wasmparser::PrimitiveValType::String => PrimitiveValType::String,
}
ty.try_into().unwrap()
}

fn module_type(&self, state: &mut TypeState<'a>, id: ComponentCoreModuleTypeId) -> u32 {
Expand Down Expand Up @@ -701,7 +630,7 @@ impl<'a> TypeEncoder<'a> {
) -> ComponentValType {
match ty {
wasmparser::types::ComponentValType::Primitive(ty) => {
ComponentValType::Primitive(Self::primitive(ty))
ComponentValType::Primitive(ty.into())
}
wasmparser::types::ComponentValType::Type(id) => {
ComponentValType::Type(self.ty(state, ComponentAnyTypeId::from(id).into()))
Expand All @@ -720,7 +649,7 @@ impl<'a> TypeEncoder<'a> {
.encodable
.ty()
.defined_type()
.primitive(Self::primitive(*ty));
.primitive((*ty).into());
index
}
wasmparser::types::ComponentDefinedType::Record(r) => self.record(state, r),
Expand Down
21 changes: 21 additions & 0 deletions crates/wasm-encoder/src/component/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,27 @@ impl Encode for PrimitiveValType {
}
}

#[cfg(feature = "wasmparser")]
impl From<wasmparser::PrimitiveValType> for PrimitiveValType {
fn from(ty: wasmparser::PrimitiveValType) -> Self {
match ty {
wasmparser::PrimitiveValType::Bool => PrimitiveValType::Bool,
wasmparser::PrimitiveValType::S8 => PrimitiveValType::S8,
wasmparser::PrimitiveValType::U8 => PrimitiveValType::U8,
wasmparser::PrimitiveValType::S16 => PrimitiveValType::S16,
wasmparser::PrimitiveValType::U16 => PrimitiveValType::U16,
wasmparser::PrimitiveValType::S32 => PrimitiveValType::S32,
wasmparser::PrimitiveValType::U32 => PrimitiveValType::U32,
wasmparser::PrimitiveValType::S64 => PrimitiveValType::S64,
wasmparser::PrimitiveValType::U64 => PrimitiveValType::U64,
wasmparser::PrimitiveValType::Float32 => PrimitiveValType::Float32,
wasmparser::PrimitiveValType::Float64 => PrimitiveValType::Float64,
wasmparser::PrimitiveValType::Char => PrimitiveValType::Char,
wasmparser::PrimitiveValType::String => PrimitiveValType::String,
}
}
}

/// Represents a component value type.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ComponentValType {
Expand Down
28 changes: 9 additions & 19 deletions crates/wasm-encoder/src/core/code.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{encode_section, Encode, HeapType, RefType, Section, SectionId, ValType};
use crate::{encode_section, Encode, HeapType, Section, SectionId, ValType};
use std::borrow::Cow;

/// An encoder for the code section.
Expand Down Expand Up @@ -558,8 +558,10 @@ pub enum Instruction<'a> {
ArrayInitData(u32, u32),
ArrayInitElem(u32, u32),

RefTest(RefType),
RefCast(RefType),
RefTestNonNull(HeapType),
RefTestNullable(HeapType),
RefCastNonNull(HeapType),
RefCastNullable(HeapType),
AnyConvertExtern,
ExternConvertAny,

Expand Down Expand Up @@ -1519,34 +1521,22 @@ impl Encode for Instruction<'_> {
type_index.encode(sink);
elem_index.encode(sink);
}
Instruction::RefTest(RefType {
nullable: false,
heap_type,
}) => {
Instruction::RefTestNonNull(heap_type) => {
sink.push(0xfb);
sink.push(0x14);
heap_type.encode(sink);
}
Instruction::RefTest(RefType {
nullable: true,
heap_type,
}) => {
Instruction::RefTestNullable(heap_type) => {
sink.push(0xfb);
sink.push(0x15);
heap_type.encode(sink);
}
Instruction::RefCast(RefType {
nullable: false,
heap_type,
}) => {
Instruction::RefCastNonNull(heap_type) => {
sink.push(0xfb);
sink.push(0x16);
heap_type.encode(sink);
}
Instruction::RefCast(RefType {
nullable: true,
heap_type,
}) => {
Instruction::RefCastNullable(heap_type) => {
sink.push(0xfb);
sink.push(0x17);
heap_type.encode(sink);
Expand Down
3 changes: 3 additions & 0 deletions crates/wasm-encoder/src/core/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ impl TryFrom<wasmparser::CompositeType> for CompositeType {
wasmparser::CompositeType::Func(f) => CompositeType::Func(f.try_into()?),
wasmparser::CompositeType::Array(a) => CompositeType::Array(a.try_into()?),
wasmparser::CompositeType::Struct(s) => CompositeType::Struct(s.try_into()?),
wasmparser::CompositeType::Cont(_c) => todo!(), // TODO(dhil): This shouldn't be too hard to add.
})
}
}
Expand Down Expand Up @@ -434,6 +435,8 @@ impl TryFrom<wasmparser::HeapType> for HeapType {
wasmparser::HeapType::Struct => HeapType::Struct,
wasmparser::HeapType::Array => HeapType::Array,
wasmparser::HeapType::I31 => HeapType::I31,
wasmparser::HeapType::Cont => todo!(),
wasmparser::HeapType::NoCont => todo!(), // TODO(dhil): Shouldn't be too hard.
})
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/wasm-shrink/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ fn shrink_to_empty_is_error() -> Result<()> {
let result = WasmShrink::default().run(wasm(), |_| Ok(true));
assert!(result.is_err());
let err_msg = result.err().unwrap().to_string();
assert!(dbg!(err_msg).contains("empty Wasm module"));
assert!(err_msg.contains("empty Wasm module"));
Ok(())
}

Expand Down
2 changes: 1 addition & 1 deletion crates/wasm-smith/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ indexmap = { workspace = true }
leb128 = { workspace = true }
serde = { workspace = true, optional = true }
serde_derive = { workspace = true, optional = true }
wasm-encoder = { workspace = true }
wasm-encoder = { workspace = true, features = ['wasmparser'] }
wasmparser = { workspace = true, optional = true }

[dev-dependencies]
Expand Down
2 changes: 1 addition & 1 deletion crates/wasm-smith/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,7 @@ impl<'a> Arbitrary<'a> for SwarmConfig {
max_tables,
max_memory_pages: u.arbitrary()?,
min_uleb_size: u.int_in_range(0..=5)?,
bulk_memory_enabled: reference_types_enabled || u.arbitrary()?,
bulk_memory_enabled: u.arbitrary()?,
reference_types_enabled,
simd_enabled: u.arbitrary()?,
multi_value_enabled: u.arbitrary()?,
Expand Down
71 changes: 13 additions & 58 deletions crates/wasm-smith/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -619,12 +619,12 @@ impl Module {
params: func_type
.params()
.iter()
.map(|t| convert_type(*t))
.map(|t| (*t).try_into().unwrap())
.collect(),
results: func_type
.results()
.iter()
.map(|t| convert_type(*t))
.map(|t| (*t).try_into().unwrap())
.collect(),
});
index_store.replace(new_index as u32);
Expand Down Expand Up @@ -676,11 +676,7 @@ impl Module {
}

wasmparser::TypeRef::Table(table_ty) => {
let table_ty = TableType {
element_type: convert_reftype(table_ty.element_type),
minimum: table_ty.initial,
maximum: table_ty.maximum,
};
let table_ty = TableType::try_from(*table_ty).unwrap();
let entity = EntityType::Table(table_ty);
let type_size = entity.size();
if type_size_budget < type_size || !self.can_add_local_or_import_table() {
Expand All @@ -692,12 +688,7 @@ impl Module {
}

wasmparser::TypeRef::Memory(memory_ty) => {
let memory_ty = MemoryType {
minimum: memory_ty.initial,
maximum: memory_ty.maximum,
memory64: memory_ty.memory64,
shared: memory_ty.shared,
};
let memory_ty = MemoryType::try_from(*memory_ty).unwrap();
let entity = EntityType::Memory(memory_ty);
let type_size = entity.size();
if type_size_budget < type_size || !self.can_add_local_or_import_memory() {
Expand All @@ -709,10 +700,7 @@ impl Module {
}

wasmparser::TypeRef::Global(global_ty) => {
let global_ty = GlobalType {
val_type: convert_type(global_ty.content_type),
mutable: global_ty.mutable,
};
let global_ty = (*global_ty).try_into().unwrap();
let entity = EntityType::Global(global_ty);
let type_size = entity.size();
if type_size_budget < type_size || !self.can_add_local_or_import_global() {
Expand All @@ -735,42 +723,7 @@ impl Module {
self.types.extend(new_types);
self.imports.extend(new_imports);

return Ok(());

/// Convert a wasmparser's `ValType` to a `wasm_encoder::ValType`.
fn convert_type(parsed_type: wasmparser::ValType) -> ValType {
use wasmparser::ValType::*;
match parsed_type {
I32 => ValType::I32,
I64 => ValType::I64,
F32 => ValType::F32,
F64 => ValType::F64,
V128 => ValType::V128,
Ref(ty) => ValType::Ref(convert_reftype(ty)),
}
}

fn convert_reftype(ty: wasmparser::RefType) -> RefType {
wasm_encoder::RefType {
nullable: ty.is_nullable(),
heap_type: match ty.heap_type() {
wasmparser::HeapType::Func => HeapType::Func,
wasmparser::HeapType::Extern => HeapType::Extern,
wasmparser::HeapType::Any => HeapType::Any,
wasmparser::HeapType::None => HeapType::None,
wasmparser::HeapType::NoExtern => HeapType::NoExtern,
wasmparser::HeapType::NoFunc => HeapType::NoFunc,
wasmparser::HeapType::Eq => HeapType::Eq,
wasmparser::HeapType::Struct => HeapType::Struct,
wasmparser::HeapType::Array => HeapType::Array,
wasmparser::HeapType::I31 => HeapType::I31,
wasmparser::HeapType::Concrete(i) => {
HeapType::Concrete(i.as_module_index().unwrap())
}
wasmparser::HeapType::Cont | wasmparser::HeapType::NoCont => todo!(), // TODO(dhil): Some other day.
},
}
}
Ok(())
}

fn type_of(&self, kind: ExportKind, index: u32) -> EntityType {
Expand Down Expand Up @@ -1148,13 +1101,15 @@ impl Module {
}
}

// Reference types allows us to create passive and declared element
// segments.
if self.config.reference_types_enabled() {
// Bulk memory enables passive/declared segments for funcrefs, and
// reference types additionally enables the segments for externrefs.
if self.config.bulk_memory_enabled() {
funcrefs.push(Box::new(|_| Ok((ElementKind::Passive, None))));
externrefs.push(Box::new(|_| Ok((ElementKind::Passive, None))));
funcrefs.push(Box::new(|_| Ok((ElementKind::Declared, None))));
externrefs.push(Box::new(|_| Ok((ElementKind::Declared, None))));
if self.config.reference_types_enabled() {
externrefs.push(Box::new(|_| Ok((ElementKind::Passive, None))));
externrefs.push(Box::new(|_| Ok((ElementKind::Declared, None))));
}
}

let mut choices = Vec::new();
Expand Down
6 changes: 3 additions & 3 deletions crates/wasm-smith/src/core/code_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4814,7 +4814,7 @@ fn table_grow(

#[inline]
fn table_copy_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
module.config.reference_types_enabled()
module.config.bulk_memory_enabled()
&& !module.config.disallow_traps() // Non-trapping table.copy generation not yet implemented
&& module.tables.len() > 0
&& builder.types_on_stack(&[ValType::I32, ValType::I32, ValType::I32])
Expand All @@ -4838,7 +4838,7 @@ fn table_copy(

#[inline]
fn table_init_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
module.config.reference_types_enabled()
module.config.bulk_memory_enabled()
&& !module.config.disallow_traps() // Non-trapping table.init generation not yet implemented.
&& builder.allocs.table_init_possible
&& builder.types_on_stack(&[ValType::I32, ValType::I32, ValType::I32])
Expand Down Expand Up @@ -4869,7 +4869,7 @@ fn table_init(

#[inline]
fn elem_drop_valid(module: &Module, _builder: &mut CodeBuilder) -> bool {
module.config.reference_types_enabled() && module.elems.len() > 0
module.config.bulk_memory_enabled() && module.elems.len() > 0
}

fn elem_drop(
Expand Down
Loading

0 comments on commit ac769cf

Please sign in to comment.