1 // Copyright 2006-2008 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 // The infrastructure used for (localized) message reporting in V8. 6 // 7 // Note: there's a big unresolved issue about ownership of the data 8 // structures used by this framework. 9 10 #ifndef V8_EXECUTION_MESSAGES_H_ 11 #define V8_EXECUTION_MESSAGES_H_ 12 13 #include <memory> 14 15 #include "include/v8-local-handle.h" 16 #include "src/base/optional.h" 17 #include "src/common/message-template.h" 18 #include "src/handles/handles.h" 19 20 namespace v8 { 21 namespace internal { 22 namespace wasm { 23 class WasmCode; 24 } // namespace wasm 25 26 // Forward declarations. 27 class AbstractCode; 28 class JSMessageObject; 29 class LookupIterator; 30 class PrimitiveHeapObject; 31 class SharedFunctionInfo; 32 class SourceInfo; 33 class WasmInstanceObject; 34 35 class V8_EXPORT_PRIVATE MessageLocation { 36 public: 37 // Constructors for when source positions are already known. 38 // TODO(delphick): Collapse to a single constructor with a default parameter 39 // when we stop using the GCC that requires this separation. 40 MessageLocation(Handle<Script> script, int start_pos, int end_pos); 41 MessageLocation(Handle<Script> script, int start_pos, int end_pos, 42 Handle<SharedFunctionInfo> shared); 43 // Constructor for when source positions were not collected but which can be 44 // reconstructed from the SharedFuncitonInfo and bytecode offset. 45 MessageLocation(Handle<Script> script, Handle<SharedFunctionInfo> shared, 46 int bytecode_offset); 47 MessageLocation(); 48 script()49 Handle<Script> script() const { return script_; } start_pos()50 int start_pos() const { return start_pos_; } end_pos()51 int end_pos() const { return end_pos_; } bytecode_offset()52 int bytecode_offset() const { return bytecode_offset_; } shared()53 Handle<SharedFunctionInfo> shared() const { return shared_; } 54 55 private: 56 Handle<Script> script_; 57 int start_pos_; 58 int end_pos_; 59 int bytecode_offset_; 60 Handle<SharedFunctionInfo> shared_; 61 }; 62 63 // Determines how stack trace collection skips frames. 64 enum FrameSkipMode { 65 // Unconditionally skips the first frame. Used e.g. when the Error constructor 66 // is called, in which case the first frame is always a BUILTIN_EXIT frame. 67 SKIP_FIRST, 68 // Skip all frames until a specified caller function is seen. 69 SKIP_UNTIL_SEEN, 70 SKIP_NONE, 71 }; 72 73 class ErrorUtils : public AllStatic { 74 public: 75 // |kDisabled| is useful when you don't need the stack information at all, for 76 // example when creating a deserialized error. 77 enum class StackTraceCollection { kEnabled, kDisabled }; 78 static MaybeHandle<JSObject> Construct(Isolate* isolate, 79 Handle<JSFunction> target, 80 Handle<Object> new_target, 81 Handle<Object> message, 82 Handle<Object> options); 83 static MaybeHandle<JSObject> Construct( 84 Isolate* isolate, Handle<JSFunction> target, Handle<Object> new_target, 85 Handle<Object> message, Handle<Object> options, FrameSkipMode mode, 86 Handle<Object> caller, StackTraceCollection stack_trace_collection); 87 88 V8_EXPORT_PRIVATE static MaybeHandle<String> ToString(Isolate* isolate, 89 Handle<Object> recv); 90 91 static Handle<JSObject> MakeGenericError( 92 Isolate* isolate, Handle<JSFunction> constructor, MessageTemplate index, 93 Handle<Object> arg0, Handle<Object> arg1, Handle<Object> arg2, 94 FrameSkipMode mode); 95 96 // Formats a textual stack trace from the given structured stack trace. 97 // Note that this can call arbitrary JS code through Error.prepareStackTrace. 98 static MaybeHandle<Object> FormatStackTrace(Isolate* isolate, 99 Handle<JSObject> error, 100 Handle<Object> stack_trace); 101 102 static Handle<JSObject> NewIteratorError(Isolate* isolate, 103 Handle<Object> source); 104 static Handle<JSObject> NewCalledNonCallableError(Isolate* isolate, 105 Handle<Object> source); 106 static Handle<JSObject> NewConstructedNonConstructable(Isolate* isolate, 107 Handle<Object> source); 108 // Returns the Exception sentinel. 109 static Object ThrowSpreadArgError(Isolate* isolate, MessageTemplate id, 110 Handle<Object> object); 111 // Returns the Exception sentinel. 112 static Object ThrowLoadFromNullOrUndefined(Isolate* isolate, 113 Handle<Object> object, 114 MaybeHandle<Object> key); 115 116 static MaybeHandle<Object> GetFormattedStack(Isolate* isolate, 117 Handle<JSObject> error_object); 118 static void SetFormattedStack(Isolate* isolate, Handle<JSObject> error_object, 119 Handle<Object> formatted_stack); 120 }; 121 122 class MessageFormatter { 123 public: 124 V8_EXPORT_PRIVATE static const char* TemplateString(MessageTemplate index); 125 126 V8_EXPORT_PRIVATE static MaybeHandle<String> Format(Isolate* isolate, 127 MessageTemplate index, 128 Handle<String> arg0, 129 Handle<String> arg1, 130 Handle<String> arg2); 131 132 static Handle<String> Format(Isolate* isolate, MessageTemplate index, 133 Handle<Object> arg0, 134 Handle<Object> arg1 = Handle<Object>(), 135 Handle<Object> arg2 = Handle<Object>()); 136 }; 137 138 // A message handler is a convenience interface for accessing the list 139 // of message listeners registered in an environment 140 class MessageHandler { 141 public: 142 // Returns a message object for the API to use. 143 V8_EXPORT_PRIVATE static Handle<JSMessageObject> MakeMessageObject( 144 Isolate* isolate, MessageTemplate type, const MessageLocation* location, 145 Handle<Object> argument, Handle<FixedArray> stack_frames); 146 147 // Report a formatted message (needs JS allocation). 148 V8_EXPORT_PRIVATE static void ReportMessage(Isolate* isolate, 149 const MessageLocation* loc, 150 Handle<JSMessageObject> message); 151 152 static void DefaultMessageReport(Isolate* isolate, const MessageLocation* loc, 153 Handle<Object> message_obj); 154 static Handle<String> GetMessage(Isolate* isolate, Handle<Object> data); 155 static std::unique_ptr<char[]> GetLocalizedMessage(Isolate* isolate, 156 Handle<Object> data); 157 158 private: 159 static void ReportMessageNoExceptions(Isolate* isolate, 160 const MessageLocation* loc, 161 Handle<Object> message_obj, 162 v8::Local<v8::Value> api_exception_obj); 163 }; 164 165 } // namespace internal 166 } // namespace v8 167 168 #endif // V8_EXECUTION_MESSAGES_H_ 169