remove panic, expect and unimplemented from microwasm + use Result as return value for some functions (#652)

This commit is contained in:
Patrick Ventuzelo
2019-12-03 20:58:29 +01:00
committed by Dan Gohman
parent 4fd56de4df
commit 027f6117d6
4 changed files with 323 additions and 89 deletions

View File

@@ -54,13 +54,13 @@ impl crate::compilation::Compiler for Lightbeam {
i.as_u32(), i.as_u32(),
&wasmparser::FunctionBody::new(0, function_body.data), &wasmparser::FunctionBody::new(0, function_body.data),
) )
.expect("Failed to translate function. TODO: Stop this from panicking"); .map_err(|e| CompileError::Codegen(format!("Failed to translate function: {}", e)))?;
relocations.push(reloc_sink.func_relocs); relocations.push(reloc_sink.func_relocs);
} }
let code_section = codegen_session let code_section = codegen_session
.into_translated_code_section() .into_translated_code_section()
.expect("Failed to generate output code. TODO: Stop this from panicking"); .map_err(|e| CompileError::Codegen(format!("Failed to generate output code: {}", e)))?;
// TODO pass jump table offsets to Compilation::from_buffer() when they // TODO pass jump table offsets to Compilation::from_buffer() when they
// are implemented in lightbeam -- using empty set of offsets for now. // are implemented in lightbeam -- using empty set of offsets for now.

View File

