载入中...
搜索中...
未找到
CallGraph.hpp
浏览该文件的文档.
1#pragma once
2
3#include "common/Export.h"
4
5#include <cstdint>
6#include <iterator>
7#include <string>
8#include <unordered_map>
9#include <unordered_set>
10#include <utility>
11#include <vector>
12
13namespace eve::dev {
14
17 std::string source;
18 int line = 0;
19 std::string function;
20
21 bool empty() const { return source.empty() && line <= 0 && function.empty(); }
22 bool matches(const SourceLoc& o) const;
23 std::string toString() const;
24};
25
26enum class TraceKind : uint8_t {
27 Call = 0,
28 Return,
29 Line,
30 Def, // variable definition / write
31 Use, // variable use / read
32};
33
36 uint32_t id = 0;
37 TraceKind kind = TraceKind::Line;
39 std::string name; // function name (Call/Return) or variable (Def/Use)
40 uint32_t frameId = 0; // activation record id
41 uint32_t parentEventId = 0; // control predecessor (previous event in flow)
42};
43
45 uint32_t frameId = 0;
47 uint32_t callEventId = 0;
48};
49
51 uint32_t fromEventId = 0; // Def (or Call arg)
52 uint32_t toEventId = 0; // Use (or callee)
53 std::string var;
54};
55
58 SourceLoc loc; // error site (source+line preferred)
59 std::vector<std::string> variables; // empty ⇒ all vars live at site
60 uint32_t eventId = 0; // optional exact seed event
61};
62
64 std::vector<uint32_t> eventIds; // chronological subset of the slice
65 std::vector<SourceLoc> locations; // unique source locations in slice
66 std::vector<CallFrame> callStack; // stack at criterion
67 std::vector<DataFlowEdge> dataFlow; // edges contributing to the error
68 std::string summary;
69};
70
82public:
85
86 CallGraph(const CallGraph&) = delete;
87 CallGraph& operator=(const CallGraph&) = delete;
88
89 void clear();
90 void setMaxEvents(size_t n);
91 size_t maxEvents() const { return maxEvents_; }
92 size_t eventCount() const { return count_; }
93
94 // --- recording ---------------------------------------------------------
95 uint32_t onCall(const SourceLoc& loc, const std::string& funcName = {});
96 uint32_t onReturn(const SourceLoc& loc, const std::string& funcName = {});
97 uint32_t onLine(const SourceLoc& loc);
98 uint32_t onDef(const SourceLoc& loc, const std::string& var);
99 uint32_t onUse(const SourceLoc& loc, const std::string& var);
100
102 uint32_t enter(const SourceLoc& loc, const std::string& funcName);
103
104 // --- queries -----------------------------------------------------------
107 public:
109 public:
110 using iterator_category = std::forward_iterator_tag;
112 using difference_type = std::ptrdiff_t;
113 using pointer = const TraceEvent*;
114 using reference = const TraceEvent&;
115
116 const_iterator() = default;
117 reference operator*() const { return (*g_)[idx_]; }
118 pointer operator->() const { return &(*g_)[idx_]; }
120 ++idx_;
121 return *this;
122 }
124 const_iterator t = *this;
125 ++(*this);
126 return t;
127 }
128 bool operator==(const const_iterator& o) const {
129 return g_ == o.g_ && idx_ == o.idx_;
130 }
131 bool operator!=(const const_iterator& o) const { return !(*this == o); }
132
133 private:
134 friend class EventsView;
135 const_iterator(const CallGraph* g, size_t idx) : g_(g), idx_(idx) {}
136 const CallGraph* g_ = nullptr;
137 size_t idx_ = 0;
138 };
139
140 explicit EventsView(const CallGraph* g) : g_(g) {}
141
142 const_iterator begin() const { return const_iterator(g_, 0); }
143 const_iterator end() const { return const_iterator(g_, g_ ? g_->count_ : 0); }
144 bool empty() const { return !g_ || g_->count_ == 0; }
145 size_t size() const { return g_ ? g_->count_ : 0; }
146 const TraceEvent& operator[](size_t i) const { return (*g_)[i]; }
147 const TraceEvent& front() const { return (*g_)[0]; }
148 const TraceEvent& back() const { return (*g_)[g_->count_ - 1]; }
149
150 private:
151 const CallGraph* g_ = nullptr;
152 };
153
154 EventsView events() const { return EventsView(this); }
155 const TraceEvent* event(uint32_t id) const;
156
157 std::vector<CallFrame> currentStack() const;
159 std::vector<CallFrame> stackAt(uint32_t eventId) const;
160
161 std::vector<std::pair<SourceLoc, SourceLoc>> callEdges() const;
162
168 SliceResult sliceBackward(const SliceCriterion& criterion) const;
169
171 std::string formatErrorReport(const std::string& errorMessage,
172 const SliceCriterion& criterion) const;
173
174private:
175 friend class EventsView;
177
178 uint32_t append(TraceKind kind, const SourceLoc& loc, const std::string& name);
179 void linkData(uint32_t useEventId, const std::string& var);
180 void retireSlot(size_t physical);
181 void ensureRing();
182 uint32_t findSeedEvent(const SliceCriterion& c) const;
183 void collectSeeds(const SliceCriterion& c, std::vector<uint32_t>& out) const;
184
185 size_t physicalIndex(size_t chrono) const {
186 return (head_ + chrono) % maxEvents_;
187 }
188 const TraceEvent& operator[](size_t chrono) const {
189 return slots_[physicalIndex(chrono)];
190 }
191 TraceEvent& operator[](size_t chrono) { return slots_[physicalIndex(chrono)]; }
192 TraceEvent& newest() { return (*this)[count_ - 1]; }
193
194 size_t maxEvents_ = 100000;
195
196 std::vector<TraceEvent> slots_; // fixed capacity ring
197 size_t head_ = 0; // chronological oldest
198 size_t count_ = 0;
199
200 std::vector<uint32_t> frameStack_; // active frame ids (bottom→top)
201 uint32_t nextFrameId_ = 1;
202 uint32_t nextEventId_ = 1;
203 uint32_t lastEventId_ = 0;
204
205 // last Def event id per (frameId, var)
206 std::unordered_map<uint32_t, std::unordered_map<std::string, uint32_t>> lastDef_;
207
208 // Use/Call event → Def/Call events that feed it
209 std::unordered_map<uint32_t, std::vector<uint32_t>> dataDeps_;
210
211 // frameId → Call event that opened the activation
212 std::unordered_map<uint32_t, uint32_t> frameToCallEvent_;
213};
214
215} // namespace eve::dev
int line
Tok kind
#define EVENGINE_API
宿主(eve / libmain)导出宏;插件从进程导入同一批符号。
Definition Export.h:16
glm::vec3 n
Definition Grass.cpp:64
uint32_t c
int idx
const char * name
Definition RockMesh.cpp:21
bool operator!=(const const_iterator &o) const
bool operator==(const const_iterator &o) const
Chronological view over the live ring window (oldest → newest).
const_iterator end() const
const_iterator begin() const
EventsView(const CallGraph *g)
const TraceEvent & front() const
const TraceEvent & back() const
const TraceEvent & operator[](size_t i) const
Runtime call graph + dynamic data-flow tracer with backward slicing.
Definition CallGraph.hpp:81
CallGraph(const CallGraph &)=delete
size_t eventCount() const
Definition CallGraph.hpp:92
size_t maxEvents() const
Definition CallGraph.hpp:91
CallGraph & operator=(const CallGraph &)=delete
EventsView events() const
Criterion for a Weiser-style dynamic backward slice.
Definition CallGraph.hpp:57
std::vector< std::string > variables
Definition CallGraph.hpp:59
std::vector< CallFrame > callStack
Definition CallGraph.hpp:66
std::vector< SourceLoc > locations
Definition CallGraph.hpp:65
std::vector< DataFlowEdge > dataFlow
Definition CallGraph.hpp:67
std::vector< uint32_t > eventIds
Definition CallGraph.hpp:64
Source location in a Squirrel (or synthetic) script.
Definition CallGraph.hpp:16
std::string function
Definition CallGraph.hpp:19
bool empty() const
Definition CallGraph.hpp:21
std::string source
Definition CallGraph.hpp:17
One recorded runtime event used by the dynamic slicer.
Definition CallGraph.hpp:35