diff --git a/codegen/luajit/Cargo.toml b/codegen/luajit/Cargo.toml index 1b00814..22c2b62 100644 --- a/codegen/luajit/Cargo.toml +++ b/codegen/luajit/Cargo.toml @@ -4,7 +4,7 @@ version = "0.12.0" edition = "2021" [dependencies] -wasmparser = "0.86.0" +wasmparser = "0.99.0" [dependencies.wasm-ast] path = "../../wasm-ast" diff --git a/codegen/luajit/src/translator.rs b/codegen/luajit/src/translator.rs index 0e68f99..55e8ad7 100644 --- a/codegen/luajit/src/translator.rs +++ b/codegen/luajit/src/translator.rs @@ -9,7 +9,7 @@ use wasm_ast::{ node::{FuncData, Statement}, }; use wasmparser::{ - Data, DataKind, Element, ElementItem, ElementKind, Export, Import, InitExpr, Operator, + ConstExpr, Data, DataKind, Element, ElementItems, ElementKind, Export, Import, Operator, OperatorsReader, }; @@ -49,7 +49,7 @@ fn write_named_array(name: &str, len: usize, w: &mut dyn Write) -> Result<()> { writeln!(w, "local {name} = table_new({len}, 1)") } -fn write_constant(init: &InitExpr, type_info: &TypeInfo, w: &mut dyn Write) -> Result<()> { +fn write_constant(init: &ConstExpr, type_info: &TypeInfo, w: &mut dyn Write) -> Result<()> { let code = reader_to_code(init.get_operators_reader()); let func = Factory::from_type_info(type_info).create_anonymous(&code); @@ -157,8 +157,8 @@ fn write_element_list(list: &[Element], type_info: &TypeInfo, w: &mut dyn Write) let (index, init) = match element.kind { ElementKind::Active { table_index, - init_expr, - } => (table_index, init_expr), + offset_expr, + } => (table_index, offset_expr), _ => unimplemented!(), }; @@ -171,13 +171,20 @@ fn write_element_list(list: &[Element], type_info: &TypeInfo, w: &mut dyn Write) writeln!(w)?; write!(w, "\t\tlocal data = {{ ")?; - for item in element.items.get_items_reader().unwrap() { - match item.unwrap() { - ElementItem::Func(index) => write!(w, "FUNC_LIST[{index}],"), - ElementItem::Expr(init) => write_constant(&init, type_info, w), - }?; + match element.items.clone() { + ElementItems::Functions(functions) => { + for index in functions { + let index = index.unwrap(); + write!(w, "FUNC_LIST[{index}],")?; + } + } + ElementItems::Expressions(expressions) => { + for init in expressions { + let init = init.unwrap(); + write_constant(&init, type_info, w)?; + } + } } - writeln!(w, " }}")?; writeln!(w, "\t\ttable.move(data, 1, #data, offset, target)")?; writeln!(w, "\tend")?; @@ -192,8 +199,8 @@ fn write_data_list(list: &[Data], type_info: &TypeInfo, w: &mut dyn Write) -> Re DataKind::Passive => unimplemented!(), DataKind::Active { memory_index, - init_expr, - } => (memory_index, init_expr), + offset_expr, + } => (memory_index, offset_expr), }; write!(w, "\trt.store.string(MEMORY_LIST[{index}], ")?; diff --git a/codegen/luau/Cargo.toml b/codegen/luau/Cargo.toml index a3e398e..a6679bf 100644 --- a/codegen/luau/Cargo.toml +++ b/codegen/luau/Cargo.toml @@ -4,7 +4,7 @@ version = "0.12.0" edition = "2021" [dependencies] -wasmparser = "0.86.0" +wasmparser = "0.99.0" [dependencies.wasm-ast] path = "../../wasm-ast" diff --git a/codegen/luau/src/translator.rs b/codegen/luau/src/translator.rs index fe2730b..458d3d7 100644 --- a/codegen/luau/src/translator.rs +++ b/codegen/luau/src/translator.rs @@ -9,7 +9,7 @@ use wasm_ast::{ node::{FuncData, Statement}, }; use wasmparser::{ - Data, DataKind, Element, ElementItem, ElementKind, Export, Import, InitExpr, Operator, + ConstExpr, Data, DataKind, Element, ElementItems, ElementKind, Export, Import, Operator, OperatorsReader, ValType, }; @@ -49,7 +49,7 @@ fn write_named_array(name: &str, len: usize, w: &mut dyn Write) -> Result<()> { writeln!(w, "local {name} = table.create({len})") } -fn write_constant(init: &InitExpr, type_info: &TypeInfo, w: &mut dyn Write) -> Result<()> { +fn write_constant(init: &ConstExpr, type_info: &TypeInfo, w: &mut dyn Write) -> Result<()> { let code = reader_to_code(init.get_operators_reader()); let func = Factory::from_type_info(type_info).create_anonymous(&code); @@ -157,8 +157,8 @@ fn write_element_list(list: &[Element], type_info: &TypeInfo, w: &mut dyn Write) let (index, init) = match element.kind { ElementKind::Active { table_index, - init_expr, - } => (table_index, init_expr), + offset_expr, + } => (table_index, offset_expr), _ => unimplemented!(), }; @@ -171,11 +171,19 @@ fn write_element_list(list: &[Element], type_info: &TypeInfo, w: &mut dyn Write) writeln!(w)?; write!(w, "\t\tlocal data = {{ ")?; - for item in element.items.get_items_reader().unwrap() { - match item.unwrap() { - ElementItem::Func(index) => write!(w, "FUNC_LIST[{index}],"), - ElementItem::Expr(init) => write_constant(&init, type_info, w), - }?; + match element.items.clone() { + ElementItems::Functions(functions) => { + for index in functions { + let index = index.unwrap(); + write!(w, "FUNC_LIST[{index}],")?; + } + } + ElementItems::Expressions(expressions) => { + for init in expressions { + let init = init.unwrap(); + write_constant(&init, type_info, w)?; + } + } } writeln!(w, " }}")?; @@ -192,8 +200,8 @@ fn write_data_list(list: &[Data], type_info: &TypeInfo, w: &mut dyn Write) -> Re DataKind::Passive => unimplemented!(), DataKind::Active { memory_index, - init_expr, - } => (memory_index, init_expr), + offset_expr, + } => (memory_index, offset_expr), }; write!(w, "\trt.store.string(MEMORY_LIST[{index}], ")?; diff --git a/dev-test/Cargo.toml b/dev-test/Cargo.toml index 1dd2633..d5aa747 100644 --- a/dev-test/Cargo.toml +++ b/dev-test/Cargo.toml @@ -9,14 +9,14 @@ cargo-fuzz = true [dependencies] libfuzzer-sys = "0.4.0" -wasm-smith = "0.11.0" +wasm-smith = "0.12.0" wasm-ast = { path = "../wasm-ast" } codegen-luajit = { path = "../codegen/luajit" } codegen-luau = { path = "../codegen/luau" } [dev-dependencies] test-generator = "0.3.0" -wast = "42.0.0" +wast = "52.0.2" [[bin]] name = "luajit_translate" diff --git a/dev-test/tests/luajit_translate.rs b/dev-test/tests/luajit_translate.rs index c2d0b83..56164b7 100644 --- a/dev-test/tests/luajit_translate.rs +++ b/dev-test/tests/luajit_translate.rs @@ -5,8 +5,8 @@ use std::{ use wasm_ast::module::{Module, TypeInfo}; use wast::{ - core::{Expression, Instruction}, - AssertExpression, WastExecute, WastInvoke, Wat, + core::{WastArgCore, WastRetCore}, + WastArg, WastExecute, WastInvoke, WastRet, Wat, }; use target::{get_name_from_id, Target}; @@ -18,26 +18,22 @@ static ASSERTION: &str = include_str!("luajit_assert.lua"); struct LuaJIT; impl LuaJIT { - fn write_expression(data: &Expression, w: &mut dyn Write) -> Result<()> { - let data = &data.instrs; - - assert_eq!(data.len(), 1, "Only one instruction supported"); - - match &data[0] { - Instruction::I32Const(v) => write!(w, "{v}"), - Instruction::I64Const(v) => write!(w, "{v}LL"), - Instruction::F32Const(v) => target::write_f32(f32::from_bits(v.bits), w), - Instruction::F64Const(v) => target::write_f64(f64::from_bits(v.bits), w), - _ => panic!("Unsupported instruction"), + fn write_arg(data: &WastArg, w: &mut dyn Write) -> Result<()> { + match data { + WastArg::Core(WastArgCore::I32(v)) => write!(w, "{v}"), + WastArg::Core(WastArgCore::I64(v)) => write!(w, "{v}LL"), + WastArg::Core(WastArgCore::F32(v)) => target::write_f32(f32::from_bits(v.bits), w), + WastArg::Core(WastArgCore::F64(v)) => target::write_f64(f64::from_bits(v.bits), w), + _ => panic!("Unsupported expression"), } } - fn write_simple_expression(data: &AssertExpression, w: &mut dyn Write) -> Result<()> { + fn write_ret(data: &WastRet, w: &mut dyn Write) -> Result<()> { match data { - AssertExpression::I32(v) => write!(w, "{v}"), - AssertExpression::I64(v) => write!(w, "{v}LL"), - AssertExpression::F32(v) => target::write_f32_nan(v, w), - AssertExpression::F64(v) => target::write_f64_nan(v, w), + WastRet::Core(WastRetCore::I32(v)) => write!(w, "{v}"), + WastRet::Core(WastRetCore::I64(v)) => write!(w, "{v}LL"), + WastRet::Core(WastRetCore::F32(v)) => target::write_f32_nan(v, w), + WastRet::Core(WastRetCore::F64(v)) => target::write_f64_nan(v, w), _ => panic!("Unsupported expression"), } } @@ -51,7 +47,7 @@ impl LuaJIT { data.args.iter().try_for_each(|v| { write!(w, ", ")?; - Self::write_expression(v, w) + Self::write_arg(v, w) })?; write!(w, ")") @@ -101,7 +97,7 @@ impl Target for LuaJIT { fn write_assert_return( data: &mut WastExecute, - result: &[AssertExpression], + result: &[WastRet], w: &mut dyn Write, ) -> Result<()> { match data { @@ -112,7 +108,7 @@ impl Target for LuaJIT { write!(w, "}}, {{")?; for v in result { - Self::write_simple_expression(v, w)?; + Self::write_ret(v, w)?; write!(w, ", ")?; } @@ -124,7 +120,7 @@ impl Target for LuaJIT { write!(w, "assert_eq(")?; write!(w, r#"loaded["{name}"].global_list["{global}"].value"#)?; write!(w, ", ")?; - Self::write_simple_expression(&result[0], w)?; + Self::write_ret(&result[0], w)?; writeln!(w, ")") } WastExecute::Wat(_) => panic!("Wat not supported"), diff --git a/dev-test/tests/luau_translate.rs b/dev-test/tests/luau_translate.rs index e090e88..2c85b09 100644 --- a/dev-test/tests/luau_translate.rs +++ b/dev-test/tests/luau_translate.rs @@ -5,8 +5,8 @@ use std::{ use wasm_ast::module::{Module, TypeInfo}; use wast::{ - core::{Expression, Instruction}, - AssertExpression, WastExecute, WastInvoke, Wat, + core::{WastArgCore, WastRetCore}, + WastArg, WastExecute, WastInvoke, WastRet, Wat, }; use target::{get_name_from_id, Target}; @@ -31,26 +31,22 @@ impl Luau { write!(w, "rt.i64.from_u32({data_1}, {data_2})") } - fn write_expression(data: &Expression, w: &mut dyn Write) -> Result<()> { - let data = &data.instrs; - - assert_eq!(data.len(), 1, "Only one instruction supported"); - - match &data[0] { - Instruction::I32Const(v) => Self::write_i32(*v, w), - Instruction::I64Const(v) => Self::write_i64(*v, w), - Instruction::F32Const(v) => target::write_f32(f32::from_bits(v.bits), w), - Instruction::F64Const(v) => target::write_f64(f64::from_bits(v.bits), w), - _ => panic!("Unsupported instruction"), + fn write_arg(data: &WastArg, w: &mut dyn Write) -> Result<()> { + match data { + WastArg::Core(WastArgCore::I32(v)) => Self::write_i32(*v, w), + WastArg::Core(WastArgCore::I64(v)) => Self::write_i64(*v, w), + WastArg::Core(WastArgCore::F32(v)) => target::write_f32(f32::from_bits(v.bits), w), + WastArg::Core(WastArgCore::F64(v)) => target::write_f64(f64::from_bits(v.bits), w), + _ => panic!("Unsupported expression"), } } - fn write_simple_expression(data: &AssertExpression, w: &mut dyn Write) -> Result<()> { + fn write_ret(data: &WastRet, w: &mut dyn Write) -> Result<()> { match data { - AssertExpression::I32(v) => Self::write_i32(*v, w), - AssertExpression::I64(v) => Self::write_i64(*v, w), - AssertExpression::F32(v) => target::write_f32_nan(v, w), - AssertExpression::F64(v) => target::write_f64_nan(v, w), + WastRet::Core(WastRetCore::I32(v)) => Self::write_i32(*v, w), + WastRet::Core(WastRetCore::I64(v)) => Self::write_i64(*v, w), + WastRet::Core(WastRetCore::F32(v)) => target::write_f32_nan(v, w), + WastRet::Core(WastRetCore::F64(v)) => target::write_f64_nan(v, w), _ => panic!("Unsupported expression"), } } @@ -64,7 +60,7 @@ impl Luau { data.args.iter().try_for_each(|v| { write!(w, ", ")?; - Self::write_expression(v, w) + Self::write_arg(v, w) })?; write!(w, ")") @@ -114,7 +110,7 @@ impl Target for Luau { fn write_assert_return( data: &mut WastExecute, - result: &[AssertExpression], + result: &[WastRet], w: &mut dyn Write, ) -> Result<()> { match data { @@ -125,7 +121,7 @@ impl Target for Luau { write!(w, "}}, {{")?; for v in result { - Self::write_simple_expression(v, w)?; + Self::write_ret(v, w)?; write!(w, ", ")?; } @@ -137,7 +133,7 @@ impl Target for Luau { write!(w, "assert_eq(")?; write!(w, r#"loaded["{name}"].global_list["{global}"].value"#)?; write!(w, ", ")?; - Self::write_simple_expression(&result[0], w)?; + Self::write_ret(&result[0], w)?; writeln!(w, ")") } WastExecute::Wat(_) => panic!("Wat not supported"), diff --git a/dev-test/tests/target.rs b/dev-test/tests/target.rs index 3faa63a..d021537 100644 --- a/dev-test/tests/target.rs +++ b/dev-test/tests/target.rs @@ -7,8 +7,8 @@ use std::{ use wasm_ast::module::Module as AstModule; use wast::{ - core::Module as WaModule, parser::ParseBuffer, token::Id, AssertExpression, QuoteWat, Wast, - WastDirective, WastExecute, WastInvoke, Wat, + core::Module as WaModule, parser::ParseBuffer, token::Id, QuoteWat, Wast, WastDirective, + WastExecute, WastInvoke, WastRet, Wat, }; macro_rules! impl_write_number_nan { @@ -23,8 +23,8 @@ macro_rules! impl_write_number_nan { } } - pub fn $name_nan(data: &wast::NanPattern<$pattern>, w: &mut dyn Write) -> Result<()> { - use wast::NanPattern; + pub fn $name_nan(data: &wast::core::NanPattern<$pattern>, w: &mut dyn Write) -> Result<()> { + use wast::core::NanPattern; match data { NanPattern::CanonicalNan => write!(w, "LUA_NAN_CANONICAL"), @@ -65,7 +65,7 @@ pub trait Target: Sized { fn write_assert_return( data: &mut WastExecute, - result: &[AssertExpression], + result: &[WastRet], w: &mut dyn Write, ) -> Result<()>; diff --git a/wasm-ast/Cargo.toml b/wasm-ast/Cargo.toml index 19942a3..6cc1543 100644 --- a/wasm-ast/Cargo.toml +++ b/wasm-ast/Cargo.toml @@ -4,4 +4,4 @@ version = "0.12.0" edition = "2021" [dependencies] -wasmparser = "0.86.0" +wasmparser = "0.99.0" diff --git a/wasm-ast/src/factory.rs b/wasm-ast/src/factory.rs index 2963164..febb73b 100644 --- a/wasm-ast/src/factory.rs +++ b/wasm-ast/src/factory.rs @@ -1,4 +1,4 @@ -use wasmparser::{BlockType, FunctionBody, MemoryImmediate, Operator, Result}; +use wasmparser::{BlockType, FunctionBody, MemArg, Operator, Result}; use crate::{ module::{read_checked, TypeInfo}, @@ -82,7 +82,7 @@ impl StatList { leak_on!(leak_global_write, Global); leak_on!(leak_memory_write, Memory); - fn push_load(&mut self, load_type: LoadType, memarg: MemoryImmediate) { + fn push_load(&mut self, load_type: LoadType, memarg: MemArg) { let memory = memarg.memory.try_into().unwrap(); let offset = memarg.offset.try_into().unwrap(); @@ -96,7 +96,7 @@ impl StatList { self.stack.push_with_single(data); } - fn add_store(&mut self, store_type: StoreType, memarg: MemoryImmediate) { + fn add_store(&mut self, store_type: StoreType, memarg: MemArg) { let memory = memarg.memory.try_into().unwrap(); let offset = memarg.offset.try_into().unwrap(); @@ -429,16 +429,16 @@ impl<'a> Factory<'a> { self.target.set_terminator(Terminator::Unreachable); } Operator::Nop => {} - Operator::Block { ty } => { - self.start_block(ty, BlockVariant::Forward); + Operator::Block { blockty } => { + self.start_block(blockty, BlockVariant::Forward); } - Operator::Loop { ty } => { - self.start_block(ty, BlockVariant::Backward); + Operator::Loop { blockty } => { + self.start_block(blockty, BlockVariant::Backward); } - Operator::If { ty } => { + Operator::If { blockty } => { let cond = self.target.stack.pop(); - self.start_block(ty, BlockVariant::If); + self.start_block(blockty, BlockVariant::If); self.pending.last_mut().unwrap().stack.push(cond); } Operator::Else => { @@ -465,15 +465,15 @@ impl<'a> Factory<'a> { self.target.leak_all(); self.target.code.push(data); } - Operator::BrTable { ref table } => { + Operator::BrTable { ref targets } => { let condition = self.target.stack.pop().into(); - let data = table + let data = targets .targets() .map(Result::unwrap) .map(|v| self.get_br_terminator(v.try_into().unwrap())) .collect(); - let default = self.get_br_terminator(table.default().try_into().unwrap()); + let default = self.get_br_terminator(targets.default().try_into().unwrap()); let term = Terminator::BrTable(BrTable { condition, @@ -497,9 +497,11 @@ impl<'a> Factory<'a> { self.add_call(index); } Operator::CallIndirect { - index, table_byte, .. + type_index, + table_byte, + .. } => { - let index = index.try_into().unwrap(); + let index = type_index.try_into().unwrap(); self.add_call_indirect(index, table_byte.into()); } diff --git a/wasm-ast/src/module.rs b/wasm-ast/src/module.rs index 0aa1c8b..dc24939 100644 --- a/wasm-ast/src/module.rs +++ b/wasm-ast/src/module.rs @@ -105,11 +105,10 @@ impl<'a> Module<'a> { self.start_section = Some(func); } Payload::CustomSection(v) if v.name() == "name" => { - for name in NameSectionReader::new(v.data(), v.data_offset())? { + for name in NameSectionReader::new(v.data(), v.data_offset()) { if let Name::Function(map) = name? { - let mut iter = map.get_map()?; - - while let Ok(elem) = iter.read() { + let mut iter = map.into_iter(); + while let Some(Ok(elem)) = iter.next() { self.name_section.insert(elem.index, elem.name); } } @@ -250,7 +249,7 @@ impl<'a> TypeInfo<'a> { pub(crate) fn by_type_index(&self, index: usize) -> (usize, usize) { let Type::Func(ty) = &self.type_list[index]; - (ty.params.len(), ty.returns.len()) + (ty.params().len(), ty.results().len()) } pub(crate) fn by_func_index(&self, index: usize) -> (usize, usize) {