11cb0ef41Sopenharmony_ci// Copyright 2021 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#ifndef INCLUDE_V8_EXCEPTION_H_ 61cb0ef41Sopenharmony_ci#define INCLUDE_V8_EXCEPTION_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include <stddef.h> 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci#include "v8-local-handle.h" // NOLINT(build/include_directory) 111cb0ef41Sopenharmony_ci#include "v8config.h" // NOLINT(build/include_directory) 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_cinamespace v8 { 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_ciclass Context; 161cb0ef41Sopenharmony_ciclass Isolate; 171cb0ef41Sopenharmony_ciclass Message; 181cb0ef41Sopenharmony_ciclass StackTrace; 191cb0ef41Sopenharmony_ciclass String; 201cb0ef41Sopenharmony_ciclass Value; 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_cinamespace internal { 231cb0ef41Sopenharmony_ciclass Isolate; 241cb0ef41Sopenharmony_ciclass ThreadLocalTop; 251cb0ef41Sopenharmony_ci} // namespace internal 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ci/** 281cb0ef41Sopenharmony_ci * Create new error objects by calling the corresponding error object 291cb0ef41Sopenharmony_ci * constructor with the message. 301cb0ef41Sopenharmony_ci */ 311cb0ef41Sopenharmony_ciclass V8_EXPORT Exception { 321cb0ef41Sopenharmony_ci public: 331cb0ef41Sopenharmony_ci static Local<Value> RangeError(Local<String> message); 341cb0ef41Sopenharmony_ci static Local<Value> ReferenceError(Local<String> message); 351cb0ef41Sopenharmony_ci static Local<Value> SyntaxError(Local<String> message); 361cb0ef41Sopenharmony_ci static Local<Value> TypeError(Local<String> message); 371cb0ef41Sopenharmony_ci static Local<Value> WasmCompileError(Local<String> message); 381cb0ef41Sopenharmony_ci static Local<Value> WasmLinkError(Local<String> message); 391cb0ef41Sopenharmony_ci static Local<Value> WasmRuntimeError(Local<String> message); 401cb0ef41Sopenharmony_ci static Local<Value> Error(Local<String> message); 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_ci /** 431cb0ef41Sopenharmony_ci * Creates an error message for the given exception. 441cb0ef41Sopenharmony_ci * Will try to reconstruct the original stack trace from the exception value, 451cb0ef41Sopenharmony_ci * or capture the current stack trace if not available. 461cb0ef41Sopenharmony_ci */ 471cb0ef41Sopenharmony_ci static Local<Message> CreateMessage(Isolate* isolate, Local<Value> exception); 481cb0ef41Sopenharmony_ci 491cb0ef41Sopenharmony_ci /** 501cb0ef41Sopenharmony_ci * Returns the original stack trace that was captured at the creation time 511cb0ef41Sopenharmony_ci * of a given exception, or an empty handle if not available. 521cb0ef41Sopenharmony_ci */ 531cb0ef41Sopenharmony_ci static Local<StackTrace> GetStackTrace(Local<Value> exception); 541cb0ef41Sopenharmony_ci}; 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ci/** 571cb0ef41Sopenharmony_ci * An external exception handler. 581cb0ef41Sopenharmony_ci */ 591cb0ef41Sopenharmony_ciclass V8_EXPORT TryCatch { 601cb0ef41Sopenharmony_ci public: 611cb0ef41Sopenharmony_ci /** 621cb0ef41Sopenharmony_ci * Creates a new try/catch block and registers it with v8. Note that 631cb0ef41Sopenharmony_ci * all TryCatch blocks should be stack allocated because the memory 641cb0ef41Sopenharmony_ci * location itself is compared against JavaScript try/catch blocks. 651cb0ef41Sopenharmony_ci */ 661cb0ef41Sopenharmony_ci explicit TryCatch(Isolate* isolate); 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ci /** 691cb0ef41Sopenharmony_ci * Unregisters and deletes this try/catch block. 701cb0ef41Sopenharmony_ci */ 711cb0ef41Sopenharmony_ci ~TryCatch(); 721cb0ef41Sopenharmony_ci 731cb0ef41Sopenharmony_ci /** 741cb0ef41Sopenharmony_ci * Returns true if an exception has been caught by this try/catch block. 751cb0ef41Sopenharmony_ci */ 761cb0ef41Sopenharmony_ci bool HasCaught() const; 771cb0ef41Sopenharmony_ci 781cb0ef41Sopenharmony_ci /** 791cb0ef41Sopenharmony_ci * For certain types of exceptions, it makes no sense to continue execution. 801cb0ef41Sopenharmony_ci * 811cb0ef41Sopenharmony_ci * If CanContinue returns false, the correct action is to perform any C++ 821cb0ef41Sopenharmony_ci * cleanup needed and then return. If CanContinue returns false and 831cb0ef41Sopenharmony_ci * HasTerminated returns true, it is possible to call 841cb0ef41Sopenharmony_ci * CancelTerminateExecution in order to continue calling into the engine. 851cb0ef41Sopenharmony_ci */ 861cb0ef41Sopenharmony_ci bool CanContinue() const; 871cb0ef41Sopenharmony_ci 881cb0ef41Sopenharmony_ci /** 891cb0ef41Sopenharmony_ci * Returns true if an exception has been caught due to script execution 901cb0ef41Sopenharmony_ci * being terminated. 911cb0ef41Sopenharmony_ci * 921cb0ef41Sopenharmony_ci * There is no JavaScript representation of an execution termination 931cb0ef41Sopenharmony_ci * exception. Such exceptions are thrown when the TerminateExecution 941cb0ef41Sopenharmony_ci * methods are called to terminate a long-running script. 951cb0ef41Sopenharmony_ci * 961cb0ef41Sopenharmony_ci * If such an exception has been thrown, HasTerminated will return true, 971cb0ef41Sopenharmony_ci * indicating that it is possible to call CancelTerminateExecution in order 981cb0ef41Sopenharmony_ci * to continue calling into the engine. 991cb0ef41Sopenharmony_ci */ 1001cb0ef41Sopenharmony_ci bool HasTerminated() const; 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ci /** 1031cb0ef41Sopenharmony_ci * Throws the exception caught by this TryCatch in a way that avoids 1041cb0ef41Sopenharmony_ci * it being caught again by this same TryCatch. As with ThrowException 1051cb0ef41Sopenharmony_ci * it is illegal to execute any JavaScript operations after calling 1061cb0ef41Sopenharmony_ci * ReThrow; the caller must return immediately to where the exception 1071cb0ef41Sopenharmony_ci * is caught. 1081cb0ef41Sopenharmony_ci */ 1091cb0ef41Sopenharmony_ci Local<Value> ReThrow(); 1101cb0ef41Sopenharmony_ci 1111cb0ef41Sopenharmony_ci /** 1121cb0ef41Sopenharmony_ci * Returns the exception caught by this try/catch block. If no exception has 1131cb0ef41Sopenharmony_ci * been caught an empty handle is returned. 1141cb0ef41Sopenharmony_ci */ 1151cb0ef41Sopenharmony_ci Local<Value> Exception() const; 1161cb0ef41Sopenharmony_ci 1171cb0ef41Sopenharmony_ci /** 1181cb0ef41Sopenharmony_ci * Returns the .stack property of an object. If no .stack 1191cb0ef41Sopenharmony_ci * property is present an empty handle is returned. 1201cb0ef41Sopenharmony_ci */ 1211cb0ef41Sopenharmony_ci V8_WARN_UNUSED_RESULT static MaybeLocal<Value> StackTrace( 1221cb0ef41Sopenharmony_ci Local<Context> context, Local<Value> exception); 1231cb0ef41Sopenharmony_ci 1241cb0ef41Sopenharmony_ci /** 1251cb0ef41Sopenharmony_ci * Returns the .stack property of the thrown object. If no .stack property is 1261cb0ef41Sopenharmony_ci * present or if this try/catch block has not caught an exception, an empty 1271cb0ef41Sopenharmony_ci * handle is returned. 1281cb0ef41Sopenharmony_ci */ 1291cb0ef41Sopenharmony_ci V8_WARN_UNUSED_RESULT MaybeLocal<Value> StackTrace( 1301cb0ef41Sopenharmony_ci Local<Context> context) const; 1311cb0ef41Sopenharmony_ci 1321cb0ef41Sopenharmony_ci /** 1331cb0ef41Sopenharmony_ci * Returns the message associated with this exception. If there is 1341cb0ef41Sopenharmony_ci * no message associated an empty handle is returned. 1351cb0ef41Sopenharmony_ci */ 1361cb0ef41Sopenharmony_ci Local<v8::Message> Message() const; 1371cb0ef41Sopenharmony_ci 1381cb0ef41Sopenharmony_ci /** 1391cb0ef41Sopenharmony_ci * Clears any exceptions that may have been caught by this try/catch block. 1401cb0ef41Sopenharmony_ci * After this method has been called, HasCaught() will return false. Cancels 1411cb0ef41Sopenharmony_ci * the scheduled exception if it is caught and ReThrow() is not called before. 1421cb0ef41Sopenharmony_ci * 1431cb0ef41Sopenharmony_ci * It is not necessary to clear a try/catch block before using it again; if 1441cb0ef41Sopenharmony_ci * another exception is thrown the previously caught exception will just be 1451cb0ef41Sopenharmony_ci * overwritten. However, it is often a good idea since it makes it easier 1461cb0ef41Sopenharmony_ci * to determine which operation threw a given exception. 1471cb0ef41Sopenharmony_ci */ 1481cb0ef41Sopenharmony_ci void Reset(); 1491cb0ef41Sopenharmony_ci 1501cb0ef41Sopenharmony_ci /** 1511cb0ef41Sopenharmony_ci * Set verbosity of the external exception handler. 1521cb0ef41Sopenharmony_ci * 1531cb0ef41Sopenharmony_ci * By default, exceptions that are caught by an external exception 1541cb0ef41Sopenharmony_ci * handler are not reported. Call SetVerbose with true on an 1551cb0ef41Sopenharmony_ci * external exception handler to have exceptions caught by the 1561cb0ef41Sopenharmony_ci * handler reported as if they were not caught. 1571cb0ef41Sopenharmony_ci */ 1581cb0ef41Sopenharmony_ci void SetVerbose(bool value); 1591cb0ef41Sopenharmony_ci 1601cb0ef41Sopenharmony_ci /** 1611cb0ef41Sopenharmony_ci * Returns true if verbosity is enabled. 1621cb0ef41Sopenharmony_ci */ 1631cb0ef41Sopenharmony_ci bool IsVerbose() const; 1641cb0ef41Sopenharmony_ci 1651cb0ef41Sopenharmony_ci /** 1661cb0ef41Sopenharmony_ci * Set whether or not this TryCatch should capture a Message object 1671cb0ef41Sopenharmony_ci * which holds source information about where the exception 1681cb0ef41Sopenharmony_ci * occurred. True by default. 1691cb0ef41Sopenharmony_ci */ 1701cb0ef41Sopenharmony_ci void SetCaptureMessage(bool value); 1711cb0ef41Sopenharmony_ci 1721cb0ef41Sopenharmony_ci TryCatch(const TryCatch&) = delete; 1731cb0ef41Sopenharmony_ci void operator=(const TryCatch&) = delete; 1741cb0ef41Sopenharmony_ci 1751cb0ef41Sopenharmony_ci private: 1761cb0ef41Sopenharmony_ci // Declaring operator new and delete as deleted is not spec compliant. 1771cb0ef41Sopenharmony_ci // Therefore declare them private instead to disable dynamic alloc 1781cb0ef41Sopenharmony_ci void* operator new(size_t size); 1791cb0ef41Sopenharmony_ci void* operator new[](size_t size); 1801cb0ef41Sopenharmony_ci void operator delete(void*, size_t); 1811cb0ef41Sopenharmony_ci void operator delete[](void*, size_t); 1821cb0ef41Sopenharmony_ci 1831cb0ef41Sopenharmony_ci /** 1841cb0ef41Sopenharmony_ci * There are cases when the raw address of C++ TryCatch object cannot be 1851cb0ef41Sopenharmony_ci * used for comparisons with addresses into the JS stack. The cases are: 1861cb0ef41Sopenharmony_ci * 1) ARM, ARM64 and MIPS simulators which have separate JS stack. 1871cb0ef41Sopenharmony_ci * 2) Address sanitizer allocates local C++ object in the heap when 1881cb0ef41Sopenharmony_ci * UseAfterReturn mode is enabled. 1891cb0ef41Sopenharmony_ci * This method returns address that can be used for comparisons with 1901cb0ef41Sopenharmony_ci * addresses into the JS stack. When neither simulator nor ASAN's 1911cb0ef41Sopenharmony_ci * UseAfterReturn is enabled, then the address returned will be the address 1921cb0ef41Sopenharmony_ci * of the C++ try catch handler itself. 1931cb0ef41Sopenharmony_ci */ 1941cb0ef41Sopenharmony_ci internal::Address JSStackComparableAddressPrivate() { 1951cb0ef41Sopenharmony_ci return js_stack_comparable_address_; 1961cb0ef41Sopenharmony_ci } 1971cb0ef41Sopenharmony_ci 1981cb0ef41Sopenharmony_ci void ResetInternal(); 1991cb0ef41Sopenharmony_ci 2001cb0ef41Sopenharmony_ci internal::Isolate* isolate_; 2011cb0ef41Sopenharmony_ci TryCatch* next_; 2021cb0ef41Sopenharmony_ci void* exception_; 2031cb0ef41Sopenharmony_ci void* message_obj_; 2041cb0ef41Sopenharmony_ci internal::Address js_stack_comparable_address_; 2051cb0ef41Sopenharmony_ci bool is_verbose_ : 1; 2061cb0ef41Sopenharmony_ci bool can_continue_ : 1; 2071cb0ef41Sopenharmony_ci bool capture_message_ : 1; 2081cb0ef41Sopenharmony_ci bool rethrow_ : 1; 2091cb0ef41Sopenharmony_ci bool has_terminated_ : 1; 2101cb0ef41Sopenharmony_ci 2111cb0ef41Sopenharmony_ci friend class internal::Isolate; 2121cb0ef41Sopenharmony_ci friend class internal::ThreadLocalTop; 2131cb0ef41Sopenharmony_ci}; 2141cb0ef41Sopenharmony_ci 2151cb0ef41Sopenharmony_ci} // namespace v8 2161cb0ef41Sopenharmony_ci 2171cb0ef41Sopenharmony_ci#endif // INCLUDE_V8_EXCEPTION_H_ 218