@@ -12,6 +12,9 @@ pub enum Error {
#[error("Input error: {0}")] #[error("Input error: {0}")]
Input(String), Input(String),
#[error("Microwasm error: {0}")]
Microwasm(String),
} }
impl From<BinaryReaderError> for Error { impl From<BinaryReaderError> for Error {

View File

@@ -53,7 +53,7 @@ where
ty.params().iter().map(SigType::to_microwasm_type), ty.params().iter().map(SigType::to_microwasm_type),
ty.returns().iter().map(SigType::to_microwasm_type), ty.returns().iter().map(SigType::to_microwasm_type),
body, body,
); )?;
let _ = crate::microwasm::dis( let _ = crate::microwasm::dis(
std::io::stdout(), std::io::stdout(),
@@ -67,14 +67,18 @@ where
ty.params().iter().map(SigType::to_microwasm_type), ty.params().iter().map(SigType::to_microwasm_type),
ty.returns().iter().map(SigType::to_microwasm_type), ty.returns().iter().map(SigType::to_microwasm_type),
body, body,
); )?;
translate( let mut body = Vec::new();
session, for i in microwasm_conv {
reloc_sink, match i {
func_idx, Ok(v) => body.extend(v),
microwasm_conv.flat_map(|i| i.expect("TODO: Make this not panic")), Err(e) => return Err(Error::Microwasm(e.message.to_string())),
) };
}
translate(session, reloc_sink, func_idx, body)?;
Ok(())
} }
pub fn translate<M, I, L: Send + Sync + 'static>( pub fn translate<M, I, L: Send + Sync + 'static>(
@@ -283,7 +287,9 @@ where
entry.remove_entry(); entry.remove_entry();
} }
} else { } else {
panic!("Label defined before being declared"); return Err(Error::Microwasm(
"Label defined before being declared".to_string(),
));
} }
} }
Operator::Block { Operator::Block {

View File

@@ -1,3 +1,4 @@
use crate::error::Error;
use crate::module::{ModuleContext, SigType, Signature}; use crate::module::{ModuleContext, SigType, Signature};
use smallvec::{smallvec, SmallVec}; use smallvec::{smallvec, SmallVec};
use std::{ use std::{
@@ -7,7 +8,7 @@ use std::{
ops::RangeInclusive, ops::RangeInclusive,
}; };
use wasmparser::{ use wasmparser::{
FunctionBody, Ieee32 as WasmIeee32, Ieee64 as WasmIeee64, BinaryReaderError, FunctionBody, Ieee32 as WasmIeee32, Ieee64 as WasmIeee64,
MemoryImmediate as WasmMemoryImmediate, Operator as WasmOperator, OperatorsReader, MemoryImmediate as WasmMemoryImmediate, Operator as WasmOperator, OperatorsReader,
}; };
@@ -274,24 +275,41 @@ pub const SF32: SignfulType = Type::Float(Size::_32);
pub const SF64: SignfulType = Type::Float(Size::_64); pub const SF64: SignfulType = Type::Float(Size::_64);
impl SignlessType { impl SignlessType {
pub fn from_wasm(other: wasmparser::Type) -> Option<Self> { pub fn from_wasm(other: wasmparser::Type) -> Result<Self, BinaryReaderError> {
use wasmparser::Type; use wasmparser::Type;
match other { match other {
Type::I32 => Some(I32), Type::I32 => Ok(I32),
Type::I64 => Some(I64), Type::I64 => Ok(I64),
Type::F32 => Some(F32), Type::F32 => Ok(F32),
Type::F64 => Some(F64), Type::F64 => Ok(F64),
Type::EmptyBlockType => None, Type::EmptyBlockType => {
_ => unimplemented!(), return Err(BinaryReaderError {
message: "SignlessType with EmptyBlockType",
offset: -1isize as usize,
})
}
_ => {
return Err(BinaryReaderError {
message: "SignlessType unimplemented",
offset: -1isize as usize,
})
}
} }
} }
} }
fn create_returns_from_wasm_type(ty: wasmparser::TypeOrFuncType) -> Vec<SignlessType> { fn create_returns_from_wasm_type(
ty: wasmparser::TypeOrFuncType,
) -> Result<Vec<SignlessType>, BinaryReaderError> {
match ty { match ty {
wasmparser::TypeOrFuncType::Type(ty) => Vec::from_iter(Type::from_wasm(ty)), wasmparser::TypeOrFuncType::Type(ty) => Ok(Vec::from_iter(Type::from_wasm(ty))),
wasmparser::TypeOrFuncType::FuncType(_) => panic!("unsupported func type"), wasmparser::TypeOrFuncType::FuncType(_) => {
return Err(BinaryReaderError {
message: "Unsupported func type",
offset: -1isize as usize,
})
}
} }
} }
@@ -1046,17 +1064,19 @@ where
params: impl IntoIterator<Item = SignlessType>, params: impl IntoIterator<Item = SignlessType>,
returns: impl IntoIterator<Item = SignlessType>, returns: impl IntoIterator<Item = SignlessType>,
reader: &'a FunctionBody, reader: &'a FunctionBody,
) -> Self { ) -> Result<Self, Error> {
// TODO: Don't panic!
let locals_reader = reader let locals_reader = reader
.get_locals_reader() .get_locals_reader()
.expect("Failed to get locals reader"); .map_err(|_| Error::Microwasm("Failed to get locals reader".to_string()))?;
let mut locals = Vec::from_iter(params); let mut locals = Vec::from_iter(params);
let mut consts = Vec::new(); let mut consts = Vec::new();
for loc in locals_reader { for loc in locals_reader {
let (count, ty) = loc.expect("Getting local failed"); let (count, ty) =
let ty = Type::from_wasm(ty).expect("Invalid local type"); loc.map_err(|_| Error::Microwasm("Getting local failed".to_string()))?;
let ty = Type::from_wasm(ty)
.map_err(|_| Error::Microwasm("Invalid local type".to_string()))?;
locals.extend(std::iter::repeat(ty).take(count as _)); locals.extend(std::iter::repeat(ty).take(count as _));
consts.extend( consts.extend(
std::iter::repeat(ty) std::iter::repeat(ty)
@@ -1067,14 +1087,15 @@ where
let num_locals = locals.len() as _; let num_locals = locals.len() as _;
let operators_reader = reader
.get_operators_reader()
.map_err(|_| Error::Microwasm("Failed to get operators reader".to_string()))?;
let mut out = Self { let mut out = Self {
is_done: false, is_done: false,
stack: locals, stack: locals,
module: context, module: context,
consts_to_emit: Some(consts), consts_to_emit: Some(consts),
internal: reader internal: operators_reader,
.get_operators_reader()
.expect("Failed to get operators reader"),
current_id: 0, current_id: 0,
control_frames: vec![], control_frames: vec![],
unreachable: false, unreachable: false,
@@ -1088,10 +1109,10 @@ where
kind: ControlFrameKind::Function, kind: ControlFrameKind::Function,
}); });
out Ok(out)
} }
fn op_sig(&self, op: &WasmOperator) -> OpSig { fn op_sig(&self, op: &WasmOperator) -> Result<OpSig, BinaryReaderError> {
use self::SigT::T; use self::SigT::T;
use std::iter::{empty as none, once}; use std::iter::{empty as none, once};
@@ -1132,7 +1153,7 @@ where
}; };
} }
match op { let o = match op {
WasmOperator::Unreachable => OpSig::none(), WasmOperator::Unreachable => OpSig::none(),
WasmOperator::Nop => OpSig::none(), WasmOperator::Nop => OpSig::none(),
@@ -1221,8 +1242,18 @@ where
WasmOperator::F32Const { .. } => sig!(() -> (F32)), WasmOperator::F32Const { .. } => sig!(() -> (F32)),
WasmOperator::F64Const { .. } => sig!(() -> (F64)), WasmOperator::F64Const { .. } => sig!(() -> (F64)),
WasmOperator::RefNull => unimplemented!(), WasmOperator::RefNull => {
WasmOperator::RefIsNull => unimplemented!(), return Err(BinaryReaderError {
message: "RefNull unimplemented",
offset: -1isize as usize,
})
}
WasmOperator::RefIsNull => {
return Err(BinaryReaderError {
message: "RefIsNull unimplemented",
offset: -1isize as usize,
})
}
// All comparison operators remove 2 elements and push 1 // All comparison operators remove 2 elements and push 1
WasmOperator::I32Eqz => sig!((I32) -> (I32)), WasmOperator::I32Eqz => sig!((I32) -> (I32)),
@@ -1357,8 +1388,14 @@ where
WasmOperator::I64Extend16S => sig!((I32) -> (I64)), WasmOperator::I64Extend16S => sig!((I32) -> (I64)),
WasmOperator::I64Extend32S => sig!((I32) -> (I64)), WasmOperator::I64Extend32S => sig!((I32) -> (I64)),
_ => unimplemented!(), _ => {
return Err(BinaryReaderError {
message: "Opcode Unimplemented",
offset: -1isize as usize,
})
} }
};
Ok(o)
} }
fn next_id(&mut self) -> u32 { fn next_id(&mut self) -> u32 {
@@ -1383,14 +1420,19 @@ where
self.stack.len() as i32 - 1 - idx as i32 self.stack.len() as i32 - 1 - idx as i32
} }
fn apply_op(&mut self, sig: OpSig) { fn apply_op(&mut self, sig: OpSig) -> Result<(), BinaryReaderError> {
let mut ty_param = None; let mut ty_param = None;
for p in sig.input.iter().rev() { for p in sig.input.iter().rev() {
let stack_ty = self let stack_ty = match self.stack.pop() {
.stack Some(e) => e,
.pop() None => {
.unwrap_or_else(|| panic!("Stack is empty (while processing {:?})", sig)); return Err(BinaryReaderError {
message: "Stack is empty",
offset: -1isize as usize,
})
}
};
let ty = match p { let ty = match p {
SigT::T => { SigT::T => {
@@ -1409,21 +1451,34 @@ where
for p in sig.output.into_iter().rev() { for p in sig.output.into_iter().rev() {
let ty = match p { let ty = match p {
SigT::T => ty_param.expect("Type parameter was not set"), SigT::T => match ty_param {
Some(e) => e,
None => {
return Err(BinaryReaderError {
message: "Type parameter was not set",
offset: -1isize as usize,
})
}
},
SigT::Concrete(ty) => ty, SigT::Concrete(ty) => ty,
}; };
self.stack.push(ty); self.stack.push(ty);
} }
Ok(())
} }
fn block_params(&self) -> Vec<SignlessType> { fn block_params(&self) -> Vec<SignlessType> {
self.stack.clone() self.stack.clone()
} }
fn block_params_with_wasm_type(&self, ty: wasmparser::TypeOrFuncType) -> Vec<SignlessType> { fn block_params_with_wasm_type(
&self,
ty: wasmparser::TypeOrFuncType,
) -> Result<Vec<SignlessType>, BinaryReaderError> {
let mut out = self.block_params(); let mut out = self.block_params();
out.extend(create_returns_from_wasm_type(ty)); let return_wasm_type = create_returns_from_wasm_type(ty)?;
out out.extend(return_wasm_type);
Ok(out)
} }
} }
@@ -1483,7 +1538,15 @@ where
} }
WasmOperator::Else => { WasmOperator::Else => {
if depth == 0 { if depth == 0 {
let block = self.control_frames.last_mut().expect("Failed"); let block = match self.control_frames.last_mut() {
Some(e) => e,
None => {
return Some(Err(BinaryReaderError {
message: "unreachable Block else Failed",
offset: -1isize as usize,
}))
}
};
self.stack.truncate(block.arguments as _); self.stack.truncate(block.arguments as _);
@@ -1496,7 +1559,15 @@ where
} }
WasmOperator::End => { WasmOperator::End => {
if depth == 0 { if depth == 0 {
let block = self.control_frames.pop().expect("Failed"); let block = match self.control_frames.pop() {
Some(e) => e,
None => {
return Some(Err(BinaryReaderError {
message: "unreachable Block end Failed",
offset: -1isize as usize,
}))
}
};
if self.control_frames.is_empty() { if self.control_frames.is_empty() {
self.is_done = true; self.is_done = true;
@@ -1536,9 +1607,15 @@ where
Ok(o) => o, Ok(o) => o,
}; };
let op_sig = self.op_sig(&op); let op_sig = match self.op_sig(&op) {
Ok(o) => o,
Err(e) => return Some(Err(e)),
};
self.apply_op(op_sig); match self.apply_op(op_sig) {
Ok(o) => o,
Err(e) => return Some(Err(e)),
};
Some(Ok(match op { Some(Ok(match op {
WasmOperator::Unreachable => { WasmOperator::Unreachable => {
@@ -1548,31 +1625,44 @@ where
WasmOperator::Nop => smallvec![], WasmOperator::Nop => smallvec![],
WasmOperator::Block { ty } => { WasmOperator::Block { ty } => {
let id = self.next_id(); let id = self.next_id();
let return_type_wasm = match create_returns_from_wasm_type(ty) {
Ok(o) => o,
Err(e) => return Some(Err(e)),
};
let block_param_type_wasm = match self.block_params_with_wasm_type(ty) {
Err(e) => return Some(Err(e)),
Ok(o) => o,
};
self.control_frames.push(ControlFrame { self.control_frames.push(ControlFrame {
id, id,
arguments: self.stack.len() as u32, arguments: self.stack.len() as u32,
returns: create_returns_from_wasm_type(ty), returns: return_type_wasm,
kind: ControlFrameKind::Block { kind: ControlFrameKind::Block {
needs_end_label: false, needs_end_label: false,
}, },
}); });
smallvec![Operator::end( smallvec![Operator::end(block_param_type_wasm, (id, NameTag::End))]
self.block_params_with_wasm_type(ty),
(id, NameTag::End),
)]
} }
WasmOperator::Loop { ty } => { WasmOperator::Loop { ty } => {
let id = self.next_id(); let id = self.next_id();
let return_type_wasm = match create_returns_from_wasm_type(ty) {
Ok(o) => o,
Err(e) => return Some(Err(e)),
};
let block_param_type_wasm = match self.block_params_with_wasm_type(ty) {
Ok(o) => o,
Err(e) => return Some(Err(e)),
};
self.control_frames.push(ControlFrame { self.control_frames.push(ControlFrame {
id, id,
arguments: self.stack.len() as u32, arguments: self.stack.len() as u32,
returns: create_returns_from_wasm_type(ty), returns: return_type_wasm,
kind: ControlFrameKind::Loop, kind: ControlFrameKind::Loop,
}); });
let label = (id, NameTag::Header); let label = (id, NameTag::Header);
smallvec![ smallvec![
Operator::loop_(self.block_params(), label), Operator::loop_(self.block_params(), label),
Operator::end(self.block_params_with_wasm_type(ty), (id, NameTag::End)), Operator::end(block_param_type_wasm, (id, NameTag::End)),
Operator::Br { Operator::Br {
target: BrTarget::Label(label), target: BrTarget::Label(label),
}, },
@@ -1581,10 +1671,18 @@ where
} }
WasmOperator::If { ty } => { WasmOperator::If { ty } => {
let id = self.next_id(); let id = self.next_id();
let return_type_wasm = match create_returns_from_wasm_type(ty) {
Ok(o) => o,
Err(e) => return Some(Err(e)),
};
let block_param_type_wasm = match self.block_params_with_wasm_type(ty) {
Ok(o) => o,
Err(e) => return Some(Err(e)),
};
self.control_frames.push(ControlFrame { self.control_frames.push(ControlFrame {
id, id,
arguments: self.stack.len() as u32, arguments: self.stack.len() as u32,
returns: create_returns_from_wasm_type(ty), returns: return_type_wasm,
kind: ControlFrameKind::If { has_else: false }, kind: ControlFrameKind::If { has_else: false },
}); });
let (then, else_, end) = ( let (then, else_, end) = (
@@ -1595,7 +1693,7 @@ where
smallvec![ smallvec![
Operator::block(self.block_params(), then), Operator::block(self.block_params(), then),
Operator::block(self.block_params(), else_), Operator::block(self.block_params(), else_),
Operator::end(self.block_params_with_wasm_type(ty), end), Operator::end(block_param_type_wasm, end),
Operator::BrIf { Operator::BrIf {
then: BrTarget::Label(then).into(), then: BrTarget::Label(then).into(),
else_: BrTarget::Label(else_).into() else_: BrTarget::Label(else_).into()
@@ -1605,8 +1703,25 @@ where
} }
WasmOperator::Else => { WasmOperator::Else => {
// We don't pop it since we're still in the second block. // We don't pop it since we're still in the second block.
let to_drop = to_drop!(self.control_frames.last().expect("Failed")); let block = match self.control_frames.last() {
let block = self.control_frames.last_mut().expect("Failed"); Some(e) => e,
None => {
return Some(Err(BinaryReaderError {
message: "Block else Failed",
offset: -1isize as usize,
}))
}
};
let to_drop = to_drop!(block);
let block = match self.control_frames.last_mut() {
Some(e) => e,
None => {
return Some(Err(BinaryReaderError {
message: "Block else Failed",
offset: -1isize as usize,
}))
}
};
if let ControlFrameKind::If { has_else, .. } = &mut block.kind { if let ControlFrameKind::If { has_else, .. } = &mut block.kind {
*has_else = true; *has_else = true;
@@ -1627,7 +1742,15 @@ where
) )
} }
WasmOperator::End => { WasmOperator::End => {
let block = self.control_frames.pop().expect("Failed"); let block = match self.control_frames.pop() {
Some(e) => e,
None => {
return Some(Err(BinaryReaderError {
message: "Block End Failed",
offset: -1isize as usize,
}))
}
};
let to_drop = to_drop!(block); let to_drop = to_drop!(block);
@@ -1772,25 +1895,47 @@ where
WasmOperator::GetLocal { local_index } => { WasmOperator::GetLocal { local_index } => {
// `- 1` because we apply the stack difference _before_ this point // `- 1` because we apply the stack difference _before_ this point
let depth = self.local_depth(local_index) - 1; let depth = self.local_depth(local_index).checked_sub(1)?;
smallvec![Operator::Pick( let depth = match depth.try_into() {
depth.try_into().expect("Local out of range") Ok(o) => o,
)] Err(_) => {
return Some(Err(BinaryReaderError {
message: "GetLocal - Local out of range",
offset: -1isize as usize,
}))
}
};
smallvec![Operator::Pick(depth)]
} }
WasmOperator::SetLocal { local_index } => { WasmOperator::SetLocal { local_index } => {
// `+ 1` because we apply the stack difference _before_ this point // `+ 1` because we apply the stack difference _before_ this point
let depth = self.local_depth(local_index) + 1; let depth = self.local_depth(local_index).checked_add(1)?;
smallvec![ let depth = match depth.try_into() {
Operator::Swap(depth.try_into().expect("Local out of range")), Ok(o) => o,
Operator::Drop(0..=0) Err(_) => {
] return Some(Err(BinaryReaderError {
message: "SetLocal - Local out of range",
offset: -1isize as usize,
}))
}
};
smallvec![Operator::Swap(depth), Operator::Drop(0..=0)]
} }
WasmOperator::TeeLocal { local_index } => { WasmOperator::TeeLocal { local_index } => {
// `+ 1` because we `pick` before `swap` // `+ 1` because we `pick` before `swap`
let depth = self.local_depth(local_index) + 1; let depth = self.local_depth(local_index).checked_add(1)?;
let depth = match depth.try_into() {
Ok(o) => o,
Err(_) => {
return Some(Err(BinaryReaderError {
message: "SetLocal - Local out of range",
offset: -1isize as usize,
}))
}
};
smallvec![ smallvec![
Operator::Pick(0), Operator::Pick(0),
Operator::Swap(depth.try_into().expect("Local out of range")), Operator::Swap(depth),
Operator::Drop(0..=0), Operator::Drop(0..=0),
] ]
} }
@@ -1904,8 +2049,18 @@ where
WasmOperator::F64Const { value } => { WasmOperator::F64Const { value } => {
smallvec![Operator::Const(Value::F64(value.into()))] smallvec![Operator::Const(Value::F64(value.into()))]
} }
WasmOperator::RefNull => unimplemented!("{:?}", op), WasmOperator::RefNull => {
WasmOperator::RefIsNull => unimplemented!("{:?}", op), return Some(Err(BinaryReaderError {
message: "RefNull unimplemented",
offset: -1isize as usize,
}))
}
WasmOperator::RefIsNull => {
return Some(Err(BinaryReaderError {
message: "RefIsNull unimplemented",
offset: -1isize as usize,
}))
}
WasmOperator::I32Eqz => smallvec![Operator::Eqz(Size::_32)], WasmOperator::I32Eqz => smallvec![Operator::Eqz(Size::_32)],
WasmOperator::I32Eq => smallvec![Operator::Eq(I32)], WasmOperator::I32Eq => smallvec![Operator::Eq(I32)],
WasmOperator::I32Ne => smallvec![Operator::Ne(I32)], WasmOperator::I32Ne => smallvec![Operator::Ne(I32)],
@@ -2086,24 +2241,94 @@ where
WasmOperator::I64ReinterpretF64 => smallvec![Operator::I64ReinterpretFromF64], WasmOperator::I64ReinterpretF64 => smallvec![Operator::I64ReinterpretFromF64],
WasmOperator::F32ReinterpretI32 => smallvec![Operator::F32ReinterpretFromI32], WasmOperator::F32ReinterpretI32 => smallvec![Operator::F32ReinterpretFromI32],
WasmOperator::F64ReinterpretI64 => smallvec![Operator::F64ReinterpretFromI64], WasmOperator::F64ReinterpretI64 => smallvec![Operator::F64ReinterpretFromI64],
WasmOperator::I32Extend8S => unimplemented!("{:?}", op), WasmOperator::I32Extend8S => {
WasmOperator::I32Extend16S => unimplemented!("{:?}", op), return Some(Err(BinaryReaderError {
WasmOperator::I64Extend8S => unimplemented!("{:?}", op), message: "I32Extend8S unimplemented",
WasmOperator::I64Extend16S => unimplemented!("{:?}", op), offset: -1isize as usize,
WasmOperator::I64Extend32S => unimplemented!("{:?}", op), }))
}
WasmOperator::I32Extend16S => {
return Some(Err(BinaryReaderError {
message: "I32Extend16S unimplemented",
offset: -1isize as usize,
}))
}
WasmOperator::I64Extend8S => {
return Some(Err(BinaryReaderError {
message: "I64Extend8S unimplemented",
offset: -1isize as usize,
}))
}
WasmOperator::I64Extend16S => {
return Some(Err(BinaryReaderError {
message: "I64Extend16S unimplemented",
offset: -1isize as usize,
}))
}
WasmOperator::I64Extend32S => {
return Some(Err(BinaryReaderError {
message: "I64Extend32S unimplemented",
offset: -1isize as usize,
}))
}
// 0xFC operators // 0xFC operators
// Non-trapping Float-to-int Conversions // Non-trapping Float-to-int Conversions
WasmOperator::I32TruncSSatF32 => unimplemented!("{:?}", op), WasmOperator::I32TruncSSatF32 => {
WasmOperator::I32TruncUSatF32 => unimplemented!("{:?}", op), return Some(Err(BinaryReaderError {
WasmOperator::I32TruncSSatF64 => unimplemented!("{:?}", op), message: "I32TruncSSatF32 unimplemented",
WasmOperator::I32TruncUSatF64 => unimplemented!("{:?}", op), offset: -1isize as usize,
WasmOperator::I64TruncSSatF32 => unimplemented!("{:?}", op), }))
WasmOperator::I64TruncUSatF32 => unimplemented!("{:?}", op), }
WasmOperator::I64TruncSSatF64 => unimplemented!("{:?}", op), WasmOperator::I32TruncUSatF32 => {
WasmOperator::I64TruncUSatF64 => unimplemented!("{:?}", op), return Some(Err(BinaryReaderError {
message: "I32TruncUSatF32 unimplemented",
offset: -1isize as usize,
}))
}
WasmOperator::I32TruncSSatF64 => {
return Some(Err(BinaryReaderError {
message: "I32TruncSSatF64 unimplemented",
offset: -1isize as usize,
}))
}
WasmOperator::I32TruncUSatF64 => {
return Some(Err(BinaryReaderError {
message: "I32TruncUSatF64 unimplemented",
offset: -1isize as usize,
}))
}
WasmOperator::I64TruncSSatF32 => {
return Some(Err(BinaryReaderError {
message: "I64TruncSSatF32 unimplemented",
offset: -1isize as usize,
}))
}
WasmOperator::I64TruncUSatF32 => {
return Some(Err(BinaryReaderError {
message: "I64TruncUSatF32 unimplemented",
offset: -1isize as usize,
}))
}
WasmOperator::I64TruncSSatF64 => {
return Some(Err(BinaryReaderError {
message: "I64TruncSSatF64 unimplemented",
offset: -1isize as usize,
}))
}
WasmOperator::I64TruncUSatF64 => {
return Some(Err(BinaryReaderError {
message: "I64TruncUSatF64 unimplemented",
offset: -1isize as usize,
}))
}
other => unimplemented!("{:?}", other), _other => {
return Some(Err(BinaryReaderError {
message: "Opcode unimplemented",
offset: -1isize as usize,
}))
}
})) }))
} }
} }