boa_engine/vm/runtime_limits.rs
1/// Represents the limits of different runtime operations.
2#[derive(Debug, Clone, Copy)]
3pub struct RuntimeLimits {
4 /// Max stack size before an error is thrown.
5 stack_size: usize,
6
7 /// Max loop iterations before an error is thrown.
8 loop_iteration: u64,
9
10 /// Max backtrace count in exception.
11 backtrace_limit: usize,
12
13 /// Max JavaScript call-frame recursion.
14 ///
15 /// This counts VM frames only. Native re-entry has its own limit.
16 recursion: usize,
17
18 /// Max nested `Context::run` re-entries from native calls.
19 ///
20 /// Accessors and other host-to-JS calls nest on the Rust stack. That is
21 /// not a JavaScript frame (V8 does not count it). It has its own cap so a
22 /// recursive getter throws `RangeError` before the thread overflows. The
23 /// default matches the historical combined budget: a recursion limit of
24 /// 512 stopped getters at about 256 nested runs.
25 host_recursion: usize,
26}
27
28impl Default for RuntimeLimits {
29 #[inline]
30 fn default() -> Self {
31 Self {
32 loop_iteration: u64::MAX,
33 recursion: 512,
34 host_recursion: 256,
35 backtrace_limit: 50,
36 stack_size: 1024 * 10,
37 }
38 }
39}
40
41impl RuntimeLimits {
42 /// Return the loop iteration limit.
43 ///
44 /// If the limit is exceeded in a loop it will throw an error.
45 ///
46 /// The limit value [`u64::MAX`] means that there is no limit.
47 #[inline]
48 #[must_use]
49 pub const fn loop_iteration_limit(&self) -> u64 {
50 self.loop_iteration
51 }
52
53 /// Set the loop iteration limit.
54 ///
55 /// If the limit is exceeded in a loop it will throw an error.
56 ///
57 /// Setting the limit to [`u64::MAX`] means that there is no limit.
58 #[inline]
59 pub fn set_loop_iteration_limit(&mut self, value: u64) {
60 self.loop_iteration = value;
61 }
62
63 /// Disable loop iteration limit.
64 #[inline]
65 pub fn disable_loop_iteration_limit(&mut self) {
66 self.loop_iteration = u64::MAX;
67 }
68
69 /// Get max backtrace limit for an exception.
70 ///
71 /// Default is 50.
72 #[inline]
73 #[must_use]
74 pub const fn backtrace_limit(&self) -> usize {
75 self.backtrace_limit
76 }
77
78 /// Set max backtrace limit for an exception.
79 #[inline]
80 pub fn set_backtrace_limit(&mut self, value: usize) {
81 self.backtrace_limit = value;
82 }
83
84 /// Get max stack size.
85 #[inline]
86 #[must_use]
87 pub const fn stack_size_limit(&self) -> usize {
88 self.stack_size
89 }
90
91 /// Set max stack size before an error is thrown.
92 #[inline]
93 pub fn set_stack_size_limit(&mut self, value: usize) {
94 self.stack_size = value;
95 }
96
97 /// Get the JavaScript call-frame limit.
98 #[inline]
99 #[must_use]
100 pub const fn recursion_limit(&self) -> usize {
101 self.recursion
102 }
103
104 /// Set the JavaScript call-frame limit before an error is thrown.
105 #[inline]
106 pub fn set_recursion_limit(&mut self, value: usize) {
107 self.recursion = value;
108 }
109
110 /// Get the native re-entry limit.
111 #[inline]
112 #[must_use]
113 pub const fn host_recursion_limit(&self) -> usize {
114 self.host_recursion
115 }
116
117 /// Set the native re-entry limit before an error is thrown.
118 #[inline]
119 pub fn set_host_recursion_limit(&mut self, value: usize) {
120 self.host_recursion = value;
121 }
122}