diff --git a/src/backend/mod.rs b/src/backend/mod.rs index e9a9160..4402ac0 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -1087,7 +1087,7 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result { memories.memory(wasm_encoder::MemoryType { minimum: mem_data.initial_pages as u64, maximum: mem_data.maximum_pages.map(|val| val as u64), - memory64: false, + memory64: mem_data.memory64, shared: false, }); } @@ -1160,7 +1160,7 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result { wasm_encoder::Elements::Functions(&[elt.index() as u32]), ); } - Type::TypedFuncRef(..) => { + Type::TypedFuncRef{..} => { elem.active( Some(table.index() as u32), &wasm_encoder::ConstExpr::i32_const(i as i32), diff --git a/src/frontend.rs b/src/frontend.rs index 40c82c5..dbf5d51 100644 --- a/src/frontend.rs +++ b/src/frontend.rs @@ -145,6 +145,7 @@ fn handle_payload<'a>( initial_pages: mem.initial as usize, maximum_pages: mem.maximum.map(|max| max as usize), segments: vec![], + memory64: mem.memory64 }); ImportKind::Memory(mem) } @@ -229,6 +230,7 @@ fn handle_payload<'a>( initial_pages: memory.initial as usize, maximum_pages: memory.maximum.map(|max| max as usize), segments: vec![], + memory64: memory.memory64 }); } } diff --git a/src/interp.rs b/src/interp.rs index a4b84f0..91a4500 100644 --- a/src/interp.rs +++ b/src/interp.rs @@ -1022,7 +1022,7 @@ pub fn const_eval( (Operator::Unreachable, []) => None, (Operator::I32Load { memory }, [ConstVal::I32(addr)]) => ctx.and_then(|global| { - let addr = addr.checked_add(memory.offset)?; + let addr = addr.checked_add(memory.offset as u32)?; if addr.checked_add(4)? > global.memories[memory.memory].data.len() as u32 { return None; } @@ -1032,7 +1032,7 @@ pub fn const_eval( ))) }), (Operator::I64Load { memory }, [ConstVal::I32(addr)]) => ctx.and_then(|global| { - let addr = addr.checked_add(memory.offset)?; + let addr = addr.checked_add(memory.offset as u32)?; if addr.checked_add(8)? > global.memories[memory.memory].data.len() as u32 { return None; } @@ -1042,7 +1042,7 @@ pub fn const_eval( ))) }), (Operator::F32Load { memory }, [ConstVal::I32(addr)]) => ctx.and_then(|global| { - let addr = addr.checked_add(memory.offset)?; + let addr = addr.checked_add(memory.offset as u32)?; if addr.checked_add(4)? > global.memories[memory.memory].data.len() as u32 { return None; } @@ -1052,7 +1052,7 @@ pub fn const_eval( ))) }), (Operator::F64Load { memory }, [ConstVal::I32(addr)]) => ctx.and_then(|global| { - let addr = addr.checked_add(memory.offset)?; + let addr = addr.checked_add(memory.offset as u32)?; if addr.checked_add(8)? > global.memories[memory.memory].data.len() as u32 { return None; } @@ -1062,7 +1062,7 @@ pub fn const_eval( ))) }), (Operator::I32Load8S { memory }, [ConstVal::I32(addr)]) => ctx.and_then(|global| { - let addr = addr.checked_add(memory.offset)?; + let addr = addr.checked_add(memory.offset as u32)?; if addr.checked_add(1)? > global.memories[memory.memory].data.len() as u32 { return None; } @@ -1071,7 +1071,7 @@ pub fn const_eval( )) }), (Operator::I32Load8U { memory }, [ConstVal::I32(addr)]) => ctx.and_then(|global| { - let addr = addr.checked_add(memory.offset)?; + let addr = addr.checked_add(memory.offset as u32)?; if addr.checked_add(4)? > global.memories[memory.memory].data.len() as u32 { return None; } @@ -1080,7 +1080,7 @@ pub fn const_eval( )) }), (Operator::I32Load16S { memory }, [ConstVal::I32(addr)]) => ctx.and_then(|global| { - let addr = addr.checked_add(memory.offset)?; + let addr = addr.checked_add(memory.offset as u32)?; if addr.checked_add(2)? > global.memories[memory.memory].data.len() as u32 { return None; } @@ -1089,7 +1089,7 @@ pub fn const_eval( )) }), (Operator::I32Load16U { memory }, [ConstVal::I32(addr)]) => ctx.and_then(|global| { - let addr = addr.checked_add(memory.offset)?; + let addr = addr.checked_add(memory.offset as u32)?; if addr.checked_add(2)? > global.memories[memory.memory].data.len() as u32 { return None; } @@ -1098,7 +1098,7 @@ pub fn const_eval( )) }), (Operator::I64Load8S { memory }, [ConstVal::I32(addr)]) => ctx.and_then(|global| { - let addr = addr.checked_add(memory.offset)?; + let addr = addr.checked_add(memory.offset as u32)?; if addr.checked_add(1)? > global.memories[memory.memory].data.len() as u32 { return None; } @@ -1107,7 +1107,7 @@ pub fn const_eval( )) }), (Operator::I64Load8U { memory }, [ConstVal::I32(addr)]) => ctx.and_then(|global| { - let addr = addr.checked_add(memory.offset)?; + let addr = addr.checked_add(memory.offset as u32)?; if addr.checked_add(1)? > global.memories[memory.memory].data.len() as u32 { return None; } @@ -1116,7 +1116,7 @@ pub fn const_eval( )) }), (Operator::I64Load16S { memory }, [ConstVal::I32(addr)]) => ctx.and_then(|global| { - let addr = addr.checked_add(memory.offset)?; + let addr = addr.checked_add(memory.offset as u32)?; if addr.checked_add(2)? > global.memories[memory.memory].data.len() as u32 { return None; } @@ -1125,7 +1125,7 @@ pub fn const_eval( )) }), (Operator::I64Load16U { memory }, [ConstVal::I32(addr)]) => ctx.and_then(|global| { - let addr = addr.checked_add(memory.offset)?; + let addr = addr.checked_add(memory.offset as u32)?; if addr.checked_add(2)? > global.memories[memory.memory].data.len() as u32 { return None; } @@ -1134,7 +1134,7 @@ pub fn const_eval( )) }), (Operator::I64Load32S { memory }, [ConstVal::I32(addr)]) => ctx.and_then(|global| { - let addr = addr.checked_add(memory.offset)?; + let addr = addr.checked_add(memory.offset as u32)?; if addr.checked_add(4)? > global.memories[memory.memory].data.len() as u32 { return None; } @@ -1143,7 +1143,7 @@ pub fn const_eval( )) }), (Operator::I64Load32U { memory }, [ConstVal::I32(addr)]) => ctx.and_then(|global| { - let addr = addr.checked_add(memory.offset)?; + let addr = addr.checked_add(memory.offset as u32)?; if addr.checked_add(4)? > global.memories[memory.memory].data.len() as u32 { return None; } @@ -1153,7 +1153,7 @@ pub fn const_eval( }), (Operator::I32Store { memory }, [ConstVal::I32(addr), ConstVal::I32(data)]) => ctx .and_then(|global| { - let addr = addr.checked_add(memory.offset)?; + let addr = addr.checked_add(memory.offset as u32)?; if addr.checked_add(4)? > global.memories[memory.memory].data.len() as u32 { return None; } @@ -1162,7 +1162,7 @@ pub fn const_eval( }), (Operator::I64Store { memory }, [ConstVal::I32(addr), ConstVal::I64(data)]) => ctx .and_then(|global| { - let addr = addr.checked_add(memory.offset)?; + let addr = addr.checked_add(memory.offset as u32)?; if addr.checked_add(8)? > global.memories[memory.memory].data.len() as u32 { return None; } @@ -1171,7 +1171,7 @@ pub fn const_eval( }), (Operator::I32Store8 { memory }, [ConstVal::I32(addr), ConstVal::I32(data)]) => ctx .and_then(|global| { - let addr = addr.checked_add(memory.offset)?; + let addr = addr.checked_add(memory.offset as u32)?; if addr.checked_add(1)? > global.memories[memory.memory].data.len() as u32 { return None; } @@ -1180,7 +1180,7 @@ pub fn const_eval( }), (Operator::I32Store16 { memory }, [ConstVal::I32(addr), ConstVal::I32(data)]) => ctx .and_then(|global| { - let addr = addr.checked_add(memory.offset)?; + let addr = addr.checked_add(memory.offset as u32)?; if addr.checked_add(2)? > global.memories[memory.memory].data.len() as u32 { return None; } @@ -1189,7 +1189,7 @@ pub fn const_eval( }), (Operator::I64Store8 { memory }, [ConstVal::I32(addr), ConstVal::I64(data)]) => ctx .and_then(|global| { - let addr = addr.checked_add(memory.offset)?; + let addr = addr.checked_add(memory.offset as u32)?; if addr.checked_add(1)? > global.memories[memory.memory].data.len() as u32 { return None; } @@ -1198,7 +1198,7 @@ pub fn const_eval( }), (Operator::I64Store16 { memory }, [ConstVal::I32(addr), ConstVal::I64(data)]) => ctx .and_then(|global| { - let addr = addr.checked_add(memory.offset)?; + let addr = addr.checked_add(memory.offset as u32)?; if addr.checked_add(2)? > global.memories[memory.memory].data.len() as u32 { return None; } @@ -1207,7 +1207,7 @@ pub fn const_eval( }), (Operator::I64Store32 { memory }, [ConstVal::I32(addr), ConstVal::I64(data)]) => ctx .and_then(|global| { - let addr = addr.checked_add(memory.offset)?; + let addr = addr.checked_add(memory.offset as u32)?; if addr.checked_add(4)? > global.memories[memory.memory].data.len() as u32 { return None; } @@ -1216,7 +1216,7 @@ pub fn const_eval( }), (Operator::F32Store { memory }, [ConstVal::I32(addr), ConstVal::F32(data)]) => ctx .and_then(|global| { - let addr = addr.checked_add(memory.offset)?; + let addr = addr.checked_add(memory.offset as u32)?; if addr.checked_add(4)? > global.memories[memory.memory].data.len() as u32 { return None; } @@ -1225,7 +1225,7 @@ pub fn const_eval( }), (Operator::F64Store { memory }, [ConstVal::I32(addr), ConstVal::F64(data)]) => ctx .and_then(|global| { - let addr = addr.checked_add(memory.offset)?; + let addr = addr.checked_add(memory.offset as u32)?; if addr.checked_add(8)? > global.memories[memory.memory].data.len() as u32 { return None; } diff --git a/src/ir.rs b/src/ir.rs index e89941b..bd7a78f 100644 --- a/src/ir.rs +++ b/src/ir.rs @@ -1,6 +1,6 @@ //! Intermediate representation for Wasm. -use crate::declare_entity; +use crate::{declare_entity, entity::EntityRef}; #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum Type { @@ -11,7 +11,10 @@ pub enum Type { V128, FuncRef, ExternRef, - TypedFuncRef(bool, u32), + TypedFuncRef { + nullable: bool, + sig_index: Signature, + }, } impl From for Type { fn from(ty: wasmparser::ValType) -> Self { @@ -33,7 +36,10 @@ impl From for Type { match ty.type_index() { Some(idx) => { let nullable = ty.is_nullable(); - Type::TypedFuncRef(nullable, idx.as_module_index().unwrap()) + Type::TypedFuncRef { + nullable: nullable, + sig_index: Signature::new(idx.as_module_index().unwrap() as usize), + } } None => Type::FuncRef, } @@ -50,11 +56,14 @@ impl std::fmt::Display for Type { Type::V128 => write!(f, "v128"), Type::FuncRef => write!(f, "funcref"), Type::ExternRef => write!(f, "externref"), - Type::TypedFuncRef(nullable, idx) => write!( + Type::TypedFuncRef { + nullable, + sig_index, + } => write!( f, "funcref({}, {})", if *nullable { "null" } else { "not_null" }, - idx + sig_index ), } } @@ -68,7 +77,7 @@ impl From for wasm_encoder::ValType { Type::F32 => wasm_encoder::ValType::F32, Type::F64 => wasm_encoder::ValType::F64, Type::V128 => wasm_encoder::ValType::V128, - Type::FuncRef | Type::TypedFuncRef(..) | Type::ExternRef => { + Type::FuncRef | Type::TypedFuncRef { .. } | Type::ExternRef => { wasm_encoder::ValType::Ref(ty.into()) } } @@ -80,9 +89,9 @@ impl From for wasm_encoder::RefType { match ty { Type::ExternRef => wasm_encoder::RefType::EXTERNREF, Type::FuncRef => wasm_encoder::RefType::FUNCREF, - Type::TypedFuncRef(nullable, idx) => wasm_encoder::RefType { + Type::TypedFuncRef{nullable,sig_index} => wasm_encoder::RefType { nullable, - heap_type: wasm_encoder::HeapType::Concrete(idx), + heap_type: wasm_encoder::HeapType::Concrete(sig_index.0), }, _ => panic!("Cannot convert {:?} into reftype", ty), } diff --git a/src/ir/module.rs b/src/ir/module.rs index 28c23c4..acd45d1 100644 --- a/src/ir/module.rs +++ b/src/ir/module.rs @@ -34,6 +34,7 @@ pub struct MemoryData { pub initial_pages: usize, pub maximum_pages: Option, pub segments: Vec, + pub memory64: bool, } #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] diff --git a/src/op_traits.rs b/src/op_traits.rs index b0cf2a4..182a4e2 100644 --- a/src/op_traits.rs +++ b/src/op_traits.rs @@ -36,30 +36,72 @@ pub fn op_inputs( &Operator::GlobalGet { .. } => Ok(Cow::Borrowed(&[])), &Operator::GlobalSet { global_index } => Ok(vec![module.globals[global_index].ty].into()), - Operator::I32Load { .. } - | Operator::I64Load { .. } - | Operator::F32Load { .. } - | Operator::F64Load { .. } - | Operator::I32Load8S { .. } - | Operator::I32Load8U { .. } - | Operator::I32Load16S { .. } - | Operator::I32Load16U { .. } - | Operator::I64Load8S { .. } - | Operator::I64Load8U { .. } - | Operator::I64Load16S { .. } - | Operator::I64Load16U { .. } - | Operator::I64Load32S { .. } - | Operator::I64Load32U { .. } => Ok(Cow::Borrowed(&[Type::I32])), + Operator::I32Load { memory } + | Operator::I64Load { memory } + | Operator::F32Load { memory } + | Operator::F64Load { memory } + | Operator::I32Load8S { memory } + | Operator::I32Load8U { memory } + | Operator::I32Load16S { memory } + | Operator::I32Load16U { memory } + | Operator::I64Load8S { memory } + | Operator::I64Load8U { memory } + | Operator::I64Load16S { memory } + | Operator::I64Load16U { memory } + | Operator::I64Load32S { memory } + | Operator::I64Load32U { memory } => { + if module.memories[memory.memory].memory64 { + Ok(Cow::Borrowed(&[Type::I64])) + } else { + Ok(Cow::Borrowed(&[Type::I32])) + } + } - Operator::I32Store { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::I32])), - Operator::I64Store { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::I64])), - Operator::F32Store { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::F32])), - Operator::F64Store { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::F64])), - Operator::I32Store8 { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::I32])), - Operator::I32Store16 { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::I32])), - Operator::I64Store8 { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::I64])), - Operator::I64Store16 { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::I64])), - Operator::I64Store32 { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::I64])), + Operator::I32Store { memory } => Ok(if module.memories[memory.memory].memory64 { + Cow::Borrowed(&[Type::I64, Type::I32]) + } else { + Cow::Borrowed(&[Type::I32, Type::I32]) + }), + Operator::I64Store { memory } => Ok(if module.memories[memory.memory].memory64 { + Cow::Borrowed(&[Type::I64, Type::I64]) + } else { + Cow::Borrowed(&[Type::I32, Type::I64]) + }), + Operator::F32Store { memory } => Ok(if module.memories[memory.memory].memory64 { + Cow::Borrowed(&[Type::I64, Type::F32]) + } else { + Cow::Borrowed(&[Type::I32, Type::F32]) + }), + Operator::F64Store { memory } => Ok(if module.memories[memory.memory].memory64 { + Cow::Borrowed(&[Type::I64, Type::F64]) + } else { + Cow::Borrowed(&[Type::I32, Type::F64]) + }), + Operator::I32Store8 { memory } => Ok(if module.memories[memory.memory].memory64 { + Cow::Borrowed(&[Type::I64, Type::I32]) + } else { + Cow::Borrowed(&[Type::I32, Type::I32]) + }), + Operator::I32Store16 { memory } => Ok(if module.memories[memory.memory].memory64 { + Cow::Borrowed(&[Type::I64, Type::I32]) + } else { + Cow::Borrowed(&[Type::I32, Type::I32]) + }), + Operator::I64Store8 { memory } => Ok(if module.memories[memory.memory].memory64 { + Cow::Borrowed(&[Type::I64, Type::I64]) + } else { + Cow::Borrowed(&[Type::I32, Type::I64]) + }), + Operator::I64Store16 { memory } => Ok(if module.memories[memory.memory].memory64 { + Cow::Borrowed(&[Type::I64, Type::I64]) + } else { + Cow::Borrowed(&[Type::I32, Type::I64]) + }), + Operator::I64Store32 { memory } => Ok(if module.memories[memory.memory].memory64 { + Cow::Borrowed(&[Type::I64, Type::I64]) + } else { + Cow::Borrowed(&[Type::I32, Type::I64]) + }), Operator::I32Const { .. } | Operator::I64Const { .. } @@ -224,30 +266,167 @@ pub fn op_inputs( } Operator::TableSize { .. } => Ok(Cow::Borrowed(&[])), Operator::MemorySize { .. } => Ok(Cow::Borrowed(&[])), - Operator::MemoryGrow { .. } => Ok(Cow::Borrowed(&[Type::I32])), + Operator::MemoryGrow { mem } => Ok(if module.memories[*mem].memory64{ + Cow::Borrowed(&[Type::I64]) + }else{ + Cow::Borrowed(&[Type::I32]) + }), - Operator::V128Load { .. } => Ok(Cow::Borrowed(&[Type::I32])), - Operator::V128Load8x8S { .. } => Ok(Cow::Borrowed(&[Type::I32])), - Operator::V128Load8x8U { .. } => Ok(Cow::Borrowed(&[Type::I32])), - Operator::V128Load16x4S { .. } => Ok(Cow::Borrowed(&[Type::I32])), - Operator::V128Load16x4U { .. } => Ok(Cow::Borrowed(&[Type::I32])), - Operator::V128Load32x2S { .. } => Ok(Cow::Borrowed(&[Type::I32])), - Operator::V128Load32x2U { .. } => Ok(Cow::Borrowed(&[Type::I32])), - Operator::V128Load8Splat { .. } => Ok(Cow::Borrowed(&[Type::I32])), - Operator::V128Load16Splat { .. } => Ok(Cow::Borrowed(&[Type::I32])), - Operator::V128Load32Splat { .. } => Ok(Cow::Borrowed(&[Type::I32])), - Operator::V128Load64Splat { .. } => Ok(Cow::Borrowed(&[Type::I32])), - Operator::V128Load32Zero { .. } => Ok(Cow::Borrowed(&[Type::I32])), - Operator::V128Load64Zero { .. } => Ok(Cow::Borrowed(&[Type::I32])), - Operator::V128Store { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::V128])), - Operator::V128Load8Lane { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::V128])), - Operator::V128Load16Lane { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::V128])), - Operator::V128Load32Lane { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::V128])), - Operator::V128Load64Lane { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::V128])), - Operator::V128Store8Lane { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::V128])), - Operator::V128Store16Lane { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::V128])), - Operator::V128Store32Lane { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::V128])), - Operator::V128Store64Lane { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::V128])), + Operator::V128Load { memory } => { + if module.memories[memory.memory].memory64 { + Ok(Cow::Borrowed(&[Type::I64])) + } else { + Ok(Cow::Borrowed(&[Type::I32])) + } + } + Operator::V128Load8x8S { memory } => { + if module.memories[memory.memory].memory64 { + Ok(Cow::Borrowed(&[Type::I64])) + } else { + Ok(Cow::Borrowed(&[Type::I32])) + } + } + Operator::V128Load8x8U { memory } => { + if module.memories[memory.memory].memory64 { + Ok(Cow::Borrowed(&[Type::I64])) + } else { + Ok(Cow::Borrowed(&[Type::I32])) + } + } + Operator::V128Load16x4S { memory } => { + if module.memories[memory.memory].memory64 { + Ok(Cow::Borrowed(&[Type::I64])) + } else { + Ok(Cow::Borrowed(&[Type::I32])) + } + } + Operator::V128Load16x4U { memory } => { + if module.memories[memory.memory].memory64 { + Ok(Cow::Borrowed(&[Type::I64])) + } else { + Ok(Cow::Borrowed(&[Type::I32])) + } + } + Operator::V128Load32x2S { memory } => { + if module.memories[memory.memory].memory64 { + Ok(Cow::Borrowed(&[Type::I64])) + } else { + Ok(Cow::Borrowed(&[Type::I32])) + } + } + Operator::V128Load32x2U { memory } => { + if module.memories[memory.memory].memory64 { + Ok(Cow::Borrowed(&[Type::I64])) + } else { + Ok(Cow::Borrowed(&[Type::I32])) + } + } + Operator::V128Load8Splat { memory } => { + if module.memories[memory.memory].memory64 { + Ok(Cow::Borrowed(&[Type::I64])) + } else { + Ok(Cow::Borrowed(&[Type::I32])) + } + } + Operator::V128Load16Splat { memory } => { + if module.memories[memory.memory].memory64 { + Ok(Cow::Borrowed(&[Type::I64])) + } else { + Ok(Cow::Borrowed(&[Type::I32])) + } + } + Operator::V128Load32Splat { memory } => { + if module.memories[memory.memory].memory64 { + Ok(Cow::Borrowed(&[Type::I64])) + } else { + Ok(Cow::Borrowed(&[Type::I32])) + } + } + Operator::V128Load64Splat { memory } => { + if module.memories[memory.memory].memory64 { + Ok(Cow::Borrowed(&[Type::I64])) + } else { + Ok(Cow::Borrowed(&[Type::I32])) + } + } + Operator::V128Load32Zero { memory } => { + if module.memories[memory.memory].memory64 { + Ok(Cow::Borrowed(&[Type::I64])) + } else { + Ok(Cow::Borrowed(&[Type::I32])) + } + } + Operator::V128Load64Zero { memory } => { + if module.memories[memory.memory].memory64 { + Ok(Cow::Borrowed(&[Type::I64])) + } else { + Ok(Cow::Borrowed(&[Type::I32])) + } + } + Operator::V128Store { memory } => { + if module.memories[memory.memory].memory64 { + Ok(Cow::Borrowed(&[Type::I64, Type::V128])) + } else { + Ok(Cow::Borrowed(&[Type::I32, Type::V128])) + } + } + Operator::V128Load8Lane { memory, .. } => { + if module.memories[memory.memory].memory64 { + Ok(Cow::Borrowed(&[Type::I64, Type::V128])) + } else { + Ok(Cow::Borrowed(&[Type::I32, Type::V128])) + } + } + + Operator::V128Load16Lane { memory, .. } => { + if module.memories[memory.memory].memory64 { + Ok(Cow::Borrowed(&[Type::I64, Type::V128])) + } else { + Ok(Cow::Borrowed(&[Type::I32, Type::V128])) + } + } + Operator::V128Load32Lane { memory, .. } => { + if module.memories[memory.memory].memory64 { + Ok(Cow::Borrowed(&[Type::I64, Type::V128])) + } else { + Ok(Cow::Borrowed(&[Type::I32, Type::V128])) + } + } + Operator::V128Load64Lane { memory, .. } => { + if module.memories[memory.memory].memory64 { + Ok(Cow::Borrowed(&[Type::I64, Type::V128])) + } else { + Ok(Cow::Borrowed(&[Type::I32, Type::V128])) + } + } + Operator::V128Store8Lane { memory, .. } => { + if module.memories[memory.memory].memory64 { + Ok(Cow::Borrowed(&[Type::I64, Type::V128])) + } else { + Ok(Cow::Borrowed(&[Type::I32, Type::V128])) + } + } + Operator::V128Store16Lane { memory, .. } => { + if module.memories[memory.memory].memory64 { + Ok(Cow::Borrowed(&[Type::I64, Type::V128])) + } else { + Ok(Cow::Borrowed(&[Type::I32, Type::V128])) + } + } + Operator::V128Store32Lane { memory, .. } => { + if module.memories[memory.memory].memory64 { + Ok(Cow::Borrowed(&[Type::I64, Type::V128])) + } else { + Ok(Cow::Borrowed(&[Type::I32, Type::V128])) + } + } + Operator::V128Store64Lane { memory, .. } => { + if module.memories[memory.memory].memory64 { + Ok(Cow::Borrowed(&[Type::I64, Type::V128])) + } else { + Ok(Cow::Borrowed(&[Type::I32, Type::V128])) + } + } Operator::V128Const { .. } => Ok(Cow::Borrowed(&[])), Operator::I8x16Shuffle { .. } => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), @@ -482,7 +661,7 @@ pub fn op_inputs( Operator::CallRef { sig_index } => { let mut params = module.signatures[*sig_index].params.to_vec(); - params.push(Type::TypedFuncRef(true, sig_index.index() as u32)); + params.push(Type::TypedFuncRef{nullable: true, sig_index: *sig_index}); Ok(params.into()) } Operator::RefIsNull => { @@ -490,8 +669,22 @@ pub fn op_inputs( } Operator::RefNull { ty } => Ok(Cow::Borrowed(&[])), Operator::RefFunc { .. } => Ok(Cow::Borrowed(&[])), - Operator::MemoryCopy { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::I32, Type::I32])), - Operator::MemoryFill { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::I32, Type::I32])), + Operator::MemoryCopy { dst_mem, src_mem } => match ( + module.memories[*dst_mem].memory64, + module.memories[*src_mem].memory64, + ) { + (false, false) => Ok(Cow::Borrowed(&[Type::I32, Type::I32, Type::I32])), + (false, true) => Ok(Cow::Borrowed(&[Type::I32, Type::I64, Type::I32])), + (true, false) => Ok(Cow::Borrowed(&[Type::I64, Type::I32, Type::I32])), + (true, true) => Ok(Cow::Borrowed(&[Type::I64, Type::I64, Type::I32])), + }, + Operator::MemoryFill { mem, .. } => { + if module.memories[*mem].memory64 { + Ok(Cow::Borrowed(&[Type::I64, Type::I32, Type::I32])) + } else { + Ok(Cow::Borrowed(&[Type::I32, Type::I32, Type::I32])) + } + } } } @@ -697,8 +890,16 @@ pub fn op_outputs( Operator::TableSet { .. } => Ok(Cow::Borrowed(&[])), Operator::TableGrow { .. } => Ok(Cow::Borrowed(&[])), Operator::TableSize { .. } => Ok(Cow::Borrowed(&[Type::I32])), - Operator::MemorySize { .. } => Ok(Cow::Borrowed(&[Type::I32])), - Operator::MemoryGrow { .. } => Ok(Cow::Borrowed(&[Type::I32])), + Operator::MemorySize { mem } => Ok(if module.memories[*mem].memory64{ + Cow::Borrowed(&[Type::I64]) + }else{ + Cow::Borrowed(&[Type::I32]) + }), + Operator::MemoryGrow { mem } => Ok(if module.memories[*mem].memory64{ + Cow::Borrowed(&[Type::I64]) + }else{ + Cow::Borrowed(&[Type::I32]) + }), Operator::MemoryCopy { .. } => Ok(Cow::Borrowed(&[])), Operator::MemoryFill { .. } => Ok(Cow::Borrowed(&[])), @@ -962,7 +1163,7 @@ pub fn op_outputs( Operator::RefIsNull => Ok(Cow::Borrowed(&[Type::I32])), Operator::RefFunc { func_index } => { let ty = module.funcs[*func_index].sig(); - Ok(vec![Type::TypedFuncRef(true, ty.index() as u32)].into()) + Ok(vec![Type::TypedFuncRef{nullable:true, sig_index:ty}].into()) } Operator::RefNull { ty } => Ok(vec![ty.clone()].into()), } @@ -1445,7 +1646,9 @@ impl Operator { pub fn is_call(&self) -> bool { match self { - Operator::Call { .. } | Operator::CallIndirect { .. } => true, + Operator::Call { .. } | Operator::CallIndirect { .. } | Operator::CallRef { .. } => { + true + } _ => false, } } diff --git a/src/ops.rs b/src/ops.rs index 3da0a4b..ef8111b 100644 --- a/src/ops.rs +++ b/src/ops.rs @@ -8,10 +8,11 @@ pub use wasmparser::{Ieee32, Ieee64}; #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct MemoryArg { pub align: u32, - pub offset: u32, + pub offset: u64 , pub memory: Memory, } + impl std::fmt::Display for MemoryArg { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!( @@ -1305,7 +1306,7 @@ impl std::convert::From for MemoryArg { fn from(value: wasmparser::MemArg) -> MemoryArg { MemoryArg { align: value.align as u32, - offset: u32::try_from(value.offset).expect("offset too large"), + offset: value.offset, memory: Memory::from(value.memory), } } @@ -1320,3 +1321,4 @@ impl std::convert::From for wasm_encoder::MemArg { } } } + diff --git a/wasm_tests/typed-funcref.wat b/wasm_tests/typed-funcref.wat index a532f58..9c90424 100644 --- a/wasm_tests/typed-funcref.wat +++ b/wasm_tests/typed-funcref.wat @@ -7,7 +7,7 @@ (elem (table $tab2) (i32.const 0) (ref null $t) (ref.func $f)) (func $callit (param i32 i32 i32) (result i32) - (call_ref $t (local.get 1) + (return_call_ref $t (local.get 1) (local.get 2) (table.get $tab (local.get 0))))