1 // Copyright 2017 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 V8_OBJECTS_SCRIPT_H_
6 #define V8_OBJECTS_SCRIPT_H_
7 
8 #include <memory>
9 
10 #include "include/v8-script.h"
11 #include "src/base/export-template.h"
12 #include "src/objects/fixed-array.h"
13 #include "src/objects/objects.h"
14 #include "src/objects/struct.h"
15 #include "torque-generated/bit-fields.h"
16 
17 // Has to be the last include (doesn't have include guards):
18 #include "src/objects/object-macros.h"
19 
20 namespace v8 {
21 
22 namespace internal {
23 
24 class FunctionLiteral;
25 
26 namespace wasm {
27 class NativeModule;
28 }  // namespace wasm
29 
30 #include "torque-generated/src/objects/script-tq.inc"
31 
32 // Script describes a script which has been added to the VM.
33 class Script : public TorqueGeneratedScript<Script, Struct> {
34  public:
35   // Script ID used for temporary scripts, which shouldn't be added to the
36   // script list.
37   static constexpr int kTemporaryScriptId = -2;
38 
39   NEVER_READ_ONLY_SPACE
40   // Script types.
41   enum Type {
42     TYPE_NATIVE = 0,
43     TYPE_EXTENSION = 1,
44     TYPE_NORMAL = 2,
45 #if V8_ENABLE_WEBASSEMBLY
46     TYPE_WASM = 3,
47 #endif  // V8_ENABLE_WEBASSEMBLY
48     TYPE_INSPECTOR = 4,
49     TYPE_WEB_SNAPSHOT = 5
50   };
51 
52   // Script compilation types.
53   enum CompilationType { COMPILATION_TYPE_HOST = 0, COMPILATION_TYPE_EVAL = 1 };
54 
55   // Script compilation state.
56   enum CompilationState {
57     COMPILATION_STATE_INITIAL = 0,
58     COMPILATION_STATE_COMPILED = 1
59   };
60 
61   // [type]: the script type.
62   DECL_INT_ACCESSORS(type)
63 
64   DECL_ACCESSORS(eval_from_shared_or_wrapped_arguments_or_sfi_table, Object)
65 
66   // [eval_from_shared]: for eval scripts the shared function info for the
67   // function from which eval was called.
68   DECL_ACCESSORS(eval_from_shared, SharedFunctionInfo)
69 
70   // [wrapped_arguments]: for the list of arguments in a wrapped script.
71   DECL_ACCESSORS(wrapped_arguments, FixedArray)
72 
73   // For web snapshots: a hash table mapping function positions to indices in
74   // shared_function_infos.
75   // TODO(v8:11525): Replace with a more efficient data structure mapping
76   // function positions to weak pointers to SharedFunctionInfos directly.
77   DECL_ACCESSORS(shared_function_info_table, ObjectHashTable)
78 
79   // Whether the script is implicitly wrapped in a function.
80   inline bool is_wrapped() const;
81 
82   // Whether the eval_from_shared field is set with a shared function info
83   // for the eval site.
84   inline bool has_eval_from_shared() const;
85 
86   // [eval_from_position]: the source position in the code for the function
87   // from which eval was called, as positive integer. Or the code offset in the
88   // code from which eval was called, as negative integer.
89   DECL_INT_ACCESSORS(eval_from_position)
90 
91   // [shared_function_infos]: weak fixed array containing all shared
92   // function infos created from this script.
93   DECL_ACCESSORS(shared_function_infos, WeakFixedArray)
94 
95   inline int shared_function_info_count() const;
96 
97 #if V8_ENABLE_WEBASSEMBLY
98   // [wasm_breakpoint_infos]: the list of {BreakPointInfo} objects describing
99   // all WebAssembly breakpoints for modules/instances managed via this script.
100   // This must only be called if the type of this script is TYPE_WASM.
101   DECL_ACCESSORS(wasm_breakpoint_infos, FixedArray)
102   inline bool has_wasm_breakpoint_infos() const;
103 
104   // [wasm_native_module]: the wasm {NativeModule} this script belongs to.
105   // This must only be called if the type of this script is TYPE_WASM.
106   DECL_ACCESSORS(wasm_managed_native_module, Object)
107   inline wasm::NativeModule* wasm_native_module() const;
108 
109   // [wasm_weak_instance_list]: the list of all {WasmInstanceObject} being
110   // affected by breakpoints that are managed via this script.
111   // This must only be called if the type of this script is TYPE_WASM.
112   DECL_ACCESSORS(wasm_weak_instance_list, WeakArrayList)
113 
114   // [break_on_entry] (wasm only): whether an instrumentation breakpoint is set
115   // for this script; this information will be transferred to existing and
116   // future instances to make sure that we stop before executing any code in
117   // this wasm module.
118   inline bool break_on_entry() const;
119   inline void set_break_on_entry(bool value);
120 
121   // Check if the script contains any Asm modules.
122   bool ContainsAsmModule();
123 #endif  // V8_ENABLE_WEBASSEMBLY
124 
125   // [compilation_type]: how the the script was compiled. Encoded in the
126   // 'flags' field.
127   inline CompilationType compilation_type();
128   inline void set_compilation_type(CompilationType type);
129 
130   // [compilation_state]: determines whether the script has already been
131   // compiled. Encoded in the 'flags' field.
132   inline CompilationState compilation_state();
133   inline void set_compilation_state(CompilationState state);
134 
135   // [is_repl_mode]: whether this script originated from a REPL via debug
136   // evaluate and therefore has different semantics, e.g. re-declaring let.
137   inline bool is_repl_mode() const;
138   inline void set_is_repl_mode(bool value);
139 
140   // [origin_options]: optional attributes set by the embedder via ScriptOrigin,
141   // and used by the embedder to make decisions about the script. V8 just passes
142   // this through. Encoded in the 'flags' field.
143   inline v8::ScriptOriginOptions origin_options();
144   inline void set_origin_options(ScriptOriginOptions origin_options);
145 
146   // If script source is an external string, check that the underlying
147   // resource is accessible. Otherwise, always return true.
148   inline bool HasValidSource();
149 
150   // If the script has a non-empty sourceURL comment.
151   inline bool HasSourceURLComment() const;
152 
153   // Streaming compilation only attaches the source to the Script upon
154   // finalization. This predicate returns true, if this script may still be
155   // unfinalized.
156   inline bool IsMaybeUnfinalized(Isolate* isolate) const;
157 
158   Object GetNameOrSourceURL();
159 
160   // Retrieve source position from where eval was called.
161   static int GetEvalPosition(Isolate* isolate, Handle<Script> script);
162 
163   // Init line_ends array with source code positions of line ends.
164   template <typename IsolateT>
165   EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
166   static void InitLineEnds(IsolateT* isolate, Handle<Script> script);
167 
168   // Carries information about a source position.
169   struct PositionInfo {
PositionInfoPositionInfo170     PositionInfo() : line(-1), column(-1), line_start(-1), line_end(-1) {}
171 
172     int line;        // Zero-based line number.
173     int column;      // Zero-based column number.
174     int line_start;  // Position of first character in line.
175     int line_end;    // Position of final linebreak character in line.
176   };
177 
178   // Specifies whether to add offsets to position infos.
179   enum OffsetFlag { NO_OFFSET = 0, WITH_OFFSET = 1 };
180 
181   // Retrieves information about the given position, optionally with an offset.
182   // Returns false on failure, and otherwise writes into the given info object
183   // on success.
184   // The static method should is preferable for handlified callsites because it
185   // initializes the line ends array, avoiding expensive recomputations.
186   // The non-static version is not allocating and safe for unhandlified
187   // callsites.
188   static bool GetPositionInfo(Handle<Script> script, int position,
189                               PositionInfo* info, OffsetFlag offset_flag);
190   V8_EXPORT_PRIVATE bool GetPositionInfo(int position, PositionInfo* info,
191                                          OffsetFlag offset_flag) const;
192 
193   bool IsUserJavaScript() const;
194 
195   // Wrappers for GetPositionInfo
196   static int GetColumnNumber(Handle<Script> script, int code_offset);
197   int GetColumnNumber(int code_pos) const;
198   V8_EXPORT_PRIVATE static int GetLineNumber(Handle<Script> script,
199                                              int code_offset);
200   int GetLineNumber(int code_pos) const;
201 
202   // Look through the list of existing shared function infos to find one
203   // that matches the function literal. Return empty handle if not found.
204   template <typename IsolateT>
205   static MaybeHandle<SharedFunctionInfo> FindSharedFunctionInfo(
206       Handle<Script> script, IsolateT* isolate,
207       FunctionLiteral* function_literal);
208 
209   static MaybeHandle<SharedFunctionInfo> FindWebSnapshotSharedFunctionInfo(
210       Handle<Script> script, Isolate* isolate,
211       FunctionLiteral* function_literal);
212 
213   static MaybeHandle<SharedFunctionInfo> FindWebSnapshotSharedFunctionInfo(
214       Handle<Script> script, LocalIsolate* isolate,
215       FunctionLiteral* function_literal);
216 
217   // Iterate over all script objects on the heap.
218   class V8_EXPORT_PRIVATE Iterator {
219    public:
220     explicit Iterator(Isolate* isolate);
221     Iterator(const Iterator&) = delete;
222     Iterator& operator=(const Iterator&) = delete;
223     Script Next();
224 
225    private:
226     WeakArrayList::Iterator iterator_;
227   };
228 
229   // Dispatched behavior.
230   DECL_PRINTER(Script)
231   DECL_VERIFIER(Script)
232 
233  private:
234   // Bit positions in the flags field.
235   DEFINE_TORQUE_GENERATED_SCRIPT_FLAGS()
236 
237   TQ_OBJECT_CONSTRUCTORS(Script)
238 };
239 
240 }  // namespace internal
241 }  // namespace v8
242 
243 #include "src/objects/object-macros-undef.h"
244 
245 #endif  // V8_OBJECTS_SCRIPT_H_
246