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 #ifndef vm_ErrorReporting_h 8 #define vm_ErrorReporting_h 9 10 #include <stdarg.h> 11 #include <utility> 12 13 #include "jsapi.h" // for JSErrorNotes, JSErrorReport 14 #include "jsfriendapi.h" // for ScriptEnvironmentPreparer 15 16 #include "js/UniquePtr.h" // for UniquePtr 17 #include "js/Utility.h" // for UniqueTwoByteChars 18 19 namespace js { 20 21 /** 22 * Metadata for a compilation error (or warning) at a particular offset, or at 23 * no offset (i.e. with respect to a script overall). 24 */ 25 struct ErrorMetadata { 26 // The file/URL where the error occurred. 27 const char* filename; 28 29 // The line and column numbers where the error occurred. If the error 30 // is with respect to the entire script and not with respect to a 31 // particular location, these will both be zero. 32 uint32_t lineNumber; 33 uint32_t columnNumber; 34 35 // If the error occurs at a particular location, context surrounding the 36 // location of the error: the line that contained the error, or a small 37 // portion of it if the line is long. (If the error occurs within a 38 // regular expression, this context is based upon its pattern characters.) 39 // 40 // This information is provided on a best-effort basis: code populating 41 // ErrorMetadata instances isn't obligated to supply this. 42 JS::UniqueTwoByteChars lineOfContext; 43 44 // If |lineOfContext| is provided, we show only a portion (a "window") of 45 // the line around the erroneous token -- the first char in the token, plus 46 // |lineOfContextRadius| chars before it and |lineOfContextRadius - 1| 47 // chars after it. This is because for a very long line, the full line is 48 // (a) not that helpful, and (b) wastes a lot of memory. See bug 634444. 49 static constexpr size_t lineOfContextRadius = 60; 50 51 // If |lineOfContext| is non-null, its length. 52 size_t lineLength; 53 54 // If |lineOfContext| is non-null, the offset within it of the token that 55 // triggered the error. 56 size_t tokenOffset; 57 58 // Whether the error is "muted" because it derives from a cross-origin 59 // load. See the comment in TransitiveCompileOptions in jsapi.h for 60 // details. 61 bool isMuted; 62 }; 63 64 class CompileError : public JSErrorReport { 65 public: 66 void throwError(JSContext* cx); 67 }; 68 69 class MOZ_STACK_CLASS ReportExceptionClosure final 70 : public ScriptEnvironmentPreparer::Closure { 71 JS::HandleValue exn_; 72 73 public: ReportExceptionClosure(JS::HandleValue exn)74 explicit ReportExceptionClosure(JS::HandleValue exn) : exn_(exn) {} 75 76 bool operator()(JSContext* cx) override; 77 }; 78 79 /** Send a JSErrorReport to the warningReporter callback. */ 80 extern void CallWarningReporter(JSContext* cx, JSErrorReport* report); 81 82 /** 83 * Report a compile error during script processing prior to execution of the 84 * script. 85 */ 86 extern void ReportCompileErrorLatin1(JSContext* cx, ErrorMetadata&& metadata, 87 UniquePtr<JSErrorNotes> notes, 88 unsigned errorNumber, va_list* args); 89 90 extern void ReportCompileErrorUTF8(JSContext* cx, ErrorMetadata&& metadata, 91 UniquePtr<JSErrorNotes> notes, 92 unsigned errorNumber, va_list* args); 93 94 /** 95 * Report a compile warning during script processing prior to execution of the 96 * script. Returns true if the warning was successfully reported, false if an 97 * error occurred. 98 */ 99 extern MOZ_MUST_USE bool ReportCompileWarning(JSContext* cx, 100 ErrorMetadata&& metadata, 101 UniquePtr<JSErrorNotes> notes, 102 unsigned errorNumber, 103 va_list* args); 104 105 class GlobalObject; 106 107 /** 108 * Report the given error Value to the given global. The JSContext is not 109 * assumed to be in any particular realm, but the global and error are 110 * expected to be same-compartment. 111 */ 112 extern void ReportErrorToGlobal(JSContext* cx, 113 JS::Handle<js::GlobalObject*> global, 114 JS::HandleValue error); 115 116 enum ErrorArgumentsType { 117 ArgumentsAreUnicode, 118 ArgumentsAreASCII, 119 ArgumentsAreLatin1, 120 ArgumentsAreUTF8 121 }; 122 123 enum class IsWarning { No, Yes }; 124 125 /** 126 * Report an exception, using printf-style APIs to generate the error 127 * message. 128 */ 129 extern bool ReportErrorVA(JSContext* cx, IsWarning isWarning, 130 const char* format, ErrorArgumentsType argumentsType, 131 va_list ap) MOZ_FORMAT_PRINTF(3, 0); 132 133 extern bool ReportErrorNumberVA(JSContext* cx, IsWarning isWarning, 134 JSErrorCallback callback, void* userRef, 135 const unsigned errorNumber, 136 ErrorArgumentsType argumentsType, va_list ap); 137 138 extern bool ReportErrorNumberUCArray(JSContext* cx, IsWarning isWarning, 139 JSErrorCallback callback, void* userRef, 140 const unsigned errorNumber, 141 const char16_t** args); 142 143 extern bool ReportErrorNumberUTF8Array(JSContext* cx, IsWarning isWarning, 144 JSErrorCallback callback, void* userRef, 145 const unsigned errorNumber, 146 const char** args); 147 148 extern bool ExpandErrorArgumentsVA(JSContext* cx, JSErrorCallback callback, 149 void* userRef, const unsigned errorNumber, 150 const char16_t** messageArgs, 151 ErrorArgumentsType argumentsType, 152 JSErrorReport* reportp, va_list ap); 153 154 extern bool ExpandErrorArgumentsVA(JSContext* cx, JSErrorCallback callback, 155 void* userRef, const unsigned errorNumber, 156 const char** messageArgs, 157 ErrorArgumentsType argumentsType, 158 JSErrorReport* reportp, va_list ap); 159 160 /* 161 * For cases when we do not have an arguments array. 162 */ 163 extern bool ExpandErrorArgumentsVA(JSContext* cx, JSErrorCallback callback, 164 void* userRef, const unsigned errorNumber, 165 ErrorArgumentsType argumentsType, 166 JSErrorReport* reportp, va_list ap); 167 168 extern bool ExpandErrorArgumentsVA(JSContext* cx, JSErrorCallback callback, 169 void* userRef, const unsigned errorNumber, 170 const char16_t** messageArgs, 171 ErrorArgumentsType argumentsType, 172 JSErrorNotes::Note* notep, va_list ap); 173 174 } // namespace js 175 176 #endif /* vm_ErrorReporting_h */ 177