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