Line data Source code
1 : // Copyright 2015 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_CONTEXTS_INL_H_
6 : #define V8_CONTEXTS_INL_H_
7 :
8 : #include "src/contexts.h"
9 :
10 : #include "src/heap/heap-write-barrier.h"
11 : #include "src/objects-inl.h"
12 : #include "src/objects/dictionary-inl.h"
13 : #include "src/objects/fixed-array-inl.h"
14 : #include "src/objects/map-inl.h"
15 : #include "src/objects/regexp-match-info.h"
16 : #include "src/objects/scope-info.h"
17 : #include "src/objects/shared-function-info.h"
18 :
19 : // Has to be the last include (doesn't have include guards):
20 : #include "src/objects/object-macros.h"
21 :
22 : namespace v8 {
23 : namespace internal {
24 :
25 26096092 : OBJECT_CONSTRUCTORS_IMPL(ScriptContextTable, FixedArray)
26 13048045 : CAST_ACCESSOR(ScriptContextTable)
27 :
28 52255226 : int ScriptContextTable::used() const { return Smi::ToInt(get(kUsedSlotIndex)); }
29 :
30 : void ScriptContextTable::set_used(int used) {
31 : set(kUsedSlotIndex, Smi::FromInt(used));
32 : }
33 :
34 : // static
35 14776535 : Handle<Context> ScriptContextTable::GetContext(Isolate* isolate,
36 : Handle<ScriptContextTable> table,
37 : int i) {
38 : DCHECK(i < table->used());
39 : return Handle<Context>::cast(
40 29553070 : FixedArray::get(*table, i + kFirstContextSlotIndex, isolate));
41 : }
42 :
43 180467396 : OBJECT_CONSTRUCTORS_IMPL(Context, HeapObject)
44 : NEVER_READ_ONLY_SPACE_IMPL(Context)
45 90233764 : CAST_ACCESSOR(Context)
46 5857822 : SMI_ACCESSORS(Context, length, kLengthOffset)
47 :
48 1114361 : CAST_ACCESSOR(NativeContext)
49 :
50 : Object Context::get(int index) const {
51 : DCHECK_LT(static_cast<unsigned>(index),
52 : static_cast<unsigned>(this->length()));
53 461765452 : return RELAXED_READ_FIELD(*this, OffsetOfElementAt(index));
54 : }
55 :
56 : void Context::set(int index, Object value) {
57 : DCHECK_LT(static_cast<unsigned>(index),
58 : static_cast<unsigned>(this->length()));
59 : int offset = OffsetOfElementAt(index);
60 10273465 : RELAXED_WRITE_FIELD(*this, offset, value);
61 10273471 : WRITE_BARRIER(*this, offset, value);
62 : }
63 :
64 : void Context::set(int index, Object value, WriteBarrierMode mode) {
65 : DCHECK_LT(static_cast<unsigned>(index),
66 : static_cast<unsigned>(this->length()));
67 : int offset = OffsetOfElementAt(index);
68 1523934 : RELAXED_WRITE_FIELD(*this, offset, value);
69 1523934 : CONDITIONAL_WRITE_BARRIER(*this, offset, value, mode);
70 : }
71 :
72 1264232 : void Context::set_scope_info(ScopeInfo scope_info) {
73 : set(SCOPE_INFO_INDEX, scope_info);
74 1264237 : }
75 :
76 4162414 : Context Context::previous() {
77 : Object result = get(PREVIOUS_INDEX);
78 : DCHECK(IsBootstrappingOrValidParentContext(result, *this));
79 4162414 : return Context::unchecked_cast(result);
80 : }
81 2528556 : void Context::set_previous(Context context) { set(PREVIOUS_INDEX, context); }
82 :
83 37443327 : Object Context::next_context_link() { return get(Context::NEXT_CONTEXT_LINK); }
84 :
85 577256 : bool Context::has_extension() { return !extension()->IsTheHole(); }
86 38826115 : HeapObject Context::extension() {
87 38826116 : return HeapObject::cast(get(EXTENSION_INDEX));
88 : }
89 2755546 : void Context::set_extension(HeapObject object) { set(EXTENSION_INDEX, object); }
90 :
91 165778520 : NativeContext Context::native_context() const {
92 : Object result = get(NATIVE_CONTEXT_INDEX);
93 : DCHECK(IsBootstrappingOrNativeContext(this->GetIsolate(), result));
94 165778601 : return NativeContext::unchecked_cast(result);
95 : }
96 :
97 1264127 : void Context::set_native_context(NativeContext context) {
98 : set(NATIVE_CONTEXT_INDEX, context);
99 1264127 : }
100 :
101 12995522 : bool Context::IsFunctionContext() const {
102 12995522 : return map()->instance_type() == FUNCTION_CONTEXT_TYPE;
103 : }
104 :
105 2841773 : bool Context::IsCatchContext() const {
106 2841773 : return map()->instance_type() == CATCH_CONTEXT_TYPE;
107 : }
108 :
109 29347424 : bool Context::IsWithContext() const {
110 29347424 : return map()->instance_type() == WITH_CONTEXT_TYPE;
111 : }
112 :
113 3219453 : bool Context::IsDebugEvaluateContext() const {
114 3219453 : return map()->instance_type() == DEBUG_EVALUATE_CONTEXT_TYPE;
115 : }
116 :
117 : bool Context::IsAwaitContext() const {
118 : return map()->instance_type() == AWAIT_CONTEXT_TYPE;
119 : }
120 :
121 2864242 : bool Context::IsBlockContext() const {
122 2864242 : return map()->instance_type() == BLOCK_CONTEXT_TYPE;
123 : }
124 :
125 4990531 : bool Context::IsModuleContext() const {
126 4990531 : return map()->instance_type() == MODULE_CONTEXT_TYPE;
127 : }
128 :
129 2853431 : bool Context::IsEvalContext() const {
130 2853431 : return map()->instance_type() == EVAL_CONTEXT_TYPE;
131 : }
132 :
133 3303848 : bool Context::IsScriptContext() const {
134 3303848 : return map()->instance_type() == SCRIPT_CONTEXT_TYPE;
135 : }
136 :
137 4776828 : bool Context::HasSameSecurityTokenAs(Context that) const {
138 9553656 : return this->native_context()->security_token() ==
139 9553656 : that->native_context()->security_token();
140 : }
141 :
142 : #define NATIVE_CONTEXT_FIELD_ACCESSORS(index, type, name) \
143 : void Context::set_##name(type value) { \
144 : DCHECK(IsNativeContext()); \
145 : set(index, value); \
146 : } \
147 : bool Context::is_##name(type value) const { \
148 : DCHECK(IsNativeContext()); \
149 : return type::cast(get(index)) == value; \
150 : } \
151 : type Context::name() const { \
152 : DCHECK(IsNativeContext()); \
153 : return type::cast(get(index)); \
154 : }
155 208707696 : NATIVE_CONTEXT_FIELDS(NATIVE_CONTEXT_FIELD_ACCESSORS)
156 : #undef NATIVE_CONTEXT_FIELD_ACCESSORS
157 :
158 : #define CHECK_FOLLOWS2(v1, v2) STATIC_ASSERT((v1 + 1) == (v2))
159 : #define CHECK_FOLLOWS4(v1, v2, v3, v4) \
160 : CHECK_FOLLOWS2(v1, v2); \
161 : CHECK_FOLLOWS2(v2, v3); \
162 : CHECK_FOLLOWS2(v3, v4)
163 :
164 18582328 : int Context::FunctionMapIndex(LanguageMode language_mode, FunctionKind kind,
165 : bool has_prototype_slot, bool has_shared_name,
166 : bool needs_home_object) {
167 18582328 : if (IsClassConstructor(kind)) {
168 : // Like the strict function map, but with no 'name' accessor. 'name'
169 : // needs to be the last property and it is added during instantiation,
170 : // in case a static property with the same name exists"
171 : return CLASS_FUNCTION_MAP_INDEX;
172 : }
173 :
174 : int base = 0;
175 18465850 : if (IsGeneratorFunction(kind)) {
176 : CHECK_FOLLOWS4(GENERATOR_FUNCTION_MAP_INDEX,
177 : GENERATOR_FUNCTION_WITH_NAME_MAP_INDEX,
178 : GENERATOR_FUNCTION_WITH_HOME_OBJECT_MAP_INDEX,
179 : GENERATOR_FUNCTION_WITH_NAME_AND_HOME_OBJECT_MAP_INDEX);
180 : CHECK_FOLLOWS4(
181 : ASYNC_GENERATOR_FUNCTION_MAP_INDEX,
182 : ASYNC_GENERATOR_FUNCTION_WITH_NAME_MAP_INDEX,
183 : ASYNC_GENERATOR_FUNCTION_WITH_HOME_OBJECT_MAP_INDEX,
184 : ASYNC_GENERATOR_FUNCTION_WITH_NAME_AND_HOME_OBJECT_MAP_INDEX);
185 :
186 : base = IsAsyncFunction(kind) ? ASYNC_GENERATOR_FUNCTION_MAP_INDEX
187 12594 : : GENERATOR_FUNCTION_MAP_INDEX;
188 :
189 18453256 : } else if (IsAsyncFunction(kind)) {
190 : CHECK_FOLLOWS4(ASYNC_FUNCTION_MAP_INDEX, ASYNC_FUNCTION_WITH_NAME_MAP_INDEX,
191 : ASYNC_FUNCTION_WITH_HOME_OBJECT_MAP_INDEX,
192 : ASYNC_FUNCTION_WITH_NAME_AND_HOME_OBJECT_MAP_INDEX);
193 :
194 : base = ASYNC_FUNCTION_MAP_INDEX;
195 :
196 52810035 : } else if (IsArrowFunction(kind) || IsConciseMethod(kind) ||
197 : IsAccessorFunction(kind)) {
198 : DCHECK_IMPLIES(IsArrowFunction(kind), !needs_home_object);
199 : CHECK_FOLLOWS4(STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX,
200 : METHOD_WITH_NAME_MAP_INDEX,
201 : METHOD_WITH_HOME_OBJECT_MAP_INDEX,
202 : METHOD_WITH_NAME_AND_HOME_OBJECT_MAP_INDEX);
203 :
204 : base = STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX;
205 :
206 : } else {
207 : DCHECK(!needs_home_object);
208 : CHECK_FOLLOWS2(SLOPPY_FUNCTION_MAP_INDEX,
209 : SLOPPY_FUNCTION_WITH_NAME_MAP_INDEX);
210 : CHECK_FOLLOWS2(STRICT_FUNCTION_MAP_INDEX,
211 : STRICT_FUNCTION_WITH_NAME_MAP_INDEX);
212 :
213 : base = is_strict(language_mode) ? STRICT_FUNCTION_MAP_INDEX
214 16738888 : : SLOPPY_FUNCTION_MAP_INDEX;
215 : }
216 18465850 : int offset = static_cast<int>(!has_shared_name) |
217 18465850 : (static_cast<int>(needs_home_object) << 1);
218 : DCHECK_EQ(0, offset & ~3);
219 :
220 18465850 : return base + offset;
221 : }
222 :
223 : #undef CHECK_FOLLOWS2
224 : #undef CHECK_FOLLOWS4
225 :
226 4166383 : Map Context::GetInitialJSArrayMap(ElementsKind kind) const {
227 : DCHECK(IsNativeContext());
228 4166383 : if (!IsFastElementsKind(kind)) return Map();
229 : DisallowHeapAllocation no_gc;
230 : Object const initial_js_array_map = get(Context::ArrayMapIndex(kind));
231 : DCHECK(!initial_js_array_map->IsUndefined());
232 : return Map::cast(initial_js_array_map);
233 : }
234 :
235 279 : MicrotaskQueue* NativeContext::microtask_queue() const {
236 : return reinterpret_cast<MicrotaskQueue*>(
237 11010 : READ_INTPTR_FIELD(this, kMicrotaskQueueOffset));
238 : }
239 :
240 : void NativeContext::set_microtask_queue(MicrotaskQueue* microtask_queue) {
241 92307 : WRITE_INTPTR_FIELD(this, kMicrotaskQueueOffset,
242 92307 : reinterpret_cast<intptr_t>(microtask_queue));
243 : }
244 :
245 2228732 : OBJECT_CONSTRUCTORS_IMPL(NativeContext, Context)
246 :
247 : } // namespace internal
248 : } // namespace v8
249 :
250 : #include "src/objects/object-macros-undef.h"
251 :
252 : #endif // V8_CONTEXTS_INL_H_
|