mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-22 13:11:32 +00:00
Restructure to use external crate, add integration
This commit is contained in:
@ -120,6 +120,8 @@ pub struct CompilerConfig {
|
||||
pub cpu_features: Option<String>,
|
||||
|
||||
pub backend_specific_config: Option<BackendCompilerConfig>,
|
||||
|
||||
pub generate_debug_info: bool,
|
||||
}
|
||||
|
||||
/// An exception table for a `RunnableModule`.
|
||||
@ -210,6 +212,11 @@ pub trait RunnableModule: Send + Sync {
|
||||
None
|
||||
}
|
||||
|
||||
/// TODO: document before shipppping
|
||||
fn get_local_function_pointers_and_lengths(&self) -> Option<Vec<(*const u8, usize)>> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Returns the inline breakpoint size corresponding to an Architecture (None in case is not implemented)
|
||||
fn get_inline_breakpoint_size(&self, _arch: Architecture) -> Option<usize> {
|
||||
None
|
||||
|
@ -114,12 +114,21 @@ pub trait ModuleCodeGenerator<FCG: FunctionCodeGenerator<E>, RM: RunnableModule,
|
||||
/// Creates a new function and returns the function-scope code generator for it.
|
||||
fn next_function(&mut self, module_info: Arc<RwLock<ModuleInfo>>) -> Result<&mut FCG, E>;
|
||||
/// Finalizes this module.
|
||||
fn finalize(self, module_info: &ModuleInfo) -> Result<(RM, Box<dyn CacheGen>), E>;
|
||||
fn finalize(self, module_info: &ModuleInfo) -> Result<((RM, Option<DebugMetadata>), Box<dyn CacheGen>), E>;
|
||||
|
||||
/// Creates a module from cache.
|
||||
unsafe fn from_cache(cache: Artifact, _: Token) -> Result<ModuleInner, CacheError>;
|
||||
}
|
||||
|
||||
use cranelift_entity::PrimaryMap;
|
||||
/// missing documentation!
|
||||
pub struct DebugMetadata {
|
||||
///f unc info
|
||||
pub func_info: PrimaryMap<FuncIndex, wasm_debug::types::CompiledFunctionData>,
|
||||
/// inst_info
|
||||
pub inst_info: PrimaryMap<FuncIndex, wasm_debug::types::ValueLabelsRangesInner>,
|
||||
}
|
||||
|
||||
/// A streaming compiler which is designed to generated code for a module based on a stream
|
||||
/// of wasm parser events.
|
||||
pub struct StreamingCompiler<
|
||||
@ -221,6 +230,7 @@ impl<
|
||||
CGEN: Fn() -> MiddlewareChain,
|
||||
> Compiler for StreamingCompiler<MCG, FCG, RM, E, CGEN>
|
||||
{
|
||||
#[allow(unused_variables)]
|
||||
fn compile(
|
||||
&self,
|
||||
wasm: &[u8],
|
||||
@ -231,6 +241,7 @@ impl<
|
||||
validate_with_features(wasm, &compiler_config.features)?;
|
||||
}
|
||||
|
||||
|
||||
let mut mcg = match MCG::backend_id() {
|
||||
"llvm" => MCG::new_with_target(
|
||||
compiler_config.triple.clone(),
|
||||
@ -241,11 +252,43 @@ impl<
|
||||
};
|
||||
let mut chain = (self.middleware_chain_generator)();
|
||||
let info = crate::parse::read_module(wasm, &mut mcg, &mut chain, &compiler_config)?;
|
||||
let (exec_context, cache_gen) =
|
||||
let ((exec_context, debug_metadata), cache_gen) =
|
||||
mcg.finalize(&info.read().unwrap())
|
||||
.map_err(|x| CompileError::InternalError {
|
||||
msg: format!("{:?}", x),
|
||||
})?;
|
||||
|
||||
use target_lexicon::{Triple, Architecture, Vendor, OperatingSystem, Environment, BinaryFormat};
|
||||
const X86_64_OSX: Triple = Triple {
|
||||
architecture: Architecture::X86_64,
|
||||
vendor: Vendor::Apple,
|
||||
operating_system: OperatingSystem::Darwin,
|
||||
environment: Environment::Unknown,
|
||||
binary_format: BinaryFormat::Macho,
|
||||
};
|
||||
|
||||
if compiler_config.generate_debug_info {
|
||||
let debug_metadata = debug_metadata.expect("debug metadata");
|
||||
let debug_info = wasm_debug::read_debuginfo(wasm);
|
||||
let extra_info = wasm_debug::types::ModuleVmctxInfo {
|
||||
memory_offset: 0,
|
||||
stack_slot_offsets: cranelift_entity::PrimaryMap::new(),
|
||||
};
|
||||
// lazy type hack (TODO:)
|
||||
let compiled_fn_map = unsafe { std::mem::transmute(debug_metadata.func_info) };
|
||||
let range_map = unsafe { std::mem::transmute(debug_metadata.inst_info) };
|
||||
let raw_func_slice = vec![];//exec_context.get_local_function_pointers_and_lengths().expect("raw func slice");
|
||||
dbg!("DEBUG INFO GENERATED");
|
||||
let debug_image = wasm_debug::emit_debugsections_image(X86_64_OSX,
|
||||
std::mem::size_of::<usize>() as u8,
|
||||
&debug_info,
|
||||
&extra_info,
|
||||
&compiled_fn_map,
|
||||
&range_map,
|
||||
&raw_func_slice).expect("make debug image");
|
||||
|
||||
crate::jit_debug::register_new_jit_code_entry(&debug_image, crate::jit_debug::JITAction::JIT_REGISTER_FN);
|
||||
}
|
||||
Ok(ModuleInner {
|
||||
cache_gen,
|
||||
runnable_module: Arc::new(Box::new(exec_context)),
|
||||
|
92
lib/runtime-core/src/jit_debug.rs
Normal file
92
lib/runtime-core/src/jit_debug.rs
Normal file
@ -0,0 +1,92 @@
|
||||
#![allow(missing_docs)]
|
||||
use std::ptr;
|
||||
|
||||
// =============================================================================
|
||||
// LLDB hook magic:
|
||||
// see lldb/packages/Python/lldbsuite/test/functionalities/jitloader_gdb in
|
||||
// llvm repo for example
|
||||
//
|
||||
// see also https://sourceware.org/gdb/current/onlinedocs/gdb.html#JIT-Interface
|
||||
|
||||
#[inline(never)]
|
||||
pub extern "C" fn __jit_debug_register_code() {
|
||||
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(Debug)]
|
||||
#[repr(u32)]
|
||||
pub enum JITAction { JIT_NOACTION = 0, JIT_REGISTER_FN = 1, JIT_UNREGISTER_FN = 2 }
|
||||
|
||||
#[no_mangle]
|
||||
#[repr(C)]
|
||||
pub struct JITCodeEntry {
|
||||
next: *mut JITCodeEntry,
|
||||
prev: *mut JITCodeEntry,
|
||||
// TODO: use CStr here?
|
||||
symfile_addr: *const u8,
|
||||
symfile_size: u64,
|
||||
}
|
||||
|
||||
impl Default for JITCodeEntry {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
next: ptr::null_mut(),
|
||||
prev: ptr::null_mut(),
|
||||
symfile_addr: ptr::null(),
|
||||
symfile_size: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[repr(C)]
|
||||
pub struct JitDebugDescriptor {
|
||||
version: u32,
|
||||
action_flag: u32,
|
||||
relevant_entry: *mut JITCodeEntry,
|
||||
first_entry: *mut JITCodeEntry,
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[allow(non_upper_case_globals)]
|
||||
pub static mut __jit_debug_descriptor: JitDebugDescriptor = JitDebugDescriptor {
|
||||
version: 1,
|
||||
action_flag: JITAction::JIT_NOACTION as _,
|
||||
relevant_entry: ptr::null_mut(),
|
||||
first_entry: ptr::null_mut(),
|
||||
};
|
||||
|
||||
/// Prepend an item to the front of the `__jit_debug_descriptor` entry list
|
||||
///
|
||||
/// # Safety
|
||||
/// - Pointer to [`JITCodeEntry`] should point to a valid entry and stay alive
|
||||
/// for the 'static lifetime
|
||||
unsafe fn push_front(jce: *mut JITCodeEntry) {
|
||||
if __jit_debug_descriptor.first_entry.is_null() {
|
||||
__jit_debug_descriptor.first_entry = jce;
|
||||
} else {
|
||||
let old_first = __jit_debug_descriptor.first_entry;
|
||||
debug_assert!((*old_first).prev.is_null());
|
||||
(*jce).next = old_first;
|
||||
(*old_first).prev = jce;
|
||||
__jit_debug_descriptor.first_entry = jce;
|
||||
}
|
||||
}
|
||||
|
||||
// deleted static (added and deleted by Mark): TODO:
|
||||
pub fn register_new_jit_code_entry(bytes: &[u8], action: JITAction) -> *mut JITCodeEntry {
|
||||
let entry: *mut JITCodeEntry = Box::into_raw(Box::new(JITCodeEntry {
|
||||
symfile_addr: bytes.as_ptr(),
|
||||
symfile_size: bytes.len() as _,
|
||||
..JITCodeEntry::default()
|
||||
}));
|
||||
|
||||
unsafe {
|
||||
push_front(entry);
|
||||
__jit_debug_descriptor.relevant_entry = entry;
|
||||
__jit_debug_descriptor.action_flag = action as u32;
|
||||
}
|
||||
|
||||
entry
|
||||
}
|
@ -69,6 +69,7 @@ pub mod fault;
|
||||
pub mod state;
|
||||
#[cfg(feature = "managed")]
|
||||
pub mod tiering;
|
||||
pub mod jit_debug;
|
||||
|
||||
use self::error::CompileResult;
|
||||
#[doc(inline)]
|
||||
|
@ -502,6 +502,17 @@ define_map_index![
|
||||
| imported: ImportedFuncIndex, ImportedMemoryIndex, ImportedTableIndex, ImportedGlobalIndex,
|
||||
];
|
||||
|
||||
// lol
|
||||
impl cranelift_entity::EntityRef for FuncIndex {
|
||||
fn index(self) -> usize {
|
||||
self.0 as usize
|
||||
}
|
||||
|
||||
fn new(x: usize) -> Self {
|
||||
Self(x as u32)
|
||||
}
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
macro_rules! define_local_or_import {
|
||||
($ty:ident, $local_ty:ident, $imported_ty:ident, $imports:ident) => {
|
||||
|
Reference in New Issue
Block a user