From f6ac165ff67b594adab7c9d6c226a6dc82ca22b3 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Mon, 1 Jul 2019 12:23:14 +0200 Subject: [PATCH] [wasm] Don't panic when seeing unexpected types but properly fail instead; --- cranelift/wasm/src/code_translator.rs | 6 ++-- cranelift/wasm/src/sections_translator.rs | 20 ++++++------- cranelift/wasm/src/translation_utils.rs | 36 +++++++++++++++++------ 3 files changed, 40 insertions(+), 22 deletions(-) diff --git a/cranelift/wasm/src/code_translator.rs b/cranelift/wasm/src/code_translator.rs index 839e178f7e..6365ed7e68 100644 --- a/cranelift/wasm/src/code_translator.rs +++ b/cranelift/wasm/src/code_translator.rs @@ -135,7 +135,7 @@ pub fn translate_operator( if let Ok(ty_cre) = blocktype_to_type(ty) { builder.append_ebb_param(next, ty_cre); } - state.push_block(next, num_return_values(ty)); + state.push_block(next, num_return_values(ty)?); } Operator::Loop { ty } => { let loop_body = builder.create_ebb(); @@ -144,7 +144,7 @@ pub fn translate_operator( builder.append_ebb_param(next, ty_cre); } builder.ins().jump(loop_body, &[]); - state.push_loop(loop_body, next, num_return_values(ty)); + state.push_loop(loop_body, next, num_return_values(ty)?); builder.switch_to_block(loop_body); environ.translate_loop_header(builder.cursor())?; } @@ -161,7 +161,7 @@ pub fn translate_operator( if let Ok(ty_cre) = blocktype_to_type(ty) { builder.append_ebb_param(if_not, ty_cre); } - state.push_if(jump_inst, if_not, num_return_values(ty)); + state.push_if(jump_inst, if_not, num_return_values(ty)?); } Operator::Else => { // We take the control frame pushed by the if, use its ebb as the else body diff --git a/cranelift/wasm/src/sections_translator.rs b/cranelift/wasm/src/sections_translator.rs index 1236e943dc..f0975d9643 100644 --- a/cranelift/wasm/src/sections_translator.rs +++ b/cranelift/wasm/src/sections_translator.rs @@ -7,10 +7,10 @@ //! The special case of the initialize expressions for table elements offsets or global variables //! is handled, according to the semantics of WebAssembly, to only specific expressions that are //! interpreted on the fly. -use crate::environ::{ModuleEnvironment, WasmResult}; +use crate::environ::{ModuleEnvironment, WasmError, WasmResult}; use crate::translation_utils::{ - type_to_type, FuncIndex, Global, GlobalIndex, GlobalInit, Memory, MemoryIndex, SignatureIndex, - Table, TableElementType, TableIndex, + tabletype_to_type, type_to_type, FuncIndex, Global, GlobalIndex, GlobalInit, Memory, + MemoryIndex, SignatureIndex, Table, TableElementType, TableIndex, }; use core::convert::TryFrom; use cranelift_codegen::ir::{self, AbiParam, Signature}; @@ -51,7 +51,7 @@ pub fn parse_type_section( })); environ.declare_signature(sig); } - ref s => panic!("unsupported type: {:?}", s), + _ => return Err(WasmError::Unsupported("unsupported type in type section")), } } Ok(()) @@ -101,9 +101,9 @@ pub fn parse_import_section<'data>( ImportSectionEntryType::Table(ref tab) => { environ.declare_table_import( Table { - ty: match type_to_type(tab.element_type) { - Ok(t) => TableElementType::Val(t), - Err(()) => TableElementType::Func, + ty: match tabletype_to_type(tab.element_type)? { + Some(t) => TableElementType::Val(t), + None => TableElementType::Func, }, minimum: tab.limits.initial, maximum: tab.limits.maximum, @@ -144,9 +144,9 @@ pub fn parse_table_section( for entry in tables { let table = entry?; environ.declare_table(Table { - ty: match type_to_type(table.element_type) { - Ok(t) => TableElementType::Val(t), - Err(()) => TableElementType::Func, + ty: match tabletype_to_type(table.element_type)? { + Some(t) => TableElementType::Val(t), + None => TableElementType::Func, }, minimum: table.limits.initial, maximum: table.limits.maximum, diff --git a/cranelift/wasm/src/translation_utils.rs b/cranelift/wasm/src/translation_utils.rs index 18d69c7641..c221f751ff 100644 --- a/cranelift/wasm/src/translation_utils.rs +++ b/cranelift/wasm/src/translation_utils.rs @@ -1,4 +1,5 @@ //! Helper functions and structures for the translation. +use crate::environ::{WasmError, WasmResult}; use core::u32; use cranelift_codegen::entity::entity_impl; use cranelift_codegen::ir; @@ -109,21 +110,36 @@ pub struct Memory { } /// Helper function translating wasmparser types to Cranelift types when possible. -pub fn type_to_type(ty: wasmparser::Type) -> Result { +pub fn type_to_type(ty: wasmparser::Type) -> WasmResult { Ok(match ty { wasmparser::Type::I32 => ir::types::I32, wasmparser::Type::I64 => ir::types::I64, wasmparser::Type::F32 => ir::types::F32, wasmparser::Type::F64 => ir::types::F64, - _ => return Err(()), + _ => return Err(WasmError::Unsupported("unsupported wasm type")), + }) +} + +/// Helper function translating wasmparser possible table types to Cranelift types when possible, +/// or None for Func tables. +pub fn tabletype_to_type(ty: wasmparser::Type) -> WasmResult> { + Ok(match ty { + wasmparser::Type::I32 => Some(ir::types::I32), + wasmparser::Type::I64 => Some(ir::types::I64), + wasmparser::Type::F32 => Some(ir::types::F32), + wasmparser::Type::F64 => Some(ir::types::F64), + wasmparser::Type::AnyFunc => None, + _ => return Err(WasmError::Unsupported("unsupported table wasm type")), }) } /// Helper function translating wasmparser block signatures to Cranelift types when possible. -pub fn blocktype_to_type(ty: wasmparser::TypeOrFuncType) -> Result { +pub fn blocktype_to_type(ty: wasmparser::TypeOrFuncType) -> WasmResult { match ty { wasmparser::TypeOrFuncType::Type(ty) => type_to_type(ty), - wasmparser::TypeOrFuncType::FuncType(_) => unimplemented!("multi-value block signatures"), + wasmparser::TypeOrFuncType::FuncType(_) => { + Err(WasmError::Unsupported("multi-value block signatures")) + } } } @@ -138,17 +154,19 @@ pub fn f64_translation(x: wasmparser::Ieee64) -> ir::immediates::Ieee64 { } /// Translate a `wasmparser` type into its `Cranelift` equivalent, when possible -pub fn num_return_values(ty: wasmparser::TypeOrFuncType) -> usize { +pub fn num_return_values(ty: wasmparser::TypeOrFuncType) -> WasmResult { match ty { wasmparser::TypeOrFuncType::Type(ty) => match ty { - wasmparser::Type::EmptyBlockType => 0, + wasmparser::Type::EmptyBlockType => Ok(0), wasmparser::Type::I32 | wasmparser::Type::F32 | wasmparser::Type::I64 - | wasmparser::Type::F64 => 1, - _ => panic!("unsupported return value type"), + | wasmparser::Type::F64 => Ok(1), + _ => Err(WasmError::Unsupported("unsupported return value type")), }, - wasmparser::TypeOrFuncType::FuncType(_) => unimplemented!("multi-value block signatures"), + wasmparser::TypeOrFuncType::FuncType(_) => { + Err(WasmError::Unsupported("multi-value block signatures")) + } } }