Propagate module-linking types to wasmtime (#2115)
This commit adds lots of plumbing to get the type section from the module linking proposal plumbed all the way through to the `wasmtime` crate and the `wasmtime-c-api` crate. This isn't all that useful right now because Wasmtime doesn't support imported/exported modules/instances, but this is all necessary groundwork to getting that exported at some point. I've added some light tests but I suspect the bulk of the testing will come in a future commit. One major change in this commit is that `SignatureIndex` no longer follows type type index space in a wasm module. Instead a new `TypeIndex` type is used to track that. Function signatures, still indexed by `SignatureIndex`, are then packed together tightly.
This commit is contained in:
@@ -77,7 +77,7 @@ use crate::state::{ControlStackFrame, ElseData, FuncTranslationState};
|
||||
use crate::translation_utils::{
|
||||
block_with_params, blocktype_params_results, f32_translation, f64_translation,
|
||||
};
|
||||
use crate::translation_utils::{FuncIndex, GlobalIndex, MemoryIndex, SignatureIndex, TableIndex};
|
||||
use crate::translation_utils::{FuncIndex, GlobalIndex, MemoryIndex, TableIndex, TypeIndex};
|
||||
use crate::wasm_unsupported;
|
||||
use core::convert::TryInto;
|
||||
use core::{i32, u32};
|
||||
@@ -587,7 +587,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
||||
builder.cursor(),
|
||||
TableIndex::from_u32(*table_index),
|
||||
table,
|
||||
SignatureIndex::from_u32(*index),
|
||||
TypeIndex::from_u32(*index),
|
||||
sigref,
|
||||
callee,
|
||||
state.peekn(num_args),
|
||||
|
||||
@@ -12,7 +12,7 @@ use crate::environ::{
|
||||
use crate::func_translator::FuncTranslator;
|
||||
use crate::translation_utils::{
|
||||
DataIndex, DefinedFuncIndex, ElemIndex, FuncIndex, Global, GlobalIndex, Memory, MemoryIndex,
|
||||
SignatureIndex, Table, TableIndex,
|
||||
Table, TableIndex, TypeIndex,
|
||||
};
|
||||
use core::convert::TryFrom;
|
||||
use cranelift_codegen::cursor::FuncCursor;
|
||||
@@ -58,7 +58,7 @@ pub struct DummyModuleInfo {
|
||||
config: TargetFrontendConfig,
|
||||
|
||||
/// Signatures as provided by `declare_signature`.
|
||||
pub signatures: PrimaryMap<SignatureIndex, ir::Signature>,
|
||||
pub signatures: PrimaryMap<TypeIndex, ir::Signature>,
|
||||
|
||||
/// Module and field names of imported functions as provided by `declare_func_import`.
|
||||
pub imported_funcs: Vec<(String, String)>,
|
||||
@@ -73,7 +73,7 @@ pub struct DummyModuleInfo {
|
||||
pub imported_memories: Vec<(String, String)>,
|
||||
|
||||
/// Functions, imported and local.
|
||||
pub functions: PrimaryMap<FuncIndex, Exportable<SignatureIndex>>,
|
||||
pub functions: PrimaryMap<FuncIndex, Exportable<TypeIndex>>,
|
||||
|
||||
/// Function bodies.
|
||||
pub function_bodies: PrimaryMap<DefinedFuncIndex, ir::Function>,
|
||||
@@ -157,7 +157,7 @@ impl DummyEnvironment {
|
||||
DummyFuncEnvironment::new(&self.info, self.return_mode)
|
||||
}
|
||||
|
||||
fn get_func_type(&self, func_index: FuncIndex) -> SignatureIndex {
|
||||
fn get_func_type(&self, func_index: FuncIndex) -> TypeIndex {
|
||||
self.info.functions[func_index].entity
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ impl<'dummy_environment> DummyFuncEnvironment<'dummy_environment> {
|
||||
|
||||
// Create a signature for `sigidx` amended with a `vmctx` argument after the standard wasm
|
||||
// arguments.
|
||||
fn vmctx_sig(&self, sigidx: SignatureIndex) -> ir::Signature {
|
||||
fn vmctx_sig(&self, sigidx: TypeIndex) -> ir::Signature {
|
||||
let mut sig = self.mod_info.signatures[sigidx].clone();
|
||||
sig.params.push(ir::AbiParam::special(
|
||||
self.pointer_type(),
|
||||
@@ -283,7 +283,7 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ
|
||||
fn make_indirect_sig(
|
||||
&mut self,
|
||||
func: &mut ir::Function,
|
||||
index: SignatureIndex,
|
||||
index: TypeIndex,
|
||||
) -> WasmResult<ir::SigRef> {
|
||||
// A real implementation would probably change the calling convention and add `vmctx` and
|
||||
// signature index arguments.
|
||||
@@ -312,7 +312,7 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ
|
||||
mut pos: FuncCursor,
|
||||
_table_index: TableIndex,
|
||||
_table: ir::Table,
|
||||
_sig_index: SignatureIndex,
|
||||
_sig_index: TypeIndex,
|
||||
sig_ref: ir::SigRef,
|
||||
callee: ir::Value,
|
||||
call_args: &[ir::Value],
|
||||
@@ -572,14 +572,14 @@ impl TargetEnvironment for DummyEnvironment {
|
||||
}
|
||||
|
||||
impl<'data> ModuleEnvironment<'data> for DummyEnvironment {
|
||||
fn declare_signature(&mut self, _wasm: WasmFuncType, sig: ir::Signature) -> WasmResult<()> {
|
||||
fn declare_type_func(&mut self, _wasm: WasmFuncType, sig: ir::Signature) -> WasmResult<()> {
|
||||
self.info.signatures.push(sig);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn declare_func_import(
|
||||
&mut self,
|
||||
sig_index: SignatureIndex,
|
||||
index: TypeIndex,
|
||||
module: &'data str,
|
||||
field: &'data str,
|
||||
) -> WasmResult<()> {
|
||||
@@ -588,15 +588,15 @@ impl<'data> ModuleEnvironment<'data> for DummyEnvironment {
|
||||
self.info.imported_funcs.len(),
|
||||
"Imported functions must be declared first"
|
||||
);
|
||||
self.info.functions.push(Exportable::new(sig_index));
|
||||
self.info.functions.push(Exportable::new(index));
|
||||
self.info
|
||||
.imported_funcs
|
||||
.push((String::from(module), String::from(field)));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn declare_func_type(&mut self, sig_index: SignatureIndex) -> WasmResult<()> {
|
||||
self.info.functions.push(Exportable::new(sig_index));
|
||||
fn declare_func_type(&mut self, index: TypeIndex) -> WasmResult<()> {
|
||||
self.info.functions.push(Exportable::new(index));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
|
||||
use crate::state::FuncTranslationState;
|
||||
use crate::translation_utils::{
|
||||
DataIndex, ElemIndex, FuncIndex, Global, GlobalIndex, Memory, MemoryIndex, SignatureIndex,
|
||||
Table, TableIndex,
|
||||
DataIndex, ElemIndex, EntityType, FuncIndex, Global, GlobalIndex, Memory, MemoryIndex, Table,
|
||||
TableIndex, TypeIndex,
|
||||
};
|
||||
use core::convert::From;
|
||||
use core::convert::TryFrom;
|
||||
@@ -293,7 +293,7 @@ pub trait FuncEnvironment: TargetEnvironment {
|
||||
fn make_indirect_sig(
|
||||
&mut self,
|
||||
func: &mut ir::Function,
|
||||
index: SignatureIndex,
|
||||
index: TypeIndex,
|
||||
) -> WasmResult<ir::SigRef>;
|
||||
|
||||
/// Set up an external function definition in the preamble of `func` that can be used to
|
||||
@@ -328,7 +328,7 @@ pub trait FuncEnvironment: TargetEnvironment {
|
||||
pos: FuncCursor,
|
||||
table_index: TableIndex,
|
||||
table: ir::Table,
|
||||
sig_index: SignatureIndex,
|
||||
sig_index: TypeIndex,
|
||||
sig_ref: ir::SigRef,
|
||||
callee: ir::Value,
|
||||
call_args: &[ir::Value],
|
||||
@@ -630,19 +630,35 @@ pub trait FuncEnvironment: TargetEnvironment {
|
||||
/// [`translate_module`](fn.translate_module.html) function. These methods should not be called
|
||||
/// by the user, they are only for `cranelift-wasm` internal use.
|
||||
pub trait ModuleEnvironment<'data>: TargetEnvironment {
|
||||
/// Provides the number of signatures up front. By default this does nothing, but
|
||||
/// Provides the number of types up front. By default this does nothing, but
|
||||
/// implementations can use this to preallocate memory if desired.
|
||||
fn reserve_signatures(&mut self, _num: u32) -> WasmResult<()> {
|
||||
fn reserve_types(&mut self, _num: u32) -> WasmResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Declares a function signature to the environment.
|
||||
fn declare_signature(
|
||||
fn declare_type_func(
|
||||
&mut self,
|
||||
wasm_func_type: WasmFuncType,
|
||||
sig: ir::Signature,
|
||||
) -> WasmResult<()>;
|
||||
|
||||
/// Declares a module type signature to the environment.
|
||||
fn declare_type_module(
|
||||
&mut self,
|
||||
imports: &[(&'data str, Option<&'data str>, EntityType)],
|
||||
exports: &[(&'data str, EntityType)],
|
||||
) -> WasmResult<()> {
|
||||
drop((imports, exports));
|
||||
Err(WasmError::Unsupported("module linking".to_string()))
|
||||
}
|
||||
|
||||
/// Declares an instance type signature to the environment.
|
||||
fn declare_type_instance(&mut self, exports: &[(&'data str, EntityType)]) -> WasmResult<()> {
|
||||
drop(exports);
|
||||
Err(WasmError::Unsupported("module linking".to_string()))
|
||||
}
|
||||
|
||||
/// Provides the number of imports up front. By default this does nothing, but
|
||||
/// implementations can use this to preallocate memory if desired.
|
||||
fn reserve_imports(&mut self, _num: u32) -> WasmResult<()> {
|
||||
@@ -652,7 +668,7 @@ pub trait ModuleEnvironment<'data>: TargetEnvironment {
|
||||
/// Declares a function import to the environment.
|
||||
fn declare_func_import(
|
||||
&mut self,
|
||||
sig_index: SignatureIndex,
|
||||
index: TypeIndex,
|
||||
module: &'data str,
|
||||
field: &'data str,
|
||||
) -> WasmResult<()>;
|
||||
@@ -681,6 +697,28 @@ pub trait ModuleEnvironment<'data>: TargetEnvironment {
|
||||
field: &'data str,
|
||||
) -> WasmResult<()>;
|
||||
|
||||
/// Declares a module import to the environment.
|
||||
fn declare_module_import(
|
||||
&mut self,
|
||||
ty_index: TypeIndex,
|
||||
module: &'data str,
|
||||
field: &'data str,
|
||||
) -> WasmResult<()> {
|
||||
drop((ty_index, module, field));
|
||||
Err(WasmError::Unsupported("module linking".to_string()))
|
||||
}
|
||||
|
||||
/// Declares an instance import to the environment.
|
||||
fn declare_instance_import(
|
||||
&mut self,
|
||||
ty_index: TypeIndex,
|
||||
module: &'data str,
|
||||
field: &'data str,
|
||||
) -> WasmResult<()> {
|
||||
drop((ty_index, module, field));
|
||||
Err(WasmError::Unsupported("module linking".to_string()))
|
||||
}
|
||||
|
||||
/// Notifies the implementation that all imports have been declared.
|
||||
fn finish_imports(&mut self) -> WasmResult<()> {
|
||||
Ok(())
|
||||
@@ -693,7 +731,7 @@ pub trait ModuleEnvironment<'data>: TargetEnvironment {
|
||||
}
|
||||
|
||||
/// Declares the type (signature) of a local function in the module.
|
||||
fn declare_func_type(&mut self, sig_index: SignatureIndex) -> WasmResult<()>;
|
||||
fn declare_func_type(&mut self, index: TypeIndex) -> WasmResult<()>;
|
||||
|
||||
/// Provides the number of defined tables up front. By default this does nothing, but
|
||||
/// implementations can use this to preallocate memory if desired.
|
||||
|
||||
@@ -65,11 +65,7 @@ pub use crate::func_translator::FuncTranslator;
|
||||
pub use crate::module_translator::translate_module;
|
||||
pub use crate::state::func_state::FuncTranslationState;
|
||||
pub use crate::state::module_state::ModuleTranslationState;
|
||||
pub use crate::translation_utils::{
|
||||
get_vmctx_value_label, DataIndex, DefinedFuncIndex, DefinedGlobalIndex, DefinedMemoryIndex,
|
||||
DefinedTableIndex, ElemIndex, FuncIndex, Global, GlobalIndex, GlobalInit, Memory, MemoryIndex,
|
||||
SignatureIndex, Table, TableElementType, TableIndex,
|
||||
};
|
||||
pub use crate::translation_utils::*;
|
||||
pub use cranelift_frontend::FunctionBuilder;
|
||||
|
||||
// Convenience reexport of the wasmparser crate that we're linking against,
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
use crate::environ::{ModuleEnvironment, WasmError, WasmResult};
|
||||
use crate::state::ModuleTranslationState;
|
||||
use crate::translation_utils::{
|
||||
tabletype_to_type, type_to_type, DataIndex, ElemIndex, FuncIndex, Global, GlobalIndex,
|
||||
GlobalInit, Memory, MemoryIndex, SignatureIndex, Table, TableElementType, TableIndex,
|
||||
tabletype_to_type, type_to_type, DataIndex, ElemIndex, EntityType, FuncIndex, Global,
|
||||
GlobalIndex, GlobalInit, Memory, MemoryIndex, Table, TableElementType, TableIndex, TypeIndex,
|
||||
};
|
||||
use crate::wasm_unsupported;
|
||||
use core::convert::TryFrom;
|
||||
@@ -27,18 +27,71 @@ use wasmparser::{
|
||||
ElementSectionReader, Export, ExportSectionReader, ExternalKind, FunctionSectionReader,
|
||||
GlobalSectionReader, GlobalType, ImportSectionEntryType, ImportSectionReader,
|
||||
MemorySectionReader, MemoryType, NameSectionReader, Naming, Operator, TableSectionReader,
|
||||
TypeDef, TypeSectionReader,
|
||||
TableType, TypeDef, TypeSectionReader,
|
||||
};
|
||||
|
||||
fn entity_type(
|
||||
ty: ImportSectionEntryType,
|
||||
environ: &mut dyn ModuleEnvironment<'_>,
|
||||
) -> WasmResult<EntityType> {
|
||||
Ok(match ty {
|
||||
ImportSectionEntryType::Function(sig) => EntityType::Function(TypeIndex::from_u32(sig)),
|
||||
ImportSectionEntryType::Module(sig) => EntityType::Module(TypeIndex::from_u32(sig)),
|
||||
ImportSectionEntryType::Instance(sig) => EntityType::Instance(TypeIndex::from_u32(sig)),
|
||||
ImportSectionEntryType::Memory(ty) => EntityType::Memory(memory(ty)),
|
||||
ImportSectionEntryType::Global(ty) => {
|
||||
EntityType::Global(global(ty, environ, GlobalInit::Import)?)
|
||||
}
|
||||
ImportSectionEntryType::Table(ty) => EntityType::Table(table(ty, environ)?),
|
||||
})
|
||||
}
|
||||
|
||||
fn memory(ty: MemoryType) -> Memory {
|
||||
match ty {
|
||||
MemoryType::M32 { limits, shared } => Memory {
|
||||
minimum: limits.initial,
|
||||
maximum: limits.maximum,
|
||||
shared: shared,
|
||||
},
|
||||
// FIXME(#2361)
|
||||
MemoryType::M64 { .. } => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn table(ty: TableType, environ: &mut dyn ModuleEnvironment<'_>) -> WasmResult<Table> {
|
||||
Ok(Table {
|
||||
wasm_ty: ty.element_type.try_into()?,
|
||||
ty: match tabletype_to_type(ty.element_type, environ)? {
|
||||
Some(t) => TableElementType::Val(t),
|
||||
None => TableElementType::Func,
|
||||
},
|
||||
minimum: ty.limits.initial,
|
||||
maximum: ty.limits.maximum,
|
||||
})
|
||||
}
|
||||
|
||||
fn global(
|
||||
ty: GlobalType,
|
||||
environ: &mut dyn ModuleEnvironment<'_>,
|
||||
initializer: GlobalInit,
|
||||
) -> WasmResult<Global> {
|
||||
Ok(Global {
|
||||
wasm_ty: ty.content_type.try_into()?,
|
||||
ty: type_to_type(ty.content_type, environ).unwrap(),
|
||||
mutability: ty.mutable,
|
||||
initializer,
|
||||
})
|
||||
}
|
||||
|
||||
/// Parses the Type section of the wasm module.
|
||||
pub fn parse_type_section(
|
||||
types: TypeSectionReader,
|
||||
pub fn parse_type_section<'a>(
|
||||
types: TypeSectionReader<'a>,
|
||||
module_translation_state: &mut ModuleTranslationState,
|
||||
environ: &mut dyn ModuleEnvironment,
|
||||
environ: &mut dyn ModuleEnvironment<'a>,
|
||||
) -> WasmResult<()> {
|
||||
let count = types.get_count();
|
||||
module_translation_state.wasm_types.reserve(count as usize);
|
||||
environ.reserve_signatures(count)?;
|
||||
environ.reserve_types(count)?;
|
||||
|
||||
for entry in types {
|
||||
match entry? {
|
||||
@@ -55,28 +108,31 @@ pub fn parse_type_section(
|
||||
.expect("only numeric types are supported in function signatures");
|
||||
AbiParam::new(cret_arg)
|
||||
}));
|
||||
environ.declare_signature(wasm_func_ty.clone().try_into()?, sig)?;
|
||||
environ.declare_type_func(wasm_func_ty.clone().try_into()?, sig)?;
|
||||
module_translation_state
|
||||
.wasm_types
|
||||
.push((wasm_func_ty.params, wasm_func_ty.returns));
|
||||
}
|
||||
|
||||
// Not implemented yet for module linking. Push dummy function types
|
||||
// though to keep the function type index space consistent. We'll
|
||||
// want an actual implementation here that handles this eventually.
|
||||
TypeDef::Module(_) | TypeDef::Instance(_) => {
|
||||
let sig =
|
||||
Signature::new(ModuleEnvironment::target_config(environ).default_call_conv);
|
||||
environ.declare_signature(
|
||||
crate::environ::WasmFuncType {
|
||||
params: Box::new([]),
|
||||
returns: Box::new([]),
|
||||
},
|
||||
sig,
|
||||
)?;
|
||||
module_translation_state
|
||||
.wasm_types
|
||||
.push((Box::new([]), Box::new([])));
|
||||
TypeDef::Module(t) => {
|
||||
let imports = t
|
||||
.imports
|
||||
.iter()
|
||||
.map(|i| Ok((i.module, i.field, entity_type(i.ty, environ)?)))
|
||||
.collect::<WasmResult<Vec<_>>>()?;
|
||||
let exports = t
|
||||
.exports
|
||||
.iter()
|
||||
.map(|e| Ok((e.name, entity_type(e.ty, environ)?)))
|
||||
.collect::<WasmResult<Vec<_>>>()?;
|
||||
environ.declare_type_module(&imports, &exports)?;
|
||||
}
|
||||
TypeDef::Instance(t) => {
|
||||
let exports = t
|
||||
.exports
|
||||
.iter()
|
||||
.map(|e| Ok((e.name, entity_type(e.ty, environ)?)))
|
||||
.collect::<WasmResult<Vec<_>>>()?;
|
||||
environ.declare_type_instance(&exports)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -94,61 +150,24 @@ pub fn parse_import_section<'data>(
|
||||
let import = entry?;
|
||||
let module_name = import.module;
|
||||
let field_name = import.field.unwrap(); // TODO Handle error when module linking is implemented.
|
||||
|
||||
match import.ty {
|
||||
ImportSectionEntryType::Function(sig) => {
|
||||
environ.declare_func_import(
|
||||
SignatureIndex::from_u32(sig),
|
||||
module_name,
|
||||
field_name,
|
||||
)?;
|
||||
match entity_type(import.ty, environ)? {
|
||||
EntityType::Function(idx) => {
|
||||
environ.declare_func_import(idx, module_name, field_name)?;
|
||||
}
|
||||
ImportSectionEntryType::Module(_sig) | ImportSectionEntryType::Instance(_sig) => {
|
||||
unimplemented!("module linking not implemented yet")
|
||||
EntityType::Module(idx) => {
|
||||
environ.declare_module_import(idx, module_name, field_name)?;
|
||||
}
|
||||
ImportSectionEntryType::Memory(MemoryType::M32 {
|
||||
limits: ref memlimits,
|
||||
shared,
|
||||
}) => {
|
||||
environ.declare_memory_import(
|
||||
Memory {
|
||||
minimum: memlimits.initial,
|
||||
maximum: memlimits.maximum,
|
||||
shared,
|
||||
},
|
||||
module_name,
|
||||
field_name,
|
||||
)?;
|
||||
EntityType::Instance(idx) => {
|
||||
environ.declare_instance_import(idx, module_name, field_name)?;
|
||||
}
|
||||
ImportSectionEntryType::Memory(MemoryType::M64 { .. }) => {
|
||||
unimplemented!();
|
||||
EntityType::Memory(ty) => {
|
||||
environ.declare_memory_import(ty, module_name, field_name)?;
|
||||
}
|
||||
ImportSectionEntryType::Global(ref ty) => {
|
||||
environ.declare_global_import(
|
||||
Global {
|
||||
wasm_ty: ty.content_type.try_into()?,
|
||||
ty: type_to_type(ty.content_type, environ).unwrap(),
|
||||
mutability: ty.mutable,
|
||||
initializer: GlobalInit::Import,
|
||||
},
|
||||
module_name,
|
||||
field_name,
|
||||
)?;
|
||||
EntityType::Global(ty) => {
|
||||
environ.declare_global_import(ty, module_name, field_name)?;
|
||||
}
|
||||
ImportSectionEntryType::Table(ref tab) => {
|
||||
environ.declare_table_import(
|
||||
Table {
|
||||
wasm_ty: tab.element_type.try_into()?,
|
||||
ty: match tabletype_to_type(tab.element_type, environ)? {
|
||||
Some(t) => TableElementType::Val(t),
|
||||
None => TableElementType::Func,
|
||||
},
|
||||
minimum: tab.limits.initial,
|
||||
maximum: tab.limits.maximum,
|
||||
},
|
||||
module_name,
|
||||
field_name,
|
||||
)?;
|
||||
EntityType::Table(ty) => {
|
||||
environ.declare_table_import(ty, module_name, field_name)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -172,7 +191,7 @@ pub fn parse_function_section(
|
||||
|
||||
for entry in functions {
|
||||
let sigindex = entry?;
|
||||
environ.declare_func_type(SignatureIndex::from_u32(sigindex))?;
|
||||
environ.declare_func_type(TypeIndex::from_u32(sigindex))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -186,16 +205,8 @@ pub fn parse_table_section(
|
||||
environ.reserve_tables(tables.get_count())?;
|
||||
|
||||
for entry in tables {
|
||||
let table = entry?;
|
||||
environ.declare_table(Table {
|
||||
wasm_ty: table.element_type.try_into()?,
|
||||
ty: match tabletype_to_type(table.element_type, environ)? {
|
||||
Some(t) => TableElementType::Val(t),
|
||||
None => TableElementType::Func,
|
||||
},
|
||||
minimum: table.limits.initial,
|
||||
maximum: table.limits.maximum,
|
||||
})?;
|
||||
let ty = table(entry?, environ)?;
|
||||
environ.declare_table(ty)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -209,17 +220,8 @@ pub fn parse_memory_section(
|
||||
environ.reserve_memories(memories.get_count())?;
|
||||
|
||||
for entry in memories {
|
||||
let memory = entry?;
|
||||
match memory {
|
||||
MemoryType::M32 { limits, shared } => {
|
||||
environ.declare_memory(Memory {
|
||||
minimum: limits.initial,
|
||||
maximum: limits.maximum,
|
||||
shared: shared,
|
||||
})?;
|
||||
}
|
||||
MemoryType::M64 { .. } => unimplemented!(),
|
||||
}
|
||||
let memory = memory(entry?);
|
||||
environ.declare_memory(memory)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -233,13 +235,7 @@ pub fn parse_global_section(
|
||||
environ.reserve_globals(globals.get_count())?;
|
||||
|
||||
for entry in globals {
|
||||
let wasmparser::Global {
|
||||
ty: GlobalType {
|
||||
content_type,
|
||||
mutable,
|
||||
},
|
||||
init_expr,
|
||||
} = entry?;
|
||||
let wasmparser::Global { ty, init_expr } = entry?;
|
||||
let mut init_expr_reader = init_expr.get_binary_reader();
|
||||
let initializer = match init_expr_reader.read_operator()? {
|
||||
Operator::I32Const { value } => GlobalInit::I32Const(value),
|
||||
@@ -263,13 +259,8 @@ pub fn parse_global_section(
|
||||
));
|
||||
}
|
||||
};
|
||||
let global = Global {
|
||||
wasm_ty: content_type.try_into()?,
|
||||
ty: type_to_type(content_type, environ).unwrap(),
|
||||
mutability: mutable,
|
||||
initializer,
|
||||
};
|
||||
environ.declare_global(global)?;
|
||||
let ty = global(ty, environ, initializer)?;
|
||||
environ.declare_global(ty)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
//! value and control stacks during the translation of a single function.
|
||||
|
||||
use crate::environ::{FuncEnvironment, GlobalVariable, WasmResult};
|
||||
use crate::translation_utils::{FuncIndex, GlobalIndex, MemoryIndex, SignatureIndex, TableIndex};
|
||||
use crate::translation_utils::{FuncIndex, GlobalIndex, MemoryIndex, TableIndex, TypeIndex};
|
||||
use crate::{HashMap, Occupied, Vacant};
|
||||
use cranelift_codegen::ir::{self, Block, Inst, Value};
|
||||
use std::vec::Vec;
|
||||
@@ -236,7 +236,7 @@ pub struct FuncTranslationState {
|
||||
// Map of indirect call signatures that have been created by
|
||||
// `FuncEnvironment::make_indirect_sig()`.
|
||||
// Stores both the signature reference and the number of WebAssembly arguments
|
||||
signatures: HashMap<SignatureIndex, (ir::SigRef, usize)>,
|
||||
signatures: HashMap<TypeIndex, (ir::SigRef, usize)>,
|
||||
|
||||
// Imported and local functions that have been created by
|
||||
// `FuncEnvironment::make_direct_func()`.
|
||||
@@ -498,7 +498,7 @@ impl FuncTranslationState {
|
||||
index: u32,
|
||||
environ: &mut FE,
|
||||
) -> WasmResult<(ir::SigRef, usize)> {
|
||||
let index = SignatureIndex::from_u32(index);
|
||||
let index = TypeIndex::from_u32(index);
|
||||
match self.signatures.entry(index) {
|
||||
Occupied(entry) => Ok(*entry.get()),
|
||||
Vacant(entry) => {
|
||||
|
||||
@@ -73,6 +73,65 @@ entity_impl!(DataIndex);
|
||||
pub struct ElemIndex(u32);
|
||||
entity_impl!(ElemIndex);
|
||||
|
||||
/// Index type of a type inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub struct TypeIndex(u32);
|
||||
entity_impl!(TypeIndex);
|
||||
|
||||
/// Index type of a module inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub struct ModuleIndex(u32);
|
||||
entity_impl!(ModuleIndex);
|
||||
|
||||
/// Index type of an instance inside the WebAssembly module.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub struct InstanceIndex(u32);
|
||||
entity_impl!(InstanceIndex);
|
||||
|
||||
/// An index of an entity.
|
||||
#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub enum EntityIndex {
|
||||
/// Function index.
|
||||
Function(FuncIndex),
|
||||
/// Table index.
|
||||
Table(TableIndex),
|
||||
/// Memory index.
|
||||
Memory(MemoryIndex),
|
||||
/// Global index.
|
||||
Global(GlobalIndex),
|
||||
/// Module index.
|
||||
Module(ModuleIndex),
|
||||
/// Instance index.
|
||||
Instance(InstanceIndex),
|
||||
}
|
||||
|
||||
/// A type of an item in a wasm module where an item is typically something that
|
||||
/// can be exported.
|
||||
#[allow(missing_docs)]
|
||||
#[derive(Clone, Debug)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub enum EntityType {
|
||||
/// A global variable with the specified content type
|
||||
Global(Global),
|
||||
/// A linear memory with the specified limits
|
||||
Memory(Memory),
|
||||
/// A table with the specified element type and limits
|
||||
Table(Table),
|
||||
/// A function type where the index points to the type section and records a
|
||||
/// function signature.
|
||||
Function(TypeIndex),
|
||||
/// An instance where the index points to the type section and records a
|
||||
/// instance's exports.
|
||||
Instance(TypeIndex),
|
||||
/// A module where the index points to the type section and records a
|
||||
/// module's imports and exports.
|
||||
Module(TypeIndex),
|
||||
}
|
||||
|
||||
/// A WebAssembly global.
|
||||
///
|
||||
/// Note that we record both the original Wasm type and the Cranelift IR type
|
||||
|
||||
Reference in New Issue
Block a user