From acf8ad0df7b6373946a85de97bf0e770dede6591 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 22 May 2020 15:00:52 -0700 Subject: [PATCH] cranelift_wasm: expose the original Wasm function signature In the `ModuleEnvironment::declare_signature` callback, also pass the original Wasm function signature, so that consumers may associate this information with each compiled function. This is often necessary because while each Wasm signature gets compiled down into a single native signature, multiple Wasm signatures might compile down into the same native signature, and in these cases the original Wasm signature is required for dynamic type checking of calls. --- cranelift/wasm/src/environ/dummy.rs | 5 ++- cranelift/wasm/src/environ/mod.rs | 2 +- cranelift/wasm/src/environ/spec.rs | 13 ++++++- cranelift/wasm/src/lib.rs | 2 +- cranelift/wasm/src/sections_translator.rs | 46 +++++++++-------------- crates/environ/src/module_environ.rs | 4 +- 6 files changed, 36 insertions(+), 36 deletions(-) diff --git a/cranelift/wasm/src/environ/dummy.rs b/cranelift/wasm/src/environ/dummy.rs index d5c9d63e40..671414bcb6 100644 --- a/cranelift/wasm/src/environ/dummy.rs +++ b/cranelift/wasm/src/environ/dummy.rs @@ -6,7 +6,8 @@ //! [Wasmtime]: https://github.com/bytecodealliance/wasmtime use crate::environ::{ - FuncEnvironment, GlobalVariable, ModuleEnvironment, ReturnMode, TargetEnvironment, WasmResult, + FuncEnvironment, GlobalVariable, ModuleEnvironment, ReturnMode, TargetEnvironment, + WasmFuncType, WasmResult, }; use crate::func_translator::FuncTranslator; use crate::state::ModuleTranslationState; @@ -534,7 +535,7 @@ impl TargetEnvironment for DummyEnvironment { } impl<'data> ModuleEnvironment<'data> for DummyEnvironment { - fn declare_signature(&mut self, sig: ir::Signature) -> WasmResult<()> { + fn declare_signature(&mut self, _wasm: &WasmFuncType, sig: ir::Signature) -> WasmResult<()> { self.info.signatures.push(sig); Ok(()) } diff --git a/cranelift/wasm/src/environ/mod.rs b/cranelift/wasm/src/environ/mod.rs index 1cdb0b292a..bb4b7cc34e 100644 --- a/cranelift/wasm/src/environ/mod.rs +++ b/cranelift/wasm/src/environ/mod.rs @@ -7,5 +7,5 @@ mod spec; pub use crate::environ::dummy::DummyEnvironment; pub use crate::environ::spec::{ FuncEnvironment, GlobalVariable, ModuleEnvironment, ReturnMode, TargetEnvironment, WasmError, - WasmResult, + WasmFuncType, WasmResult, WasmType, }; diff --git a/cranelift/wasm/src/environ/spec.rs b/cranelift/wasm/src/environ/spec.rs index aeec47cede..0473ad3c5a 100644 --- a/cranelift/wasm/src/environ/spec.rs +++ b/cranelift/wasm/src/environ/spec.rs @@ -22,6 +22,13 @@ use thiserror::Error; use wasmparser::BinaryReaderError; use wasmparser::Operator; +// Re-export `wasmparser`'s function and value types so that consumers can +// associate this the original Wasm signature with each compiled function. This +// is often necessary because while each Wasm signature gets compiled down into +// a single native signature, multiple Wasm signatures might compile down into +// the same native signature. +pub use wasmparser::{FuncType as WasmFuncType, Type as WasmType}; + /// The value of a WebAssembly global variable. #[derive(Clone, Copy)] pub enum GlobalVariable { @@ -472,7 +479,11 @@ pub trait ModuleEnvironment<'data>: TargetEnvironment { } /// Declares a function signature to the environment. - fn declare_signature(&mut self, sig: ir::Signature) -> WasmResult<()>; + fn declare_signature( + &mut self, + wasm_func_type: &WasmFuncType, + sig: ir::Signature, + ) -> WasmResult<()>; /// Provides the number of imports up front. By default this does nothing, but /// implementations can use this to preallocate memory if desired. diff --git a/cranelift/wasm/src/lib.rs b/cranelift/wasm/src/lib.rs index 366dd7a0dc..b3836fd251 100644 --- a/cranelift/wasm/src/lib.rs +++ b/cranelift/wasm/src/lib.rs @@ -59,7 +59,7 @@ mod translation_utils; pub use crate::environ::{ DummyEnvironment, FuncEnvironment, GlobalVariable, ModuleEnvironment, ReturnMode, - TargetEnvironment, WasmError, WasmResult, + TargetEnvironment, WasmError, WasmFuncType, WasmResult, WasmType, }; pub use crate::func_translator::FuncTranslator; pub use crate::module_translator::translate_module; diff --git a/cranelift/wasm/src/sections_translator.rs b/cranelift/wasm/src/sections_translator.rs index bb51945d69..967612178a 100644 --- a/cranelift/wasm/src/sections_translator.rs +++ b/cranelift/wasm/src/sections_translator.rs @@ -23,7 +23,7 @@ use std::boxed::Box; use std::vec::Vec; use wasmparser::{ self, CodeSectionReader, Data, DataKind, DataSectionReader, Element, ElementItem, ElementItems, - ElementKind, ElementSectionReader, Export, ExportSectionReader, ExternalKind, FuncType, + ElementKind, ElementSectionReader, Export, ExportSectionReader, ExternalKind, FunctionSectionReader, GlobalSectionReader, GlobalType, ImportSectionEntryType, ImportSectionReader, MemorySectionReader, MemoryType, NameSectionReader, Naming, NamingReader, Operator, TableSectionReader, Type, TypeSectionReader, @@ -40,34 +40,22 @@ pub fn parse_type_section( environ.reserve_signatures(count)?; for entry in types { - match entry? { - FuncType { - form: wasmparser::Type::Func, - params, - returns, - } => { - let mut sig = - Signature::new(ModuleEnvironment::target_config(environ).default_call_conv); - sig.params.extend(params.iter().map(|ty| { - let cret_arg: ir::Type = type_to_type(*ty, environ) - .expect("only numeric types are supported in function signatures"); - AbiParam::new(cret_arg) - })); - sig.returns.extend(returns.iter().map(|ty| { - let cret_arg: ir::Type = type_to_type(*ty, environ) - .expect("only numeric types are supported in function signatures"); - AbiParam::new(cret_arg) - })); - environ.declare_signature(sig)?; - module_translation_state.wasm_types.push((params, returns)); - } - ty => { - return Err(wasm_unsupported!( - "unsupported type in type section: {:?}", - ty - )) - } - } + let wasm_func_ty = entry?; + let mut sig = Signature::new(ModuleEnvironment::target_config(environ).default_call_conv); + sig.params.extend(wasm_func_ty.params.iter().map(|ty| { + let cret_arg: ir::Type = type_to_type(*ty, environ) + .expect("only numeric types are supported in function signatures"); + AbiParam::new(cret_arg) + })); + sig.returns.extend(wasm_func_ty.returns.iter().map(|ty| { + let cret_arg: ir::Type = type_to_type(*ty, environ) + .expect("only numeric types are supported in function signatures"); + AbiParam::new(cret_arg) + })); + environ.declare_signature(&wasm_func_ty, sig)?; + module_translation_state + .wasm_types + .push((wasm_func_ty.params, wasm_func_ty.returns)); } Ok(()) } diff --git a/crates/environ/src/module_environ.rs b/crates/environ/src/module_environ.rs index 118570b124..9061775d66 100644 --- a/crates/environ/src/module_environ.rs +++ b/crates/environ/src/module_environ.rs @@ -7,7 +7,7 @@ use cranelift_entity::PrimaryMap; use cranelift_wasm::{ self, translate_module, DataIndex, DefinedFuncIndex, ElemIndex, FuncIndex, Global, GlobalIndex, Memory, MemoryIndex, ModuleTranslationState, SignatureIndex, Table, TableIndex, - TargetEnvironment, WasmError, WasmResult, + TargetEnvironment, WasmError, WasmFuncType, WasmResult, }; use std::convert::TryFrom; use std::sync::Arc; @@ -106,7 +106,7 @@ impl<'data> cranelift_wasm::ModuleEnvironment<'data> for ModuleEnvironment<'data Ok(()) } - fn declare_signature(&mut self, sig: ir::Signature) -> WasmResult<()> { + fn declare_signature(&mut self, _wasm: &WasmFuncType, sig: ir::Signature) -> WasmResult<()> { let sig = translate_signature(sig, self.pointer_type()); // TODO: Deduplicate signatures. self.result.module.local.signatures.push(sig);