diff --git a/lib/llvm-backend/cpp/object_loader.cpp b/lib/llvm-backend/cpp/object_loader.cpp index 9d1d8c731..3c36707c5 100644 --- a/lib/llvm-backend/cpp/object_loader.cpp +++ b/lib/llvm-backend/cpp/object_loader.cpp @@ -117,6 +117,8 @@ private: struct SymbolLookup : llvm::JITSymbolResolver { public: + SymbolLookup(callbacks_t callbacks) : callbacks(callbacks) {} + virtual llvm::Expected lookup(const LookupSet& symbols) override { LookupResult result; @@ -140,10 +142,12 @@ public: private: llvm::JITEvaluatedSymbol symbol_lookup(llvm::StringRef name) { std::cout << "symbol name: " << (std::string)name << std::endl; - uint64_t addr = 0; + uint64_t addr = callbacks.lookup_vm_symbol(name.data(), name.size()); return llvm::JITEvaluatedSymbol(addr, llvm::JITSymbolFlags::None); } + + callbacks_t callbacks; }; WasmModule::WasmModule( @@ -156,7 +160,7 @@ WasmModule::WasmModule( llvm::StringRef((const char *)object_start, object_size), "object" ))); - SymbolLookup symbol_resolver; + SymbolLookup symbol_resolver(callbacks); runtime_dyld = std::unique_ptr(new llvm::RuntimeDyld(*memory_manager, symbol_resolver)); runtime_dyld->setProcessAllSections(true); diff --git a/lib/llvm-backend/cpp/object_loader.hh b/lib/llvm-backend/cpp/object_loader.hh index 969f16150..8134385fd 100644 --- a/lib/llvm-backend/cpp/object_loader.hh +++ b/lib/llvm-backend/cpp/object_loader.hh @@ -20,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); +typedef uintptr_t (*lookup_vm_symbol_t)(const char* name_ptr, size_t length); typedef struct { /* Memory management. */ diff --git a/lib/llvm-backend/src/backend.rs b/lib/llvm-backend/src/backend.rs index 98b0bc6e0..5b9299ce9 100644 --- a/lib/llvm-backend/src/backend.rs +++ b/lib/llvm-backend/src/backend.rs @@ -13,6 +13,7 @@ use std::{ ffi::CString, mem, ptr::{self, NonNull}, + slice, str, }; use wasmer_runtime_core::{ backend::{FuncResolver, ProtectedCaller, Token, UserTrapper}, @@ -22,6 +23,7 @@ use wasmer_runtime_core::{ structures::TypedIndex, types::{FuncIndex, FuncSig, LocalFuncIndex, LocalOrImport, SigIndex, Type, Value}, vm::{self, ImportBacking}, + vmcalls, }; #[repr(C)] @@ -56,7 +58,7 @@ struct Callbacks { 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, + lookup_vm_symbol: extern "C" fn(*const c_char, usize) -> *const vm::Func, } extern "C" { @@ -136,8 +138,31 @@ fn get_callbacks() -> Callbacks { } } - extern "C" fn lookup_vm_symbol(_name_ptr: *const c_char) -> *const vm::Func { - ptr::null() + extern "C" fn lookup_vm_symbol(name_ptr: *const c_char, length: usize) -> *const vm::Func { + #[cfg(target_os = "macos")] + macro_rules! fn_name { + ($s:literal) => { + concat!("_", $s) + }; + } + + #[cfg(not(target_os = "macos"))] + macro_rules! fn_name { + ($s:literal) => { + $s + }; + } + + let name_slice = unsafe { slice::from_raw_parts(name_ptr as *const u8, length) }; + let name = str::from_utf8(name_slice).unwrap(); + + match name { + fn_name!("vm.memory.grow.dynamic.local") => vmcalls::local_dynamic_memory_grow as _, + fn_name!("vm.memory.size.dynamic.local") => vmcalls::local_dynamic_memory_size as _, + fn_name!("vm.memory.grow.static.local") => vmcalls::local_static_memory_grow as _, + fn_name!("vm.memory.size.static.local") => vmcalls::local_static_memory_size as _, + _ => ptr::null(), + } } Callbacks { @@ -241,6 +266,7 @@ impl FuncResolver for LLVMBackend { module: &ModuleInner, local_func_index: LocalFuncIndex, ) -> Option> { + unimplemented!(); self.get_func(&module.info, local_func_index) } } @@ -264,6 +290,7 @@ impl ProtectedCaller for LLVMProtectedCaller { vmctx: *mut vm::Ctx, _: Token, ) -> RuntimeResult> { + unimplemented!(); let (func_ptr, ctx, signature, sig_index) = get_func_from_index(&module, import_backing, func_index); diff --git a/lib/llvm-backend/src/code.rs b/lib/llvm-backend/src/code.rs index dd7ec30c7..aeb050cd5 100644 --- a/lib/llvm-backend/src/code.rs +++ b/lib/llvm-backend/src/code.rs @@ -110,7 +110,7 @@ pub fn parse_function_bodies( })?; } - // module.print_to_stderr(); + module.print_to_stderr(); generate_trampolines(info, &signatures, &module, &context, &builder, &intrinsics); @@ -475,22 +475,8 @@ fn parse_function( builder.build_unconditional_branch(frame.code_after()); for phi in frame.phis().iter().rev() { - if phi.count_incoming() != 0 { - let value = state.pop1()?; - phi.add_incoming(&[(&value, ¤t_block)]) - } else { - let basic_ty = phi.as_basic_value().get_type(); - let placeholder_value = match basic_ty { - BasicTypeEnum::IntType(int_ty) => { - int_ty.const_int(0, false).as_basic_value_enum() - } - BasicTypeEnum::FloatType(float_ty) => { - float_ty.const_float(0.0).as_basic_value_enum() - } - _ => unimplemented!(), - }; - phi.add_incoming(&[(&placeholder_value, ¤t_block)]); - } + let value = state.pop1()?; + phi.add_incoming(&[(&value, ¤t_block)]); } } @@ -558,6 +544,7 @@ fn parse_function( // it will emit a `ud2` instruction on x86_64 arches. ctx.build_trap(); builder.build_unreachable(); + state.reachable = false; } @@ -747,12 +734,13 @@ fn parse_function( ) }; - let sigindices_equal = builder.build_int_compare( - IntPredicate::EQ, - expected_dynamic_sigindex, - found_dynamic_sigindex, - "sigindices_equal", - ); + // let sigindices_equal = builder.build_int_compare( + // IntPredicate::EQ, + // expected_dynamic_sigindex, + // found_dynamic_sigindex, + // "sigindices_equal", + // ); + let sigindices_equal = intrinsics.i1_ty.const_int(1, false); // Tell llvm that `expected_dynamic_sigindex` should equal `found_dynamic_sigindex`. let sigindices_equal = builder @@ -1227,18 +1215,18 @@ fn parse_function( state.push1(res); } Operator::F32Copysign => { - let input = state.pop1()?; + let (mag, sgn) = state.pop2()?; let res = builder - .build_call(intrinsics.copysign_f32, &[input], &state.var_name()) + .build_call(intrinsics.copysign_f32, &[mag, sgn], &state.var_name()) .try_as_basic_value() .left() .unwrap(); state.push1(res); } Operator::F64Copysign => { - let input = state.pop1()?; + let (msg, sgn) = state.pop2()?; let res = builder - .build_call(intrinsics.copysign_f64, &[input], &state.var_name()) + .build_call(intrinsics.copysign_f64, &[msg, sgn], &state.var_name()) .try_as_basic_value() .left() .unwrap(); @@ -1549,7 +1537,7 @@ fn parse_function( &mut state, &mut ctx, memarg, - intrinsics.i32_ptr_ty, + intrinsics.f32_ptr_ty, )?; let result = builder.build_load(effective_address, &state.var_name()); state.push1(result); diff --git a/lib/llvm-backend/src/intrinsics.rs b/lib/llvm-backend/src/intrinsics.rs index 97af89a5b..c3f2191f3 100644 --- a/lib/llvm-backend/src/intrinsics.rs +++ b/lib/llvm-backend/src/intrinsics.rs @@ -231,11 +231,11 @@ impl Intrinsics { sqrt_f32: module.add_function("llvm.sqrt.f32", ret_f32_take_f32, None), sqrt_f64: module.add_function("llvm.sqrt.f64", ret_f64_take_f64, None), - minimum_f32: module.add_function("llvm.minimum.f32", ret_f32_take_f32_f32, None), - minimum_f64: module.add_function("llvm.minimum.f64", ret_f64_take_f64_f64, None), + minimum_f32: module.add_function("llvm.minnum.f32", ret_f32_take_f32_f32, None), + minimum_f64: module.add_function("llvm.minnum.f64", ret_f64_take_f64_f64, None), - maximum_f32: module.add_function("llvm.maximum.f32", ret_f32_take_f32_f32, None), - maximum_f64: module.add_function("llvm.maximum.f64", ret_f64_take_f64_f64, None), + maximum_f32: module.add_function("llvm.maxnum.f32", ret_f32_take_f32_f32, None), + maximum_f64: module.add_function("llvm.maxnum.f64", ret_f64_take_f64_f64, None), ceil_f32: module.add_function("llvm.ceil.f32", ret_f32_take_f32, None), ceil_f64: module.add_function("llvm.ceil.f64", ret_f64_take_f64, None),