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_INL_H_
6#define V8_OBJECTS_SCRIPT_INL_H_
7
8#include "src/objects/managed.h"
9#include "src/objects/script.h"
10#include "src/objects/shared-function-info.h"
11#include "src/objects/smi-inl.h"
12#include "src/objects/string-inl.h"
13
14// Has to be the last include (doesn't have include guards):
15#include "src/objects/object-macros.h"
16
17namespace v8 {
18namespace internal {
19
20#include "torque-generated/src/objects/script-tq-inl.inc"
21
22TQ_OBJECT_CONSTRUCTORS_IMPL(Script)
23
24NEVER_READ_ONLY_SPACE_IMPL(Script)
25
26#if V8_ENABLE_WEBASSEMBLY
27ACCESSORS_CHECKED(Script, wasm_breakpoint_infos, FixedArray,
28                  kEvalFromSharedOrWrappedArgumentsOrSfiTableOffset,
29                  this->type() == TYPE_WASM)
30ACCESSORS_CHECKED(Script, wasm_managed_native_module, Object,
31                  kEvalFromPositionOffset, this->type() == TYPE_WASM)
32ACCESSORS_CHECKED(Script, wasm_weak_instance_list, WeakArrayList,
33                  kSharedFunctionInfosOffset, this->type() == TYPE_WASM)
34#define CHECK_SCRIPT_NOT_WASM this->type() != TYPE_WASM
35#else
36#define CHECK_SCRIPT_NOT_WASM true
37#endif  // V8_ENABLE_WEBASSEMBLY
38
39SMI_ACCESSORS(Script, type, kScriptTypeOffset)
40ACCESSORS_CHECKED(Script, eval_from_shared_or_wrapped_arguments_or_sfi_table,
41                  Object, kEvalFromSharedOrWrappedArgumentsOrSfiTableOffset,
42                  CHECK_SCRIPT_NOT_WASM)
43SMI_ACCESSORS_CHECKED(Script, eval_from_position, kEvalFromPositionOffset,
44                      CHECK_SCRIPT_NOT_WASM)
45#undef CHECK_SCRIPT_NOT_WASM
46
47bool Script::is_wrapped() const {
48  return eval_from_shared_or_wrapped_arguments_or_sfi_table().IsFixedArray() &&
49         type() != TYPE_WEB_SNAPSHOT;
50}
51
52bool Script::has_eval_from_shared() const {
53  return eval_from_shared_or_wrapped_arguments_or_sfi_table()
54      .IsSharedFunctionInfo();
55}
56
57void Script::set_eval_from_shared(SharedFunctionInfo shared,
58                                  WriteBarrierMode mode) {
59  DCHECK(!is_wrapped());
60  DCHECK_NE(type(), TYPE_WEB_SNAPSHOT);
61  set_eval_from_shared_or_wrapped_arguments_or_sfi_table(shared, mode);
62}
63
64SharedFunctionInfo Script::eval_from_shared() const {
65  DCHECK(has_eval_from_shared());
66  return SharedFunctionInfo::cast(
67      eval_from_shared_or_wrapped_arguments_or_sfi_table());
68}
69
70void Script::set_wrapped_arguments(FixedArray value, WriteBarrierMode mode) {
71  DCHECK(!has_eval_from_shared());
72  DCHECK_NE(type(), TYPE_WEB_SNAPSHOT);
73  set_eval_from_shared_or_wrapped_arguments_or_sfi_table(value, mode);
74}
75
76FixedArray Script::wrapped_arguments() const {
77  DCHECK(is_wrapped());
78  return FixedArray::cast(eval_from_shared_or_wrapped_arguments_or_sfi_table());
79}
80
81void Script::set_shared_function_info_table(ObjectHashTable value,
82                                            WriteBarrierMode mode) {
83  DCHECK(!has_eval_from_shared());
84  DCHECK(!is_wrapped());
85  DCHECK_EQ(type(), TYPE_WEB_SNAPSHOT);
86  set_eval_from_shared_or_wrapped_arguments_or_sfi_table(value, mode);
87}
88
89ObjectHashTable Script::shared_function_info_table() const {
90  DCHECK_EQ(type(), TYPE_WEB_SNAPSHOT);
91  return ObjectHashTable::cast(
92      eval_from_shared_or_wrapped_arguments_or_sfi_table());
93}
94
95DEF_GETTER(Script, shared_function_infos, WeakFixedArray) {
96#if V8_ENABLE_WEBASSEMBLY
97  if (type() == TYPE_WASM) {
98    return ReadOnlyRoots(GetHeap()).empty_weak_fixed_array();
99  }
100#endif  // V8_ENABLE_WEBASSEMBLY
101  return TaggedField<WeakFixedArray, kSharedFunctionInfosOffset>::load(*this);
102}
103
104void Script::set_shared_function_infos(WeakFixedArray value,
105                                       WriteBarrierMode mode) {
106#if V8_ENABLE_WEBASSEMBLY
107  DCHECK_NE(TYPE_WASM, type());
108#endif  // V8_ENABLE_WEBASSEMBLY
109  TaggedField<WeakFixedArray, kSharedFunctionInfosOffset>::store(*this, value);
110  CONDITIONAL_WRITE_BARRIER(*this, kSharedFunctionInfosOffset, value, mode);
111}
112
113int Script::shared_function_info_count() const {
114  if V8_UNLIKELY (type() == TYPE_WEB_SNAPSHOT) {
115    // +1 because the 0th element in shared_function_infos is reserved for the
116    // top-level SharedFunctionInfo which doesn't exist.
117    return shared_function_info_table().NumberOfElements() + 1;
118  }
119  return shared_function_infos().length();
120}
121
122#if V8_ENABLE_WEBASSEMBLY
123bool Script::has_wasm_breakpoint_infos() const {
124  return type() == TYPE_WASM && wasm_breakpoint_infos().length() > 0;
125}
126
127wasm::NativeModule* Script::wasm_native_module() const {
128  return Managed<wasm::NativeModule>::cast(wasm_managed_native_module()).raw();
129}
130
131bool Script::break_on_entry() const { return BreakOnEntryBit::decode(flags()); }
132
133void Script::set_break_on_entry(bool value) {
134  set_flags(BreakOnEntryBit::update(flags(), value));
135}
136#endif  // V8_ENABLE_WEBASSEMBLY
137
138Script::CompilationType Script::compilation_type() {
139  return CompilationTypeBit::decode(flags());
140}
141void Script::set_compilation_type(CompilationType type) {
142  set_flags(CompilationTypeBit::update(flags(), type));
143}
144Script::CompilationState Script::compilation_state() {
145  return CompilationStateBit::decode(flags());
146}
147void Script::set_compilation_state(CompilationState state) {
148  set_flags(CompilationStateBit::update(flags(), state));
149}
150
151bool Script::is_repl_mode() const { return IsReplModeBit::decode(flags()); }
152
153void Script::set_is_repl_mode(bool value) {
154  set_flags(IsReplModeBit::update(flags(), value));
155}
156
157ScriptOriginOptions Script::origin_options() {
158  return ScriptOriginOptions(OriginOptionsBits::decode(flags()));
159}
160void Script::set_origin_options(ScriptOriginOptions origin_options) {
161  DCHECK(!(origin_options.Flags() & ~((1 << OriginOptionsBits::kSize) - 1)));
162  set_flags(OriginOptionsBits::update(flags(), origin_options.Flags()));
163}
164
165bool Script::HasValidSource() {
166  Object src = this->source();
167  if (!src.IsString()) return true;
168  String src_str = String::cast(src);
169  if (!StringShape(src_str).IsExternal()) return true;
170  if (src_str.IsOneByteRepresentation()) {
171    return ExternalOneByteString::cast(src).resource() != nullptr;
172  } else if (src_str.IsTwoByteRepresentation()) {
173    return ExternalTwoByteString::cast(src).resource() != nullptr;
174  }
175  return true;
176}
177
178bool Script::HasSourceURLComment() const {
179  return source_url().IsString() && String::cast(source_url()).length() != 0;
180}
181
182bool Script::IsMaybeUnfinalized(Isolate* isolate) const {
183  // TODO(v8:12051): A more robust detection, e.g. with a dedicated sentinel
184  // value.
185  return source().IsUndefined(isolate) || String::cast(source()).length() == 0;
186}
187
188}  // namespace internal
189}  // namespace v8
190
191#include "src/objects/object-macros-undef.h"
192
193#endif  // V8_OBJECTS_SCRIPT_INL_H_
194