rune/runtime/
debug.rs
1use core::fmt;
4
5use serde::{Deserialize, Serialize};
6
7use crate as rune;
8use crate::alloc::prelude::*;
9use crate::alloc::{Box, HashMap, Vec};
10use crate::ast::Span;
11use crate::runtime::DebugLabel;
12use crate::{Hash, ItemBuf, SourceId};
13
14#[derive(Debug, TryClone, Default, Serialize, Deserialize)]
16#[non_exhaustive]
17pub struct DebugInfo {
18 pub instructions: HashMap<usize, DebugInst>,
20 pub functions: HashMap<Hash, DebugSignature>,
22 pub functions_rev: HashMap<usize, Hash>,
24 pub hash_to_ident: HashMap<Hash, Box<str>>,
26}
27
28impl DebugInfo {
29 pub fn instruction_at(&self, ip: usize) -> Option<&DebugInst> {
31 self.instructions.get(&ip)
32 }
33
34 pub fn function_at(&self, ip: usize) -> Option<(Hash, &DebugSignature)> {
36 let hash = *self.functions_rev.get(&ip)?;
37 let signature = self.functions.get(&hash)?;
38 Some((hash, signature))
39 }
40
41 pub fn ident_for_hash(&self, hash: Hash) -> Option<&str> {
43 Some(self.hash_to_ident.get(&hash)?)
44 }
45}
46
47#[derive(Debug, TryClone, Serialize, Deserialize)]
49#[non_exhaustive]
50pub struct DebugInst {
51 pub source_id: SourceId,
53 pub span: Span,
55 pub comment: Option<Box<str>>,
57 pub labels: Vec<DebugLabel>,
59}
60
61impl DebugInst {
62 pub fn new(
64 source_id: SourceId,
65 span: Span,
66 comment: Option<Box<str>>,
67 labels: Vec<DebugLabel>,
68 ) -> Self {
69 Self {
70 source_id,
71 span,
72 comment,
73 labels,
74 }
75 }
76}
77
78#[derive(Debug, TryClone, Serialize, Deserialize)]
80pub enum DebugArgs {
81 EmptyArgs,
83 TupleArgs(usize),
85 Named(Box<[Box<str>]>),
87}
88
89#[derive(Debug, TryClone, Serialize, Deserialize)]
91#[non_exhaustive]
92pub struct DebugSignature {
93 pub path: ItemBuf,
95 pub args: DebugArgs,
97}
98
99impl DebugSignature {
100 pub fn new(path: ItemBuf, args: DebugArgs) -> Self {
102 Self { path, args }
103 }
104}
105
106impl fmt::Display for DebugSignature {
107 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
108 match &self.args {
109 DebugArgs::EmptyArgs => {
110 write!(fmt, "{}", self.path)?;
111 }
112 DebugArgs::TupleArgs(args) if *args > 0 => {
113 write!(fmt, "{}(", self.path)?;
114
115 let mut it = 0..*args;
116 let last = it.next_back();
117
118 for arg in it {
119 write!(fmt, "{}, ", arg)?;
120 }
121
122 if let Some(arg) = last {
123 write!(fmt, "{}", arg)?;
124 }
125
126 write!(fmt, ")")?;
127 }
128 DebugArgs::Named(args) => {
129 write!(fmt, "{}(", self.path)?;
130
131 let mut it = args.iter();
132 let last = it.next_back();
133
134 for arg in it {
135 write!(fmt, "{}, ", arg)?;
136 }
137
138 if let Some(arg) = last {
139 write!(fmt, "{}", arg)?;
140 }
141
142 write!(fmt, ")")?;
143 }
144 _ => (),
145 }
146
147 Ok(())
148 }
149}