Skip to main content

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}