Skip to content

Commit

Permalink
feat: update deps and add support for gc
Browse files Browse the repository at this point in the history
  • Loading branch information
d3lm committed Jan 26, 2024
1 parent 656d25f commit 25eeb97
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 46 deletions.
20 changes: 10 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"] }
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
78 changes: 50 additions & 28 deletions src/serialize.rs
Original file line number Diff line number Diff line change
@@ -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<FuncType>,
types: Vec<CompositeType>,
functions: Vec<FuncType>,
globals: Vec<GlobalType>,
memories: Vec<MemoryType>,
Expand All @@ -19,6 +29,17 @@ struct FuncType {
results: Vec<String>,
}

#[derive(Serialize)]
struct StructType {
fields: Vec<FieldType>,
}

#[derive(Serialize)]
struct FieldType {
element_type: String,
mutable: bool,
}

#[derive(Serialize)]
struct GlobalType {
content_type: String,
Expand All @@ -40,21 +61,6 @@ pub struct TableType {
maximum: Option<u32>,
}

struct ValueType<'a>(pub(crate) &'a ValType);

impl<'a> Into<String> 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<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
Expand All @@ -77,7 +83,7 @@ impl Serialize for Types {

fn serialize_elements(types: &ExternalTypes) -> Vec<String> {
(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::<Vec<String>>()
}

Expand All @@ -89,7 +95,7 @@ fn serialize_tables(types: &ExternalTypes) -> Vec<TableType> {
TableType {
initial: table.initial,
maximum: table.maximum,
element_type: ValueType(&ValType::Ref(table.element_type)).into(),
element_type: table.element_type.to_string(),
}
})
.collect::<Vec<TableType>>()
Expand All @@ -116,7 +122,7 @@ fn serialize_globals(types: &ExternalTypes) -> Vec<GlobalType> {
let global = types.global_at(index);

GlobalType {
content_type: ValueType(&global.content_type).into(),
content_type: global.content_type.to_string(),
mutable: global.mutable,
}
})
Expand All @@ -137,27 +143,43 @@ fn serialize_functions(types: &ExternalTypes) -> Vec<FuncType> {
.collect::<Vec<FuncType>>()
}

fn serialize_types(types: &ExternalTypes) -> Vec<FuncType> {
fn serialize_types(types: &ExternalTypes) -> Vec<CompositeType> {
(0..types.type_count() as u32)
.map(|index| {
let type_id = match types.core_type_at(index) {
ComponentCoreTypeId::Sub(sub_type) => sub_type,
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::<Vec<FuncType>>()
.collect::<Vec<CompositeType>>()
}

fn serialize_val_types(val_types: &[ValType]) -> Vec<String> {
val_types
.iter()
.map(|val_type| ValueType(val_type).into())
.map(|val_type| val_type.to_string())
.collect::<Vec<String>>()
}
33 changes: 31 additions & 2 deletions src/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<CompositeType>;
functions: Array<{ params: ValueType[]; results: ValueType[] }>;
globals: Array<{ content_type: string; mutable: boolean }>;
memories: Array<{ memory64: boolean; shared: boolean; initial: number; maximum?: number }>;
Expand Down
2 changes: 1 addition & 1 deletion test/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"start": "vite",
"build": "tsc && vite build",
"preview": "vite preview"
},
Expand Down
6 changes: 5 additions & 1 deletion test/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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));

0 comments on commit 25eeb97

Please sign in to comment.