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.
This commit is contained in:
@@ -6,7 +6,8 @@
|
|||||||
//! [Wasmtime]: https://github.com/bytecodealliance/wasmtime
|
//! [Wasmtime]: https://github.com/bytecodealliance/wasmtime
|
||||||
|
|
||||||
use crate::environ::{
|
use crate::environ::{
|
||||||
FuncEnvironment, GlobalVariable, ModuleEnvironment, ReturnMode, TargetEnvironment, WasmResult,
|
FuncEnvironment, GlobalVariable, ModuleEnvironment, ReturnMode, TargetEnvironment,
|
||||||
|
WasmFuncType, WasmResult,
|
||||||
};
|
};
|
||||||
use crate::func_translator::FuncTranslator;
|
use crate::func_translator::FuncTranslator;
|
||||||
use crate::state::ModuleTranslationState;
|
use crate::state::ModuleTranslationState;
|
||||||
@@ -534,7 +535,7 @@ impl TargetEnvironment for DummyEnvironment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'data> ModuleEnvironment<'data> 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);
|
self.info.signatures.push(sig);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,5 +7,5 @@ mod spec;
|
|||||||
pub use crate::environ::dummy::DummyEnvironment;
|
pub use crate::environ::dummy::DummyEnvironment;
|
||||||
pub use crate::environ::spec::{
|
pub use crate::environ::spec::{
|
||||||
FuncEnvironment, GlobalVariable, ModuleEnvironment, ReturnMode, TargetEnvironment, WasmError,
|
FuncEnvironment, GlobalVariable, ModuleEnvironment, ReturnMode, TargetEnvironment, WasmError,
|
||||||
WasmResult,
|
WasmFuncType, WasmResult, WasmType,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,6 +22,13 @@ use thiserror::Error;
|
|||||||
use wasmparser::BinaryReaderError;
|
use wasmparser::BinaryReaderError;
|
||||||
use wasmparser::Operator;
|
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.
|
/// The value of a WebAssembly global variable.
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum GlobalVariable {
|
pub enum GlobalVariable {
|
||||||
@@ -472,7 +479,11 @@ pub trait ModuleEnvironment<'data>: TargetEnvironment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Declares a function signature to the environment.
|
/// 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
|
/// Provides the number of imports up front. By default this does nothing, but
|
||||||
/// implementations can use this to preallocate memory if desired.
|
/// implementations can use this to preallocate memory if desired.
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ mod translation_utils;
|
|||||||
|
|
||||||
pub use crate::environ::{
|
pub use crate::environ::{
|
||||||
DummyEnvironment, FuncEnvironment, GlobalVariable, ModuleEnvironment, ReturnMode,
|
DummyEnvironment, FuncEnvironment, GlobalVariable, ModuleEnvironment, ReturnMode,
|
||||||
TargetEnvironment, WasmError, WasmResult,
|
TargetEnvironment, WasmError, WasmFuncType, WasmResult, WasmType,
|
||||||
};
|
};
|
||||||
pub use crate::func_translator::FuncTranslator;
|
pub use crate::func_translator::FuncTranslator;
|
||||||
pub use crate::module_translator::translate_module;
|
pub use crate::module_translator::translate_module;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ use std::boxed::Box;
|
|||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
use wasmparser::{
|
use wasmparser::{
|
||||||
self, CodeSectionReader, Data, DataKind, DataSectionReader, Element, ElementItem, ElementItems,
|
self, CodeSectionReader, Data, DataKind, DataSectionReader, Element, ElementItem, ElementItems,
|
||||||
ElementKind, ElementSectionReader, Export, ExportSectionReader, ExternalKind, FuncType,
|
ElementKind, ElementSectionReader, Export, ExportSectionReader, ExternalKind,
|
||||||
FunctionSectionReader, GlobalSectionReader, GlobalType, ImportSectionEntryType,
|
FunctionSectionReader, GlobalSectionReader, GlobalType, ImportSectionEntryType,
|
||||||
ImportSectionReader, MemorySectionReader, MemoryType, NameSectionReader, Naming, NamingReader,
|
ImportSectionReader, MemorySectionReader, MemoryType, NameSectionReader, Naming, NamingReader,
|
||||||
Operator, TableSectionReader, Type, TypeSectionReader,
|
Operator, TableSectionReader, Type, TypeSectionReader,
|
||||||
@@ -40,34 +40,22 @@ pub fn parse_type_section(
|
|||||||
environ.reserve_signatures(count)?;
|
environ.reserve_signatures(count)?;
|
||||||
|
|
||||||
for entry in types {
|
for entry in types {
|
||||||
match entry? {
|
let wasm_func_ty = entry?;
|
||||||
FuncType {
|
let mut sig = Signature::new(ModuleEnvironment::target_config(environ).default_call_conv);
|
||||||
form: wasmparser::Type::Func,
|
sig.params.extend(wasm_func_ty.params.iter().map(|ty| {
|
||||||
params,
|
let cret_arg: ir::Type = type_to_type(*ty, environ)
|
||||||
returns,
|
.expect("only numeric types are supported in function signatures");
|
||||||
} => {
|
AbiParam::new(cret_arg)
|
||||||
let mut sig =
|
}));
|
||||||
Signature::new(ModuleEnvironment::target_config(environ).default_call_conv);
|
sig.returns.extend(wasm_func_ty.returns.iter().map(|ty| {
|
||||||
sig.params.extend(params.iter().map(|ty| {
|
let cret_arg: ir::Type = type_to_type(*ty, environ)
|
||||||
let cret_arg: ir::Type = type_to_type(*ty, environ)
|
.expect("only numeric types are supported in function signatures");
|
||||||
.expect("only numeric types are supported in function signatures");
|
AbiParam::new(cret_arg)
|
||||||
AbiParam::new(cret_arg)
|
}));
|
||||||
}));
|
environ.declare_signature(&wasm_func_ty, sig)?;
|
||||||
sig.returns.extend(returns.iter().map(|ty| {
|
module_translation_state
|
||||||
let cret_arg: ir::Type = type_to_type(*ty, environ)
|
.wasm_types
|
||||||
.expect("only numeric types are supported in function signatures");
|
.push((wasm_func_ty.params, wasm_func_ty.returns));
|
||||||
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
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use cranelift_entity::PrimaryMap;
|
|||||||
use cranelift_wasm::{
|
use cranelift_wasm::{
|
||||||
self, translate_module, DataIndex, DefinedFuncIndex, ElemIndex, FuncIndex, Global, GlobalIndex,
|
self, translate_module, DataIndex, DefinedFuncIndex, ElemIndex, FuncIndex, Global, GlobalIndex,
|
||||||
Memory, MemoryIndex, ModuleTranslationState, SignatureIndex, Table, TableIndex,
|
Memory, MemoryIndex, ModuleTranslationState, SignatureIndex, Table, TableIndex,
|
||||||
TargetEnvironment, WasmError, WasmResult,
|
TargetEnvironment, WasmError, WasmFuncType, WasmResult,
|
||||||
};
|
};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@@ -106,7 +106,7 @@ impl<'data> cranelift_wasm::ModuleEnvironment<'data> for ModuleEnvironment<'data
|
|||||||
Ok(())
|
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());
|
let sig = translate_signature(sig, self.pointer_type());
|
||||||
// TODO: Deduplicate signatures.
|
// TODO: Deduplicate signatures.
|
||||||
self.result.module.local.signatures.push(sig);
|
self.result.module.local.signatures.push(sig);
|
||||||
|
|||||||
Reference in New Issue
Block a user