This commit is contained in:
Graham Kelly 2024-06-03 15:18:53 -04:00
parent 36e3059be7
commit 284d141c36
8 changed files with 306 additions and 89 deletions

View file

@ -1087,7 +1087,7 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result<wasm_encoder::Module> {
memories.memory(wasm_encoder::MemoryType { memories.memory(wasm_encoder::MemoryType {
minimum: mem_data.initial_pages as u64, minimum: mem_data.initial_pages as u64,
maximum: mem_data.maximum_pages.map(|val| val as u64), maximum: mem_data.maximum_pages.map(|val| val as u64),
memory64: false, memory64: mem_data.memory64,
shared: false, shared: false,
}); });
} }
@ -1160,7 +1160,7 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result<wasm_encoder::Module> {
wasm_encoder::Elements::Functions(&[elt.index() as u32]), wasm_encoder::Elements::Functions(&[elt.index() as u32]),
); );
} }
Type::TypedFuncRef(..) => { Type::TypedFuncRef{..} => {
elem.active( elem.active(
Some(table.index() as u32), Some(table.index() as u32),
&wasm_encoder::ConstExpr::i32_const(i as i32), &wasm_encoder::ConstExpr::i32_const(i as i32),

View file

@ -145,6 +145,7 @@ fn handle_payload<'a>(
initial_pages: mem.initial as usize, initial_pages: mem.initial as usize,
maximum_pages: mem.maximum.map(|max| max as usize), maximum_pages: mem.maximum.map(|max| max as usize),
segments: vec![], segments: vec![],
memory64: mem.memory64
}); });
ImportKind::Memory(mem) ImportKind::Memory(mem)
} }
@ -229,6 +230,7 @@ fn handle_payload<'a>(
initial_pages: memory.initial as usize, initial_pages: memory.initial as usize,
maximum_pages: memory.maximum.map(|max| max as usize), maximum_pages: memory.maximum.map(|max| max as usize),
segments: vec![], segments: vec![],
memory64: memory.memory64
}); });
} }
} }

View file

