null refs

This commit is contained in:
Graham Kelly 2024-04-09 13:52:02 -04:00
parent 9d16b582ea
commit 908ad937e1
6 changed files with 235 additions and 206 deletions

View file

@ -945,6 +945,10 @@ impl<'a> WasmFuncBackend<'a> {
Operator::RefFunc { func_index } => { Operator::RefFunc { func_index } => {
Some(wasm_encoder::Instruction::RefFunc(func_index.index() as u32)) Some(wasm_encoder::Instruction::RefFunc(func_index.index() as u32))
} }
Operator::RefNull { ty } => {
let h: wasm_encoder::RefType = ty.clone().into();
Some(wasm_encoder::Instruction::RefNull(h.heap_type))
}
}; };
if let Some(inst) = inst { if let Some(inst) = inst {

View file

@ -18,7 +18,8 @@ pub struct InterpContext {
pub globals: PerEntity<Global, ConstVal>, pub globals: PerEntity<Global, ConstVal>,
pub fuel: u64, pub fuel: u64,
pub trace_handler: Option<Box<dyn Fn(usize, Vec<ConstVal>) -> bool + Send>>, pub trace_handler: Option<Box<dyn Fn(usize, Vec<ConstVal>) -> bool + Send>>,
pub import_hander: Option<Box<dyn FnMut(&mut InterpContext,&str,&[ConstVal]) -> InterpResult>> pub import_hander:
Option<Box<dyn FnMut(&mut InterpContext, &str, &[ConstVal]) -> InterpResult>>,
} }
type MultiVal = SmallVec<[ConstVal; 2]>; type MultiVal = SmallVec<[ConstVal; 2]>;
@ -155,7 +156,11 @@ impl InterpContext {
_ => return result, _ => return result,
} }
} }
&ValueDef::Operator(Operator::CallIndirect { table_index, .. }, args, _) => { &ValueDef::Operator(
Operator::CallIndirect { table_index, .. },
args,
_,
) => {
let args = body.arg_pool[args] let args = body.arg_pool[args]
.iter() .iter()
.map(|&arg| { .map(|&arg| {
@ -221,7 +226,9 @@ impl InterpContext {
} }
smallvec![] smallvec![]
} }
&ValueDef::None | &ValueDef::Placeholder(..) | &ValueDef::BlockParam(..) => { &ValueDef::None
| &ValueDef::Placeholder(..)
| &ValueDef::BlockParam(..) => {
unreachable!(); unreachable!();
} }
}; };
@ -253,7 +260,10 @@ impl InterpContext {
// let result = self.call(module, func, &args[..args.len() - 1]); // let result = self.call(module, func, &args[..args.len() - 1]);
// return result; // return result;
} }
&Terminator::ReturnCall { func: fu, args: ref args2 } => { &Terminator::ReturnCall {
func: fu,
args: ref args2,
} => {
let args2 = args2 let args2 = args2
.iter() .iter()
.map(|&arg| { .map(|&arg| {

View file

@ -68,7 +68,9 @@ 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 => wasm_encoder::ValType::Ref(ty.into()), Type::FuncRef | Type::TypedFuncRef(..) | Type::ExternRef => {
wasm_encoder::ValType::Ref(ty.into())
}
} }
} }
} }

View file

@ -485,7 +485,10 @@ pub fn op_inputs(
params.push(Type::TypedFuncRef(true, sig_index.index() as u32)); params.push(Type::TypedFuncRef(true, sig_index.index() as u32));
Ok(params.into()) Ok(params.into())
} }
Operator::RefIsNull => Ok(vec![op_stack.context("in getting stack")?.last().unwrap().0].into()), Operator::RefIsNull => {
Ok(vec![op_stack.context("in getting stack")?.last().unwrap().0].into())
}
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 { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::I32, Type::I32])),
Operator::MemoryFill { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::I32, Type::I32])), Operator::MemoryFill { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::I32, Type::I32])),
@ -961,6 +964,7 @@ pub fn op_outputs(
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(true, ty.index() as u32)].into())
} }
Operator::RefNull { ty } => Ok(vec![ty.clone()].into()),
} }
} }
@ -1431,6 +1435,7 @@ impl Operator {
Operator::CallRef { .. } => &[All], Operator::CallRef { .. } => &[All],
Operator::RefIsNull => &[], Operator::RefIsNull => &[],
Operator::RefFunc { .. } => &[], Operator::RefFunc { .. } => &[],
Operator::RefNull { ty } => &[],
} }
} }
@ -1927,6 +1932,7 @@ impl std::fmt::Display for Operator {
Operator::CallRef { sig_index } => write!(f, "call_ref<{}>", sig_index)?, Operator::CallRef { sig_index } => write!(f, "call_ref<{}>", sig_index)?,
Operator::RefIsNull => write!(f, "ref_is_null")?, Operator::RefIsNull => write!(f, "ref_is_null")?,
Operator::RefFunc { func_index } => write!(f, "ref_func<{}>", func_index)?, Operator::RefFunc { func_index } => write!(f, "ref_func<{}>", func_index)?,
Operator::RefNull { ty } => write!(f, "ref_null<{}>", ty)?,
} }
Ok(()) Ok(())

View file

@ -1,6 +1,7 @@
//! Operators. //! Operators.
use crate::{entity::EntityRef, Func, Global, Memory, Signature, Table, Type}; use crate::{entity::EntityRef, Func, Global, Memory, Signature, Table, Type};
use anyhow::Context;
use std::convert::TryFrom; use std::convert::TryFrom;
pub use wasmparser::{Ieee32, Ieee64}; pub use wasmparser::{Ieee32, Ieee64};
@ -635,6 +636,9 @@ pub enum Operator {
sig_index: Signature, sig_index: Signature,
}, },
RefIsNull, RefIsNull,
RefNull {
ty: Type,
},
RefFunc { RefFunc {
func_index: Func, func_index: Func,
}, },
@ -1289,6 +1293,9 @@ impl<'a, 'b> std::convert::TryFrom<&'b wasmparser::Operator<'a>> for Operator {
&wasmparser::Operator::MemoryFill { mem } => Ok(Operator::MemoryFill { &wasmparser::Operator::MemoryFill { mem } => Ok(Operator::MemoryFill {
mem: Memory::from(mem), mem: Memory::from(mem),
}), }),
&wasmparser::Operator::RefNull { hty } => Ok(Operator::RefNull {
ty: wasmparser::RefType::new(true, hty).unwrap().into(),
}),
_ => Err(()), _ => Err(()),
} }
} }