#![allow(improper_ctypes)] use std::cell::RefCell; use std::collections::hash_map::HashMap; use std::rc::Rc; use target_lexicon::HOST; use wasmtime_environ::entity::PrimaryMap; use wasmtime_environ::ir::types; use wasmtime_environ::wasm::{ DefinedFuncIndex, Global, GlobalInit, Memory, Table, TableElementType, }; use wasmtime_environ::{ir, isa}; use wasmtime_environ::{translate_signature, Export, MemoryPlan, Module, TablePlan}; use wasmtime_jit::target_tunables; use wasmtime_runtime::{Imports, InstanceHandle, InstantiationError, VMContext, VMFunctionBody}; extern "C" fn spectest_print() {} #[allow(clippy::print_stdout)] extern "C" fn spectest_print_i32(_vmctx: &mut VMContext, x: i32) { println!("{}: i32", x); } #[allow(clippy::print_stdout)] extern "C" fn spectest_print_i64(_vmctx: &mut VMContext, x: i64) { println!("{}: i64", x); } #[allow(clippy::print_stdout)] extern "C" fn spectest_print_f32(_vmctx: &mut VMContext, x: f32) { println!("{}: f32", x); } #[allow(clippy::print_stdout)] extern "C" fn spectest_print_f64(_vmctx: &mut VMContext, x: f64) { println!("{}: f64", x); } #[allow(clippy::print_stdout)] extern "C" fn spectest_print_i32_f32(_vmctx: &mut VMContext, x: i32, y: f32) { println!("{}: i32", x); println!("{}: f32", y); } #[allow(clippy::print_stdout)] extern "C" fn spectest_print_f64_f64(_vmctx: &mut VMContext, x: f64, y: f64) { println!("{}: f64", x); println!("{}: f64", y); } /// Return an instance implementing the "spectest" interface used in the /// spec testsuite. pub fn instantiate_spectest() -> Result { let call_conv = isa::CallConv::triple_default(&HOST); let pointer_type = types::Type::triple_pointer_type(&HOST); let mut module = Module::new(); let mut finished_functions: PrimaryMap = PrimaryMap::new(); let sig = module.signatures.push(translate_signature( ir::Signature { params: vec![], returns: vec![], call_conv, }, pointer_type, )); let func = module.functions.push(sig); module .exports .insert("print".to_owned(), Export::Function(func)); finished_functions.push(spectest_print as *const VMFunctionBody); let sig = module.signatures.push(translate_signature( ir::Signature { params: vec![ir::AbiParam::new(types::I32)], returns: vec![], call_conv, }, pointer_type, )); let func = module.functions.push(sig); module .exports .insert("print_i32".to_owned(), Export::Function(func)); finished_functions.push(spectest_print_i32 as *const VMFunctionBody); let sig = module.signatures.push(translate_signature( ir::Signature { params: vec![ir::AbiParam::new(types::I64)], returns: vec![], call_conv, }, pointer_type, )); let func = module.functions.push(sig); module .exports .insert("print_i64".to_owned(), Export::Function(func)); finished_functions.push(spectest_print_i64 as *const VMFunctionBody); let sig = module.signatures.push(translate_signature( ir::Signature { params: vec![ir::AbiParam::new(types::F32)], returns: vec![], call_conv, }, pointer_type, )); let func = module.functions.push(sig); module .exports .insert("print_f32".to_owned(), Export::Function(func)); finished_functions.push(spectest_print_f32 as *const VMFunctionBody); let sig = module.signatures.push(translate_signature( ir::Signature { params: vec![ir::AbiParam::new(types::F64)], returns: vec![], call_conv, }, pointer_type, )); let func = module.functions.push(sig); module .exports .insert("print_f64".to_owned(), Export::Function(func)); finished_functions.push(spectest_print_f64 as *const VMFunctionBody); let sig = module.signatures.push(translate_signature( ir::Signature { params: vec![ir::AbiParam::new(types::I32), ir::AbiParam::new(types::F32)], returns: vec![], call_conv, }, pointer_type, )); let func = module.functions.push(sig); module .exports .insert("print_i32_f32".to_owned(), Export::Function(func)); finished_functions.push(spectest_print_i32_f32 as *const VMFunctionBody); let sig = module.signatures.push(translate_signature( ir::Signature { params: vec![ir::AbiParam::new(types::F64), ir::AbiParam::new(types::F64)], returns: vec![], call_conv, }, pointer_type, )); let func = module.functions.push(sig); module .exports .insert("print_f64_f64".to_owned(), Export::Function(func)); finished_functions.push(spectest_print_f64_f64 as *const VMFunctionBody); let global = module.globals.push(Global { ty: types::I32, mutability: false, initializer: GlobalInit::I32Const(666), }); module .exports .insert("global_i32".to_owned(), Export::Global(global)); let global = module.globals.push(Global { ty: types::I64, mutability: false, initializer: GlobalInit::I64Const(666), }); module .exports .insert("global_i64".to_owned(), Export::Global(global)); let global = module.globals.push(Global { ty: types::F32, mutability: false, initializer: GlobalInit::F32Const(0x44268000), }); module .exports .insert("global_f32".to_owned(), Export::Global(global)); let global = module.globals.push(Global { ty: types::F64, mutability: false, initializer: GlobalInit::F64Const(0x4084d00000000000), }); module .exports .insert("global_f64".to_owned(), Export::Global(global)); let tunables = target_tunables(&HOST); let table = module.table_plans.push(TablePlan::for_table( Table { ty: TableElementType::Func, minimum: 10, maximum: Some(20), }, &tunables, )); module .exports .insert("table".to_owned(), Export::Table(table)); let memory = module.memory_plans.push(MemoryPlan::for_memory( Memory { minimum: 1, maximum: Some(2), shared: false, }, &tunables, )); module .exports .insert("memory".to_owned(), Export::Memory(memory)); let imports = Imports::none(); let data_initializers = Vec::new(); let signatures = PrimaryMap::new(); InstanceHandle::new( Rc::new(module), Rc::new(RefCell::new(HashMap::new())), finished_functions.into_boxed_slice(), imports, &data_initializers, signatures.into_boxed_slice(), None, Box::new(()), ) }