From d4ae5cdd409fefdb4cf8a684389c3ae31f4a9d31 Mon Sep 17 00:00:00 2001 From: Lachlan Sneff Date: Thu, 28 Feb 2019 12:31:39 -0800 Subject: [PATCH] Get function addresses from llvm-compiled code --- Cargo.lock | 46 +++-- lib/llvm-backend/Cargo.toml | 4 +- lib/llvm-backend/cpp/object_loader.cpp | 74 ++++---- lib/llvm-backend/cpp/object_loader.hh | 27 ++- lib/llvm-backend/src/backend.rs | 235 ++++++++++++++++++++++--- lib/llvm-backend/src/code.rs | 5 +- lib/llvm-backend/src/lib.rs | 67 ++----- 7 files changed, 313 insertions(+), 145 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 566a1514b..5e7852448 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -106,6 +106,22 @@ name = "byteorder" version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "capstone" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "capstone-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "capstone-sys" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "cast" version = "0.2.2" @@ -262,28 +278,6 @@ dependencies = [ "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "dlopen" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "dlopen_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "dlopen_derive" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "either" version = "1.5.1" @@ -491,16 +485,16 @@ dependencies = [ name = "llvm-backend" version = "0.1.0" dependencies = [ + "capstone 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "dlopen 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "goblin 0.0.20 (registry+https://github.com/rust-lang/crates.io-index)", "hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "inkwell 0.1.0 (git+https://github.com/TheDan64/inkwell?branch=llvm7-0)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", "wasmer-runtime-core 0.1.2", "wasmparser 0.28.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1373,6 +1367,8 @@ dependencies = [ "checksum block-padding 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d75255892aeb580d3c566f213a2b6fdc1c66667839f45719ee1d30ebf2aea591" "checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" "checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" +"checksum capstone 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "00be9d203fa0e078b93b24603633fb081851dfe0c1086364431f52587a47157e" +"checksum capstone-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2dc8d32bc5c1e6d0fcde10af411c98b07d93498d51654f678757f08fa2acd6a6" "checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427" "checksum cbindgen 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "32e01024aaf5390d6a8145047371a4f5b0063a14c1e411bc731353bd2278ca44" "checksum cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "4390a3b5f4f6bce9c1d0c00128379df433e53777fdd30e92f16a529332baec4e" @@ -1390,8 +1386,6 @@ dependencies = [ "checksum cranelift-native 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)" = "474bee81d620a473bf43411a3d6f10ffbf7965141dc5e5b76d8d2151dde3285d" "checksum cranelift-wasm 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49723365dab9a48b354bdc24cb6d9d5719bc1d3b858ffd2ea179d0d7d885804a" "checksum digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c" -"checksum dlopen 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8c301a18a3404a48d5d078e86b011ac834a6c4c742217e9aa8ceadd8a7e09e0" -"checksum dlopen_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6e16e4e343d6090ba47113c55bf6aa94e9b1eb5ab0c5abc9510d4c15074f30e9" "checksum either 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c67353c641dc847124ea1902d69bd753dee9bb3beff9aa3662ecf86c971d1fac" "checksum enum-methods 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7798e7da2d4cb0d6d6fc467e8d6b5bf247e9e989f786dde1732d79899c32bb10" "checksum env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afb070faf94c85d17d50ca44f6ad076bce18ae92f0037d350947240a36e9d42e" diff --git a/lib/llvm-backend/Cargo.toml b/lib/llvm-backend/Cargo.toml index 3ec83d77c..eadc2c12f 100644 --- a/lib/llvm-backend/Cargo.toml +++ b/lib/llvm-backend/Cargo.toml @@ -11,8 +11,8 @@ inkwell = { git = "https://github.com/TheDan64/inkwell", branch = "llvm7-0" } hashbrown = "0.1.8" smallvec = "0.6.8" goblin = "0.0.20" -dlopen = "0.1.6" -tempfile = "3.0.7" +libc = "0.2.49" +capstone = "0.5.0" [build-dependencies] cc = "1.0" diff --git a/lib/llvm-backend/cpp/object_loader.cpp b/lib/llvm-backend/cpp/object_loader.cpp index 52625b64b..9265f8739 100644 --- a/lib/llvm-backend/cpp/object_loader.cpp +++ b/lib/llvm-backend/cpp/object_loader.cpp @@ -1,5 +1,4 @@ #include "object_loader.hh" -#include #include #include @@ -40,20 +39,26 @@ public: uintptr_t read_write_data_size, uint32_t read_write_data_align ) override { - uint8_t *ptr_out = nullptr; - size_t size_out = 0; + uint8_t *code_ptr_out = nullptr; + size_t code_size_out = 0; + auto code_result = callbacks->alloc_memory(code_size, PROTECT_READ_WRITE, &code_ptr_out, &code_size_out); + assert(code_result == RESULT_OK); + code_section = Section { code_ptr_out, code_size_out }; + code_bump_ptr = (uintptr_t)code_ptr_out; - auto code_result = callbacks->alloc_memory(code_size, PROTECT_READ_WRITE, &ptr_out, &size_out); - code_section = Section { ptr_out, size_out }; - code_bump_ptr = (uintptr_t)ptr_out; + uint8_t *read_ptr_out = nullptr; + size_t read_size_out = 0; + auto read_result = callbacks->alloc_memory(read_data_size, PROTECT_READ_WRITE, &read_ptr_out, &read_size_out); + assert(read_result == RESULT_OK); + read_section = Section { read_ptr_out, read_size_out }; + read_bump_ptr = (uintptr_t)read_ptr_out; - auto read_result = callbacks->alloc_memory(read_data_size, PROTECT_READ_WRITE, &ptr_out, &size_out); - read_section = Section { ptr_out, size_out }; - read_bump_ptr = (uintptr_t)ptr_out; - - auto readwrite_result = callbacks->alloc_memory(read_write_data_size, PROTECT_READ_WRITE, &ptr_out, &size_out); - readwrite_section = Section { ptr_out, size_out }; - readwrite_bump_ptr = (uintptr_t)ptr_out; + uint8_t *readwrite_ptr_out = nullptr; + size_t readwrite_size_out = 0; + auto readwrite_result = callbacks->alloc_memory(read_write_data_size, PROTECT_READ_WRITE, &readwrite_ptr_out, &readwrite_size_out); + assert(readwrite_result == RESULT_OK); + readwrite_section = Section { readwrite_ptr_out, readwrite_size_out }; + readwrite_bump_ptr = (uintptr_t)readwrite_ptr_out; } /* Turn on the `reserveAllocationSpace` callback. */ @@ -145,32 +150,37 @@ private: } }; -class WasmModule { -public: - WasmModule( +WasmModule::WasmModule( const uint8_t *object_start, size_t object_size, callbacks_t *callbacks +) : memory_manager(std::unique_ptr(new MemoryManager(callbacks))) +{ + object_file = llvm::cantFail(llvm::object::ObjectFile::createObjectFile(llvm::MemoryBufferRef( + llvm::StringRef((const char *)object_start, object_size), "object" + ))); - ) : memory_manager(std::unique_ptr(new MemoryManager(callbacks))) { - object_file = llvm::cantFail(llvm::object::ObjectFile::createObjectFile(llvm::MemoryBufferRef( - llvm::StringRef((const char *)object_start, object_size), "object" - ))); + SymbolLookup symbol_resolver; + llvm::RuntimeDyld loader(*memory_manager, symbol_resolver); - SymbolLookup symbol_resolver; - llvm::RuntimeDyld loader(*memory_manager, symbol_resolver); + loader.setProcessAllSections(true); - loader.setProcessAllSections(true); + auto loaded_object_info = loader.loadObject(*object_file); + loader.finalizeWithMemoryManagerLocking(); - auto loaded_object_info = loader.loadObject(*object_file); - loader.finalizeWithMemoryManagerLocking(); + assert(!loader.hasError()); - assert(!loader.hasError()); - - + symbol_table = loader.getSymbolTable(); + for (auto const& pair : symbol_table) { + std::cout << "symbol: (" << (std::string)pair.first << ") => " << (void*)pair.second.getAddress() << std::endl; } -private: - std::unique_ptr memory_manager; - std::unique_ptr object_file; -}; \ No newline at end of file +} + +void* WasmModule::get_func(llvm::StringRef name) const { + try { + return (void*)symbol_table.at(name).getAddress(); + } catch (const std::out_of_range& e) { + return nullptr; + } +} \ No newline at end of file diff --git a/lib/llvm-backend/cpp/object_loader.hh b/lib/llvm-backend/cpp/object_loader.hh index 50b618b38..9db12ce96 100644 --- a/lib/llvm-backend/cpp/object_loader.hh +++ b/lib/llvm-backend/cpp/object_loader.hh @@ -1,5 +1,6 @@ #include #include +#include typedef enum { PROTECT_NONE, @@ -19,7 +20,7 @@ typedef enum { typedef result_t (*alloc_memory_t)(size_t size, mem_protect_t protect, uint8_t** ptr_out, size_t* size_out); typedef result_t (*protect_memory_t)(uint8_t* ptr, size_t size, mem_protect_t protect); typedef result_t (*dealloc_memory_t)(uint8_t* ptr, size_t size); -typedef uintptr_t (*lookup_vm_symbol_t)(char* name_ptr, size_t name_size); +typedef uintptr_t (*lookup_vm_symbol_t)(char* name_ptr); typedef struct { /* Memory management. */ @@ -30,11 +31,31 @@ typedef struct { lookup_vm_symbol_t lookup_vm_symbol; } callbacks_t; + + +class WasmModule { +public: + WasmModule( + const uint8_t *object_start, + size_t object_size, + callbacks_t *callbacks + ); + + void *get_func(llvm::StringRef name) const; +private: + std::unique_ptr memory_manager; + std::unique_ptr object_file; + std::map symbol_table; +}; + extern "C" { - result_t object_load(uint8_t* mem_ptr, size_t mem_size, callbacks_t* callbacks) { + result_t object_load(const uint8_t* mem_ptr, size_t mem_size, callbacks_t* callbacks, WasmModule** module_out) { + *module_out = new WasmModule(mem_ptr, mem_size, callbacks); + return RESULT_OK; } - void test_cpp() { + void* get_func_symbol(WasmModule* module, const char* name) { + return module->get_func(llvm::StringRef(name)); } } \ No newline at end of file diff --git a/lib/llvm-backend/src/backend.rs b/lib/llvm-backend/src/backend.rs index 2b4bb7023..94310fd79 100644 --- a/lib/llvm-backend/src/backend.rs +++ b/lib/llvm-backend/src/backend.rs @@ -1,19 +1,153 @@ use crate::intrinsics::Intrinsics; -use dlopen::symbor::Library; use inkwell::{ module::Module, targets::{CodeModel, FileType, InitializationConfig, RelocMode, Target, TargetMachine}, OptimizationLevel, }; -use std::{io::Write, ptr::NonNull}; -use tempfile::NamedTempFile; +use libc::{ + c_char, mmap, mprotect, munmap, MAP_ANON, MAP_PRIVATE, PROT_EXEC, PROT_NONE, PROT_READ, + PROT_WRITE, +}; +use std::{ + ffi::CString, + ptr::{self, NonNull}, +}; use wasmer_runtime_core::{ - backend::FuncResolver, module::ModuleInner, structures::TypedIndex, types::LocalFuncIndex, vm, + backend::FuncResolver, + module::{ModuleInfo, ModuleInner}, + structures::TypedIndex, + types::LocalFuncIndex, + vm, }; +#[repr(C)] +struct LLVMModule { + _private: [u8; 0], +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[repr(C)] +enum MemProtect { + NONE, + READ, + READ_WRITE, + READ_EXECUTE, +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[repr(C)] +enum LLVMResult { + OK, + ALLOCATE_FAILURE, + PROTECT_FAILURE, + DEALLOC_FAILURE, + OBJECT_LOAD_FAILURE, +} + +#[repr(C)] +struct Callbacks { + alloc_memory: extern "C" fn(usize, MemProtect, &mut *mut u8, &mut usize) -> LLVMResult, + protect_memory: extern "C" fn(*mut u8, usize, MemProtect) -> LLVMResult, + dealloc_memory: extern "C" fn(*mut u8, usize) -> LLVMResult, + + lookup_vm_symbol: extern "C" fn(*const c_char) -> *const vm::Func, +} + +extern "C" { + fn object_load( + mem_ptr: *const u8, + mem_size: usize, + callbacks: *const Callbacks, + module_out: &mut *mut LLVMModule, + ) -> LLVMResult; + fn get_func_symbol(module: *mut LLVMModule, name: *const c_char) -> *const vm::Func; +} + +fn get_callbacks() -> Callbacks { + fn round_up_to_page_size(size: usize) -> usize { + (size + (4096 - 1)) & !(4096 - 1) + } + + extern "C" fn alloc_memory( + size: usize, + protect: MemProtect, + ptr_out: &mut *mut u8, + size_out: &mut usize, + ) -> LLVMResult { + println!("size: {}", size); + let ptr = unsafe { + mmap( + ptr::null_mut(), + round_up_to_page_size(size), + match protect { + MemProtect::NONE => PROT_NONE, + MemProtect::READ => PROT_READ, + MemProtect::READ_WRITE => PROT_READ | PROT_WRITE, + MemProtect::READ_EXECUTE => PROT_READ | PROT_EXEC, + }, + MAP_PRIVATE | MAP_ANON, + -1, + 0, + ) + }; + if ptr as isize == -1 { + return LLVMResult::ALLOCATE_FAILURE; + } + *ptr_out = ptr as _; + *size_out = size; + LLVMResult::OK + } + + extern "C" fn protect_memory(ptr: *mut u8, size: usize, protect: MemProtect) -> LLVMResult { + println!("protect memory: {:p}:{} -> {:?}", ptr, size, protect); + let res = unsafe { + mprotect( + ptr as _, + round_up_to_page_size(size), + match protect { + MemProtect::NONE => PROT_NONE, + MemProtect::READ => PROT_READ, + MemProtect::READ_WRITE => PROT_READ | PROT_WRITE, + MemProtect::READ_EXECUTE => PROT_READ | PROT_EXEC, + }, + ) + }; + + if res == 0 { + LLVMResult::OK + } else { + LLVMResult::PROTECT_FAILURE + } + } + + extern "C" fn dealloc_memory(ptr: *mut u8, size: usize) -> LLVMResult { + println!("dealloc_memory"); + let res = unsafe { munmap(ptr as _, round_up_to_page_size(size)) }; + + if res == 0 { + LLVMResult::OK + } else { + LLVMResult::DEALLOC_FAILURE + } + } + + extern "C" fn lookup_vm_symbol(_name_ptr: *const c_char) -> *const vm::Func { + ptr::null() + } + + Callbacks { + alloc_memory, + protect_memory, + dealloc_memory, + lookup_vm_symbol, + } +} + +unsafe impl Send for LLVMBackend {} +unsafe impl Sync for LLVMBackend {} + pub struct LLVMBackend { - tempfile: NamedTempFile, - library: Library, + module: *mut LLVMModule, } impl LLVMBackend { @@ -42,14 +176,50 @@ impl LLVMBackend { let memory_buffer = target_machine .write_to_memory_buffer(&module, FileType::Object) .unwrap(); + let mem_buf_slice = memory_buffer.as_slice(); - let mut tempfile = NamedTempFile::new().unwrap(); - tempfile.write_all(memory_buffer.as_slice()).unwrap(); - tempfile.flush().unwrap(); + let callbacks = get_callbacks(); + let mut module: *mut LLVMModule = ptr::null_mut(); - let library = Library::open(tempfile.path()).unwrap(); + let res = unsafe { + object_load( + mem_buf_slice.as_ptr(), + mem_buf_slice.len(), + &callbacks, + &mut module, + ) + }; - Self { tempfile, library } + if res != LLVMResult::OK { + panic!("failed to load object") + } + + Self { module } + } + + pub fn get_func( + &self, + info: &ModuleInfo, + local_func_index: LocalFuncIndex, + ) -> Option> { + let index = local_func_index.index(); + let name = if cfg!(target_os = "macos") { + format!("_fn{}", index) + } else { + format!("fn{}", index) + }; + + println!("name: {}", name); + + let c_str = CString::new(name).ok()?; + + let ptr = unsafe { get_func_symbol(self.module, c_str.as_ptr()) }; + + unsafe { + disass_ptr(ptr as _, 0x20, 4); + } + + NonNull::new(ptr as _) } } @@ -59,18 +229,35 @@ impl FuncResolver for LLVMBackend { module: &ModuleInner, local_func_index: LocalFuncIndex, ) -> Option> { - let index = module.info.imported_functions.len() + local_func_index.index(); - let name = if cfg!(macos) { - format!("_fn{}", index) - } else { - format!("fn{}", index) - }; - - unsafe { - self.library - .symbol::>(&name) - .ok() - .map(|symbol| *symbol) - } + self.get_func(&module.info, local_func_index) + } +} + +unsafe fn disass_ptr(ptr: *const u8, size: usize, inst_count: usize) { + use capstone::arch::BuildsCapstone; + let mut cs = capstone::Capstone::new() // Call builder-pattern + .x86() // X86 architecture + .mode(capstone::arch::x86::ArchMode::Mode64) // 64-bit mode + .detail(true) // Generate extra instruction details + .build() + .expect("Failed to create Capstone object"); + + // Get disassembled instructions + let insns = cs + .disasm_count( + std::slice::from_raw_parts(ptr, size), + ptr as u64, + inst_count, + ) + .expect("Failed to disassemble"); + + println!("count = {}", insns.len()); + for insn in insns.iter() { + println!( + "0x{:x}: {:6} {}", + insn.address(), + insn.mnemonic().unwrap_or(""), + insn.op_str().unwrap_or("") + ); } } diff --git a/lib/llvm-backend/src/code.rs b/lib/llvm-backend/src/code.rs index b0e8f2912..70382bd0b 100644 --- a/lib/llvm-backend/src/code.rs +++ b/lib/llvm-backend/src/code.rs @@ -615,8 +615,9 @@ fn parse_function( // This is a multi-value return. let struct_value = basic_value.into_struct_value(); for i in 0..(count as u32) { - let value = - builder.build_extract_value(struct_value, i, &state.var_name()).unwrap(); + let value = builder + .build_extract_value(struct_value, i, &state.var_name()) + .unwrap(); state.push1(value); } } diff --git a/lib/llvm-backend/src/lib.rs b/lib/llvm-backend/src/lib.rs index e06b081af..692ba091f 100644 --- a/lib/llvm-backend/src/lib.rs +++ b/lib/llvm-backend/src/lib.rs @@ -88,24 +88,18 @@ impl Compiler for LLVMCompiler { #[test] fn test_read_module() { + use std::mem::transmute; use wabt::wat2wasm; - use wasmer_runtime_core::vmcalls; + use wasmer_runtime_core::{structures::TypedIndex, types::LocalFuncIndex, vm, vmcalls}; // let wasm = include_bytes!("../../spectests/examples/simple/simple.wasm") as &[u8]; let wat = r#" (module (type $t0 (func (param i32) (result i32))) (type $t1 (func (result i32))) (memory 1) - (table 10 anyfunc) - (elem (i32.const 0) $foobar) (global $g0 (mut i32) (i32.const 0)) (func $foo (type $t0) (param i32) (result i32) get_local 0 - i32.const 0 - call_indirect (type $t0) - ) - (func $foobar (type $t0) - get_local 0 )) "#; let wasm = wat2wasm(wat).unwrap(); @@ -114,54 +108,15 @@ fn test_read_module() { let (module, intrinsics) = code::parse_function_bodies(&info, code_reader).unwrap(); - // let backend = backend::LLVMBackend::new(module, intrinsics); + let backend = backend::LLVMBackend::new(module, intrinsics); - extern "C" { - fn test_cpp(); + let func_ptr = backend.get_func(&info, LocalFuncIndex::new(0)).unwrap(); + + println!("func_ptr: {:p}", func_ptr.as_ptr()); + + unsafe { + let func: unsafe extern "C" fn(*mut vm::Ctx, i32) -> i32 = transmute(func_ptr); + let result = func(0 as _, 42); + println!("result: {}", result); } - - unsafe { test_cpp() }; - - // let exec_engine = module - // .create_jit_execution_engine(OptimizationLevel::Default) - // .unwrap(); - - // exec_engine.add_global_mapping( - // &intrinsics.memory_grow_dynamic_local, - // vmcalls::local_dynamic_memory_grow as usize, - // ); - // exec_engine.add_global_mapping( - // &intrinsics.memory_grow_static_local, - // vmcalls::local_static_memory_grow as usize, - // ); - // exec_engine.add_global_mapping( - // &intrinsics.memory_grow_dynamic_import, - // vmcalls::imported_dynamic_memory_grow as usize, - // ); - // exec_engine.add_global_mapping( - // &intrinsics.memory_grow_static_import, - // vmcalls::imported_static_memory_grow as usize, - // ); - // exec_engine.add_global_mapping( - // &intrinsics.memory_size_dynamic_local, - // vmcalls::local_dynamic_memory_size as usize, - // ); - // exec_engine.add_global_mapping( - // &intrinsics.memory_size_static_local, - // vmcalls::local_static_memory_size as usize, - // ); - // exec_engine.add_global_mapping( - // &intrinsics.memory_size_dynamic_import, - // vmcalls::imported_dynamic_memory_size as usize, - // ); - // exec_engine.add_global_mapping( - // &intrinsics.memory_size_static_import, - // vmcalls::imported_static_memory_size as usize, - // ); - - // unsafe { - // let func: JitFunction i32> = exec_engine.get_function("fn0").unwrap(); - // let result = func.call(0 as _, 0); - // println!("result: {}", result); - // } }