1// Copyright 2021 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#ifndef INCLUDE_V8_DEBUG_H_
6#define INCLUDE_V8_DEBUG_H_
7
8#include <stdint.h>
9
10#include "v8-script.h"  // NOLINT(build/include_directory)
11#include "v8config.h"   // NOLINT(build/include_directory)
12
13namespace v8 {
14
15class Isolate;
16class String;
17
18/**
19 * A single JavaScript stack frame.
20 */
21class V8_EXPORT StackFrame {
22 public:
23  /**
24   * Returns the source location, 0-based, for the associated function call.
25   */
26  Location GetLocation() const;
27
28  /**
29   * Returns the number, 1-based, of the line for the associate function call.
30   * This method will return Message::kNoLineNumberInfo if it is unable to
31   * retrieve the line number, or if kLineNumber was not passed as an option
32   * when capturing the StackTrace.
33   */
34  int GetLineNumber() const { return GetLocation().GetLineNumber() + 1; }
35
36  /**
37   * Returns the 1-based column offset on the line for the associated function
38   * call.
39   * This method will return Message::kNoColumnInfo if it is unable to retrieve
40   * the column number, or if kColumnOffset was not passed as an option when
41   * capturing the StackTrace.
42   */
43  int GetColumn() const { return GetLocation().GetColumnNumber() + 1; }
44
45  /**
46   * Returns the id of the script for the function for this StackFrame.
47   * This method will return Message::kNoScriptIdInfo if it is unable to
48   * retrieve the script id, or if kScriptId was not passed as an option when
49   * capturing the StackTrace.
50   */
51  int GetScriptId() const;
52
53  /**
54   * Returns the name of the resource that contains the script for the
55   * function for this StackFrame.
56   */
57  Local<String> GetScriptName() const;
58
59  /**
60   * Returns the name of the resource that contains the script for the
61   * function for this StackFrame or sourceURL value if the script name
62   * is undefined and its source ends with //# sourceURL=... string or
63   * deprecated //@ sourceURL=... string.
64   */
65  Local<String> GetScriptNameOrSourceURL() const;
66
67  /**
68   * Returns the source of the script for the function for this StackFrame.
69   */
70  Local<String> GetScriptSource() const;
71
72  /**
73   * Returns the source mapping URL (if one is present) of the script for
74   * the function for this StackFrame.
75   */
76  Local<String> GetScriptSourceMappingURL() const;
77
78  /**
79   * Returns the name of the function associated with this stack frame.
80   */
81  Local<String> GetFunctionName() const;
82
83  /**
84   * Returns whether or not the associated function is compiled via a call to
85   * eval().
86   */
87  bool IsEval() const;
88
89  /**
90   * Returns whether or not the associated function is called as a
91   * constructor via "new".
92   */
93  bool IsConstructor() const;
94
95  /**
96   * Returns whether or not the associated functions is defined in wasm.
97   */
98  bool IsWasm() const;
99
100  /**
101   * Returns whether or not the associated function is defined by the user.
102   */
103  bool IsUserJavaScript() const;
104};
105
106/**
107 * Representation of a JavaScript stack trace. The information collected is a
108 * snapshot of the execution stack and the information remains valid after
109 * execution continues.
110 */
111class V8_EXPORT StackTrace {
112 public:
113  /**
114   * Flags that determine what information is placed captured for each
115   * StackFrame when grabbing the current stack trace.
116   * Note: these options are deprecated and we always collect all available
117   * information (kDetailed).
118   */
119  enum StackTraceOptions {
120    kLineNumber = 1,
121    kColumnOffset = 1 << 1 | kLineNumber,
122    kScriptName = 1 << 2,
123    kFunctionName = 1 << 3,
124    kIsEval = 1 << 4,
125    kIsConstructor = 1 << 5,
126    kScriptNameOrSourceURL = 1 << 6,
127    kScriptId = 1 << 7,
128    kExposeFramesAcrossSecurityOrigins = 1 << 8,
129    kOverview = kLineNumber | kColumnOffset | kScriptName | kFunctionName,
130    kDetailed = kOverview | kIsEval | kIsConstructor | kScriptNameOrSourceURL
131  };
132
133  /**
134   * Returns a StackFrame at a particular index.
135   */
136  Local<StackFrame> GetFrame(Isolate* isolate, uint32_t index) const;
137
138  /**
139   * Returns the number of StackFrames.
140   */
141  int GetFrameCount() const;
142
143  /**
144   * Grab a snapshot of the current JavaScript execution stack.
145   *
146   * \param frame_limit The maximum number of stack frames we want to capture.
147   * \param options Enumerates the set of things we will capture for each
148   *   StackFrame.
149   */
150  static Local<StackTrace> CurrentStackTrace(
151      Isolate* isolate, int frame_limit, StackTraceOptions options = kDetailed);
152
153  /**
154   * Returns the first valid script name or source URL starting at the top of
155   * the JS stack. The returned string is either an empty handle if no script
156   * name/url was found or a non-zero-length string.
157   *
158   * This method is equivalent to calling StackTrace::CurrentStackTrace and
159   * walking the resulting frames from the beginning until a non-empty script
160   * name/url is found. The difference is that this method won't allocate
161   * a stack trace.
162   */
163  static Local<String> CurrentScriptNameOrSourceURL(Isolate* isolate);
164};
165
166}  // namespace v8
167
168#endif  // INCLUDE_V8_DEBUG_H_
169