|
1 | | -//! KV 路径与成员分隔符统一管理(对齐 keytree/const.go、entry.go、frame.go、 |
2 | | -//! member.go、vthread.go、sys.go)。所有构造 KV 路径的地方均须使用本模块常量。 |
| 1 | +//! KV 路径与成员分隔符统一管理。所有构造 KV 路径的地方均须使用本模块常量。 |
3 | 2 |
|
4 | 3 | // ── 常量 ───────────────────────────────────────────────────────────── |
5 | 4 |
|
6 | 5 | pub const MEMBER_SEP: &str = "·"; // 成员访问分隔符(U+00B7 中点号):释放 '.' 供小数 key 使用 |
7 | 6 | pub const RUNTIME_MEMBER_SEP: &str = "\u{2025}"; // U+2025,运行时保留字段前缀 |
8 | | -pub const PATH_SEG_SEP: &str = "/"; // 路径分隔符 |
9 | | -pub const PATH_SEG_LIB: &str = "lib"; // /lib |
10 | | -pub const PATH_SEG_VTHREAD: &str = "vthread"; // /vthread |
11 | | - |
12 | | -pub const SEG_RO: &str = "ro"; |
13 | | -pub const SEG_RPARAM: &str = "rparam"; |
14 | | -pub const SEG_WPARAM: &str = "wparam"; |
15 | | -pub const SEG_PC: &str = "pc"; |
16 | | -pub const SEG_CALLPC: &str = "callpc"; |
17 | | -pub const SEG_RETURNPC: &str = "returnpc"; |
18 | | -pub const SEG_STATUS: &str = "status"; |
19 | | -pub const SEG_CTIME: &str = "ctime"; |
20 | | -pub const SEG_DEBUGGER: &str = "debugger"; |
21 | | - |
22 | | -pub const SEG_LIB: &str = "\u{2025}lib"; // 帧 extindex 标记 |
23 | 7 | pub const SEG_LABELS: &str = "labels"; // /lib/<func>/‥labels/<name> → irseq |
24 | 8 | pub const SRC_EXT: &str = ".src"; // 函数源码文件后缀 |
25 | 9 |
|
26 | 10 | pub const LIB_ROOT: &str = "/lib"; |
27 | 11 | pub const RWIR_ROOT: &str = "/lib"; |
28 | | -pub const VTHREAD_ROOT: &str = "/vthread"; |
29 | 12 |
|
30 | 13 | // ── /lib ───────────────────────────────────────────────────────────── |
31 | 14 |
|
@@ -59,90 +42,8 @@ pub fn rwir(opcode: &str) -> String { |
59 | 42 | format!("{RWIR_ROOT}/{opcode}") |
60 | 43 | } |
61 | 44 |
|
62 | | -// ── 帧路径 ─────────────────────────────────────────────────────────── |
63 | | - |
64 | | -fn frame_member(root: &str, seg: &str) -> String { |
65 | | - format!("{}{}{}", stack(root), RUNTIME_MEMBER_SEP, seg) |
66 | | -} |
67 | | - |
68 | | -pub fn stack(root: &str) -> String { |
69 | | - format!("{}/", root.trim_end_matches(PATH_SEG_SEP)) |
70 | | -} |
71 | | - |
72 | | -pub fn frame_ro(root: &str) -> String { |
73 | | - frame_member(root, SEG_RO) |
74 | | -} |
75 | | - |
76 | | -pub fn call_pc(root: &str) -> String { |
77 | | - frame_member(root, SEG_CALLPC) |
78 | | -} |
79 | | - |
80 | | -pub fn return_pc(root: &str) -> String { |
81 | | - frame_member(root, SEG_RETURNPC) |
82 | | -} |
83 | | - |
84 | | -/// Frame root of a PC (`/vthread/42/[3]/[5,0]` → `/vthread/42/[3]`). |
85 | | -pub fn frame_root(pc: &str) -> &str { |
86 | | - if let Some(idx) = pc.rfind("/[") { |
87 | | - &pc[..idx] |
88 | | - } else { |
89 | | - panic!("frame_root: pc has no /[coord] segment: {pc:?}") |
90 | | - } |
91 | | -} |
92 | | - |
93 | | -pub fn entry_pc(root: &str) -> String { |
94 | | - format!("{}/[1,0]", root.trim_end_matches(PATH_SEG_SEP)) |
95 | | -} |
96 | | - |
97 | | -pub fn is_entry_pc(pc: &str) -> bool { |
98 | | - pc.ends_with("/[1,0]") |
99 | | -} |
100 | | - |
101 | 45 | // ── 成员 ───────────────────────────────────────────────────────────── |
102 | 46 |
|
103 | 47 | pub fn member(base: &str, name: &str) -> String { |
104 | 48 | format!("{base}{MEMBER_SEP}{name}") |
105 | 49 | } |
106 | | - |
107 | | -// ── /vthread ───────────────────────────────────────────────────────── |
108 | | - |
109 | | -pub fn v_thread(vtid: &str) -> String { |
110 | | - format!("{VTHREAD_ROOT}/{vtid}") |
111 | | -} |
112 | | - |
113 | | -fn vt_member(vtid: &str, seg: &str) -> String { |
114 | | - format!("{}/{}{}", v_thread(vtid), RUNTIME_MEMBER_SEP, seg) |
115 | | -} |
116 | | - |
117 | | -pub fn v_thread_pc(vtid: &str) -> String { |
118 | | - vt_member(vtid, SEG_PC) |
119 | | -} |
120 | | - |
121 | | -pub fn v_thread_status(vtid: &str) -> String { |
122 | | - vt_member(vtid, SEG_STATUS) |
123 | | -} |
124 | | - |
125 | | -pub fn v_thread_ctime(vtid: &str) -> String { |
126 | | - vt_member(vtid, SEG_CTIME) |
127 | | -} |
128 | | - |
129 | | -pub fn v_thread_debugger(vtid: &str) -> String { |
130 | | - vt_member(vtid, SEG_DEBUGGER) |
131 | | -} |
132 | | - |
133 | | -pub fn v_thread_at(vtid: &str, key: &str) -> String { |
134 | | - format!("{}/{key}", v_thread(vtid)) |
135 | | -} |
136 | | - |
137 | | -/// 从 pc(/vthread/<vtid>/...)提取 vtid。 |
138 | | -pub fn vtid_from_pc(pc: &str) -> String { |
139 | | - let prefix = format!("{VTHREAD_ROOT}/"); |
140 | | - if !pc.starts_with(&prefix) { |
141 | | - return String::new(); |
142 | | - } |
143 | | - let rest = &pc[prefix.len()..]; |
144 | | - match rest.find(PATH_SEG_SEP) { |
145 | | - Some(i) => rest[..i].to_string(), |
146 | | - None => rest.to_string(), |
147 | | - } |
148 | | -} |
0 commit comments