messages.h 9.69 KB
Newer Older
1
// Copyright 2006-2008 the V8 project authors. All rights reserved.
2 3
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
4 5 6 7 8 9 10 11 12

// The infrastructure used for (localized) message reporting in V8.
//
// Note: there's a big unresolved issue about ownership of the data
// structures used by this framework.

#ifndef V8_MESSAGES_H_
#define V8_MESSAGES_H_

13 14
#include <memory>

15
#include "src/handles.h"
16
#include "src/message-template.h"
17

18 19
namespace v8 {
namespace internal {
20 21 22
namespace wasm {
class WasmCode;
}
23

24
// Forward declarations.
25 26
class AbstractCode;
class FrameArray;
27 28
class JSMessageObject;
class LookupIterator;
29
class SharedFunctionInfo;
30
class SourceInfo;
31
class WasmInstanceObject;
32 33 34

class MessageLocation {
 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 41 42

  Handle<Script> script() const { return script_; }
  int start_pos() const { return start_pos_; }
  int end_pos() const { return end_pos_; }
43
  Handle<SharedFunctionInfo> shared() const { return shared_; }
44 45 46 47 48

 private:
  Handle<Script> script_;
  int start_pos_;
  int end_pos_;
49
  Handle<SharedFunctionInfo> shared_;
50 51
};

52
class StackFrameBase {
53
 public:
54
  virtual ~StackFrameBase() = default;
55 56 57 58 59 60 61 62 63

  virtual Handle<Object> GetReceiver() const = 0;
  virtual Handle<Object> GetFunction() const = 0;

  virtual Handle<Object> GetFileName() = 0;
  virtual Handle<Object> GetFunctionName() = 0;
  virtual Handle<Object> GetScriptNameOrSourceUrl() = 0;
  virtual Handle<Object> GetMethodName() = 0;
  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 71
  virtual int GetColumnNumber() = 0;

72 73 74
  // Returns index for Promise.all() async frames, or -1 for other frames.
  virtual int GetPromiseIndex() const = 0;

75 76
  virtual bool IsNative() = 0;
  virtual bool IsToplevel() = 0;
77
  virtual bool IsEval();
78
  virtual bool IsAsync() const = 0;
79
  virtual bool IsPromiseAll() const = 0;
80 81 82 83
  virtual bool IsConstructor() = 0;
  virtual bool IsStrict() const = 0;

  virtual MaybeHandle<String> ToString() = 0;
84 85

 protected:
86
  StackFrameBase() = default;
87 88 89 90 91 92
  explicit StackFrameBase(Isolate* isolate) : isolate_(isolate) {}
  Isolate* isolate_;

 private:
  virtual bool HasScript() const = 0;
  virtual Handle<Script> GetScript() const = 0;
93 94 95 96 97 98 99
};

class JSStackFrame : public StackFrameBase {
 public:
  JSStackFrame(Isolate* isolate, Handle<Object> receiver,
               Handle<JSFunction> function, Handle<AbstractCode> code,
               int offset);
100
  ~JSStackFrame() override = default;
101 102 103 104 105 106 107 108 109 110 111 112 113

  Handle<Object> GetReceiver() const override { return receiver_; }
  Handle<Object> GetFunction() const override;

  Handle<Object> GetFileName() override;
  Handle<Object> GetFunctionName() override;
  Handle<Object> GetScriptNameOrSourceUrl() override;
  Handle<Object> GetMethodName() override;
  Handle<Object> GetTypeName() override;

  int GetPosition() const override;
  int GetLineNumber() override;
  int GetColumnNumber() override;
114

115 116
  int GetPromiseIndex() const override;

117 118
  bool IsNative() override;
  bool IsToplevel() override;
119
  bool IsAsync() const override { return is_async_; }
120
  bool IsPromiseAll() const override { return is_promise_all_; }
121
  bool IsConstructor() override { return is_constructor_; }
122
  bool IsStrict() const override { return is_strict_; }
123

124
  MaybeHandle<String> ToString() override;
125 126

 private:
127
  JSStackFrame() = default;
128 129
  void FromFrameArray(Isolate* isolate, Handle<FrameArray> array, int frame_ix);

130 131
  bool HasScript() const override;
  Handle<Script> GetScript() const override;
132

133
  Handle<Object> receiver_;
134 135 136 137
  Handle<JSFunction> function_;
  Handle<AbstractCode> code_;
  int offset_;

138 139
  bool is_async_ : 1;
  bool is_constructor_ : 1;
140
  bool is_promise_all_ : 1;
141
  bool is_strict_ : 1;
142 143 144 145 146 147

  friend class FrameArrayIterator;
};

class WasmStackFrame : public StackFrameBase {
 public:
148
  ~WasmStackFrame() override = default;
149

150
  Handle<Object> GetReceiver() const override;
151 152 153 154 155 156 157 158 159 160 161 162
  Handle<Object> GetFunction() const override;

  Handle<Object> GetFileName() override { return Null(); }
  Handle<Object> GetFunctionName() override;
  Handle<Object> GetScriptNameOrSourceUrl() override { return Null(); }
  Handle<Object> GetMethodName() override { return Null(); }
  Handle<Object> GetTypeName() override { return Null(); }

