amberjs 1.17.0

JavaScript/TypeScript runtime built with Rust and V8
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
// 调用栈分析模块
// 分析函数调用栈,识别热点路径和性能瓶颈

use std::collections::BTreeMap;
use std::collections::HashMap;
use std::collections::VecDeque;
use std::time::SystemTime;
use std::time::{Duration, Instant};

/// 调用栈帧
#[derive(Debug, Clone)]
pub struct StackFrame {
    /// 函数名称
    pub function_name: String,
    /// 文件路径(可选)
    pub file: Option<String>,
    /// 行号(可选)
    pub line: Option<u32>,
    /// 列号(可选)
    pub column: Option<u32>,
    /// 执行时间
    pub execution_time: Duration,
    /// 内存使用
    pub memory_used: usize,
    /// 调用深度
    pub depth: usize,
    /// 时间戳
    pub timestamp: u64, // 使用 u64 而不是 Instant,便于序列化
}
/// 调用栈分析结果
#[derive(Debug, Clone)]
pub struct CallStackAnalysis {
    /// 热点路径(最频繁的调用链)
    pub hot_path: Vec<String>,
    /// 性能瓶颈
    pub bottlenecks: Vec<Bottleneck>,
    /// 递归调用
    pub recursion: Vec<RecursionInfo>,
    /// 调用深度统计
    pub depth_stats: DepthStats,
}
/// 性能瓶颈信息
#[derive(Debug, Clone)]
pub struct Bottleneck {
    /// 函数名称
    pub function: String,
    /// 瓶颈类型
    pub bottleneck_type: BottleneckType,
    /// 描述
    pub description: String,
    /// 影响程度 (0.0 - 1.0)
    pub impact: f64,
}
/// 瓶颈类型
#[derive(Debug, Clone, PartialEq)]
pub enum BottleneckType {
    /// 执行时间过长
    SlowExecution,
    /// 内存使用过多
    HighMemoryUsage,
    /// 调用频率过高,
    HighCallFrequency,
    /// 嵌套过深
    DeepNesting,
}
/// 递归调用信息
#[derive(Debug, Clone)]
pub struct RecursionInfo {
    /// 函数名称
    pub function: String,
    /// 递归深度
    pub recursion_depth: usize,
    /// 递归次数
    pub recursion_count: usize,
    /// 是否有直接递归
    pub is_direct_recursion: bool,
}
/// 调用深度统计
#[derive(Debug, Clone)]
pub struct DepthStats {
    /// 最大调用深度
    pub max_depth: usize,
    /// 平均调用深度
    pub avg_depth: f64,
    /// 深度分布
    pub depth_distribution: HashMap<usize, usize>,
}
/// 调用栈分析器
#[derive(Debug)]
pub struct CallStackAnalyzer {
    /// 最大调用深度限制
    max_depth: usize,
    /// 当前调用栈
    current_stack: VecDeque<StackFrame>,
    /// 调用历史
    call_history: Vec<StackFrame>,
    /// 函数调用计数
    function_call_counts: HashMap<String, usize>,
    /// 递归检测
    recursion_tracker: RecursionTracker,
    /// 统计信息
    stats: AnalyzerStats,
}
/// 递归跟踪器
#[derive(Debug)]
struct RecursionTracker {
    /// 当前递归栈(存储 &str 切片以避免所有权问题)
    current_recursion_stack: Vec<String>,
    /// 递归信息
    recursion_info: HashMap<String, RecursionInfo>,
}
/// 分析器统计信息
#[derive(Debug, Clone, Default)]
pub struct AnalyzerStats {
    /// 总函数调用数
    pub total_calls: u64,
    /// 最大调用深度
    pub max_call_depth: usize,
    /// 检测到的瓶颈数
    pub bottlenecks_detected: u64,
    /// 检测到的递归数
    pub recursion_detected: u64,
    /// 分析次数
    pub analysis_count: u64,
}
impl CallStackAnalyzer {
    /// 创建新的调用栈分析器
    pub fn new(max_depth: usize) -> Self {
        Self {
            max_depth,
            current_stack: VecDeque::new(),
            call_history: Vec::new(),
            function_call_counts: HashMap::new(),
            recursion_tracker: RecursionTracker {
                current_recursion_stack: Vec::new(),
                recursion_info: HashMap::new(),
            },
            stats: AnalyzerStats::default(),
        }
    }
    /// 记录函数进入
    pub fn enter_function(
        &mut self,
        function_name: &str,
        file: Option<String>,
        line: Option<u32>,
        column: Option<u32>,
        timestamp: u64,
    ) {
        let depth: _ = self.current_stack.len();
        // 检查深度限制
        if depth >= self.max_depth {
            // 达到最大深度,记录警告但仍然添加
            eprintln!("Warning: Maximum call depth {} reached", self.max_depth);
        }
        let frame: _ = StackFrame {
            function_name: function_name.to_string(),
            file,
            line,
            column,
            execution_time: Duration::from_nanos(0),
            memory_used: 0,
            depth,
            timestamp,
        };
        self.current_stack.push_back(frame);
        self.stats.total_calls += 1;
        if depth > self.stats.max_call_depth {
            self.stats.max_call_depth = depth;
        }
        // 更新调用计数
        *self
            .function_call_counts
            .entry(function_name.to_string())
            .or_insert(0) += 1;
        // 检查递归
        self.check_recursion(function_name);
    }
    /// 记录函数退出
    pub fn exit_function(
        &mut self,
        function_name: &str,
        end_timestamp: u64,
        memory_used: usize,
    ) -> Option<StackFrame> {
        if let Some(frame) = self.current_stack.pop_back() {
            if frame.function_name == function_name {
                let execution_time: _ = Duration::from_nanos(end_timestamp - frame.timestamp);
                let mut completed_frame = frame;
                completed_frame.execution_time = execution_time;
                completed_frame.memory_used = memory_used;
                self.call_history.push(completed_frame.clone());
                // 从递归栈中移除
                if let Some(pos) = self
                    .recursion_tracker
                    .current_recursion_stack
                    .iter()
                    .position(|f| f == function_name)
                {
                    self.recursion_tracker.current_recursion_stack.remove(pos);
                }
                return Some(completed_frame);
            } else {
                // 函数不匹配,重新放回栈中
                self.current_stack.push_back(frame);
            }
        }
        None
    }
    /// 检查递归调用
    fn check_recursion(&mut self, function_name: &str) {
        // 检查当前递归栈中是否已有此函数
        if self
            .recursion_tracker
            .current_recursion_stack
            .iter()
            .any(|s| s == function_name)
        {
            // 检测到递归
            let depth: _ = self
                .recursion_tracker
                .current_recursion_stack
                .iter()
                .rev()
                .position(|f| f == function_name)
                .map(|pos| self.recursion_tracker.current_recursion_stack.len() - pos)
                .unwrap_or(1);
            let recursion_info: _ = self
                .recursion_tracker
                .recursion_info
                .entry(function_name.to_string())
                .or_insert_with(|| RecursionInfo {
                    function: function_name.to_string(),
                    recursion_depth: 0,
                    recursion_count: 0,
                    is_direct_recursion: true,
                });
            recursion_info.recursion_depth = recursion_info.recursion_depth.max(depth);
            recursion_info.recursion_count += 1;
            self.stats.recursion_detected += 1;
        } else {
            // 添加到递归栈
            self.recursion_tracker
                .current_recursion_stack
                .push(function_name.to_string());
        }
    }
    /// 分析调用栈
    pub fn analyze_stack(&mut self) -> CallStackAnalysis {
        let hot_path: _ = self.identify_hot_path();
        let bottlenecks: _ = self.identify_bottlenecks();
        let recursion: _ = self.get_recursion_info();
        let depth_stats: _ = self.calculate_depth_stats();
        CallStackAnalysis {
            hot_path,
            bottlenecks,
            recursion,
            depth_stats,
        }
    }
    /// 识别热点路径
    fn identify_hot_path(&self) -> Vec<String> {
        // 简化实现:返回最频繁调用的函数序列
        let mut function_counts: Vec<(&String, &usize)> =
            self.function_call_counts.iter().collect();
        function_counts.sort_by(|a, b| b.1.cmp(a.1));
        function_counts
            .into_iter()
            .take(5)
            .map(|(name, _)| name.clone())
            .collect()
    }
    /// 识别性能瓶颈
    fn identify_bottlenecks(&mut self) -> Vec<Bottleneck> {
        let mut bottlenecks = Vec::new();
        // 分析每个函数的性能
        for (function_name, call_count) in &self.function_call_counts {
            // 计算平均执行时间(简化)
            let total_execution_time: Duration = self
                .call_history
                .iter()
                .filter(|frame| &frame.function_name == function_name)
                .map(|frame| frame.execution_time)
                .sum();
            let avg_execution_time: _ = if *call_count > 0 {
                Duration::from_nanos(total_execution_time.as_nanos() as u64 / *call_count as u64)
            } else {
                Duration::from_nanos(0)
            };
            // 检测执行时间过长
            if avg_execution_time > Duration::from_millis(10) {
                bottlenecks.push(Bottleneck {
                    function: function_name.clone(),
                    bottleneck_type: BottleneckType::SlowExecution,
                    description: format!("Average execution time: {:?}", avg_execution_time),
                    impact: 0.8,
                });
            }
            // 检测调用频率过高
            if *call_count > 1000 {
                bottlenecks.push(Bottleneck {
                    function: function_name.clone(),
                    bottleneck_type: BottleneckType::HighCallFrequency,
                    description: format!("Call count: {}", call_count),
                    impact: 0.6,
                });
            }
        }
        // 检测嵌套过深
        if self.stats.max_call_depth > 10 {
            bottlenecks.push(Bottleneck {
                function: "Deep Nesting".to_string(),
                bottleneck_type: BottleneckType::DeepNesting,
                description: format!("Maximum call depth: {}", self.stats.max_call_depth),
                impact: 0.7,
            });
        }
        self.stats.bottlenecks_detected += bottlenecks.len() as u64;
        bottlenecks
    }
    /// 获取递归信息
    fn get_recursion_info(&self) -> Vec<RecursionInfo> {
        self.recursion_tracker
            .recursion_info
            .values()
            .cloned()
            .collect()
    }
    /// 计算深度统计
    fn calculate_depth_stats(&self) -> DepthStats {
        let mut depth_distribution: HashMap<usize, usize> = HashMap::new();
        for frame in &self.call_history {
            *depth_distribution.entry(frame.depth).or_insert(0) += 1;
        }
        let total_calls: _ = self.call_history.len() as f64;
        let avg_depth: _ = if total_calls > 0.0 {
            self.call_history
                .iter()
                .map(|frame| frame.depth as f64)
                .sum::<f64>()
                / total_calls
        } else {
            0.0
        };
        DepthStats {
            max_depth: self.stats.max_call_depth,
            avg_depth,
            depth_distribution,
        }
    }
    /// 获取当前调用栈
    pub fn get_current_stack(&self) -> Vec<&StackFrame> {
        self.current_stack.iter().collect()
    }
    /// 获取函数调用统计
    pub fn get_function_call_counts(&self) -> HashMap<String, usize> {
        self.function_call_counts.clone()
    }
    /// 获取统计信息
    pub fn get_stats(&self) -> &AnalyzerStats {
        &self.stats
    }
    /// 清除所有数据
    pub fn clear(&mut self) {
        self.current_stack.clear();
        self.call_history.clear();
        self.function_call_counts.clear();
        self.recursion_tracker.current_recursion_stack.clear();
        self.recursion_tracker.recursion_info.clear();
        self.stats = AnalyzerStats::default();
    }
    /// 获取调用历史
    pub fn get_call_history(&self) -> &[StackFrame] {
        &self.call_history
    }
    /// 检查是否正在递归
    pub fn is_recursive_call(&self, function_name: &str) -> bool {
        self.recursion_tracker
            .current_recursion_stack
            .iter()
            .any(|s| s == function_name)
    }
    /// 获取当前递归深度
    pub fn get_current_recursion_depth(&self) -> usize {
        self.recursion_tracker.current_recursion_stack.len()
    }
}
#[cfg(test)]
mod tests {
    #[test]
    fn test_call_stack_analyzer_creation() {
        let analyzer: _ = CallStackAnalyzer::new(100);
        assert_eq!(analyzer.get_stats().total_calls, 0);
    }
    #[test]
    fn test_enter_and_exit_function() {
        let mut analyzer = CallStackAnalyzer::new(10);
        let start_time: _ = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .unwrap()
            .as_nanos() as u64;
        analyzer.enter_function("test_func", None, None, None, start_time);
        std::thread::sleep(Duration::from_millis(10));
        let end_time: _ = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .unwrap()
            .as_nanos() as u64;
        let frame: _ = analyzer.exit_function("test_func", end_time, 1024);
        assert!(frame.is_some());
        let frame_data: _ = frame.unwrap();
        assert_eq!(frame_data.function_name, "test_func");
        assert!(frame_data.execution_time >= Duration::from_millis(10));
    }
    #[test]
    fn test_recursion_detection() {
        let mut analyzer = CallStackAnalyzer::new(10);
        let start_time: _ = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .unwrap()
            .as_nanos() as u64;
        analyzer.enter_function("recursive_func", None, None, None, start_time);
        assert!(!analyzer.is_recursive_call("recursive_func"));
        analyzer.enter_function("recursive_func", None, None, None, start_time);
        assert!(analyzer.is_recursive_call("recursive_func"));
        let end_time: _ = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .unwrap()
            .as_nanos() as u64;
        analyzer.exit_function("recursive_func", end_time, 0);
        assert!(!analyzer.is_recursive_call("recursive_func"));
    }
    #[test]
    fn test_analyze_stack() {
        let mut analyzer = CallStackAnalyzer::new(10);
        let start_time: _ = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .unwrap()
            .as_nanos() as u64;
        // 模拟函数调用
        analyzer.enter_function("func_a", None, None, None, start_time);
        analyzer.enter_function("func_b", None, None, None, start_time);
        let end_time: _ = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .unwrap()
            .as_nanos() as u64;
        analyzer.exit_function("func_b", end_time, 0);
        analyzer.exit_function("func_a", end_time, 0);
        let analysis: _ = analyzer.analyze_stack();
        assert!(!analysis.hot_path.is_empty());
        assert!(analysis.depth_stats.max_depth > 0);
    }
    #[test]
    fn test_bottleneck_detection() {
        let mut analyzer = CallStackAnalyzer::new(10);
        // 模拟频繁调用的函数
        for _ in 0..1100 {
            let start_time: _ = SystemTime::now()
                .duration_since(UNIX_EPOCH)
                .unwrap()
                .as_nanos() as u64;
            analyzer.enter_function("frequent_func", None, None, None, start_time);
            let end_time: _ = SystemTime::now()
                .duration_since(UNIX_EPOCH)
                .unwrap()
                .as_nanos() as u64;
            analyzer.exit_function("frequent_func", end_time, 0);
        }
        let analysis: _ = analyzer.analyze_stack();
        let has_frequency_bottleneck: _ = analysis.bottlenecks.iter().any(|b| {
            b.function == "frequent_func" && b.bottleneck_type == BottleneckType::HighCallFrequency
        });
        assert!(has_frequency_bottleneck);
    }
    #[test]
    fn test_max_depth_limit() {
        let mut analyzer = CallStackAnalyzer::new(3);
        let start_time: _ = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .unwrap()
            .as_nanos() as u64;
        // 尝试超过最大深度
        for i in 0..5 {
            analyzer.enter_function(&format!("func_{}", i), None, None, None, start_time);
        }
        let stats: _ = analyzer.get_stats();
        assert_eq!(stats.max_call_depth, 4); // 从0开始计数
    }
    #[test]
    fn test_clear() {
        let mut analyzer = CallStackAnalyzer::new(10);
        let start_time: _ = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .unwrap()
            .as_nanos() as u64;
        analyzer.enter_function("test_func", None, None, None, start_time);
        let end_time: _ = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .unwrap()
            .as_nanos() as u64;
        analyzer.exit_function("test_func", end_time, 0);
        analyzer.clear();
        assert_eq!(analyzer.get_stats().total_calls, 0);
        assert_eq!(analyzer.get_call_history().len(), 0);
    }
    #[test]
    fn test_depth_statistics() {
        let mut analyzer = CallStackAnalyzer::new(10);
        let start_time: _ = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .unwrap()
            .as_nanos() as u64;
        // 不同深度的调用
        analyzer.enter_function("depth_0", None, None, None, start_time);
        analyzer.enter_function("depth_1", None, None, None, start_time);
        let end_time: _ = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .unwrap()
            .as_nanos() as u64;
        analyzer.exit_function("depth_1", end_time, 0);
        analyzer.exit_function("depth_0", end_time, 0);
        let analysis: _ = analyzer.analyze_stack();
        assert!(analysis.depth_stats.avg_depth >= 0.0);
        assert!(analysis.depth_stats.max_depth > 0);
    }
}