/src/node/deps/v8/include/v8-exception.h
Line | Count | Source |
1 | | // Copyright 2021 the V8 project authors. All rights reserved. |
2 | | // Use of this source code is governed by a BSD-style license that can be |
3 | | // found in the LICENSE file. |
4 | | |
5 | | #ifndef INCLUDE_V8_EXCEPTION_H_ |
6 | | #define INCLUDE_V8_EXCEPTION_H_ |
7 | | |
8 | | #include <stddef.h> |
9 | | |
10 | | #include "v8-local-handle.h" // NOLINT(build/include_directory) |
11 | | #include "v8-object.h" // NOLINT(build/include_directory) |
12 | | #include "v8config.h" // NOLINT(build/include_directory) |
13 | | |
14 | | namespace v8 { |
15 | | |
16 | | class Context; |
17 | | class Isolate; |
18 | | class Message; |
19 | | class StackTrace; |
20 | | class String; |
21 | | class Value; |
22 | | |
23 | | namespace internal { |
24 | | class Isolate; |
25 | | class ThreadLocalTop; |
26 | | } // namespace internal |
27 | | |
28 | | /** |
29 | | * Create new error objects by calling the corresponding error object |
30 | | * constructor with the message. |
31 | | */ |
32 | | class V8_EXPORT Exception { |
33 | | public: |
34 | | static Local<Value> RangeError(Local<String> message, |
35 | | Local<Value> options = {}); |
36 | | static Local<Value> ReferenceError(Local<String> message, |
37 | | Local<Value> options = {}); |
38 | | static Local<Value> SyntaxError(Local<String> message, |
39 | | Local<Value> options = {}); |
40 | | static Local<Value> TypeError(Local<String> message, |
41 | | Local<Value> options = {}); |
42 | | static Local<Value> WasmCompileError(Local<String> message, |
43 | | Local<Value> options = {}); |
44 | | static Local<Value> WasmLinkError(Local<String> message, |
45 | | Local<Value> options = {}); |
46 | | static Local<Value> WasmRuntimeError(Local<String> message, |
47 | | Local<Value> options = {}); |
48 | | static Local<Value> WasmSuspendError(Local<String> message, |
49 | | Local<Value> options = {}); |
50 | | static Local<Value> Error(Local<String> message, Local<Value> options = {}); |
51 | | |
52 | | /** |
53 | | * Creates an error message for the given exception. |
54 | | * Will try to reconstruct the original stack trace from the exception value, |
55 | | * or capture the current stack trace if not available. |
56 | | */ |
57 | | static Local<Message> CreateMessage(Isolate* isolate, Local<Value> exception); |
58 | | |
59 | | /** |
60 | | * Returns the original stack trace that was captured at the creation time |
61 | | * of a given exception, or an empty handle if not available. |
62 | | */ |
63 | | static Local<StackTrace> GetStackTrace(Local<Value> exception); |
64 | | |
65 | | /** |
66 | | * Captures the current stack trace and attaches it to the given object in the |
67 | | * form of `stack` property. |
68 | | */ |
69 | | static Maybe<bool> CaptureStackTrace(Local<Context> context, |
70 | | Local<Object> object); |
71 | | }; |
72 | | |
73 | | /** |
74 | | * This is a part of experimental Api and might be changed without further |
75 | | * notice. |
76 | | * Do not use it. |
77 | | */ |
78 | | enum class ExceptionContext : uint32_t { |
79 | | kUnknown, |
80 | | kConstructor, |
81 | | kOperation, |
82 | | kAttributeGet, |
83 | | kAttributeSet, |
84 | | kIndexedQuery, |
85 | | kIndexedGetter, |
86 | | kIndexedDescriptor, |
87 | | kIndexedSetter, |
88 | | kIndexedDefiner, |
89 | | kIndexedDeleter, |
90 | | kNamedQuery, |
91 | | kNamedGetter, |
92 | | kNamedDescriptor, |
93 | | kNamedSetter, |
94 | | kNamedDefiner, |
95 | | kNamedDeleter, |
96 | | kNamedEnumerator |
97 | | }; |
98 | | |
99 | | /** |
100 | | * This is a part of experimental Api and might be changed without further |
101 | | * notice. |
102 | | * Do not use it. |
103 | | */ |
104 | | class ExceptionPropagationMessage { |
105 | | public: |
106 | | ExceptionPropagationMessage(v8::Isolate* isolate, Local<Object> exception, |
107 | | Local<String> interface_name, |
108 | | Local<String> property_name, |
109 | | ExceptionContext exception_context) |
110 | | : isolate_(isolate), |
111 | | exception_(exception), |
112 | | interface_name_(interface_name), |
113 | | property_name_(property_name), |
114 | 0 | exception_context_(exception_context) {} |
115 | | |
116 | 0 | V8_INLINE Isolate* GetIsolate() const { return isolate_; } |
117 | 0 | V8_INLINE Local<Object> GetException() const { return exception_; } |
118 | 0 | V8_INLINE Local<String> GetInterfaceName() const { return interface_name_; } |
119 | 0 | V8_INLINE Local<String> GetPropertyName() const { return property_name_; } |
120 | 0 | V8_INLINE ExceptionContext GetExceptionContext() const { |
121 | 0 | return exception_context_; |
122 | 0 | } |
123 | | |
124 | | private: |
125 | | Isolate* isolate_; |
126 | | Local<Object> exception_; |
127 | | Local<String> interface_name_; |
128 | | Local<String> property_name_; |
129 | | ExceptionContext exception_context_; |
130 | | }; |
131 | | |
132 | | using ExceptionPropagationCallback = |
133 | | void (*)(ExceptionPropagationMessage message); |
134 | | |
135 | | /** |
136 | | * An external exception handler. |
137 | | */ |
138 | | class V8_EXPORT TryCatch { |
139 | | public: |
140 | | /** |
141 | | * Creates a new try/catch block and registers it with v8. Note that |
142 | | * all TryCatch blocks should be stack allocated because the memory |
143 | | * location itself is compared against JavaScript try/catch blocks. |
144 | | */ |
145 | | explicit TryCatch(Isolate* isolate); |
146 | | |
147 | | /** |
148 | | * Unregisters and deletes this try/catch block. |
149 | | */ |
150 | | ~TryCatch(); |
151 | | |
152 | | /** |
153 | | * Returns true if an exception has been caught by this try/catch block. |
154 | | */ |
155 | | bool HasCaught() const; |
156 | | |
157 | | /** |
158 | | * For certain types of exceptions, it makes no sense to continue execution. |
159 | | * |
160 | | * If CanContinue returns false, the correct action is to perform any C++ |
161 | | * cleanup needed and then return. If CanContinue returns false and |
162 | | * HasTerminated returns true, it is possible to call |
163 | | * CancelTerminateExecution in order to continue calling into the engine. |
164 | | */ |
165 | | bool CanContinue() const; |
166 | | |
167 | | /** |
168 | | * Returns true if an exception has been caught due to script execution |
169 | | * being terminated. |
170 | | * |
171 | | * There is no JavaScript representation of an execution termination |
172 | | * exception. Such exceptions are thrown when the TerminateExecution |
173 | | * methods are called to terminate a long-running script. |
174 | | * |
175 | | * If such an exception has been thrown, HasTerminated will return true, |
176 | | * indicating that it is possible to call CancelTerminateExecution in order |
177 | | * to continue calling into the engine. |
178 | | */ |
179 | | bool HasTerminated() const; |
180 | | |
181 | | /** |
182 | | * Throws the exception caught by this TryCatch in a way that avoids |
183 | | * it being caught again by this same TryCatch. As with ThrowException |
184 | | * it is illegal to execute any JavaScript operations after calling |
185 | | * ReThrow; the caller must return immediately to where the exception |
186 | | * is caught. |
187 | | */ |
188 | | Local<Value> ReThrow(); |
189 | | |
190 | | /** |
191 | | * Returns the exception caught by this try/catch block. If no exception has |
192 | | * been caught an empty handle is returned. |
193 | | */ |
194 | | Local<Value> Exception() const; |
195 | | |
196 | | /** |
197 | | * Returns the .stack property of an object. If no .stack |
198 | | * property is present an empty handle is returned. |
199 | | */ |
200 | | V8_WARN_UNUSED_RESULT static MaybeLocal<Value> StackTrace( |
201 | | Local<Context> context, Local<Value> exception); |
202 | | |
203 | | /** |
204 | | * Returns the .stack property of the thrown object. If no .stack property is |
205 | | * present or if this try/catch block has not caught an exception, an empty |
206 | | * handle is returned. |
207 | | */ |
208 | | V8_WARN_UNUSED_RESULT MaybeLocal<Value> StackTrace( |
209 | | Local<Context> context) const; |
210 | | |
211 | | /** |
212 | | * Returns the message associated with this exception. If there is |
213 | | * no message associated an empty handle is returned. |
214 | | */ |
215 | | Local<v8::Message> Message() const; |
216 | | |
217 | | /** |
218 | | * Clears any exceptions that may have been caught by this try/catch block. |
219 | | * After this method has been called, HasCaught() will return false. Cancels |
220 | | * the scheduled exception if it is caught and ReThrow() is not called before. |
221 | | * |
222 | | * It is not necessary to clear a try/catch block before using it again; if |
223 | | * another exception is thrown the previously caught exception will just be |
224 | | * overwritten. However, it is often a good idea since it makes it easier |
225 | | * to determine which operation threw a given exception. |
226 | | */ |
227 | | void Reset(); |
228 | | |
229 | | /** |
230 | | * Set verbosity of the external exception handler. |
231 | | * |
232 | | * By default, exceptions that are caught by an external exception |
233 | | * handler are not reported. Call SetVerbose with true on an |
234 | | * external exception handler to have exceptions caught by the |
235 | | * handler reported as if they were not caught. |
236 | | */ |
237 | | void SetVerbose(bool value); |
238 | | |
239 | | /** |
240 | | * Returns true if verbosity is enabled. |
241 | | */ |
242 | | bool IsVerbose() const; |
243 | | |
244 | | /** |
245 | | * Set whether or not this TryCatch should capture a Message object |
246 | | * which holds source information about where the exception |
247 | | * occurred. True by default. |
248 | | */ |
249 | | void SetCaptureMessage(bool value); |
250 | | |
251 | | TryCatch(const TryCatch&) = delete; |
252 | | void operator=(const TryCatch&) = delete; |
253 | | |
254 | | private: |
255 | | // Declaring operator new and delete as deleted is not spec compliant. |
256 | | // Therefore declare them private instead to disable dynamic alloc |
257 | | void* operator new(size_t size); |
258 | | void* operator new[](size_t size); |
259 | | void operator delete(void*, size_t); |
260 | | void operator delete[](void*, size_t); |
261 | | |
262 | | /** |
263 | | * There are cases when the raw address of C++ TryCatch object cannot be |
264 | | * used for comparisons with addresses into the JS stack. The cases are: |
265 | | * 1) ARM, ARM64 and MIPS simulators which have separate JS stack. |
266 | | * 2) Address sanitizer allocates local C++ object in the heap when |
267 | | * UseAfterReturn mode is enabled. |
268 | | * This method returns address that can be used for comparisons with |
269 | | * addresses into the JS stack. When neither simulator nor ASAN's |
270 | | * UseAfterReturn is enabled, then the address returned will be the address |
271 | | * of the C++ try catch handler itself. |
272 | | */ |
273 | 0 | internal::Address JSStackComparableAddressPrivate() { |
274 | 0 | return js_stack_comparable_address_; |
275 | 0 | } |
276 | | |
277 | | void ResetInternal(); |
278 | | |
279 | | internal::Isolate* i_isolate_; |
280 | | TryCatch* next_; |
281 | | void* exception_; |
282 | | void* message_obj_; |
283 | | internal::Address js_stack_comparable_address_; |
284 | | bool is_verbose_ : 1; |
285 | | bool can_continue_ : 1; |
286 | | bool capture_message_ : 1; |
287 | | bool rethrow_ : 1; |
288 | | |
289 | | friend class internal::Isolate; |
290 | | friend class internal::ThreadLocalTop; |
291 | | }; |
292 | | |
293 | | } // namespace v8 |
294 | | |
295 | | #endif // INCLUDE_V8_EXCEPTION_H_ |