wasmer_types/stack/
sourceloc.rs

1// This file contains code from external sources.
2// Attributions: https://github.com/wasmerio/wasmer/blob/main/docs/ATTRIBUTIONS.md
3
4//! Source locations.
5//!
6//! A [`SourceLoc`] determines the position of a certain instruction
7//! relative to the WebAssembly module. This is used mainly for debugging
8//! and tracing errors.
9
10use crate::lib::std::fmt;
11use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
12#[cfg(feature = "enable-serde")]
13use serde::{Deserialize, Serialize};
14
15/// A source location.
16///
17/// The default source location uses the all-ones bit pattern `!0`. It is used for instructions
18/// that can't be given a real source location.
19#[cfg_attr(
20    feature = "enable-serde",
21    derive(Serialize, Deserialize),
22    serde(transparent)
23)]
24#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))]
25#[derive(RkyvSerialize, RkyvDeserialize, Archive)]
26#[repr(transparent)]
27#[derive(Debug, Clone, Copy, PartialEq, Eq)]
28#[rkyv(derive(Debug))]
29pub struct SourceLoc(u32);
30
31impl SourceLoc {
32    /// Create a new source location with the given bits.
33    pub fn new(bits: u32) -> Self {
34        Self(bits)
35    }
36
37    /// Is this the default source location?
38    pub fn is_default(self) -> bool {
39        self == Default::default()
40    }
41
42    /// Read the bits of this source location.
43    pub fn bits(self) -> u32 {
44        self.0
45    }
46}
47
48impl Default for SourceLoc {
49    fn default() -> Self {
50        Self(!0)
51    }
52}
53
54impl fmt::Display for SourceLoc {
55    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
56        if self.is_default() {
57            write!(f, "0x-")
58        } else {
59            write!(f, "0x{:04x}", self.0)
60        }
61    }
62}
63
64#[cfg(test)]
65mod tests {
66    use super::SourceLoc;
67    use crate::lib::std::string::ToString;
68
69    #[test]
70    fn display() {
71        assert_eq!(SourceLoc::default().to_string(), "0x-");
72        assert_eq!(SourceLoc::new(0).to_string(), "0x0000");
73        assert_eq!(SourceLoc::new(16).to_string(), "0x0010");
74        assert_eq!(SourceLoc::new(0xabcdef).to_string(), "0xabcdef");
75    }
76}