mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-17 02:41:21 +00:00
Merge remote-tracking branch 'origin/master' into feature/llvm-osr
This commit is contained in:
@ -1,19 +1,19 @@
|
||||
use super::stackmap::{self, StackmapRegistry, StkMapRecord, StkSizeRecord};
|
||||
use crate::intrinsics::Intrinsics;
|
||||
use crate::structs::{Callbacks, LLVMModule, LLVMResult, MemProtect};
|
||||
use inkwell::{
|
||||
memory_buffer::MemoryBuffer,
|
||||
module::Module,
|
||||
targets::{CodeModel, FileType, InitializationConfig, RelocMode, Target, TargetMachine},
|
||||
OptimizationLevel,
|
||||
};
|
||||
use libc::{
|
||||
c_char, mmap, mprotect, munmap, MAP_ANON, MAP_PRIVATE, PROT_EXEC, PROT_NONE, PROT_READ,
|
||||
PROT_WRITE,
|
||||
};
|
||||
use libc::c_char;
|
||||
use std::{
|
||||
any::Any,
|
||||
collections::BTreeMap,
|
||||
ffi::{c_void, CString},
|
||||
fs::File,
|
||||
io::Write,
|
||||
mem,
|
||||
ops::Deref,
|
||||
ptr::{self, NonNull},
|
||||
@ -34,42 +34,6 @@ use wasmer_runtime_core::{
|
||||
vm, vmcalls,
|
||||
};
|
||||
|
||||
#[repr(C)]
|
||||
struct LLVMModule {
|
||||
_private: [u8; 0],
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types, dead_code)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
#[repr(C)]
|
||||
enum MemProtect {
|
||||
NONE,
|
||||
READ,
|
||||
READ_WRITE,
|
||||
READ_EXECUTE,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types, dead_code)]
|
||||
#[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, usize) -> *const vm::Func,
|
||||
visit_fde: extern "C" fn(*mut u8, usize, extern "C" fn(*mut u8)),
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
fn module_load(
|
||||
mem_ptr: *const u8,
|
||||
@ -84,7 +48,8 @@ extern "C" {
|
||||
fn llvm_backend_get_code_ptr(module: *const LLVMModule) -> *const u8;
|
||||
fn llvm_backend_get_code_size(module: *const LLVMModule) -> usize;
|
||||
|
||||
fn throw_trap(ty: i32);
|
||||
fn throw_trap(ty: i32) -> !;
|
||||
fn throw_breakpoint(ty: i64) -> !;
|
||||
|
||||
/// This should be the same as spliting up the fat pointer into two arguments,
|
||||
/// but this is cleaner, I think?
|
||||
@ -106,69 +71,21 @@ extern "C" {
|
||||
}
|
||||
|
||||
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 {
|
||||
let size = round_up_to_page_size(size);
|
||||
let ptr = unsafe {
|
||||
mmap(
|
||||
ptr::null_mut(),
|
||||
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
|
||||
unsafe { crate::platform::alloc_memory(size, protect, ptr_out, size_out) }
|
||||
}
|
||||
|
||||
extern "C" fn protect_memory(ptr: *mut u8, size: usize, protect: MemProtect) -> LLVMResult {
|
||||
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
|
||||
}
|
||||
unsafe { crate::platform::protect_memory(ptr, size, protect) }
|
||||
}
|
||||
|
||||
extern "C" fn dealloc_memory(ptr: *mut u8, size: usize) -> LLVMResult {
|
||||
let res = unsafe { munmap(ptr as _, round_up_to_page_size(size)) };
|
||||
|
||||
if res == 0 {
|
||||
LLVMResult::OK
|
||||
} else {
|
||||
LLVMResult::DEALLOC_FAILURE
|
||||
}
|
||||
unsafe { crate::platform::dealloc_memory(ptr, size) }
|
||||
}
|
||||
|
||||
extern "C" fn lookup_vm_symbol(name_ptr: *const c_char, length: usize) -> *const vm::Func {
|
||||
@ -195,7 +112,13 @@ fn get_callbacks() -> Callbacks {
|
||||
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 _,
|
||||
|
||||
fn_name!("vm.memory.grow.dynamic.import") => vmcalls::imported_dynamic_memory_grow as _,
|
||||
fn_name!("vm.memory.size.dynamic.import") => vmcalls::imported_dynamic_memory_size as _,
|
||||
fn_name!("vm.memory.grow.static.import") => vmcalls::imported_static_memory_grow as _,
|
||||
fn_name!("vm.memory.size.static.import") => vmcalls::imported_static_memory_size as _,
|
||||
|
||||
fn_name!("vm.exception.trap") => throw_trap as _,
|
||||
fn_name!("vm.breakpoint") => throw_breakpoint as _,
|
||||
|
||||
_ => ptr::null(),
|
||||
}
|
||||
@ -275,6 +198,14 @@ impl LLVMBackend {
|
||||
.unwrap();
|
||||
let mem_buf_slice = memory_buffer.as_slice();
|
||||
|
||||
if let Some(path) = unsafe { &crate::GLOBAL_OPTIONS.obj_file } {
|
||||
let mut file = File::create(path).unwrap();
|
||||
let mut pos = 0;
|
||||
while pos < mem_buf_slice.len() {
|
||||
pos += file.write(&mem_buf_slice[pos..]).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
let callbacks = get_callbacks();
|
||||
let mut module: *mut LLVMModule = ptr::null_mut();
|
||||
|
||||
|
Reference in New Issue
Block a user