• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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