From 25eeb97e5f723011059fc67a59942dffa5e4621b Mon Sep 17 00:00:00 2001 From: Dominic Elm Date: Fri, 26 Jan 2024 20:47:06 +0100 Subject: [PATCH] feat: update deps and add support for gc --- Cargo.lock | 20 ++++++------ Cargo.toml | 6 ++-- package.json | 2 +- src/serialize.rs | 78 ++++++++++++++++++++++++++++++----------------- src/validate.rs | 33 ++++++++++++++++++-- test/package.json | 2 +- test/src/main.ts | 6 +++- 7 files changed, 101 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 501bfc4..5f4b7d0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -243,18 +243,18 @@ checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" [[package]] name = "wasm-encoder" -version = "0.19.1" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9424cdab516a16d4ea03c8f4a01b14e7b2d04a129dcc2bcdde5bcc5f68f06c41" +checksum = "d162eb64168969ae90e8668ca0593b0e47667e315aa08e717a9c9574d700d826" dependencies = [ "leb128", ] [[package]] name = "wasmparser" -version = "0.119.0" +version = "0.120.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c35daf77afb4f9b14016625144a391085ec2ca99ca9cc53ed291bb53ab5278d" +checksum = "e9148127f39cbffe43efee8d5442b16ecdba21567785268daa1ec9e134389705" dependencies = [ "bitflags", "indexmap", @@ -263,9 +263,9 @@ dependencies = [ [[package]] name = "wasmprinter" -version = "0.2.76" +version = "0.2.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cac2a7745372074e5573e365e17100f5a26058740576313784ef03fb900ea8d2" +checksum = "d8389a95eb0b3165fea0537a6988960cc23a33d9be650e63fc3d63065fe20dcb" dependencies = [ "anyhow", "wasmparser", @@ -273,9 +273,9 @@ dependencies = [ [[package]] name = "wast" -version = "49.0.0" +version = "70.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ef81fcd60d244cafffeafac3d17615fdb2fddda6aca18f34a8ae233353587c" +checksum = "f5d415036fe747a32b30c76c8bd6c73f69b7705fb7ebca5f16e852eef0c95802" dependencies = [ "leb128", "memchr", @@ -285,9 +285,9 @@ dependencies = [ [[package]] name = "wat" -version = "1.0.51" +version = "1.0.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c347c4460ffb311e95aafccd8c29e4888f241b9e4b3bb0e0ccbd998de2c8c0d" +checksum = "8241f34599d413d2243a21015ab43aef68bfb32a0e447c54eef8d423525ca15e" dependencies = [ "wast", ] diff --git a/Cargo.toml b/Cargo.toml index faffdd2..0f6a6c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,9 +12,9 @@ default = [] crate-type = ["cdylib"] [dependencies] -wat = "1.0.51" -wasmprinter = "0.2.76" -wasmparser = "0.119.0" +wat = "1.0.84" +wasmprinter = "0.2.77" +wasmparser = "0.120.0" wasm-bindgen = "0.2.89" js-sys = "0.3.66" serde = { version = "1.0.195", features = ["derive"] } diff --git a/package.json b/package.json index d91118e..2d2af10 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "js-wasm-tools", - "version": "1.2.0", + "version": "1.3.0", "author": "Dominic Elm", "description": "JavaScript version of wasm-tools, low level tooling for WebAssembly in Rust", "type": "module", diff --git a/src/serialize.rs b/src/serialize.rs index 6935cf8..c1bb3dd 100644 --- a/src/serialize.rs +++ b/src/serialize.rs @@ -1,11 +1,21 @@ use serde::{Serialize, Serializer}; -use wasmparser::{types::ComponentCoreTypeId, types::Types as ExternalTypes, ValType}; +use wasmparser::{ + types::ComponentCoreTypeId, types::Types as ExternalTypes, CompositeType as ExternalCompositeType, ValType, +}; pub struct Types(pub(crate) ExternalTypes); +#[derive(Serialize)] +#[serde(tag = "type")] +enum CompositeType { + Func(FuncType), + Struct(StructType), + Array(FieldType), +} + #[derive(Serialize)] struct SerializedTypes { - types: Vec, + types: Vec, functions: Vec, globals: Vec, memories: Vec, @@ -19,6 +29,17 @@ struct FuncType { results: Vec, } +#[derive(Serialize)] +struct StructType { + fields: Vec, +} + +#[derive(Serialize)] +struct FieldType { + element_type: String, + mutable: bool, +} + #[derive(Serialize)] struct GlobalType { content_type: String, @@ -40,21 +61,6 @@ pub struct TableType { maximum: Option, } -struct ValueType<'a>(pub(crate) &'a ValType); - -impl<'a> Into for ValueType<'a> { - fn into(self) -> String { - match self.0 { - ValType::I32 => String::from("i32"), - ValType::I64 => String::from("i64"), - ValType::F32 => String::from("f32"), - ValType::F64 => String::from("f64"), - ValType::V128 => String::from("v128"), - ValType::Ref(ref_type) => ref_type.to_string(), - } - } -} - impl Serialize for Types { fn serialize(&self, serializer: S) -> Result where @@ -77,7 +83,7 @@ impl Serialize for Types { fn serialize_elements(types: &ExternalTypes) -> Vec { (0..types.element_count() as u32) - .map(|index| ValueType(&ValType::Ref(types.element_at(index))).into()) + .map(|index| types.element_at(index).to_string()) .collect::>() } @@ -89,7 +95,7 @@ fn serialize_tables(types: &ExternalTypes) -> Vec { TableType { initial: table.initial, maximum: table.maximum, - element_type: ValueType(&ValType::Ref(table.element_type)).into(), + element_type: table.element_type.to_string(), } }) .collect::>() @@ -116,7 +122,7 @@ fn serialize_globals(types: &ExternalTypes) -> Vec { let global = types.global_at(index); GlobalType { - content_type: ValueType(&global.content_type).into(), + content_type: global.content_type.to_string(), mutable: global.mutable, } }) @@ -137,7 +143,7 @@ fn serialize_functions(types: &ExternalTypes) -> Vec { .collect::>() } -fn serialize_types(types: &ExternalTypes) -> Vec { +fn serialize_types(types: &ExternalTypes) -> Vec { (0..types.type_count() as u32) .map(|index| { let type_id = match types.core_type_at(index) { @@ -145,19 +151,35 @@ fn serialize_types(types: &ExternalTypes) -> Vec { ComponentCoreTypeId::Module(_) => panic!("type is expected to be a sub type"), }; - let function = types[type_id].unwrap_func(); - - FuncType { - params: serialize_val_types(function.params()), - results: serialize_val_types(function.results()), + match &types[type_id].composite_type { + ExternalCompositeType::Array(array_type) => CompositeType::Array(FieldType { + element_type: array_type.0.element_type.to_string(), + mutable: array_type.0.mutable, + }), + ExternalCompositeType::Struct(struct_type) => CompositeType::Struct(StructType { + fields: struct_type + .fields + .iter() + .map({ + |field_type| FieldType { + element_type: field_type.element_type.to_string(), + mutable: field_type.mutable, + } + }) + .collect(), + }), + ExternalCompositeType::Func(func_type) => CompositeType::Func(FuncType { + params: serialize_val_types(func_type.params()), + results: serialize_val_types(func_type.results()), + }), } }) - .collect::>() + .collect::>() } fn serialize_val_types(val_types: &[ValType]) -> Vec { val_types .iter() - .map(|val_type| ValueType(val_type).into()) + .map(|val_type| val_type.to_string()) .collect::>() } diff --git a/src/validate.rs b/src/validate.rs index 92e8640..0e307f1 100644 --- a/src/validate.rs +++ b/src/validate.rs @@ -25,12 +25,41 @@ interface Features { memory64?: boolean; extended_const?: boolean; component_model?: boolean; + component_model_values?: boolean; + component_model_nested_names?: boolean; + floats?: boolean; + function_references?: boolean; + memory_control?: boolean; + gc?: boolean; } -type ValueType = 'i32' | 'i64' | 'f32' | 'f64' | 'v128' | 'funcref' | 'externref'; +type StorageType = 'i8' | 'i16' | ValueType; +type ValueType = 'i32' | 'i64' | 'f32' | 'f64' | 'v128' | 'funcref' | 'externref' | '(ref func)'; + +interface FieldType { + element_type: StorageType; + mutable: boolean; +} + +interface FuncType { + type: 'Func'; + params: ValueType[]; + results: ValueType[]; +} + +interface StructType { + type: 'Struct'; + fields: FieldType[]; +} + +type ArrayType = { + type: 'Array'; +} & FieldType; + +type CompositeType = FuncType | StructType | ArrayType; interface Types { - types: Array<{ params: ValueType[]; results: ValueType[] }>; + types: Array; functions: Array<{ params: ValueType[]; results: ValueType[] }>; globals: Array<{ content_type: string; mutable: boolean }>; memories: Array<{ memory64: boolean; shared: boolean; initial: number; maximum?: number }>; diff --git a/test/package.json b/test/package.json index 23e45e6..9535190 100644 --- a/test/package.json +++ b/test/package.json @@ -4,7 +4,7 @@ "version": "0.0.0", "type": "module", "scripts": { - "dev": "vite", + "start": "vite", "build": "tsc && vite build", "preview": "vite preview" }, diff --git a/test/src/main.ts b/test/src/main.ts index da54bf3..b15ce18 100644 --- a/test/src/main.ts +++ b/test/src/main.ts @@ -6,6 +6,7 @@ await initWasmTools(WASM_TOOLS_WASM_URL); const source = ` (module (type (func (param i32 i32))) + (type $vec (array i32)) (memory 1 100 shared) (table 1 1 funcref) (elem (i32.const 0) func $foo) @@ -16,11 +17,14 @@ const source = ` end drop ) + (func $simd (export "simd") (result (ref $vec)) + (array.new_default $vec (i32.const 3)) + ) ) `; const bytes = wasmTools.parseWat(source); -console.log(wasmTools.validate(bytes)); +console.log(wasmTools.validate(bytes, { gc: true, reference_types: true, threads: true })); console.log(wasmTools.printBytes(bytes));