jsexn.h (5511B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 /* 8 * JS runtime exception classes. 9 */ 10 11 #ifndef jsexn_h 12 #define jsexn_h 13 14 #include "mozilla/Assertions.h" 15 16 #include "jspubtd.h" 17 #include "jstypes.h" 18 #include "NamespaceImports.h" 19 20 #include "js/ErrorReport.h" 21 #include "js/Exception.h" 22 #include "js/friend/ErrorMessages.h" // JSErr_Limit 23 #include "js/RootingAPI.h" 24 #include "js/TypeDecls.h" 25 #include "js/UniquePtr.h" 26 #include "js/Utility.h" 27 28 extern const JSErrorFormatString js_ErrorFormatString[JSErr_Limit]; 29 30 namespace js { 31 32 class ErrorObject; 33 34 UniquePtr<JSErrorNotes::Note> CopyErrorNote(JSContext* cx, 35 JSErrorNotes::Note* note); 36 37 UniquePtr<JSErrorReport> CopyErrorReport(JSContext* cx, JSErrorReport* report); 38 39 // Cut off the stack if it gets too deep (most commonly for infinite recursion 40 // errors). 41 static const size_t MAX_REPORTED_STACK_DEPTH = 1u << 7; 42 43 bool CaptureStack(JSContext* cx, MutableHandleObject stack); 44 45 JSString* ComputeStackString(JSContext* cx); 46 47 /* 48 * Given a JSErrorReport, check to see if there is an exception associated with 49 * the error number. If there is, then create an appropriate Error object, 50 * set it as the pending exception. 51 * 52 * It's possible we fail (due to OOM or some other error) and end up setting 53 * JSContext::unwrappedException to a different exception. 54 * The original error described by reportp typically won't be reported anywhere 55 * in this case. 56 * 57 * Returns true if the error was converted to an exception. If the error code 58 * is unrecognized, we fail due to OOM, or if we decided to do nothing in order 59 * to avoid recursion, we return false and this error is just being swept under 60 * the rug. 61 */ 62 extern bool ErrorToException(JSContext* cx, JSErrorReport* reportp, 63 JSErrorCallback callback, void* userRef); 64 65 extern JSErrorReport* ErrorFromException(JSContext* cx, HandleObject obj); 66 67 /* 68 * Make a copy of errobj parented to cx's compartment's global. 69 * 70 * errobj may be in a different compartment than cx, but it must be an Error 71 * object (not a wrapper of one) and it must not be one of the standard error 72 * prototype objects (errobj->getPrivate() must not be nullptr). 73 */ 74 extern JSObject* CopyErrorObject(JSContext* cx, 75 JS::Handle<ErrorObject*> errobj); 76 77 static_assert( 78 JSEXN_ERR == 0 && 79 JSProto_Error + int(JSEXN_INTERNALERR) == JSProto_InternalError && 80 JSProto_Error + int(JSEXN_AGGREGATEERR) == JSProto_AggregateError && 81 JSProto_Error + int(JSEXN_EVALERR) == JSProto_EvalError && 82 JSProto_Error + int(JSEXN_RANGEERR) == JSProto_RangeError && 83 JSProto_Error + int(JSEXN_REFERENCEERR) == JSProto_ReferenceError && 84 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT 85 JSProto_Error + int(JSEXN_SUPPRESSEDERR) == JSProto_SuppressedError && 86 #endif 87 JSProto_Error + int(JSEXN_SYNTAXERR) == JSProto_SyntaxError && 88 JSProto_Error + int(JSEXN_TYPEERR) == JSProto_TypeError && 89 JSProto_Error + int(JSEXN_URIERR) == JSProto_URIError && 90 JSProto_Error + int(JSEXN_DEBUGGEEWOULDRUN) == 91 JSProto_DebuggeeWouldRun && 92 JSProto_Error + int(JSEXN_WASMCOMPILEERROR) == JSProto_CompileError && 93 JSProto_Error + int(JSEXN_WASMLINKERROR) == JSProto_LinkError && 94 JSProto_Error + int(JSEXN_WASMRUNTIMEERROR) == JSProto_RuntimeError && 95 #ifdef ENABLE_WASM_JSPI 96 JSProto_Error + int(JSEXN_WASMSUSPENDERROR) == JSProto_SuspendError && 97 JSEXN_WASMSUSPENDERROR + 1 == JSEXN_WARN && 98 #else 99 JSEXN_WASMRUNTIMEERROR + 1 == JSEXN_WARN && 100 #endif 101 JSEXN_WARN + 1 == JSEXN_NOTE && JSEXN_NOTE + 1 == JSEXN_LIMIT, 102 "GetExceptionProtoKey and ExnTypeFromProtoKey require that " 103 "each corresponding JSExnType and JSProtoKey value be separated " 104 "by the same constant value"); 105 106 static inline constexpr JSProtoKey GetExceptionProtoKey(JSExnType exn) { 107 MOZ_ASSERT(JSEXN_ERR <= exn); 108 MOZ_ASSERT(exn < JSEXN_WARN); 109 return JSProtoKey(JSProto_Error + int(exn)); 110 } 111 112 static inline JSExnType ExnTypeFromProtoKey(JSProtoKey key) { 113 JSExnType type = static_cast<JSExnType>(key - JSProto_Error); 114 MOZ_ASSERT(type >= JSEXN_ERR); 115 MOZ_ASSERT(type < JSEXN_ERROR_LIMIT); 116 return type; 117 } 118 119 static inline bool IsErrorProtoKey(JSProtoKey key) { 120 int type = key - JSProto_Error; 121 return type >= JSEXN_ERR && type < JSEXN_ERROR_LIMIT; 122 } 123 124 class AutoClearPendingException { 125 JSContext* cx; 126 127 public: 128 explicit AutoClearPendingException(JSContext* cxArg) : cx(cxArg) {} 129 130 ~AutoClearPendingException() { JS_ClearPendingException(cx); } 131 }; 132 133 // Convert the given value to a string for use in an error message. This 134 // function never returns nullptr and never reports an exception. 135 extern const char* ValueToSourceForError(JSContext* cx, HandleValue val, 136 JS::UniqueChars& bytes); 137 138 bool GetInternalError(JSContext* cx, unsigned errorNumber, 139 MutableHandleValue error); 140 bool GetTypeError(JSContext* cx, unsigned errorNumber, 141 MutableHandleValue error); 142 bool GetAggregateError(JSContext* cx, unsigned errorNumber, 143 MutableHandleValue error); 144 145 } // namespace js 146 147 #endif /* jsexn_h */