/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_  |