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 IncrementalStringBuilder;
28 : class JSMessageObject;
29 : class LookupIterator;
30 : class SharedFunctionInfo;
31 : class SourceInfo;
32 : class WasmInstanceObject;
33 :
34 : class MessageLocation {
35 : public:
36 : MessageLocation(Handle<Script> script, int start_pos, int end_pos);
37 : MessageLocation(Handle<Script> script, int start_pos, int end_pos,
38 : Handle<SharedFunctionInfo> shared);
39 : MessageLocation();
40 :
41 : Handle<Script> script() const { return script_; }
42 : int start_pos() const { return start_pos_; }
43 : int end_pos() const { return end_pos_; }
44 : Handle<SharedFunctionInfo> shared() const { return shared_; }
45 :
46 : private:
47 : Handle<Script> script_;
48 : int start_pos_;
49 : int end_pos_;
50 : Handle<SharedFunctionInfo> shared_;
51 : };
52 :
53 : class StackFrameBase {
54 : public:
55 985911 : virtual ~StackFrameBase() = default;
56 :
57 : virtual Handle<Object> GetReceiver() const = 0;
58 : virtual Handle<Object> GetFunction() const = 0;
59 :
60 : virtual Handle<Object> GetFileName() = 0;
61 : virtual Handle<Object> GetFunctionName() = 0;
62 : virtual Handle<Object> GetScriptNameOrSourceUrl() = 0;
63 : virtual Handle<Object> GetMethodName() = 0;
64 : virtual Handle<Object> GetTypeName() = 0;
65 : virtual Handle<Object> GetEvalOrigin();
66 :
67 : // Returns the script ID if one is attached, -1 otherwise.
68 : int GetScriptId() const;
69 :
70 : virtual int GetPosition() const = 0;
71 : // Return 1-based line number, including line offset.
72 : virtual int GetLineNumber() = 0;
73 : // Return 1-based column number, including column offset if first line.
74 : virtual int GetColumnNumber() = 0;
75 :
76 : // Returns index for Promise.all() async frames, or -1 for other frames.
77 : virtual int GetPromiseIndex() const = 0;
78 :
79 : virtual bool IsNative() = 0;
80 : virtual bool IsToplevel() = 0;
81 : virtual bool IsEval();
82 : virtual bool IsAsync() const = 0;
83 : virtual bool IsPromiseAll() const = 0;
84 : virtual bool IsConstructor() = 0;
85 : virtual bool IsStrict() const = 0;
86 :
87 : MaybeHandle<String> ToString();
88 : virtual void ToString(IncrementalStringBuilder& builder) = 0;
89 :
90 : // Used to signal that the requested field is unknown.
91 : static const int kNone = -1;
92 :
93 : protected:
94 985911 : StackFrameBase() = default;
95 0 : explicit StackFrameBase(Isolate* isolate) : isolate_(isolate) {}
96 : Isolate* isolate_;
97 :
98 : private:
99 : virtual bool HasScript() const = 0;
100 : virtual Handle<Script> GetScript() const = 0;
101 : };
102 :
103 : class JSStackFrame : public StackFrameBase {
104 : public:
105 : JSStackFrame(Isolate* isolate, Handle<Object> receiver,
106 : Handle<JSFunction> function, Handle<AbstractCode> code,
107 : int offset);
108 646503 : ~JSStackFrame() override = default;
109 :
110 191 : Handle<Object> GetReceiver() const override { return receiver_; }
111 : Handle<Object> GetFunction() const override;
112 :
113 : Handle<Object> GetFileName() override;
114 : Handle<Object> GetFunctionName() override;
115 : Handle<Object> GetScriptNameOrSourceUrl() override;
116 : Handle<Object> GetMethodName() override;
117 : Handle<Object> GetTypeName() override;
118 :
119 : int GetPosition() const override;
120 : int GetLineNumber() override;
121 : int GetColumnNumber() override;
122 :
123 : int GetPromiseIndex() const override;
124 :
125 : bool IsNative() override;
126 : bool IsToplevel() override;
127 60191 : bool IsAsync() const override { return is_async_; }
128 60164 : bool IsPromiseAll() const override { return is_promise_all_; }
129 101553 : bool IsConstructor() override { return is_constructor_; }
130 758 : bool IsStrict() const override { return is_strict_; }
131 :
132 : void ToString(IncrementalStringBuilder& builder) override;
133 :
134 : private:
135 328637 : JSStackFrame() = default;
136 : void FromFrameArray(Isolate* isolate, Handle<FrameArray> array, int frame_ix);
137 :
138 : bool HasScript() const override;
139 : Handle<Script> GetScript() const override;
140 :
141 : Handle<Object> receiver_;
142 : Handle<JSFunction> function_;
143 : Handle<AbstractCode> code_;
144 : int offset_;
145 :
146 : bool is_async_ : 1;
147 : bool is_constructor_ : 1;
148 : bool is_promise_all_ : 1;
149 : bool is_strict_ : 1;
150 :
151 : friend class FrameArrayIterator;
152 : };
153 :
154 : class WasmStackFrame : public StackFrameBase {
155 : public:
156 1293006 : ~WasmStackFrame() override = default;
157 :
158 : Handle<Object> GetReceiver() const override;
159 : Handle<Object> GetFunction() const override;
160 :
161 1032 : Handle<Object> GetFileName() override { return Null(); }
162 : Handle<Object> GetFunctionName() override;
163 888 : Handle<Object> GetScriptNameOrSourceUrl() override { return Null(); }
164 0 : Handle<Object> GetMethodName() override { return Null(); }
165 0 : Handle<Object> GetTypeName() override { return Null(); }
166 :
167 : int GetPosition() const override;
168 644 : int GetLineNumber() override { return wasm_func_index_; }
169 0 : int GetColumnNumber() override { return kNone; }
170 :
171 0 : int GetPromiseIndex() const override { return kNone; }
172 :
173 88 : bool IsNative() override { return false; }
174 0 : bool IsToplevel() override { return false; }
175 0 : bool IsAsync() const override { return false; }
176 0 : bool IsPromiseAll() const override { return false; }
177 444 : bool IsConstructor() override { return false; }
178 208 : bool IsStrict() const override { return false; }
179 : bool IsInterpreted() const { return code_ == nullptr; }
180 :
181 : void ToString(IncrementalStringBuilder& builder) override;
182 :
183 : protected:
184 : Handle<Object> Null() const;
185 :
186 : bool HasScript() const override;
187 : Handle<Script> GetScript() const override;
188 :
189 : Handle<WasmInstanceObject> wasm_instance_;
190 : uint32_t wasm_func_index_;
191 : wasm::WasmCode* code_; // null for interpreted frames.
192 : int offset_;
193 :
194 : private:
195 657274 : WasmStackFrame() = default;
196 : void FromFrameArray(Isolate* isolate, Handle<FrameArray> array, int frame_ix);
197 :
198 : friend class FrameArrayIterator;
199 : friend class AsmJsWasmStackFrame;
200 : };
201 :
202 : class AsmJsWasmStackFrame : public WasmStackFrame {
203 : public:
204 646503 : ~AsmJsWasmStackFrame() override = default;
205 :
206 : Handle<Object> GetReceiver() const override;
207 : Handle<Object> GetFunction() const override;
208 :
209 : Handle<Object> GetFileName() override;
210 : Handle<Object> GetScriptNameOrSourceUrl() override;
211 :
212 : int GetPosition() const override;
213 : int GetLineNumber() override;
214 : int GetColumnNumber() override;
215 :
216 : void ToString(IncrementalStringBuilder& builder) override;
217 :
218 : private:
219 : friend class FrameArrayIterator;
220 328637 : AsmJsWasmStackFrame() = default;
221 : void FromFrameArray(Isolate* isolate, Handle<FrameArray> array, int frame_ix);
222 :
223 : bool is_at_number_conversion_;
224 : };
225 :
226 328637 : class FrameArrayIterator {
227 : public:
228 : FrameArrayIterator(Isolate* isolate, Handle<FrameArray> array,
229 : int frame_ix = 0);
230 :
231 : StackFrameBase* Frame();
232 :
233 : bool HasFrame() const;
234 : void Advance();
235 :
236 : private:
237 : Isolate* isolate_;
238 :
239 : Handle<FrameArray> array_;
240 : int frame_ix_;
241 :
242 : WasmStackFrame wasm_frame_;
243 : AsmJsWasmStackFrame asm_wasm_frame_;
244 : JSStackFrame js_frame_;
245 : };
246 :
247 : // Determines how stack trace collection skips frames.
248 : enum FrameSkipMode {
249 : // Unconditionally skips the first frame. Used e.g. when the Error constructor
250 : // is called, in which case the first frame is always a BUILTIN_EXIT frame.
251 : SKIP_FIRST,
252 : // Skip all frames until a specified caller function is seen.
253 : SKIP_UNTIL_SEEN,
254 : SKIP_NONE,
255 : };
256 :
257 : class ErrorUtils : public AllStatic {
258 : public:
259 : static MaybeHandle<Object> Construct(
260 : Isolate* isolate, Handle<JSFunction> target, Handle<Object> new_target,
261 : Handle<Object> message, FrameSkipMode mode, Handle<Object> caller,
262 : bool suppress_detailed_trace);
263 :
264 : static MaybeHandle<String> ToString(Isolate* isolate, Handle<Object> recv);
265 :
266 : static MaybeHandle<Object> MakeGenericError(
267 : Isolate* isolate, Handle<JSFunction> constructor, MessageTemplate index,
268 : Handle<Object> arg0, Handle<Object> arg1, Handle<Object> arg2,
269 : FrameSkipMode mode);
270 :
271 : // Formats a textual stack trace from the given structured stack trace.
272 : // Note that this can call arbitrary JS code through Error.prepareStackTrace.
273 : static MaybeHandle<Object> FormatStackTrace(Isolate* isolate,
274 : Handle<JSObject> error,
275 : Handle<Object> stack_trace);
276 : };
277 :
278 : class MessageFormatter {
279 : public:
280 : static const char* TemplateString(MessageTemplate index);
281 :
282 : static MaybeHandle<String> Format(Isolate* isolate, MessageTemplate index,
283 : Handle<String> arg0, Handle<String> arg1,
284 : Handle<String> arg2);
285 :
286 : static Handle<String> Format(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_
|