mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-22 05:01:33 +00:00
Split codegen into multiple modules
This commit is contained in:
@ -42,7 +42,7 @@ impl LocalBacking {
|
||||
|
||||
let vm_memories = Self::finalize_memories(module, imports, &mut memories);
|
||||
let vm_tables = Self::finalize_tables(module, imports, &mut tables, vmctx);
|
||||
let vm_globals = Self::finalize_globals(module, globals);
|
||||
let vm_globals = Self::finalize_globals(module, imports, globals);
|
||||
|
||||
Self {
|
||||
memories,
|
||||
@ -86,16 +86,27 @@ impl LocalBacking {
|
||||
.iter()
|
||||
.filter(|init| init.data.len() > 0)
|
||||
{
|
||||
assert!(init.base.is_none(), "global base not supported yet");
|
||||
let init_base = match init.base {
|
||||
Initializer::Const(Value::I32(offset)) => offset as u32,
|
||||
Initializer::Const(_) => panic!("a const initializer must be the i32 type"),
|
||||
Initializer::GetGlobal(imported_global_index) => {
|
||||
if module.imported_globals[imported_global_index].1.ty == Type::I32 {
|
||||
unsafe { (*imports.globals[imported_global_index].global).data as u32 }
|
||||
} else {
|
||||
panic!("unsupported global type for initialzer")
|
||||
}
|
||||
}
|
||||
} as usize;
|
||||
|
||||
match init.memory_index.local_or_import(module) {
|
||||
LocalOrImport::Local(local_memory_index) => {
|
||||
let memory_desc = &module.memories[local_memory_index];
|
||||
let data_top = init.offset + init.data.len();
|
||||
assert!(memory_desc.min as usize >= data_top);
|
||||
let data_top = init_base + init.data.len();
|
||||
println!("data_top: {}", data_top);
|
||||
assert!((memory_desc.min * LinearMemory::PAGE_SIZE) as usize >= data_top);
|
||||
let mem: &mut LinearMemory = &mut memories[local_memory_index];
|
||||
|
||||
let to_init = &mut mem[init.offset..init.offset + init.data.len()];
|
||||
let to_init = &mut mem[init_base..init_base + init.data.len()];
|
||||
to_init.copy_from_slice(&init.data);
|
||||
}
|
||||
LocalOrImport::Import(imported_memory_index) => {
|
||||
@ -130,12 +141,12 @@ impl LocalBacking {
|
||||
tables: &mut SliceMap<LocalTableIndex, TableBacking>,
|
||||
vmctx: *mut vm::Ctx,
|
||||
) -> BoxedMap<LocalTableIndex, vm::LocalTable> {
|
||||
for init in &module.table_initializers {
|
||||
for init in &module.elem_initializers {
|
||||
let init_base = match init.base {
|
||||
Initializer::Const(Value::I32(offset)) => offset as u32,
|
||||
Initializer::Const(_) => panic!("a const initializer must be the i32 type"),
|
||||
Initializer::GetGlobal(imported_global_index) => {
|
||||
if module.imported_globals[imported_global_index].1.desc.ty == Type::I32 {
|
||||
if module.imported_globals[imported_global_index].1.ty == Type::I32 {
|
||||
unsafe { (*imports.globals[imported_global_index].global).data as u32 }
|
||||
} else {
|
||||
panic!("unsupported global type for initialzer")
|
||||
@ -243,14 +254,20 @@ impl LocalBacking {
|
||||
|
||||
fn finalize_globals(
|
||||
module: &ModuleInner,
|
||||
imports: &ImportBacking,
|
||||
mut globals: BoxedMap<LocalGlobalIndex, vm::LocalGlobal>,
|
||||
) -> BoxedMap<LocalGlobalIndex, vm::LocalGlobal> {
|
||||
for ((_, to), (_, from)) in globals.iter_mut().zip(module.globals.into_iter()) {
|
||||
for ((_, to), (_, from)) in globals.iter_mut().zip(module.globals.iter()) {
|
||||
to.data = match from.init {
|
||||
Value::I32(x) => x as u64,
|
||||
Value::I64(x) => x as u64,
|
||||
Value::F32(x) => x.to_bits() as u64,
|
||||
Value::F64(x) => x.to_bits(),
|
||||
Initializer::Const(ref value) => match value {
|
||||
Value::I32(x) => *x as u64,
|
||||
Value::I64(x) => *x as u64,
|
||||
Value::F32(x) => x.to_bits() as u64,
|
||||
Value::F64(x) => x.to_bits(),
|
||||
},
|
||||
Initializer::GetGlobal(imported_global_index) => unsafe {
|
||||
(*imports.globals[imported_global_index].global).data
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@ -416,13 +433,13 @@ fn import_globals(
|
||||
imports: &mut Imports,
|
||||
) -> Result<BoxedMap<ImportedGlobalIndex, vm::ImportedGlobal>, String> {
|
||||
let mut globals = Map::with_capacity(module.imported_globals.len());
|
||||
for (_, (ImportName { namespace, name }, imported_global)) in &module.imported_globals {
|
||||
for (_, (ImportName { namespace, name }, imported_global_desc)) in &module.imported_globals {
|
||||
let import = imports
|
||||
.get_namespace(namespace)
|
||||
.and_then(|namespace| namespace.get_export(name));
|
||||
match import {
|
||||
Some(Export::Global { local, global }) => {
|
||||
if global == imported_global.desc {
|
||||
if global == *imported_global_desc {
|
||||
globals.push(vm::ImportedGlobal {
|
||||
global: local.inner(),
|
||||
});
|
||||
|
@ -277,13 +277,16 @@ impl InstanceInner {
|
||||
)
|
||||
}
|
||||
LocalOrImport::Import(imported_global_index) => {
|
||||
let &(_, imported_global) = &module
|
||||
let &(_, imported_global_desc) = &module
|
||||
.imported_globals
|
||||
.get(imported_global_index)
|
||||
.expect("missing imported global index");
|
||||
let vm::ImportedGlobal { global } =
|
||||
&self.import_backing.globals[imported_global_index];
|
||||
(unsafe { GlobalPointer::new(*global) }, imported_global.desc)
|
||||
(
|
||||
unsafe { GlobalPointer::new(*global) },
|
||||
*imported_global_desc,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ use crate::{
|
||||
sig_registry::SigRegistry,
|
||||
structures::Map,
|
||||
types::{
|
||||
FuncIndex, Global, GlobalIndex, ImportedFuncIndex, ImportedGlobal, ImportedGlobalIndex,
|
||||
FuncIndex, Global, GlobalDesc, GlobalIndex, ImportedFuncIndex, ImportedGlobalIndex,
|
||||
ImportedMemoryIndex, ImportedTableIndex, Initializer, LocalGlobalIndex, LocalMemoryIndex,
|
||||
LocalTableIndex, Memory, MemoryIndex, SigIndex, Table, TableIndex,
|
||||
},
|
||||
@ -26,12 +26,13 @@ pub struct ModuleInner {
|
||||
pub imported_functions: Map<ImportedFuncIndex, ImportName>,
|
||||
pub imported_memories: Map<ImportedMemoryIndex, (ImportName, Memory)>,
|
||||
pub imported_tables: Map<ImportedTableIndex, (ImportName, Table)>,
|
||||
pub imported_globals: Map<ImportedGlobalIndex, (ImportName, ImportedGlobal)>,
|
||||
pub imported_globals: Map<ImportedGlobalIndex, (ImportName, GlobalDesc)>,
|
||||
|
||||
pub exports: HashMap<String, ExportIndex>,
|
||||
|
||||
pub data_initializers: Vec<DataInitializer>,
|
||||
pub table_initializers: Vec<TableInitializer>,
|
||||
pub elem_initializers: Vec<TableInitializer>,
|
||||
|
||||
pub start_func: Option<FuncIndex>,
|
||||
|
||||
pub func_assoc: Map<FuncIndex, SigIndex>,
|
||||
@ -82,10 +83,8 @@ pub enum ExportIndex {
|
||||
pub struct DataInitializer {
|
||||
/// The index of the memory to initialize.
|
||||
pub memory_index: MemoryIndex,
|
||||
/// Optionally a globalvalue base to initialize at.
|
||||
pub base: Option<GlobalIndex>,
|
||||
/// A constant offset to initialize at.
|
||||
pub offset: usize,
|
||||
/// Either a constant offset or a `get_global`
|
||||
pub base: Initializer,
|
||||
/// The initialization data.
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ use std::{
|
||||
marker::PhantomData,
|
||||
mem,
|
||||
ops::{Deref, DerefMut},
|
||||
slice,
|
||||
slice, vec,
|
||||
};
|
||||
|
||||
/// Dense item map
|
||||
@ -45,6 +45,10 @@ where
|
||||
K::new(len)
|
||||
}
|
||||
|
||||
pub fn next_index(&self) -> K {
|
||||
K::new(self.len())
|
||||
}
|
||||
|
||||
pub fn reserve_exact(&mut self, size: usize) {
|
||||
self.elems.reserve_exact(size);
|
||||
}
|
||||
@ -105,6 +109,49 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub struct IntoIter<K, V>
|
||||
where
|
||||
K: TypedIndex,
|
||||
{
|
||||
enumerated: iter::Enumerate<vec::IntoIter<V>>,
|
||||
_marker: PhantomData<K>,
|
||||
}
|
||||
|
||||
impl<K, V> IntoIter<K, V>
|
||||
where
|
||||
K: TypedIndex,
|
||||
{
|
||||
pub(in crate::structures) fn new(into_iter: vec::IntoIter<V>) -> Self {
|
||||
Self {
|
||||
enumerated: into_iter.enumerate(),
|
||||
_marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> Iterator for IntoIter<K, V>
|
||||
where
|
||||
K: TypedIndex,
|
||||
{
|
||||
type Item = (K, V);
|
||||
|
||||
fn next(&mut self) -> Option<(K, V)> {
|
||||
self.enumerated.next().map(|(i, v)| (K::new(i), v))
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> IntoIterator for Map<K, V>
|
||||
where
|
||||
K: TypedIndex,
|
||||
{
|
||||
type Item = (K, V);
|
||||
type IntoIter = IntoIter<K, V>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
IntoIter::new(self.elems.into_iter())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K, V> IntoIterator for &'a Map<K, V>
|
||||
where
|
||||
K: TypedIndex,
|
||||
|
@ -7,6 +7,8 @@ pub use self::map::{Iter, IterMut, Map};
|
||||
pub use self::slice::SliceMap;
|
||||
|
||||
pub trait TypedIndex {
|
||||
#[doc(hidden)]
|
||||
fn new(index: usize) -> Self;
|
||||
#[doc(hidden)]
|
||||
fn index(&self) -> usize;
|
||||
}
|
||||
|
@ -101,23 +101,11 @@ pub struct GlobalDesc {
|
||||
pub ty: Type,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum ImportedGlobalInit {
|
||||
GetGlobal(ImportedGlobalIndex),
|
||||
Import,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct ImportedGlobal {
|
||||
pub desc: GlobalDesc,
|
||||
pub init: ImportedGlobalInit,
|
||||
}
|
||||
|
||||
/// A wasm global.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Global {
|
||||
pub desc: GlobalDesc,
|
||||
pub init: Value,
|
||||
pub init: Initializer,
|
||||
}
|
||||
|
||||
/// A wasm memory.
|
||||
@ -174,10 +162,12 @@ macro_rules! define_map_index {
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub struct $ty (u32);
|
||||
impl TypedIndex for $ty {
|
||||
#[doc(hidden)]
|
||||
fn new(index: usize) -> Self {
|
||||
$ty (index as _)
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
fn index(&self) -> usize {
|
||||
self.0 as usize
|
||||
}
|
||||
@ -247,10 +237,12 @@ define_local_or_import![
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub struct SigIndex(u32);
|
||||
impl TypedIndex for SigIndex {
|
||||
#[doc(hidden)]
|
||||
fn new(index: usize) -> Self {
|
||||
SigIndex(index as _)
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
fn index(&self) -> usize {
|
||||
self.0 as usize
|
||||
}
|
||||
@ -263,3 +255,22 @@ where
|
||||
Local(T::Local),
|
||||
Import(T::Import),
|
||||
}
|
||||
|
||||
impl<T> LocalOrImport<T>
|
||||
where
|
||||
T: LocalImport,
|
||||
{
|
||||
pub fn local(self) -> Option<T::Local> {
|
||||
match self {
|
||||
LocalOrImport::Local(local) => Some(local),
|
||||
LocalOrImport::Import(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn import(self) -> Option<T::Import> {
|
||||
match self {
|
||||
LocalOrImport::Import(import) => Some(import),
|
||||
LocalOrImport::Local(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -127,6 +127,10 @@ impl LocalTable {
|
||||
pub fn offset_current_elements() -> u8 {
|
||||
1 * (mem::size_of::<usize>() as u8)
|
||||
}
|
||||
|
||||
pub fn size() -> u8 {
|
||||
mem::size_of::<Self>() as u8
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@ -146,6 +150,10 @@ impl ImportedTable {
|
||||
pub fn offset_vmctx() -> u8 {
|
||||
1 * (mem::size_of::<usize>() as u8)
|
||||
}
|
||||
|
||||
pub fn size() -> u8 {
|
||||
mem::size_of::<Self>() as u8
|
||||
}
|
||||
}
|
||||
|
||||
/// Definition of a memory used by the VM.
|
||||
@ -166,6 +174,10 @@ impl LocalMemory {
|
||||
pub fn offset_size() -> u8 {
|
||||
1 * (mem::size_of::<usize>() as u8)
|
||||
}
|
||||
|
||||
pub fn size() -> u8 {
|
||||
mem::size_of::<Self>() as u8
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@ -184,6 +196,10 @@ impl ImportedMemory {
|
||||
pub fn offset_vmctx() -> u8 {
|
||||
1 * (mem::size_of::<usize>() as u8)
|
||||
}
|
||||
|
||||
pub fn size() -> u8 {
|
||||
mem::size_of::<Self>() as u8
|
||||
}
|
||||
}
|
||||
|
||||
/// Definition of a global used by the VM.
|
||||
@ -257,6 +273,10 @@ impl Anyfunc {
|
||||
pub fn offset_sig_id() -> u8 {
|
||||
2 * (mem::size_of::<usize>() as u8)
|
||||
}
|
||||
|
||||
pub fn size() -> u8 {
|
||||
mem::size_of::<Self>() as u8
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
Reference in New Issue
Block a user