  int GetPosition() const override;
  int GetLineNumber() override { return wasm_func_index_; }
  int GetColumnNumber() override { return -1; }

163 164
  int GetPromiseIndex() const override { return -1; }

165 166
  bool IsNative() override { return false; }
  bool IsToplevel() override { return false; }
167
  bool IsAsync() const override { return false; }
168
  bool IsPromiseAll() const override { return false; }
169 170
  bool IsConstructor() override { return false; }
  bool IsStrict() const override { return false; }
171
  bool IsInterpreted() const { return code_ == nullptr; }
172 173 174

  MaybeHandle<String> ToString() override;

175
 protected:
176 177
  Handle<Object> Null() const;

178 179
  bool HasScript() const override;
  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 185
  int offset_;

186
 private:
187
  WasmStackFrame() = default;
188 189
  void FromFrameArray(Isolate* isolate, Handle<FrameArray> array, int frame_ix);

190
  friend class FrameArrayIterator;
191
  friend class AsmJsWasmStackFrame;
192 193
};

194 195
class AsmJsWasmStackFrame : public WasmStackFrame {
 public:
196
  ~AsmJsWasmStackFrame() override = default;
197 198 199 200 201 202 203 204 205 206 207 208

  Handle<Object> GetReceiver() const override;
  Handle<Object> GetFunction() const override;

  Handle<Object> GetFileName() override;
  Handle<Object> GetScriptNameOrSourceUrl() override;

  int GetPosition() const override;
  int GetLineNumber() override;
  int GetColumnNumber() override;

  MaybeHandle<String> ToString() override;
209 210 211

 private:
  friend class FrameArrayIterator;
212
  AsmJsWasmStackFrame() = default;
213 214 215
  void FromFrameArray(Isolate* isolate, Handle<FrameArray> array, int frame_ix);

  bool is_at_number_conversion_;
216 217
};

218 219 220 221 222 223 224
class FrameArrayIterator {
 public:
  FrameArrayIterator(Isolate* isolate, Handle<FrameArray> array,
                     int frame_ix = 0);

  StackFrameBase* Frame();

225 226
  bool HasFrame() const;
  void Advance();
227 228 229 230 231

 private:
  Isolate* isolate_;

  Handle<FrameArray> array_;
232
  int frame_ix_;
233 234

  WasmStackFrame wasm_frame_;
235
  AsmJsWasmStackFrame asm_wasm_frame_;
236
  JSStackFrame js_frame_;
237 238
};

239 240 241 242 243 244 245 246 247 248
// Determines how stack trace collection skips frames.
enum FrameSkipMode {
  // Unconditionally skips the first frame. Used e.g. when the Error constructor
  // is called, in which case the first frame is always a BUILTIN_EXIT frame.
  SKIP_FIRST,
  // Skip all frames until a specified caller function is seen.
  SKIP_UNTIL_SEEN,
  SKIP_NONE,
};

jgruber's avatar
jgruber committed
249 250 251 252
class ErrorUtils : public AllStatic {
 public:
  static MaybeHandle<Object> Construct(
      Isolate* isolate, Handle<JSFunction> target, Handle<Object> new_target,
253 254
      Handle<Object> message, FrameSkipMode mode, Handle<Object> caller,
      bool suppress_detailed_trace);
jgruber's avatar
jgruber committed
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 261
      Handle<Object> arg0, Handle<Object> arg1, Handle<Object> arg2,
      FrameSkipMode mode);
262 263 264 265 266 267

  // Formats a textual stack trace from the given structured stack trace.
  // Note that this can call arbitrary JS code through Error.prepareStackTrace.
  static MaybeHandle<Object> FormatStackTrace(Isolate* isolate,
                                              Handle<JSObject> error,
                                              Handle<Object> stack_trace);
jgruber's avatar
jgruber committed
268 269
};

270
class MessageFormatter {
271
 public:
272
  static const char* TemplateString(MessageTemplate index);
273

274 275
  static MaybeHandle<String> FormatMessage(Isolate* isolate,
                                           MessageTemplate index,
276 277 278
                                           Handle<String> arg0,
                                           Handle<String> arg1,
                                           Handle<String> arg2);
279

280
  static Handle<String> FormatMessage(Isolate* isolate, MessageTemplate index,
281 282 283 284 285 286 287 288 289 290
                                      Handle<Object> arg);
};


// A message handler is a convenience interface for accessing the list
// of message listeners registered in an environment
class MessageHandler {
 public:
  // Returns a message object for the API to use.
  static Handle<JSMessageObject> MakeMessageObject(
291 292
      Isolate* isolate, MessageTemplate type, const MessageLocation* location,
      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 299 300

  static void DefaultMessageReport(Isolate* isolate, const MessageLocation* loc,
                                   Handle<Object> message_obj);
  static Handle<String> GetMessage(Isolate* isolate, Handle<Object> data);
301 302
  static std::unique_ptr<char[]> GetLocalizedMessage(Isolate* isolate,
                                                     Handle<Object> data);
303 304 305 306 307 308

 private:
  static void ReportMessageNoExceptions(Isolate* isolate,
                                        const MessageLocation* loc,
                                        Handle<Object> message_obj,
                                        v8::Local<v8::Value> api_exception_obj);
309
};
310 311


312 313
}  // namespace internal
}  // namespace v8
314 315

#endif  // V8_MESSAGES_H_