mirror of
https://github.com/mii443/wasmer.git
synced 2025-09-04 08:29:16 +00:00
Moved FrameInfo into wasmer types
This commit is contained in:
@ -3,6 +3,7 @@ use std::fmt;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use wasm_bindgen::{prelude::*, JsValue};
|
use wasm_bindgen::{prelude::*, JsValue};
|
||||||
use wasm_bindgen_downcast::DowncastJS;
|
use wasm_bindgen_downcast::DowncastJS;
|
||||||
|
use wasmer_types::FrameInfo;
|
||||||
|
|
||||||
pub trait CoreError: fmt::Debug + fmt::Display {
|
pub trait CoreError: fmt::Debug + fmt::Display {
|
||||||
fn source(&self) -> Option<&(dyn CoreError + 'static)> {
|
fn source(&self) -> Option<&(dyn CoreError + 'static)> {
|
||||||
@ -169,6 +170,13 @@ impl RuntimeError {
|
|||||||
wasm_bindgen::throw_val(js_error)
|
wasm_bindgen::throw_val(js_error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a list of function frames in WebAssembly code that led to this
|
||||||
|
/// trap happening.
|
||||||
|
pub fn trace(&self) -> &[FrameInfo] {
|
||||||
|
// unimplemented!();
|
||||||
|
return &[];
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a custom user Error.
|
/// Creates a custom user Error.
|
||||||
///
|
///
|
||||||
/// This error object can be passed through Wasm frames and later retrieved
|
/// This error object can be passed through Wasm frames and later retrieved
|
||||||
|
@ -470,10 +470,10 @@ pub use wasmer_derive::ValueType;
|
|||||||
// TODO: OnCalledAction is needed for asyncify. It will be refactored with https://github.com/wasmerio/wasmer/issues/3451
|
// TODO: OnCalledAction is needed for asyncify. It will be refactored with https://github.com/wasmerio/wasmer/issues/3451
|
||||||
pub use wasmer_types::{
|
pub use wasmer_types::{
|
||||||
is_wasm, Bytes, CompileError, CpuFeature, DeserializeError, ExportIndex, ExportType,
|
is_wasm, Bytes, CompileError, CpuFeature, DeserializeError, ExportIndex, ExportType,
|
||||||
ExternType, FunctionType, GlobalInit, GlobalType, ImportType, LocalFunctionIndex, MemoryError,
|
ExternType, FrameInfo, FunctionType, GlobalInit, GlobalType, ImportType, LocalFunctionIndex,
|
||||||
MemoryType, MiddlewareError, Mutability, OnCalledAction, Pages, ParseCpuFeatureError,
|
MemoryError, MemoryType, MiddlewareError, Mutability, OnCalledAction, Pages,
|
||||||
SerializeError, TableType, Target, Type, ValueType, WasmError, WasmResult, WASM_MAX_PAGES,
|
ParseCpuFeatureError, SerializeError, TableType, Target, Type, ValueType, WasmError,
|
||||||
WASM_MIN_PAGES, WASM_PAGE_SIZE,
|
WasmResult, WASM_MAX_PAGES, WASM_MIN_PAGES, WASM_PAGE_SIZE,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "wat")]
|
#[cfg(feature = "wat")]
|
||||||
pub use wat::parse_bytes as wat2wasm;
|
pub use wat::parse_bytes as wat2wasm;
|
||||||
|
@ -14,7 +14,7 @@ pub use target_lexicon::{Architecture, CallingConvention, OperatingSystem, Tripl
|
|||||||
pub use wasmer_compiler::{
|
pub use wasmer_compiler::{
|
||||||
wasmparser, CompilerConfig, FunctionMiddleware, MiddlewareReaderState, ModuleMiddleware,
|
wasmparser, CompilerConfig, FunctionMiddleware, MiddlewareReaderState, ModuleMiddleware,
|
||||||
};
|
};
|
||||||
pub use wasmer_compiler::{Artifact, EngineBuilder, Features, FrameInfo, Tunables};
|
pub use wasmer_compiler::{Artifact, EngineBuilder, Features, Tunables};
|
||||||
#[cfg(feature = "cranelift")]
|
#[cfg(feature = "cranelift")]
|
||||||
pub use wasmer_compiler_cranelift::{Cranelift, CraneliftOptLevel};
|
pub use wasmer_compiler_cranelift::{Cranelift, CraneliftOptLevel};
|
||||||
#[cfg(feature = "llvm")]
|
#[cfg(feature = "llvm")]
|
||||||
|
@ -254,7 +254,7 @@ fn test_run() {
|
|||||||
println!("outputting batch to {}", path.display());
|
println!("outputting batch to {}", path.display());
|
||||||
std::fs::write(&path, vcvars_modified).unwrap();
|
std::fs::write(&path, vcvars_modified).unwrap();
|
||||||
|
|
||||||
print_wasmer_root_to_stdout(&config);
|
// print_wasmer_root_to_stdout(&config);
|
||||||
|
|
||||||
let mut vcvars = std::process::Command::new("cmd");
|
let mut vcvars = std::process::Command::new("cmd");
|
||||||
vcvars.arg("/C");
|
vcvars.arg("/C");
|
||||||
@ -270,7 +270,7 @@ fn test_run() {
|
|||||||
if !output.status.success() {
|
if !output.status.success() {
|
||||||
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
|
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
|
||||||
println!("stdout: {}", String::from_utf8_lossy(&output.stderr));
|
println!("stdout: {}", String::from_utf8_lossy(&output.stderr));
|
||||||
print_wasmer_root_to_stdout(&config);
|
// print_wasmer_root_to_stdout(&config);
|
||||||
panic!("failed to compile {test}");
|
panic!("failed to compile {test}");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,7 +296,7 @@ fn test_run() {
|
|||||||
println!("{output:#?}");
|
println!("{output:#?}");
|
||||||
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
|
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
|
||||||
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
|
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
|
||||||
print_wasmer_root_to_stdout(&config);
|
// print_wasmer_root_to_stdout(&config);
|
||||||
panic!("failed to execute {test}");
|
panic!("failed to execute {test}");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -353,7 +353,7 @@ fn test_run() {
|
|||||||
if !output.status.success() {
|
if !output.status.success() {
|
||||||
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
|
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
|
||||||
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
|
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
|
||||||
print_wasmer_root_to_stdout(&config);
|
// print_wasmer_root_to_stdout(&config);
|
||||||
panic!("failed to compile {test}: {command:#?}");
|
panic!("failed to compile {test}: {command:#?}");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,7 +368,7 @@ fn test_run() {
|
|||||||
if !output.status.success() {
|
if !output.status.success() {
|
||||||
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
|
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
|
||||||
println!("stdout: {}", String::from_utf8_lossy(&output.stderr));
|
println!("stdout: {}", String::from_utf8_lossy(&output.stderr));
|
||||||
print_wasmer_root_to_stdout(&config);
|
// print_wasmer_root_to_stdout(&config);
|
||||||
panic!("failed to execute {test} executable");
|
panic!("failed to execute {test} executable");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,7 +161,7 @@ fn test_ok() {
|
|||||||
println!();
|
println!();
|
||||||
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
|
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
|
||||||
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
|
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
|
||||||
print_wasmer_root_to_stdout(&config);
|
// print_wasmer_root_to_stdout(&config);
|
||||||
panic!("failed to invoke vcvars64.bat {test}");
|
panic!("failed to invoke vcvars64.bat {test}");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,7 +203,7 @@ fn test_ok() {
|
|||||||
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
|
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
|
||||||
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
|
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
|
||||||
println!("output: {:#?}", output);
|
println!("output: {:#?}", output);
|
||||||
print_wasmer_root_to_stdout(&config);
|
// print_wasmer_root_to_stdout(&config);
|
||||||
panic!("failed to compile {test}");
|
panic!("failed to compile {test}");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,7 +225,7 @@ fn test_ok() {
|
|||||||
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
|
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
|
||||||
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
|
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
|
||||||
println!("output: {:#?}", output);
|
println!("output: {:#?}", output);
|
||||||
print_wasmer_root_to_stdout(&config);
|
// print_wasmer_root_to_stdout(&config);
|
||||||
panic!("failed to execute {test}");
|
panic!("failed to execute {test}");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,7 +275,7 @@ fn test_ok() {
|
|||||||
command.arg("-o");
|
command.arg("-o");
|
||||||
command.arg(&format!("{manifest_dir}/../{test}"));
|
command.arg(&format!("{manifest_dir}/../{test}"));
|
||||||
|
|
||||||
print_wasmer_root_to_stdout(&config);
|
// print_wasmer_root_to_stdout(&config);
|
||||||
|
|
||||||
println!("compile: {command:#?}");
|
println!("compile: {command:#?}");
|
||||||
// compile
|
// compile
|
||||||
@ -288,7 +288,7 @@ fn test_ok() {
|
|||||||
if !output.status.success() {
|
if !output.status.success() {
|
||||||
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
|
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
|
||||||
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
|
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
|
||||||
print_wasmer_root_to_stdout(&config);
|
// print_wasmer_root_to_stdout(&config);
|
||||||
panic!("failed to compile {test}: {command:#?}");
|
panic!("failed to compile {test}: {command:#?}");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,7 +303,7 @@ fn test_ok() {
|
|||||||
if !output.status.success() {
|
if !output.status.success() {
|
||||||
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
|
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
|
||||||
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
|
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
|
||||||
print_wasmer_root_to_stdout(&config);
|
// print_wasmer_root_to_stdout(&config);
|
||||||
panic!("failed to execute {test}: {command:#?}");
|
panic!("failed to execute {test}: {command:#?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
use super::frame_info::{FrameInfo, GlobalFrameInfo, FRAME_INFO};
|
use super::frame_info::{GlobalFrameInfo, FRAME_INFO};
|
||||||
use backtrace::Backtrace;
|
use backtrace::Backtrace;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use wasmer_types::FrameInfo;
|
||||||
use wasmer_vm::{Trap, TrapCode};
|
use wasmer_vm::{Trap, TrapCode};
|
||||||
|
|
||||||
/// A struct representing an aborted instruction execution, with a message
|
/// A struct representing an aborted instruction execution, with a message
|
||||||
@ -44,8 +45,6 @@ struct RuntimeErrorInner {
|
|||||||
source: RuntimeErrorSource,
|
source: RuntimeErrorSource,
|
||||||
/// The reconstructed Wasm trace (from the native trace and the `GlobalFrameInfo`).
|
/// The reconstructed Wasm trace (from the native trace and the `GlobalFrameInfo`).
|
||||||
wasm_trace: Vec<FrameInfo>,
|
wasm_trace: Vec<FrameInfo>,
|
||||||
/// The native backtrace
|
|
||||||
native_trace: Option<Backtrace>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _assert_trap_is_sync_and_send(t: &Trap) -> (&dyn Sync, &dyn Send) {
|
fn _assert_trap_is_sync_and_send(t: &Trap) -> (&dyn Sync, &dyn Send) {
|
||||||
@ -191,7 +190,6 @@ impl RuntimeError {
|
|||||||
inner: Arc::new(RuntimeErrorInner {
|
inner: Arc::new(RuntimeErrorInner {
|
||||||
source,
|
source,
|
||||||
wasm_trace,
|
wasm_trace,
|
||||||
native_trace: Some(native_trace),
|
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -257,7 +255,6 @@ impl fmt::Debug for RuntimeError {
|
|||||||
f.debug_struct("RuntimeError")
|
f.debug_struct("RuntimeError")
|
||||||
.field("source", &self.inner.source)
|
.field("source", &self.inner.source)
|
||||||
.field("wasm_trace", &self.inner.wasm_trace)
|
.field("wasm_trace", &self.inner.wasm_trace)
|
||||||
.field("native_trace", &self.inner.native_trace)
|
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,9 @@ use std::cmp;
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
use wasmer_types::entity::{BoxedSlice, EntityRef, PrimaryMap};
|
use wasmer_types::entity::{BoxedSlice, EntityRef, PrimaryMap};
|
||||||
use wasmer_types::{CompiledFunctionFrameInfo, SourceLoc, TrapInformation};
|
use wasmer_types::{
|
||||||
use wasmer_types::{LocalFunctionIndex, ModuleInfo};
|
CompiledFunctionFrameInfo, FrameInfo, LocalFunctionIndex, ModuleInfo, TrapInformation,
|
||||||
|
};
|
||||||
use wasmer_vm::FunctionBodyPtr;
|
use wasmer_vm::FunctionBodyPtr;
|
||||||
|
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
@ -240,97 +241,3 @@ pub fn register(
|
|||||||
assert!(prev.is_none());
|
assert!(prev.is_none());
|
||||||
Some(GlobalFrameInfoRegistration { key: max })
|
Some(GlobalFrameInfoRegistration { key: max })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Description of a frame in a backtrace for a [`RuntimeError::trace`](crate::RuntimeError::trace).
|
|
||||||
///
|
|
||||||
/// Whenever a WebAssembly trap occurs an instance of [`RuntimeError`]
|
|
||||||
/// is created. Each [`RuntimeError`] has a backtrace of the
|
|
||||||
/// WebAssembly frames that led to the trap, and each frame is
|
|
||||||
/// described by this structure.
|
|
||||||
///
|
|
||||||
/// [`RuntimeError`]: crate::RuntimeError
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct FrameInfo {
|
|
||||||
module_name: String,
|
|
||||||
func_index: u32,
|
|
||||||
function_name: Option<String>,
|
|
||||||
func_start: SourceLoc,
|
|
||||||
instr: SourceLoc,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FrameInfo {
|
|
||||||
/// Creates a new [FrameInfo], useful for testing.
|
|
||||||
pub fn new(
|
|
||||||
module_name: String,
|
|
||||||
func_index: u32,
|
|
||||||
function_name: Option<String>,
|
|
||||||
func_start: SourceLoc,
|
|
||||||
instr: SourceLoc,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
|
||||||
module_name,
|
|
||||||
func_index,
|
|
||||||
function_name,
|
|
||||||
func_start,
|
|
||||||
instr,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the WebAssembly function index for this frame.
|
|
||||||
///
|
|
||||||
/// This function index is the index in the function index space of the
|
|
||||||
/// WebAssembly module that this frame comes from.
|
|
||||||
pub fn func_index(&self) -> u32 {
|
|
||||||
self.func_index
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the identifer of the module that this frame is for.
|
|
||||||
///
|
|
||||||
/// ModuleInfo identifiers are present in the `name` section of a WebAssembly
|
|
||||||
/// binary, but this may not return the exact item in the `name` section.
|
|
||||||
/// ModuleInfo names can be overwritten at construction time or perhaps inferred
|
|
||||||
/// from file names. The primary purpose of this function is to assist in
|
|
||||||
/// debugging and therefore may be tweaked over time.
|
|
||||||
///
|
|
||||||
/// This function returns `None` when no name can be found or inferred.
|
|
||||||
pub fn module_name(&self) -> &str {
|
|
||||||
&self.module_name
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a descriptive name of the function for this frame, if one is
|
|
||||||
/// available.
|
|
||||||
///
|
|
||||||
/// The name of this function may come from the `name` section of the
|
|
||||||
/// WebAssembly binary, or wasmer may try to infer a better name for it if
|
|
||||||
/// not available, for example the name of the export if it's exported.
|
|
||||||
///
|
|
||||||
/// This return value is primarily used for debugging and human-readable
|
|
||||||
/// purposes for things like traps. Note that the exact return value may be
|
|
||||||
/// tweaked over time here and isn't guaranteed to be something in
|
|
||||||
/// particular about a wasm module due to its primary purpose of assisting
|
|
||||||
/// in debugging.
|
|
||||||
///
|
|
||||||
/// This function returns `None` when no name could be inferred.
|
|
||||||
pub fn function_name(&self) -> Option<&str> {
|
|
||||||
self.function_name.as_deref()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the offset within the original wasm module this frame's program
|
|
||||||
/// counter was at.
|
|
||||||
///
|
|
||||||
/// The offset here is the offset from the beginning of the original wasm
|
|
||||||
/// module to the instruction that this frame points to.
|
|
||||||
pub fn module_offset(&self) -> usize {
|
|
||||||
self.instr.bits() as usize
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the offset from the original wasm module's function to this
|
|
||||||
/// frame's program counter.
|
|
||||||
///
|
|
||||||
/// The offset here is the offset from the beginning of the defining
|
|
||||||
/// function of this frame (within the wasm module) to the instruction this
|
|
||||||
/// frame points to.
|
|
||||||
pub fn func_offset(&self) -> usize {
|
|
||||||
(self.instr.bits() - self.func_start.bits()) as usize
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -2,6 +2,5 @@ mod error;
|
|||||||
mod frame_info;
|
mod frame_info;
|
||||||
pub use error::RuntimeError;
|
pub use error::RuntimeError;
|
||||||
pub use frame_info::{
|
pub use frame_info::{
|
||||||
register as register_frame_info, FrameInfo, FunctionExtent, GlobalFrameInfoRegistration,
|
register as register_frame_info, FunctionExtent, GlobalFrameInfoRegistration, FRAME_INFO,
|
||||||
FRAME_INFO,
|
|
||||||
};
|
};
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
//! Data structures to provide transformation of the source
|
//! Data structures to provide transformation of the source
|
||||||
// addresses of a WebAssembly module into the native code.
|
// addresses of a WebAssembly module into the native code.
|
||||||
|
|
||||||
use super::sourceloc::SourceLoc;
|
|
||||||
use crate::lib::std::vec::Vec;
|
use crate::lib::std::vec::Vec;
|
||||||
|
use crate::SourceLoc;
|
||||||
use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
|
use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
|
||||||
#[cfg(feature = "enable-serde")]
|
#[cfg(feature = "enable-serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
//! A `Compilation` contains the compiled function bodies for a WebAssembly
|
//! A `Compilation` contains the compiled function bodies for a WebAssembly
|
||||||
//! module (`CompiledFunction`).
|
//! module (`CompiledFunction`).
|
||||||
|
|
||||||
use super::trap::TrapInformation;
|
|
||||||
use crate::entity::PrimaryMap;
|
use crate::entity::PrimaryMap;
|
||||||
use crate::lib::std::vec::Vec;
|
use crate::lib::std::vec::Vec;
|
||||||
|
use crate::TrapInformation;
|
||||||
use crate::{CompiledFunctionUnwindInfo, FunctionAddressMap};
|
use crate::{CompiledFunctionUnwindInfo, FunctionAddressMap};
|
||||||
use crate::{
|
use crate::{
|
||||||
CustomSection, FunctionIndex, LocalFunctionIndex, Relocation, SectionIndex, SignatureIndex,
|
CustomSection, FunctionIndex, LocalFunctionIndex, Relocation, SectionIndex, SignatureIndex,
|
||||||
|
@ -5,8 +5,6 @@ pub mod function;
|
|||||||
pub mod module;
|
pub mod module;
|
||||||
pub mod relocation;
|
pub mod relocation;
|
||||||
pub mod section;
|
pub mod section;
|
||||||
pub mod sourceloc;
|
|
||||||
pub mod symbols;
|
pub mod symbols;
|
||||||
pub mod target;
|
pub mod target;
|
||||||
pub mod trap;
|
|
||||||
pub mod unwind;
|
pub mod unwind;
|
||||||
|
@ -62,6 +62,7 @@ mod libcalls;
|
|||||||
mod memory;
|
mod memory;
|
||||||
mod module;
|
mod module;
|
||||||
mod serialize;
|
mod serialize;
|
||||||
|
mod stack;
|
||||||
mod store_id;
|
mod store_id;
|
||||||
mod table;
|
mod table;
|
||||||
mod trapcode;
|
mod trapcode;
|
||||||
@ -125,11 +126,10 @@ pub use crate::compilation::function::{
|
|||||||
Functions,
|
Functions,
|
||||||
};
|
};
|
||||||
pub use crate::compilation::module::CompileModuleInfo;
|
pub use crate::compilation::module::CompileModuleInfo;
|
||||||
pub use crate::compilation::sourceloc::SourceLoc;
|
|
||||||
pub use crate::compilation::symbols::{Symbol, SymbolRegistry};
|
pub use crate::compilation::symbols::{Symbol, SymbolRegistry};
|
||||||
pub use crate::compilation::trap::TrapInformation;
|
|
||||||
pub use crate::compilation::unwind::CompiledFunctionUnwindInfo;
|
pub use crate::compilation::unwind::CompiledFunctionUnwindInfo;
|
||||||
|
|
||||||
|
pub use crate::stack::{FrameInfo, SourceLoc, TrapInformation};
|
||||||
pub use crate::store_id::StoreId;
|
pub use crate::store_id::StoreId;
|
||||||
|
|
||||||
/// Offset in bytes from the beginning of the function.
|
/// Offset in bytes from the beginning of the function.
|
||||||
|
100
lib/types/src/stack/frame.rs
Normal file
100
lib/types/src/stack/frame.rs
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
use crate::SourceLoc;
|
||||||
|
|
||||||
|
/// Description of a frame in a backtrace for a [`RuntimeError::trace`](crate::RuntimeError::trace).
|
||||||
|
///
|
||||||
|
/// Whenever a WebAssembly trap occurs an instance of [`RuntimeError`]
|
||||||
|
/// is created. Each [`RuntimeError`] has a backtrace of the
|
||||||
|
/// WebAssembly frames that led to the trap, and each frame is
|
||||||
|
/// described by this structure.
|
||||||
|
///
|
||||||
|
/// [`RuntimeError`]: crate::RuntimeError
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct FrameInfo {
|
||||||
|
/// The name of the module
|
||||||
|
pub module_name: String,
|
||||||
|
/// The index of the function in the module
|
||||||
|
pub func_index: u32,
|
||||||
|
/// The function name, if one is available.
|
||||||
|
pub function_name: Option<String>,
|
||||||
|
/// The source location of the function
|
||||||
|
pub func_start: SourceLoc,
|
||||||
|
/// The source location of the instruction
|
||||||
|
pub instr: SourceLoc,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FrameInfo {
|
||||||
|
/// Creates a new [FrameInfo], useful for testing.
|
||||||
|
pub fn new(
|
||||||
|
module_name: String,
|
||||||
|
func_index: u32,
|
||||||
|
function_name: Option<String>,
|
||||||
|
func_start: SourceLoc,
|
||||||
|
instr: SourceLoc,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
module_name,
|
||||||
|
func_index,
|
||||||
|
function_name,
|
||||||
|
func_start,
|
||||||
|
instr,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the WebAssembly function index for this frame.
|
||||||
|
///
|
||||||
|
/// This function index is the index in the function index space of the
|
||||||
|
/// WebAssembly module that this frame comes from.
|
||||||
|
pub fn func_index(&self) -> u32 {
|
||||||
|
self.func_index
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the identifer of the module that this frame is for.
|
||||||
|
///
|
||||||
|
/// ModuleInfo identifiers are present in the `name` section of a WebAssembly
|
||||||
|
/// binary, but this may not return the exact item in the `name` section.
|
||||||
|
/// ModuleInfo names can be overwritten at construction time or perhaps inferred
|
||||||
|
/// from file names. The primary purpose of this function is to assist in
|
||||||
|
/// debugging and therefore may be tweaked over time.
|
||||||
|
///
|
||||||
|
/// This function returns `None` when no name can be found or inferred.
|
||||||
|
pub fn module_name(&self) -> &str {
|
||||||
|
&self.module_name
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a descriptive name of the function for this frame, if one is
|
||||||
|
/// available.
|
||||||
|
///
|
||||||
|
/// The name of this function may come from the `name` section of the
|
||||||
|
/// WebAssembly binary, or wasmer may try to infer a better name for it if
|
||||||
|
/// not available, for example the name of the export if it's exported.
|
||||||
|
///
|
||||||
|
/// This return value is primarily used for debugging and human-readable
|
||||||
|
/// purposes for things like traps. Note that the exact return value may be
|
||||||
|
/// tweaked over time here and isn't guaranteed to be something in
|
||||||
|
/// particular about a wasm module due to its primary purpose of assisting
|
||||||
|
/// in debugging.
|
||||||
|
///
|
||||||
|
/// This function returns `None` when no name could be inferred.
|
||||||
|
pub fn function_name(&self) -> Option<&str> {
|
||||||
|
self.function_name.as_deref()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the offset within the original wasm module this frame's program
|
||||||
|
/// counter was at.
|
||||||
|
///
|
||||||
|
/// The offset here is the offset from the beginning of the original wasm
|
||||||
|
/// module to the instruction that this frame points to.
|
||||||
|
pub fn module_offset(&self) -> usize {
|
||||||
|
self.instr.bits() as usize
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the offset from the original wasm module's function to this
|
||||||
|
/// frame's program counter.
|
||||||
|
///
|
||||||
|
/// The offset here is the offset from the beginning of the defining
|
||||||
|
/// function of this frame (within the wasm module) to the instruction this
|
||||||
|
/// frame points to.
|
||||||
|
pub fn func_offset(&self) -> usize {
|
||||||
|
(self.instr.bits() - self.func_start.bits()) as usize
|
||||||
|
}
|
||||||
|
}
|
9
lib/types/src/stack/mod.rs
Normal file
9
lib/types/src/stack/mod.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
//! Types for the stack tracing / frames.
|
||||||
|
|
||||||
|
mod frame;
|
||||||
|
mod sourceloc;
|
||||||
|
mod trap;
|
||||||
|
|
||||||
|
pub use frame::FrameInfo;
|
||||||
|
pub use sourceloc::SourceLoc;
|
||||||
|
pub use trap::TrapInformation;
|
Reference in New Issue
Block a user