@ -1022,7 +1022,7 @@ pub fn const_eval(
(Operator::Unreachable, []) => None, (Operator::Unreachable, []) => None,
(Operator::I32Load { memory }, [ConstVal::I32(addr)]) => ctx.and_then(|global| { (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 { if addr.checked_add(4)? > global.memories[memory.memory].data.len() as u32 {
return None; return None;
} }
@ -1032,7 +1032,7 @@ pub fn const_eval(
))) )))
}), }),
(Operator::I64Load { memory }, [ConstVal::I32(addr)]) => ctx.and_then(|global| { (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 { if addr.checked_add(8)? > global.memories[memory.memory].data.len() as u32 {
return None; return None;
} }
@ -1042,7 +1042,7 @@ pub fn const_eval(
))) )))
}), }),
(Operator::F32Load { memory }, [ConstVal::I32(addr)]) => ctx.and_then(|global| { (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 { if addr.checked_add(4)? > global.memories[memory.memory].data.len() as u32 {
return None; return None;
} }
@ -1052,7 +1052,7 @@ pub fn const_eval(
))) )))
}), }),
(Operator::F64Load { memory }, [ConstVal::I32(addr)]) => ctx.and_then(|global| { (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 { if addr.checked_add(8)? > global.memories[memory.memory].data.len() as u32 {
return None; return None;
} }
@ -1062,7 +1062,7 @@ pub fn const_eval(
))) )))
}), }),
(Operator::I32Load8S { memory }, [ConstVal::I32(addr)]) => ctx.and_then(|global| { (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 { if addr.checked_add(1)? > global.memories[memory.memory].data.len() as u32 {
return None; return None;
} }
@ -1071,7 +1071,7 @@ pub fn const_eval(
)) ))
}), }),
(Operator::I32Load8U { memory }, [ConstVal::I32(addr)]) => ctx.and_then(|global| { (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 { if addr.checked_add(4)? > global.memories[memory.memory].data.len() as u32 {
return None; return None;
} }
@ -1080,7 +1080,7 @@ pub fn const_eval(
)) ))
}), }),
(Operator::I32Load16S { memory }, [ConstVal::I32(addr)]) => ctx.and_then(|global| { (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 { if addr.checked_add(2)? > global.memories[memory.memory].data.len() as u32 {
return None; return None;
} }
@ -1089,7 +1089,7 @@ pub fn const_eval(
)) ))
}), }),
(Operator::I32Load16U { memory }, [ConstVal::I32(addr)]) => ctx.and_then(|global| { (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 { if addr.checked_add(2)? > global.memories[memory.memory].data.len() as u32 {
return None; return None;
} }
@ -1098,7 +1098,7 @@ pub fn const_eval(
)) ))
}), }),
(Operator::I64Load8S { memory }, [ConstVal::I32(addr)]) => ctx.and_then(|global| { (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 { if addr.checked_add(1)? > global.memories[memory.memory].data.len() as u32 {
return None; return None;
} }
@ -1107,7 +1107,7 @@ pub fn const_eval(
)) ))
}), }),
(Operator::I64Load8U { memory }, [ConstVal::I32(addr)]) => ctx.and_then(|global| { (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 { if addr.checked_add(1)? > global.memories[memory.memory].data.len() as u32 {
return None; return None;
} }
@ -1116,7 +1116,7 @@ pub fn const_eval(
)) ))
}), }),
(Operator::I64Load16S { memory }, [ConstVal::I32(addr)]) => ctx.and_then(|global| { (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 { if addr.checked_add(2)? > global.memories[memory.memory].data.len() as u32 {
return None; return None;
} }
@ -1125,7 +1125,7 @@ pub fn const_eval(
)) ))
}), }),
(Operator::I64Load16U { memory }, [ConstVal::I32(addr)]) => ctx.and_then(|global| { (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 { if addr.checked_add(2)? > global.memories[memory.memory].data.len() as u32 {
return None; return None;
} }
@ -1134,7 +1134,7 @@ pub fn const_eval(
)) ))
}), }),
(Operator::I64Load32S { memory }, [ConstVal::I32(addr)]) => ctx.and_then(|global| { (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 { if addr.checked_add(4)? > global.memories[memory.memory].data.len() as u32 {
return None; return None;
} }
@ -1143,7 +1143,7 @@ pub fn const_eval(
)) ))
}), }),
(Operator::I64Load32U { memory }, [ConstVal::I32(addr)]) => ctx.and_then(|global| { (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 { if addr.checked_add(4)? > global.memories[memory.memory].data.len() as u32 {
return None; return None;
} }
@ -1153,7 +1153,7 @@ pub fn const_eval(
}), }),
(Operator::I32Store { memory }, [ConstVal::I32(addr), ConstVal::I32(data)]) => ctx (Operator::I32Store { memory }, [ConstVal::I32(addr), ConstVal::I32(data)]) => ctx
.and_then(|global| { .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 { if addr.checked_add(4)? > global.memories[memory.memory].data.len() as u32 {
return None; return None;
} }
@ -1162,7 +1162,7 @@ pub fn const_eval(
}), }),
(Operator::I64Store { memory }, [ConstVal::I32(addr), ConstVal::I64(data)]) => ctx (Operator::I64Store { memory }, [ConstVal::I32(addr), ConstVal::I64(data)]) => ctx
.and_then(|global| { .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 { if addr.checked_add(8)? > global.memories[memory.memory].data.len() as u32 {
return None; return None;
} }
@ -1171,7 +1171,7 @@ pub fn const_eval(
}), }),
(Operator::I32Store8 { memory }, [ConstVal::I32(addr), ConstVal::I32(data)]) => ctx (Operator::I32Store8 { memory }, [ConstVal::I32(addr), ConstVal::I32(data)]) => ctx
.and_then(|global| { .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 { if addr.checked_add(1)? > global.memories[memory.memory].data.len() as u32 {
return None; return None;
} }
@ -1180,7 +1180,7 @@ pub fn const_eval(
}), }),
(Operator::I32Store16 { memory }, [ConstVal::I32(addr), ConstVal::I32(data)]) => ctx (Operator::I32Store16 { memory }, [ConstVal::I32(addr), ConstVal::I32(data)]) => ctx
.and_then(|global| { .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 { if addr.checked_add(2)? > global.memories[memory.memory].data.len() as u32 {
return None; return None;
} }
@ -1189,7 +1189,7 @@ pub fn const_eval(
}), }),
(Operator::I64Store8 { memory }, [ConstVal::I32(addr), ConstVal::I64(data)]) => ctx (Operator::I64Store8 { memory }, [ConstVal::I32(addr), ConstVal::I64(data)]) => ctx
.and_then(|global| { .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 { if addr.checked_add(1)? > global.memories[memory.memory].data.len() as u32 {
return None; return None;
} }
@ -1198,7 +1198,7 @@ pub fn const_eval(
}), }),
(Operator::I64Store16 { memory }, [ConstVal::I32(addr), ConstVal::I64(data)]) => ctx (Operator::I64Store16 { memory }, [ConstVal::I32(addr), ConstVal::I64(data)]) => ctx
.and_then(|global| { .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 { if addr.checked_add(2)? > global.memories[memory.memory].data.len() as u32 {
return None; return None;
} }
@ -1207,7 +1207,7 @@ pub fn const_eval(
}), }),
(Operator::I64Store32 { memory }, [ConstVal::I32(addr), ConstVal::I64(data)]) => ctx (Operator::I64Store32 { memory }, [ConstVal::I32(addr), ConstVal::I64(data)]) => ctx
.and_then(|global| { .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 { if addr.checked_add(4)? > global.memories[memory.memory].data.len() as u32 {
return None; return None;
} }
@ -1216,7 +1216,7 @@ pub fn const_eval(
}), }),
(Operator::F32Store { memory }, [ConstVal::I32(addr), ConstVal::F32(data)]) => ctx (Operator::F32Store { memory }, [ConstVal::I32(addr), ConstVal::F32(data)]) => ctx
.and_then(|global| { .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 { if addr.checked_add(4)? > global.memories[memory.memory].data.len() as u32 {
return None; return None;
} }
@ -1225,7 +1225,7 @@ pub fn const_eval(
}), }),
(Operator::F64Store { memory }, [ConstVal::I32(addr), ConstVal::F64(data)]) => ctx (Operator::F64Store { memory }, [ConstVal::I32(addr), ConstVal::F64(data)]) => ctx
.and_then(|global| { .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 { if addr.checked_add(8)? > global.memories[memory.memory].data.len() as u32 {
return None; return None;
} }

View file

@ -1,6 +1,6 @@
//! Intermediate representation for Wasm. //! Intermediate representation for Wasm.
use crate::declare_entity; use crate::{declare_entity, entity::EntityRef};
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Type { pub enum Type {
@ -11,7 +11,10 @@ pub enum Type {
V128, V128,
FuncRef, FuncRef,
ExternRef, ExternRef,
TypedFuncRef(bool, u32), TypedFuncRef {
nullable: bool,
sig_index: Signature,
},
} }
impl From<wasmparser::ValType> for Type { impl From<wasmparser::ValType> for Type {
fn from(ty: wasmparser::ValType) -> Self { fn from(ty: wasmparser::ValType) -> Self {
@ -33,7 +36,10 @@ impl From<wasmparser::RefType> for Type {
match ty.type_index() { match ty.type_index() {
Some(idx) => { Some(idx) => {
let nullable = ty.is_nullable(); 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, None => Type::FuncRef,
} }
@ -50,11 +56,14 @@ impl std::fmt::Display for Type {
Type::V128 => write!(f, "v128"), Type::V128 => write!(f, "v128"),
Type::FuncRef => write!(f, "funcref"), Type::FuncRef => write!(f, "funcref"),
Type::ExternRef => write!(f, "externref"), Type::ExternRef => write!(f, "externref"),
Type::TypedFuncRef(nullable, idx) => write!( Type::TypedFuncRef {
nullable,
sig_index,
} => write!(
f, f,
"funcref({}, {})", "funcref({}, {})",
if *nullable { "null" } else { "not_null" }, if *nullable { "null" } else { "not_null" },
idx sig_index
), ),
} }
} }
@ -68,7 +77,7 @@ impl From<Type> for wasm_encoder::ValType {
Type::F32 => wasm_encoder::ValType::F32, Type::F32 => wasm_encoder::ValType::F32,
Type::F64 => wasm_encoder::ValType::F64, Type::F64 => wasm_encoder::ValType::F64,
Type::V128 => wasm_encoder::ValType::V128, Type::V128 => wasm_encoder::ValType::V128,
Type::FuncRef | Type::TypedFuncRef(..) | Type::ExternRef => { Type::FuncRef | Type::TypedFuncRef { .. } | Type::ExternRef => {
wasm_encoder::ValType::Ref(ty.into()) wasm_encoder::ValType::Ref(ty.into())
} }
} }
@ -80,9 +89,9 @@ impl From<Type> for wasm_encoder::RefType {
match ty { match ty {
Type::ExternRef => wasm_encoder::RefType::EXTERNREF, Type::ExternRef => wasm_encoder::RefType::EXTERNREF,
Type::FuncRef => wasm_encoder::RefType::FUNCREF, Type::FuncRef => wasm_encoder::RefType::FUNCREF,
Type::TypedFuncRef(nullable, idx) => wasm_encoder::RefType { Type::TypedFuncRef{nullable,sig_index} => wasm_encoder::RefType {
nullable, nullable,
heap_type: wasm_encoder::HeapType::Concrete(idx), heap_type: wasm_encoder::HeapType::Concrete(sig_index.0),
}, },
_ => panic!("Cannot convert {:?} into reftype", ty), _ => panic!("Cannot convert {:?} into reftype", ty),
} }

View file

@ -34,6 +34,7 @@ pub struct MemoryData {
pub initial_pages: usize, pub initial_pages: usize,
pub maximum_pages: Option<usize>, pub maximum_pages: Option<usize>,
pub segments: Vec<MemorySegment>, pub segments: Vec<MemorySegment>,
pub memory64: bool,
} }
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]

View file

@ -36,30 +36,72 @@ pub fn op_inputs(
&Operator::GlobalGet { .. } => Ok(Cow::Borrowed(&[])), &Operator::GlobalGet { .. } => Ok(Cow::Borrowed(&[])),
&Operator::GlobalSet { global_index } => Ok(vec![module.globals[global_index].ty].into()), &Operator::GlobalSet { global_index } => Ok(vec![module.globals[global_index].ty].into()),
Operator::I32Load { .. } Operator::I32Load { memory }
| Operator::I64Load { .. } | Operator::I64Load { memory }
| Operator::F32Load { .. } | Operator::F32Load { memory }
| Operator::F64Load { .. } | Operator::F64Load { memory }
| Operator::I32Load8S { .. } | Operator::I32Load8S { memory }
| Operator::I32Load8U { .. } | Operator::I32Load8U { memory }
| Operator::I32Load16S { .. } | Operator::I32Load16S { memory }
| Operator::I32Load16U { .. } | Operator::I32Load16U { memory }
| Operator::I64Load8S { .. } | Operator::I64Load8S { memory }
| Operator::I64Load8U { .. } | Operator::I64Load8U { memory }
| Operator::I64Load16S { .. } | Operator::I64Load16S { memory }
| Operator::I64Load16U { .. } | Operator::I64Load16U { memory }
| Operator::I64Load32S { .. } | Operator::I64Load32S { memory }
| Operator::I64Load32U { .. } => Ok(Cow::Borrowed(&[Type::I32])), | 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::I32Store { memory } => Ok(if module.memories[memory.memory].memory64 {
Operator::I64Store { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::I64])), Cow::Borrowed(&[Type::I64, Type::I32])
Operator::F32Store { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::F32])), } else {
Operator::F64Store { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::F64])), Cow::Borrowed(&[Type::I32, Type::I32])
Operator::I32Store8 { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::I32])), }),
Operator::I32Store16 { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::I32])), Operator::I64Store { memory } => Ok(if module.memories[memory.memory].memory64 {
Operator::I64Store8 { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::I64])), Cow::Borrowed(&[Type::I64, Type::I64])
Operator::I64Store16 { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::I64])), } else {
Operator::I64Store32 { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::I64])), 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::I32Const { .. }
| Operator::I64Const { .. } | Operator::I64Const { .. }
@ -224,30 +266,167 @@ pub fn op_inputs(
} }
Operator::TableSize { .. } => Ok(Cow::Borrowed(&[])), Operator::TableSize { .. } => Ok(Cow::Borrowed(&[])),
Operator::MemorySize { .. } => 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::V128Load { memory } => {
Operator::V128Load8x8S { .. } => Ok(Cow::Borrowed(&[Type::I32])), if module.memories[memory.memory].memory64 {
Operator::V128Load8x8U { .. } => Ok(Cow::Borrowed(&[Type::I32])), Ok(Cow::Borrowed(&[Type::I64]))
Operator::V128Load16x4S { .. } => Ok(Cow::Borrowed(&[Type::I32])), } else {
Operator::V128Load16x4U { .. } => Ok(Cow::Borrowed(&[Type::I32])), 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::V128Load8x8S { memory } => {
Operator::V128Load16Splat { .. } => Ok(Cow::Borrowed(&[Type::I32])), if module.memories[memory.memory].memory64 {
Operator::V128Load32Splat { .. } => Ok(Cow::Borrowed(&[Type::I32])), Ok(Cow::Borrowed(&[Type::I64]))
Operator::V128Load64Splat { .. } => Ok(Cow::Borrowed(&[Type::I32])), } else {
Operator::V128Load32Zero { .. } => Ok(Cow::Borrowed(&[Type::I32])), 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::V128Load8x8U { memory } => {
Operator::V128Load16Lane { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::V128])), if module.memories[memory.memory].memory64 {
Operator::V128Load32Lane { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::V128])), Ok(Cow::Borrowed(&[Type::I64]))
Operator::V128Load64Lane { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::V128])), } else {
Operator::V128Store8Lane { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::V128])), Ok(Cow::Borrowed(&[Type::I32]))
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::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::V128Const { .. } => Ok(Cow::Borrowed(&[])),
Operator::I8x16Shuffle { .. } => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), Operator::I8x16Shuffle { .. } => Ok(Cow::Borrowed(&[Type::V128, Type::V128])),
@ -482,7 +661,7 @@ pub fn op_inputs(
Operator::CallRef { sig_index } => { Operator::CallRef { sig_index } => {
let mut params = module.signatures[*sig_index].params.to_vec(); 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()) Ok(params.into())
} }
Operator::RefIsNull => { Operator::RefIsNull => {
@ -490,8 +669,22 @@ pub fn op_inputs(
} }
Operator::RefNull { ty } => Ok(Cow::Borrowed(&[])), Operator::RefNull { ty } => Ok(Cow::Borrowed(&[])),
Operator::RefFunc { .. } => Ok(Cow::Borrowed(&[])), Operator::RefFunc { .. } => Ok(Cow::Borrowed(&[])),
Operator::MemoryCopy { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::I32, Type::I32])), Operator::MemoryCopy { dst_mem, src_mem } => match (
Operator::MemoryFill { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::I32, Type::I32])), 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::TableSet { .. } => Ok(Cow::Borrowed(&[])),
Operator::TableGrow { .. } => Ok(Cow::Borrowed(&[])), Operator::TableGrow { .. } => Ok(Cow::Borrowed(&[])),
Operator::TableSize { .. } => Ok(Cow::Borrowed(&[Type::I32])), Operator::TableSize { .. } => Ok(Cow::Borrowed(&[Type::I32])),
Operator::MemorySize { .. } => Ok(Cow::Borrowed(&[Type::I32])), Operator::MemorySize { mem } => Ok(if module.memories[*mem].memory64{
Operator::MemoryGrow { .. } => Ok(Cow::Borrowed(&[Type::I32])), 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::MemoryCopy { .. } => Ok(Cow::Borrowed(&[])),
Operator::MemoryFill { .. } => Ok(Cow::Borrowed(&[])), Operator::MemoryFill { .. } => Ok(Cow::Borrowed(&[])),
@ -962,7 +1163,7 @@ pub fn op_outputs(
Operator::RefIsNull => Ok(Cow::Borrowed(&[Type::I32])), Operator::RefIsNull => Ok(Cow::Borrowed(&[Type::I32])),
Operator::RefFunc { func_index } => { Operator::RefFunc { func_index } => {
let ty = module.funcs[*func_index].sig(); 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()), Operator::RefNull { ty } => Ok(vec![ty.clone()].into()),
} }
@ -1445,7 +1646,9 @@ impl Operator {
pub fn is_call(&self) -> bool { pub fn is_call(&self) -> bool {
match self { match self {
Operator::Call { .. } | Operator::CallIndirect { .. } => true, Operator::Call { .. } | Operator::CallIndirect { .. } | Operator::CallRef { .. } => {
true
}
_ => false, _ => false,
} }
} }

View file

@ -8,10 +8,11 @@ pub use wasmparser::{Ieee32, Ieee64};
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct MemoryArg { pub struct MemoryArg {
pub align: u32, pub align: u32,
pub offset: u32, pub offset: u64 ,
pub memory: Memory, pub memory: Memory,
} }
impl std::fmt::Display for MemoryArg { impl std::fmt::Display for MemoryArg {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!( write!(
@ -1305,7 +1306,7 @@ impl std::convert::From<wasmparser::MemArg> for MemoryArg {
fn from(value: wasmparser::MemArg) -> MemoryArg { fn from(value: wasmparser::MemArg) -> MemoryArg {
MemoryArg { MemoryArg {
align: value.align as u32, align: value.align as u32,
offset: u32::try_from(value.offset).expect("offset too large"), offset: value.offset,
memory: Memory::from(value.memory), memory: Memory::from(value.memory),
} }
} }
@ -1320,3 +1321,4 @@ impl std::convert::From<MemoryArg> for wasm_encoder::MemArg {
} }
} }
} }

View file

@ -7,7 +7,7 @@
(elem (table $tab2) (i32.const 0) (ref null $t) (ref.func $f)) (elem (table $tab2) (i32.const 0) (ref null $t) (ref.func $f))
(func $callit (param i32 i32 i32) (result i32) (func $callit (param i32 i32 i32) (result i32)
(call_ref $t (local.get 1) (return_call_ref $t (local.get 1)
(local.get 2) (local.get 2)
(table.get $tab (local.get 0)))) (table.get $tab (local.get 0))))