Line data Source code
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_MESSAGES_H_
11 : #define V8_MESSAGES_H_
12 :
13 : #include <memory>
14 :
15 : #include "src/handles.h"
16 : #include "src/message-template.h"
17 :
18 : namespace v8 {
19 : namespace internal {
20 : namespace wasm {
21 : class WasmCode;
22 : }
23 :
24 : // Forward declarations.
25 : class AbstractCode;
26 : class FrameArray;
27 : class JSMessageObject;
28 : class LookupIterator;
29 : class SharedFunctionInfo;
30 : class SourceInfo;
31 : class WasmInstanceObject;
32 :
33 : class MessageLocation {
34 : public:
35 : MessageLocation(Handle<Script> script, int start_pos, int end_pos);
36 : MessageLocation(Handle<Script> script, int start_pos, int end_pos,
37 : Handle<SharedFunctionInfo> shared);
38 : MessageLocation();
39 :
40 86 : Handle<Script> script() const { return script_; }
41 222 : int start_pos() const { return start_pos_; }
42 : int end_pos() const { return end_pos_; }
43 530 : Handle<SharedFunctionInfo> shared() const { return shared_; }
44 :
45 : private:
46 : Handle<Script> script_;
47 : int start_pos_;
48 : int end_pos_;
49 : Handle<SharedFunctionInfo> shared_;
50 : };
51 :
52 : class StackFrameBase {
53 : public:
54 945126 : virtual ~StackFrameBase() = default;
55 :
56 : virtual Handle<Object> GetReceiver() const = 0;
57 : virtual Handle<Object> GetFunction() const = 0;
58 :
59 : virtual Handle<Object> GetFileName() = 0;
60 : virtual Handle<Object> GetFunctionName() = 0;
61 : virtual Handle<Object> GetScriptNameOrSourceUrl() = 0;
62 : virtual Handle<Object> GetMethodName() = 0;
63 : virtual Handle<Object> GetTypeName() = 0;
64 : virtual Handle<Object> GetEvalOrigin();
65 :
66 : // Returns the script ID if one is attached, -1 otherwise.
67 : int GetScriptId() const;
68 :
69 : virtual int GetPosition() const = 0;
70 : // Return 1-based line number, including line offset.
71 : virtual int GetLineNumber() = 0;
72 : // Return 1-based column number, including column offset if first line.
73 : virtual int GetColumnNumber() = 0;
74 :
75 : // Returns index for Promise.all() async frames, or -1 for other frames.
76 : virtual int GetPromiseIndex() const = 0;
77 :
78 : virtual bool IsNative() = 0;
79 : virtual bool IsToplevel() = 0;
80 : virtual bool IsEval();
81 : virtual bool IsAsync() const = 0;
82 : virtual bool IsPromiseAll() const = 0;
83 : virtual bool IsConstructor() = 0;
84 : virtual bool IsStrict() const = 0;
85 :
86 : virtual MaybeHandle<String> ToString() = 0;
87 :
88 : // Used to signal that the requested field is unknown.
89 : static const int kNone = -1;
90 :
91 : protected:
92 977340 : StackFrameBase() = default;
93 0 : explicit StackFrameBase(Isolate* isolate) : isolate_(isolate) {}
94 : Isolate* isolate_;
95 :
96 : private:
97 : virtual bool HasScript() const = 0;
98 : virtual Handle<Script> GetScript() const = 0;
99 : };
100 :
101 : class JSStackFrame : public StackFrameBase {
102 : public:
103 : JSStackFrame(Isolate* isolate, Handle<Object> receiver,
104 : Handle<JSFunction> function, Handle<AbstractCode> code,
105 : int offset);
106 315042 : ~JSStackFrame() override = default;
107 :
108 191 : Handle<Object> GetReceiver() const override { return receiver_; }
109 : Handle<Object> GetFunction() const override;
110 :
111 : Handle<Object> GetFileName() override;
112 : Handle<Object> GetFunctionName() override;
113 : Handle<Object> GetScriptNameOrSourceUrl() override;
114 : Handle<Object> GetMethodName() override;
115 : Handle<Object> GetTypeName() override;
116 :
117 : int GetPosition() const override;
118 : int GetLineNumber() override;
119 : int GetColumnNumber() override;
120 :
121 : int GetPromiseIndex() const override;
122 :
123 : bool IsNative() override;
124 : bool IsToplevel() override;
125 59625 : bool IsAsync() const override { return is_async_; }
126 59598 : bool IsPromiseAll() const override { return is_promise_all_; }
127 100678 : bool IsConstructor() override { return is_constructor_; }
128 758 : bool IsStrict() const override { return is_strict_; }
129 :
130 : MaybeHandle<String> ToString() override;
131 :
132 : private:
133 325780 : JSStackFrame() = default;
134 : void FromFrameArray(Isolate* isolate, Handle<FrameArray> array, int frame_ix);
135 :
136 : bool HasScript() const override;
137 : Handle<Script> GetScript() const override;
138 :
139 : Handle<Object> receiver_;
140 : Handle<JSFunction> function_;
141 : Handle<AbstractCode> code_;
142 : int offset_;
143 :
144 : bool is_async_ : 1;
145 : bool is_constructor_ : 1;
146 : bool is_promise_all_ : 1;
147 : bool is_strict_ : 1;
148 :
149 : friend class FrameArrayIterator;
150 : };
151 :
152 : class WasmStackFrame : public StackFrameBase {
153 : public:
154 630084 : ~WasmStackFrame() override = default;
155 :
156 : Handle<Object> GetReceiver() const override;
157 : Handle<Object> GetFunction() const override;
158 :
159 1032 : Handle<Object> GetFileName() override { return Null(); }
160 : Handle<Object> GetFunctionName() override;
161 888 : Handle<Object> GetScriptNameOrSourceUrl() override { return Null(); }
162 0 : Handle<Object> GetMethodName() override { return Null(); }
163 0 : Handle<Object> GetTypeName() override { return Null(); }
164 :
165 : int GetPosition() const override;
166 644 : int GetLineNumber() override { return wasm_func_index_; }
167 0 : int GetColumnNumber() override { return kNone; }
168 :
169 0 : int GetPromiseIndex() const override { return kNone; }
170 :
171 88 : bool IsNative() override { return false; }
172 0 : bool IsToplevel() override { return false; }
173 0 : bool IsAsync() const override { return false; }
174 0 : bool IsPromiseAll() const override { return false; }
175 444 : bool IsConstructor() override { return false; }
176 208 : bool IsStrict() const override { return false; }
177 : bool IsInterpreted() const { return code_ == nullptr; }
178 :
179 : MaybeHandle<String> ToString() override;
180 :
181 : protected:
182 : Handle<Object> Null() const;
183 :
184 : bool HasScript() const override;
185 : Handle<Script> GetScript() const override;
186 :
187 : Handle<WasmInstanceObject> wasm_instance_;
188 : uint32_t wasm_func_index_;
189 : wasm::WasmCode* code_; // null for interpreted frames.
190 : int offset_;
191 :
192 : private:
193 651560 : WasmStackFrame() = default;
194 : void FromFrameArray(Isolate* isolate, Handle<FrameArray> array, int frame_ix);
195 :
196 : friend class FrameArrayIterator;
197 : friend class AsmJsWasmStackFrame;
198 : };
199 :
200 : class AsmJsWasmStackFrame : public WasmStackFrame {
201 : public:
202 315042 : ~AsmJsWasmStackFrame() override = default;
203 :
204 : Handle<Object> GetReceiver() const override;
205 : Handle<Object> GetFunction() const override;
206 :
207 : Handle<Object> GetFileName() override;
208 : Handle<Object> GetScriptNameOrSourceUrl() override;
209 :
210 : int GetPosition() const override;
211 : int GetLineNumber() override;
212 : int GetColumnNumber() override;
213 :
214 : MaybeHandle<String> ToString() override;
215 :
216 : private:
217 : friend class FrameArrayIterator;
218 325780 : AsmJsWasmStackFrame() = default;
219 : void FromFrameArray(Isolate* isolate, Handle<FrameArray> array, int frame_ix);
220 :
221 : bool is_at_number_conversion_;
222 : };
223 :
224 : class FrameArrayIterator {
225 : public:
226 : FrameArrayIterator(Isolate* isolate, Handle<FrameArray> array,
227 : int frame_ix = 0);
228 :
229 : StackFrameBase* Frame();
230 :
231 : bool HasFrame() const;
232 : void Advance();
233 :
234 : private:
235 : Isolate* isolate_;
236 :
237 : Handle<FrameArray> array_;
238 : int frame_ix_;
239 :
240 : WasmStackFrame wasm_frame_;
241 : AsmJsWasmStackFrame asm_wasm_frame_;
242 : JSStackFrame js_frame_;
243 : };
244 :
245 : // Determines how stack trace collection skips frames.
246 : enum FrameSkipMode {
247 : // Unconditionally skips the first frame. Used e.g. when the Error constructor
248 : // is called, in which case the first frame is always a BUILTIN_EXIT frame.
249 : SKIP_FIRST,
250 : // Skip all frames until a specified caller function is seen.
251 : SKIP_UNTIL_SEEN,
252 : SKIP_NONE,
253 : };
254 :
255 : class ErrorUtils : public AllStatic {
256 : public:
257 : static MaybeHandle<Object> Construct(
258 : Isolate* isolate, Handle<JSFunction> target, Handle<Object> new_target,
259 : Handle<Object> message, FrameSkipMode mode, Handle<Object> caller,
260 : bool suppress_detailed_trace);
261 :
262 : static MaybeHandle<String> ToString(Isolate* isolate, Handle<Object> recv);
263 :
264 : static MaybeHandle<Object> MakeGenericError(
265 : Isolate* isolate, Handle<JSFunction> constructor, MessageTemplate index,
266 : Handle<Object> arg0, Handle<Object> arg1, Handle<Object> arg2,
267 : FrameSkipMode mode);
268 :
269 : // Formats a textual stack trace from the given structured stack trace.
270 : // Note that this can call arbitrary JS code through Error.prepareStackTrace.
271 : static MaybeHandle<Object> FormatStackTrace(Isolate* isolate,
272 : Handle<JSObject> error,
273 : Handle<Object> stack_trace);
274 : };
275 :
276 : class MessageFormatter {
277 : public:
278 : static const char* TemplateString(MessageTemplate index);
279 :
280 : static MaybeHandle<String> FormatMessage(Isolate* isolate,
281 : MessageTemplate index,
282 : Handle<String> arg0,
283 : Handle<String> arg1,
284 : Handle<String> arg2);
285 :
286 : static Handle<String> FormatMessage(Isolate* isolate, MessageTemplate index,
287 : Handle<Object> arg);
288 : };
289 :
290 :
291 : // A message handler is a convenience interface for accessing the list
292 : // of message listeners registered in an environment
293 : class MessageHandler {
294 : public:
295 : // Returns a message object for the API to use.
296 : static Handle<JSMessageObject> MakeMessageObject(
297 : Isolate* isolate, MessageTemplate type, const MessageLocation* location,
298 : Handle<Object> argument, Handle<FixedArray> stack_frames);
299 :
300 : // Report a formatted message (needs JS allocation).
301 : static void ReportMessage(Isolate* isolate, const MessageLocation* loc,
302 : Handle<JSMessageObject> message);
303 :
304 : static void DefaultMessageReport(Isolate* isolate, const MessageLocation* loc,
305 : Handle<Object> message_obj);
306 : static Handle<String> GetMessage(Isolate* isolate, Handle<Object> data);
307 : static std::unique_ptr<char[]> GetLocalizedMessage(Isolate* isolate,
308 : Handle<Object> data);
309 :
310 : private:
311 : static void ReportMessageNoExceptions(Isolate* isolate,
312 : const MessageLocation* loc,
313 : Handle<Object> message_obj,
314 : v8::Local<v8::Value> api_exception_obj);
315 : };
316 :
317 :
318 : } // namespace internal
319 : } // namespace v8
320 :
321 : #endif // V8_MESSAGES_H_
|