use crate::cache::{BackendCache, CacheGenerator}; use crate::{resolver::FuncResolverBuilder, signal::Caller}; use cranelift_codegen::ir; use cranelift_entity::EntityRef; use cranelift_wasm; use std::sync::Arc; use wasmer_runtime_core::cache::{Artifact, Error as CacheError}; use wasmer_runtime_core::{ module::{ModuleInfo, ModuleInner}, structures::TypedIndex, types::{FuncIndex, FuncSig, GlobalIndex, MemoryIndex, SigIndex, TableIndex, Type}, }; /// This contains all of the items in a `ModuleInner` except the `func_resolver`. pub struct Module { pub info: ModuleInfo, } impl Module { pub fn from_cache(cache: Artifact) -> Result { let (info, compiled_code, backend_cache) = BackendCache::from_cache(cache)?; let (func_resolver_builder, trampolines, handler_data) = FuncResolverBuilder::new_from_backend_cache(backend_cache, compiled_code, &info)?; let (func_resolver, backend_cache) = func_resolver_builder .finalize( &info.signatures, Arc::clone(&trampolines), handler_data.clone(), ) .map_err(|e| CacheError::Unknown(format!("{:?}", e)))?; let cache_gen = Box::new(CacheGenerator::new( backend_cache, Arc::clone(&func_resolver.memory), )); let runnable_module = Caller::new(handler_data, trampolines, func_resolver); Ok(ModuleInner { runnable_module: Box::new(runnable_module), cache_gen, info, }) } } pub struct Converter(pub T); macro_rules! convert_clif_to_runtime_index { ($clif_index:ident, $runtime_index:ident) => { impl From> for $runtime_index { fn from(clif_index: Converter) -> Self { $runtime_index::new(clif_index.0.index()) } } impl From> for cranelift_wasm::$clif_index { fn from(runtime_index: Converter<$runtime_index>) -> Self { cranelift_wasm::$clif_index::new(runtime_index.0.index()) } } }; ($(($clif_index:ident: $runtime_index:ident),)*) => { $( convert_clif_to_runtime_index!($clif_index, $runtime_index); )* }; } convert_clif_to_runtime_index![ (FuncIndex: FuncIndex), (MemoryIndex: MemoryIndex), (TableIndex: TableIndex), (GlobalIndex: GlobalIndex), (SignatureIndex: SigIndex), ]; impl From> for FuncSig { fn from(signature: Converter) -> Self { FuncSig::new( signature .0 .params .iter() .map(|param| Converter(param.value_type).into()) .collect::>(), signature .0 .returns .iter() .map(|ret| Converter(ret.value_type).into()) .collect::>(), ) } } impl From> for Type { fn from(ty: Converter) -> Self { match ty.0 { ir::types::I32 => Type::I32, ir::types::I64 => Type::I64, ir::types::F32 => Type::F32, ir::types::F64 => Type::F64, ir::types::I32X4 => Type::V128, _ => unimplemented!("unsupported wasm type"), } } } impl From> for ir::Type { fn from(ty: Converter) -> Self { match ty.0 { Type::I32 => ir::types::I32, Type::I64 => ir::types::I64, Type::F32 => ir::types::F32, Type::F64 => ir::types::F64, Type::V128 => ir::types::I32X4, } } } impl From> for ir::AbiParam { fn from(ty: Converter) -> Self { match ty.0 { Type::I32 => ir::AbiParam::new(ir::types::I32), Type::I64 => ir::AbiParam::new(ir::types::I64), Type::F32 => ir::AbiParam::new(ir::types::F32), Type::F64 => ir::AbiParam::new(ir::types::F64), Type::V128 => ir::AbiParam::new(ir::types::I32X4), } } }