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_OBJECTS_H_
6 #define V8_OBJECTS_H_
7
8 #include <iosfwd>
9 #include <memory>
10
11 #include "include/v8.h"
12 #include "include/v8config.h"
13 #include "src/assert-scope.h"
14 #include "src/base/bits.h"
15 #include "src/base/build_config.h"
16 #include "src/base/flags.h"
17 #include "src/base/logging.h"
18 #include "src/checks.h"
19 #include "src/elements-kind.h"
20 #include "src/field-index.h"
21 #include "src/flags.h"
22 #include "src/messages.h"
23 #include "src/property-details.h"
24 #include "src/utils.h"
25
26 #if V8_TARGET_ARCH_ARM
27 #include "src/arm/constants-arm.h" // NOLINT
28 #elif V8_TARGET_ARCH_ARM64
29 #include "src/arm64/constants-arm64.h" // NOLINT
30 #elif V8_TARGET_ARCH_MIPS
31 #include "src/mips/constants-mips.h" // NOLINT
32 #elif V8_TARGET_ARCH_MIPS64
33 #include "src/mips64/constants-mips64.h" // NOLINT
34 #elif V8_TARGET_ARCH_PPC
35 #include "src/ppc/constants-ppc.h" // NOLINT
36 #elif V8_TARGET_ARCH_S390
37 #include "src/s390/constants-s390.h" // NOLINT
38 #endif
39
40 // Has to be the last include (doesn't have include guards):
41 #include "src/objects/object-macros.h"
42
43 //
44 // Most object types in the V8 JavaScript are described in this file.
45 //
46 // Inheritance hierarchy:
47 // - Object
48 // - Smi (immediate small integer)
49 // - HeapObject (superclass for everything allocated in the heap)
50 // - JSReceiver (suitable for property access)
51 // - JSObject
52 // - JSArray
53 // - JSArrayBuffer
54 // - JSArrayBufferView
55 // - JSTypedArray
56 // - JSDataView
57 // - JSBoundFunction
58 // - JSCollection
59 // - JSSet
60 // - JSMap
61 // - JSStringIterator
62 // - JSSetIterator
63 // - JSMapIterator
64 // - JSWeakCollection
65 // - JSWeakMap
66 // - JSWeakSet
67 // - JSRegExp
68 // - JSFunction
69 // - JSGeneratorObject
70 // - JSGlobalObject
71 // - JSGlobalProxy
72 // - JSValue
73 // - JSDate
74 // - JSMessageObject
75 // - JSModuleNamespace
76 // - JSLocale // If V8_INTL_SUPPORT enabled.
77 // - WasmGlobalObject
78 // - WasmInstanceObject
79 // - WasmMemoryObject
80 // - WasmModuleObject
81 // - WasmTableObject
82 // - JSProxy
83 // - FixedArrayBase
84 // - ByteArray
85 // - BytecodeArray
86 // - FixedArray
87 // - DescriptorArray
88 // - FrameArray
89 // - HashTable
90 // - Dictionary
91 // - StringTable
92 // - StringSet
93 // - CompilationCacheTable
94 // - MapCache
95 // - OrderedHashTable
96 // - OrderedHashSet
97 // - OrderedHashMap
98 // - Context
99 // - FeedbackMetadata
100 // - TemplateList
101 // - TransitionArray
102 // - ScopeInfo
103 // - ModuleInfo
104 // - ScriptContextTable
105 // - FixedArrayOfWeakCells
106 // - WasmSharedModuleData
107 // - WasmCompiledModule
108 // - FixedDoubleArray
109 // - Name
110 // - String
111 // - SeqString
112 // - SeqOneByteString
113 // - SeqTwoByteString
114 // - SlicedString
115 // - ConsString
116 // - ThinString
117 // - ExternalString
118 // - ExternalOneByteString
119 // - ExternalTwoByteString
120 // - InternalizedString
121 // - SeqInternalizedString
122 // - SeqOneByteInternalizedString
123 // - SeqTwoByteInternalizedString
124 // - ConsInternalizedString
125 // - ExternalInternalizedString
126 // - ExternalOneByteInternalizedString
127 // - ExternalTwoByteInternalizedString
128 // - Symbol
129 // - HeapNumber
130 // - BigInt
131 // - Cell
132 // - PropertyCell
133 // - PropertyArray
134 // - Code
135 // - AbstractCode, a wrapper around Code or BytecodeArray
136 // - Map
137 // - Oddball
138 // - Foreign
139 // - SmallOrderedHashTable
140 // - SmallOrderedHashMap
141 // - SmallOrderedHashSet
142 // - SharedFunctionInfo
143 // - Struct
144 // - AccessorInfo
145 // - PromiseReaction
146 // - PromiseCapability
147 // - AccessorPair
148 // - AccessCheckInfo
149 // - InterceptorInfo
150 // - CallHandlerInfo
151 // - EnumCache
152 // - TemplateInfo
153 // - FunctionTemplateInfo
154 // - ObjectTemplateInfo
155 // - Script
156 // - DebugInfo
157 // - BreakPoint
158 // - BreakPointInfo
159 // - StackFrameInfo
160 // - SourcePositionTableWithFrameCache
161 // - CodeCache
162 // - PrototypeInfo
163 // - Microtask
164 // - CallbackTask
165 // - CallableTask
166 // - PromiseReactionJobTask
167 // - PromiseFulfillReactionJobTask
168 // - PromiseRejectReactionJobTask
169 // - PromiseResolveThenableJobTask
170 // - Module
171 // - ModuleInfoEntry
172 // - PreParsedScopeData
173 // - WeakCell
174 // - FeedbackCell
175 // - FeedbackVector
176 //
177 // Formats of Object*:
178 // Smi: [31 bit signed int] 0
179 // HeapObject: [32 bit direct pointer] (4 byte aligned) | 01
180
181 namespace v8 {
182 namespace internal {
183
184 struct InliningPosition;
185 class PropertyDescriptorObject;
186
187 enum KeyedAccessLoadMode {
188 STANDARD_LOAD,
189 LOAD_IGNORE_OUT_OF_BOUNDS,
190 };
191
192 enum KeyedAccessStoreMode {
193 STANDARD_STORE,
194 STORE_TRANSITION_TO_OBJECT,
195 STORE_TRANSITION_TO_DOUBLE,
196 STORE_AND_GROW_NO_TRANSITION_HANDLE_COW,
197 STORE_AND_GROW_TRANSITION_TO_OBJECT,
198 STORE_AND_GROW_TRANSITION_TO_DOUBLE,
199 STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS,
200 STORE_NO_TRANSITION_HANDLE_COW
201 };
202
203 enum MutableMode {
204 MUTABLE,
205 IMMUTABLE
206 };
207
208
IsTransitionStoreMode(KeyedAccessStoreMode store_mode)209 static inline bool IsTransitionStoreMode(KeyedAccessStoreMode store_mode) {
210 return store_mode == STORE_TRANSITION_TO_OBJECT ||
211 store_mode == STORE_TRANSITION_TO_DOUBLE ||
212 store_mode == STORE_AND_GROW_TRANSITION_TO_OBJECT ||
213 store_mode == STORE_AND_GROW_TRANSITION_TO_DOUBLE;
214 }
215
IsCOWHandlingStoreMode(KeyedAccessStoreMode store_mode)216 static inline bool IsCOWHandlingStoreMode(KeyedAccessStoreMode store_mode) {
217 return store_mode == STORE_NO_TRANSITION_HANDLE_COW ||
218 store_mode == STORE_AND_GROW_NO_TRANSITION_HANDLE_COW;
219 }
220
GetNonTransitioningStoreMode(KeyedAccessStoreMode store_mode,bool receiver_was_cow)221 static inline KeyedAccessStoreMode GetNonTransitioningStoreMode(
222 KeyedAccessStoreMode store_mode, bool receiver_was_cow) {
223 switch (store_mode) {
224 case STORE_AND_GROW_NO_TRANSITION_HANDLE_COW:
225 case STORE_AND_GROW_TRANSITION_TO_OBJECT:
226 case STORE_AND_GROW_TRANSITION_TO_DOUBLE:
227 store_mode = STORE_AND_GROW_NO_TRANSITION_HANDLE_COW;
228 break;
229 case STANDARD_STORE:
230 case STORE_TRANSITION_TO_OBJECT:
231 case STORE_TRANSITION_TO_DOUBLE:
232 store_mode =
233 receiver_was_cow ? STORE_NO_TRANSITION_HANDLE_COW : STANDARD_STORE;
234 break;
235 case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS:
236 case STORE_NO_TRANSITION_HANDLE_COW:
237 break;
238 }
239 DCHECK(!IsTransitionStoreMode(store_mode));
240 DCHECK_IMPLIES(receiver_was_cow, IsCOWHandlingStoreMode(store_mode));
241 return store_mode;
242 }
243
244
IsGrowStoreMode(KeyedAccessStoreMode store_mode)245 static inline bool IsGrowStoreMode(KeyedAccessStoreMode store_mode) {
246 return store_mode >= STORE_AND_GROW_NO_TRANSITION_HANDLE_COW &&
247 store_mode <= STORE_AND_GROW_TRANSITION_TO_DOUBLE;
248 }
249
250
251 enum IcCheckType { ELEMENT, PROPERTY };
252
253
254 // SKIP_WRITE_BARRIER skips the write barrier.
255 // UPDATE_WEAK_WRITE_BARRIER skips the marking part of the write barrier and
256 // only performs the generational part.
257 // UPDATE_WRITE_BARRIER is doing the full barrier, marking and generational.
258 enum WriteBarrierMode {
259 SKIP_WRITE_BARRIER,
260 UPDATE_WEAK_WRITE_BARRIER,
261 UPDATE_WRITE_BARRIER
262 };
263
264
265 // PropertyNormalizationMode is used to specify whether to keep
266 // inobject properties when normalizing properties of a JSObject.
267 enum PropertyNormalizationMode {
268 CLEAR_INOBJECT_PROPERTIES,
269 KEEP_INOBJECT_PROPERTIES
270 };
271
272
273 // Indicates whether transitions can be added to a source map or not.
274 enum TransitionFlag {
275 INSERT_TRANSITION,
276 OMIT_TRANSITION
277 };
278
279
280 // Indicates whether the transition is simple: the target map of the transition
281 // either extends the current map with a new property, or it modifies the
282 // property that was added last to the current map.
283 enum SimpleTransitionFlag {
284 SIMPLE_PROPERTY_TRANSITION,
285 PROPERTY_TRANSITION,
286 SPECIAL_TRANSITION
287 };
288
289 // Indicates whether we are only interested in the descriptors of a particular
290 // map, or in all descriptors in the descriptor array.
291 enum DescriptorFlag {
292 ALL_DESCRIPTORS,
293 OWN_DESCRIPTORS
294 };
295
296 // Instance size sentinel for objects of variable size.
297 const int kVariableSizeSentinel = 0;
298
299 // We may store the unsigned bit field as signed Smi value and do not
300 // use the sign bit.
301 const int kStubMajorKeyBits = 8;
302 const int kStubMinorKeyBits = kSmiValueSize - kStubMajorKeyBits - 1;
303
304 // All Maps have a field instance_type containing a InstanceType.
305 // It describes the type of the instances.
306 //
307 // As an example, a JavaScript object is a heap object and its map
308 // instance_type is JS_OBJECT_TYPE.
309 //
310 // The names of the string instance types are intended to systematically
311 // mirror their encoding in the instance_type field of the map. The default
312 // encoding is considered TWO_BYTE. It is not mentioned in the name. ONE_BYTE
313 // encoding is mentioned explicitly in the name. Likewise, the default
314 // representation is considered sequential. It is not mentioned in the
315 // name. The other representations (e.g. CONS, EXTERNAL) are explicitly
316 // mentioned. Finally, the string is either a STRING_TYPE (if it is a normal
317 // string) or a INTERNALIZED_STRING_TYPE (if it is a internalized string).
318 //
319 // NOTE: The following things are some that depend on the string types having
320 // instance_types that are less than those of all other types:
321 // HeapObject::Size, HeapObject::IterateBody, the typeof operator, and
322 // Object::IsString.
323 //
324 // NOTE: Everything following JS_VALUE_TYPE is considered a
325 // JSObject for GC purposes. The first four entries here have typeof
326 // 'object', whereas JS_FUNCTION_TYPE has typeof 'function'.
327 //
328 // NOTE: List had to be split into two, because of conditional item(s) from
329 // INTL namespace. They can't just be appended to the end, because of the
330 // checks we do in tests (expecting JS_FUNCTION_TYPE to be last).
331 #define INSTANCE_TYPE_LIST_BEFORE_INTL(V) \
332 V(INTERNALIZED_STRING_TYPE) \
333 V(EXTERNAL_INTERNALIZED_STRING_TYPE) \
334 V(ONE_BYTE_INTERNALIZED_STRING_TYPE) \
335 V(EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE) \
336 V(EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE) \
337 V(SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE) \
338 V(SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE) \
339 V(SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE) \
340 V(STRING_TYPE) \
341 V(CONS_STRING_TYPE) \
342 V(EXTERNAL_STRING_TYPE) \
343 V(SLICED_STRING_TYPE) \
344 V(THIN_STRING_TYPE) \
345 V(ONE_BYTE_STRING_TYPE) \
346 V(CONS_ONE_BYTE_STRING_TYPE) \
347 V(EXTERNAL_ONE_BYTE_STRING_TYPE) \
348 V(SLICED_ONE_BYTE_STRING_TYPE) \
349 V(THIN_ONE_BYTE_STRING_TYPE) \
350 V(EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE) \
351 V(SHORT_EXTERNAL_STRING_TYPE) \
352 V(SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE) \
353 V(SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE) \
354 \
355 V(SYMBOL_TYPE) \
356 V(HEAP_NUMBER_TYPE) \
357 V(BIGINT_TYPE) \
358 V(ODDBALL_TYPE) \
359 \
360 V(MAP_TYPE) \
361 V(CODE_TYPE) \
362 V(MUTABLE_HEAP_NUMBER_TYPE) \
363 V(FOREIGN_TYPE) \
364 V(BYTE_ARRAY_TYPE) \
365 V(BYTECODE_ARRAY_TYPE) \
366 V(FREE_SPACE_TYPE) \
367 \
368 V(FIXED_INT8_ARRAY_TYPE) \
369 V(FIXED_UINT8_ARRAY_TYPE) \
370 V(FIXED_INT16_ARRAY_TYPE) \
371 V(FIXED_UINT16_ARRAY_TYPE) \
372 V(FIXED_INT32_ARRAY_TYPE) \
373 V(FIXED_UINT32_ARRAY_TYPE) \
374 V(FIXED_FLOAT32_ARRAY_TYPE) \
375 V(FIXED_FLOAT64_ARRAY_TYPE) \
376 V(FIXED_UINT8_CLAMPED_ARRAY_TYPE) \
377 V(FIXED_BIGINT64_ARRAY_TYPE) \
378 V(FIXED_BIGUINT64_ARRAY_TYPE) \
379 \
380 V(FIXED_DOUBLE_ARRAY_TYPE) \
381 V(FEEDBACK_METADATA_TYPE) \
382 V(FILLER_TYPE) \
383 \
384 V(ACCESS_CHECK_INFO_TYPE) \
385 V(ACCESSOR_INFO_TYPE) \
386 V(ACCESSOR_PAIR_TYPE) \
387 V(ALIASED_ARGUMENTS_ENTRY_TYPE) \
388 V(ALLOCATION_MEMENTO_TYPE) \
389 V(ALLOCATION_SITE_TYPE) \
390 V(ASYNC_GENERATOR_REQUEST_TYPE) \
391 V(DEBUG_INFO_TYPE) \
392 V(FUNCTION_TEMPLATE_INFO_TYPE) \
393 V(INTERCEPTOR_INFO_TYPE) \
394 V(INTERPRETER_DATA_TYPE) \
395 V(MODULE_INFO_ENTRY_TYPE) \
396 V(MODULE_TYPE) \
397 V(OBJECT_TEMPLATE_INFO_TYPE) \
398 V(PROMISE_CAPABILITY_TYPE) \
399 V(PROMISE_REACTION_TYPE) \
400 V(PROTOTYPE_INFO_TYPE) \
401 V(SCRIPT_TYPE) \
402 V(STACK_FRAME_INFO_TYPE) \
403 V(TUPLE2_TYPE) \
404 V(TUPLE3_TYPE) \
405 V(WASM_COMPILED_MODULE_TYPE) \
406 V(WASM_DEBUG_INFO_TYPE) \
407 V(WASM_EXPORTED_FUNCTION_DATA_TYPE) \
408 V(WASM_SHARED_MODULE_DATA_TYPE) \
409 \
410 V(CALLABLE_TASK_TYPE) \
411 V(CALLBACK_TASK_TYPE) \
412 V(PROMISE_FULFILL_REACTION_JOB_TASK_TYPE) \
413 V(PROMISE_REJECT_REACTION_JOB_TASK_TYPE) \
414 V(PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE) \
415 \
416 V(FIXED_ARRAY_TYPE) \
417 V(BOILERPLATE_DESCRIPTION_TYPE) \
418 V(DESCRIPTOR_ARRAY_TYPE) \
419 V(HASH_TABLE_TYPE) \
420 V(SCOPE_INFO_TYPE) \
421 \
422 V(BLOCK_CONTEXT_TYPE) \
423 V(CATCH_CONTEXT_TYPE) \
424 V(DEBUG_EVALUATE_CONTEXT_TYPE) \
425 V(EVAL_CONTEXT_TYPE) \
426 V(FUNCTION_CONTEXT_TYPE) \
427 V(MODULE_CONTEXT_TYPE) \
428 V(NATIVE_CONTEXT_TYPE) \
429 V(SCRIPT_CONTEXT_TYPE) \
430 V(WITH_CONTEXT_TYPE) \
431 \
432 V(WEAK_FIXED_ARRAY_TYPE) \
433 V(TRANSITION_ARRAY_TYPE) \
434 \
435 V(CALL_HANDLER_INFO_TYPE) \
436 V(CELL_TYPE) \
437 V(CODE_DATA_CONTAINER_TYPE) \
438 V(FEEDBACK_CELL_TYPE) \
439 V(FEEDBACK_VECTOR_TYPE) \
440 V(LOAD_HANDLER_TYPE) \
441 V(PROPERTY_ARRAY_TYPE) \
442 V(PROPERTY_CELL_TYPE) \
443 V(SHARED_FUNCTION_INFO_TYPE) \
444 V(SMALL_ORDERED_HASH_MAP_TYPE) \
445 V(SMALL_ORDERED_HASH_SET_TYPE) \
446 V(STORE_HANDLER_TYPE) \
447 V(WEAK_CELL_TYPE) \
448 V(WEAK_ARRAY_LIST_TYPE) \
449 \
450 V(JS_PROXY_TYPE) \
451 V(JS_GLOBAL_OBJECT_TYPE) \
452 V(JS_GLOBAL_PROXY_TYPE) \
453 V(JS_MODULE_NAMESPACE_TYPE) \
454 V(JS_SPECIAL_API_OBJECT_TYPE) \
455 V(JS_VALUE_TYPE) \
456 V(JS_API_OBJECT_TYPE) \
457 V(JS_OBJECT_TYPE) \
458 \
459 V(JS_ARGUMENTS_TYPE) \
460 V(JS_ARRAY_BUFFER_TYPE) \
461 V(JS_ARRAY_ITERATOR_TYPE) \
462 V(JS_ARRAY_TYPE) \
463 V(JS_ASYNC_FROM_SYNC_ITERATOR_TYPE) \
464 V(JS_ASYNC_GENERATOR_OBJECT_TYPE) \
465 V(JS_CONTEXT_EXTENSION_OBJECT_TYPE) \
466 V(JS_DATE_TYPE) \
467 V(JS_ERROR_TYPE) \
468 V(JS_GENERATOR_OBJECT_TYPE) \
469 V(JS_MAP_TYPE) \
470 V(JS_MAP_KEY_ITERATOR_TYPE) \
471 V(JS_MAP_KEY_VALUE_ITERATOR_TYPE) \
472 V(JS_MAP_VALUE_ITERATOR_TYPE) \
473 V(JS_MESSAGE_OBJECT_TYPE) \
474 V(JS_PROMISE_TYPE) \
475 V(JS_REGEXP_TYPE) \
476 V(JS_REGEXP_STRING_ITERATOR_TYPE) \
477 V(JS_SET_TYPE) \
478 V(JS_SET_KEY_VALUE_ITERATOR_TYPE) \
479 V(JS_SET_VALUE_ITERATOR_TYPE) \
480 V(JS_STRING_ITERATOR_TYPE) \
481 V(JS_WEAK_MAP_TYPE) \
482 V(JS_WEAK_SET_TYPE) \
483 V(JS_TYPED_ARRAY_TYPE) \
484 V(JS_DATA_VIEW_TYPE)
485
486 #define INSTANCE_TYPE_LIST_AFTER_INTL(V) \
487 V(WASM_GLOBAL_TYPE) \
488 V(WASM_INSTANCE_TYPE) \
489 V(WASM_MEMORY_TYPE) \
490 V(WASM_MODULE_TYPE) \
491 V(WASM_TABLE_TYPE) \
492 V(JS_BOUND_FUNCTION_TYPE) \
493 V(JS_FUNCTION_TYPE)
494
495 #ifdef V8_INTL_SUPPORT
496 #define INSTANCE_TYPE_LIST(V) \
497 INSTANCE_TYPE_LIST_BEFORE_INTL(V) \
498 V(JS_INTL_LOCALE_TYPE) \
499 INSTANCE_TYPE_LIST_AFTER_INTL(V)
500 #else
501 #define INSTANCE_TYPE_LIST(V) \
502 INSTANCE_TYPE_LIST_BEFORE_INTL(V) \
503 INSTANCE_TYPE_LIST_AFTER_INTL(V)
504 #endif // V8_INTL_SUPPORT
505
506 // Since string types are not consecutive, this macro is used to
507 // iterate over them.
508 #define STRING_TYPE_LIST(V) \
509 V(STRING_TYPE, kVariableSizeSentinel, string, String) \
510 V(ONE_BYTE_STRING_TYPE, kVariableSizeSentinel, one_byte_string, \
511 OneByteString) \
512 V(CONS_STRING_TYPE, ConsString::kSize, cons_string, ConsString) \
513 V(CONS_ONE_BYTE_STRING_TYPE, ConsString::kSize, cons_one_byte_string, \
514 ConsOneByteString) \
515 V(SLICED_STRING_TYPE, SlicedString::kSize, sliced_string, SlicedString) \
516 V(SLICED_ONE_BYTE_STRING_TYPE, SlicedString::kSize, sliced_one_byte_string, \
517 SlicedOneByteString) \
518 V(EXTERNAL_STRING_TYPE, ExternalTwoByteString::kSize, external_string, \
519 ExternalString) \
520 V(EXTERNAL_ONE_BYTE_STRING_TYPE, ExternalOneByteString::kSize, \
521 external_one_byte_string, ExternalOneByteString) \
522 V(EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE, ExternalTwoByteString::kSize, \
523 external_string_with_one_byte_data, ExternalStringWithOneByteData) \
524 V(SHORT_EXTERNAL_STRING_TYPE, ExternalTwoByteString::kShortSize, \
525 short_external_string, ShortExternalString) \
526 V(SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE, ExternalOneByteString::kShortSize, \
527 short_external_one_byte_string, ShortExternalOneByteString) \
528 V(SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE, \
529 ExternalTwoByteString::kShortSize, \
530 short_external_string_with_one_byte_data, \
531 ShortExternalStringWithOneByteData) \
532 \
533 V(INTERNALIZED_STRING_TYPE, kVariableSizeSentinel, internalized_string, \
534 InternalizedString) \
535 V(ONE_BYTE_INTERNALIZED_STRING_TYPE, kVariableSizeSentinel, \
536 one_byte_internalized_string, OneByteInternalizedString) \
537 V(EXTERNAL_INTERNALIZED_STRING_TYPE, ExternalTwoByteString::kSize, \
538 external_internalized_string, ExternalInternalizedString) \
539 V(EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE, ExternalOneByteString::kSize, \
540 external_one_byte_internalized_string, ExternalOneByteInternalizedString) \
541 V(EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE, \
542 ExternalTwoByteString::kSize, \
543 external_internalized_string_with_one_byte_data, \
544 ExternalInternalizedStringWithOneByteData) \
545 V(SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE, \
546 ExternalTwoByteString::kShortSize, short_external_internalized_string, \
547 ShortExternalInternalizedString) \
548 V(SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE, \
549 ExternalOneByteString::kShortSize, \
550 short_external_one_byte_internalized_string, \
551 ShortExternalOneByteInternalizedString) \
552 V(SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE, \
553 ExternalTwoByteString::kShortSize, \
554 short_external_internalized_string_with_one_byte_data, \
555 ShortExternalInternalizedStringWithOneByteData) \
556 V(THIN_STRING_TYPE, ThinString::kSize, thin_string, ThinString) \
557 V(THIN_ONE_BYTE_STRING_TYPE, ThinString::kSize, thin_one_byte_string, \
558 ThinOneByteString)
559
560 // A struct is a simple object a set of object-valued fields. Including an
561 // object type in this causes the compiler to generate most of the boilerplate
562 // code for the class including allocation and garbage collection routines,
563 // casts and predicates. All you need to define is the class, methods and
564 // object verification routines. Easy, no?
565 //
566 // Note that for subtle reasons related to the ordering or numerical values of
567 // type tags, elements in this list have to be added to the INSTANCE_TYPE_LIST
568 // manually.
569 #define STRUCT_LIST(V) \
570 V(ACCESS_CHECK_INFO, AccessCheckInfo, access_check_info) \
571 V(ACCESSOR_INFO, AccessorInfo, accessor_info) \
572 V(ACCESSOR_PAIR, AccessorPair, accessor_pair) \
573 V(ALIASED_ARGUMENTS_ENTRY, AliasedArgumentsEntry, aliased_arguments_entry) \
574 V(ALLOCATION_MEMENTO, AllocationMemento, allocation_memento) \
575 V(ALLOCATION_SITE, AllocationSite, allocation_site) \
576 V(ASYNC_GENERATOR_REQUEST, AsyncGeneratorRequest, async_generator_request) \
577 V(DEBUG_INFO, DebugInfo, debug_info) \
578 V(FUNCTION_TEMPLATE_INFO, FunctionTemplateInfo, function_template_info) \
579 V(INTERCEPTOR_INFO, InterceptorInfo, interceptor_info) \
580 V(INTERPRETER_DATA, InterpreterData, interpreter_data) \
581 V(MODULE_INFO_ENTRY, ModuleInfoEntry, module_info_entry) \
582 V(MODULE, Module, module) \
583 V(OBJECT_TEMPLATE_INFO, ObjectTemplateInfo, object_template_info) \
584 V(PROMISE_CAPABILITY, PromiseCapability, promise_capability) \
585 V(PROMISE_REACTION, PromiseReaction, promise_reaction) \
586 V(PROTOTYPE_INFO, PrototypeInfo, prototype_info) \
587 V(SCRIPT, Script, script) \
588 V(STACK_FRAME_INFO, StackFrameInfo, stack_frame_info) \
589 V(TUPLE2, Tuple2, tuple2) \
590 V(TUPLE3, Tuple3, tuple3) \
591 V(WASM_COMPILED_MODULE, WasmCompiledModule, wasm_compiled_module) \
592 V(WASM_DEBUG_INFO, WasmDebugInfo, wasm_debug_info) \
593 V(WASM_EXPORTED_FUNCTION_DATA, WasmExportedFunctionData, \
594 wasm_exported_function_data) \
595 V(WASM_SHARED_MODULE_DATA, WasmSharedModuleData, wasm_shared_module_data) \
596 V(CALLABLE_TASK, CallableTask, callable_task) \
597 V(CALLBACK_TASK, CallbackTask, callback_task) \
598 V(PROMISE_FULFILL_REACTION_JOB_TASK, PromiseFulfillReactionJobTask, \
599 promise_fulfill_reaction_job_task) \
600 V(PROMISE_REJECT_REACTION_JOB_TASK, PromiseRejectReactionJobTask, \
601 promise_reject_reaction_job_task) \
602 V(PROMISE_RESOLVE_THENABLE_JOB_TASK, PromiseResolveThenableJobTask, \
603 promise_resolve_thenable_job_task)
604
605 #define DATA_HANDLER_LIST(V) \
606 V(LOAD_HANDLER, LoadHandler, 1, load_handler1) \
607 V(LOAD_HANDLER, LoadHandler, 2, load_handler2) \
608 V(LOAD_HANDLER, LoadHandler, 3, load_handler3) \
609 V(STORE_HANDLER, StoreHandler, 0, store_handler0) \
610 V(STORE_HANDLER, StoreHandler, 1, store_handler1) \
611 V(STORE_HANDLER, StoreHandler, 2, store_handler2) \
612 V(STORE_HANDLER, StoreHandler, 3, store_handler3)
613
614 // We use the full 16 bits of the instance_type field to encode heap object
615 // instance types. All the high-order bits (bit 7-15) are cleared if the object
616 // is a string, and contain set bits if it is not a string.
617 const uint32_t kIsNotStringMask = 0xff80;
618 const uint32_t kStringTag = 0x0;
619
620 // Bit 6 indicates that the object is an internalized string (if set) or not.
621 // Bit 7 has to be clear as well.
622 const uint32_t kIsNotInternalizedMask = 0x40;
623 const uint32_t kNotInternalizedTag = 0x40;
624 const uint32_t kInternalizedTag = 0x0;
625
626 // If bit 7 is clear then bit 3 indicates whether the string consists of
627 // two-byte characters or one-byte characters.
628 const uint32_t kStringEncodingMask = 0x8;
629 const uint32_t kTwoByteStringTag = 0x0;
630 const uint32_t kOneByteStringTag = 0x8;
631
632 // If bit 7 is clear, the low-order 3 bits indicate the representation
633 // of the string.
634 const uint32_t kStringRepresentationMask = 0x07;
635 enum StringRepresentationTag {
636 kSeqStringTag = 0x0,
637 kConsStringTag = 0x1,
638 kExternalStringTag = 0x2,
639 kSlicedStringTag = 0x3,
640 kThinStringTag = 0x5
641 };
642 const uint32_t kIsIndirectStringMask = 0x1;
643 const uint32_t kIsIndirectStringTag = 0x1;
644 STATIC_ASSERT((kSeqStringTag & kIsIndirectStringMask) == 0); // NOLINT
645 STATIC_ASSERT((kExternalStringTag & kIsIndirectStringMask) == 0); // NOLINT
646 STATIC_ASSERT((kConsStringTag &
647 kIsIndirectStringMask) == kIsIndirectStringTag); // NOLINT
648 STATIC_ASSERT((kSlicedStringTag &
649 kIsIndirectStringMask) == kIsIndirectStringTag); // NOLINT
650 STATIC_ASSERT((kThinStringTag & kIsIndirectStringMask) == kIsIndirectStringTag);
651
652 // If bit 7 is clear, then bit 4 indicates whether this two-byte
653 // string actually contains one byte data.
654 const uint32_t kOneByteDataHintMask = 0x10;
655 const uint32_t kOneByteDataHintTag = 0x10;
656
657 // If bit 7 is clear and string representation indicates an external string,
658 // then bit 5 indicates whether the data pointer is cached.
659 const uint32_t kShortExternalStringMask = 0x20;
660 const uint32_t kShortExternalStringTag = 0x20;
661
662 // A ConsString with an empty string as the right side is a candidate
663 // for being shortcut by the garbage collector. We don't allocate any
664 // non-flat internalized strings, so we do not shortcut them thereby
665 // avoiding turning internalized strings into strings. The bit-masks
666 // below contain the internalized bit as additional safety.
667 // See heap.cc, mark-compact.cc and objects-visiting.cc.
668 const uint32_t kShortcutTypeMask =
669 kIsNotStringMask |
670 kIsNotInternalizedMask |
671 kStringRepresentationMask;
672 const uint32_t kShortcutTypeTag = kConsStringTag | kNotInternalizedTag;
673
IsShortcutCandidate(int type)674 static inline bool IsShortcutCandidate(int type) {
675 return ((type & kShortcutTypeMask) == kShortcutTypeTag);
676 }
677
678 enum InstanceType : uint16_t {
679 // String types.
680 INTERNALIZED_STRING_TYPE = kTwoByteStringTag | kSeqStringTag |
681 kInternalizedTag, // FIRST_PRIMITIVE_TYPE
682 ONE_BYTE_INTERNALIZED_STRING_TYPE =
683 kOneByteStringTag | kSeqStringTag | kInternalizedTag,
684 EXTERNAL_INTERNALIZED_STRING_TYPE =
685 kTwoByteStringTag | kExternalStringTag | kInternalizedTag,
686 EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE =
687 kOneByteStringTag | kExternalStringTag | kInternalizedTag,
688 EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE =
689 EXTERNAL_INTERNALIZED_STRING_TYPE | kOneByteDataHintTag |
690 kInternalizedTag,
691 SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE = EXTERNAL_INTERNALIZED_STRING_TYPE |
692 kShortExternalStringTag |
693 kInternalizedTag,
694 SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE =
695 EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE | kShortExternalStringTag |
696 kInternalizedTag,
697 SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE =
698 EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE |
699 kShortExternalStringTag | kInternalizedTag,
700 STRING_TYPE = INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
701 ONE_BYTE_STRING_TYPE =
702 ONE_BYTE_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
703 CONS_STRING_TYPE = kTwoByteStringTag | kConsStringTag | kNotInternalizedTag,
704 CONS_ONE_BYTE_STRING_TYPE =
705 kOneByteStringTag | kConsStringTag | kNotInternalizedTag,
706 SLICED_STRING_TYPE =
707 kTwoByteStringTag | kSlicedStringTag | kNotInternalizedTag,
708 SLICED_ONE_BYTE_STRING_TYPE =
709 kOneByteStringTag | kSlicedStringTag | kNotInternalizedTag,
710 EXTERNAL_STRING_TYPE =
711 EXTERNAL_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
712 EXTERNAL_ONE_BYTE_STRING_TYPE =
713 EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
714 EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE =
715 EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE |
716 kNotInternalizedTag,
717 SHORT_EXTERNAL_STRING_TYPE =
718 SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
719 SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE =
720 SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
721 SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE =
722 SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE |
723 kNotInternalizedTag,
724 THIN_STRING_TYPE = kTwoByteStringTag | kThinStringTag | kNotInternalizedTag,
725 THIN_ONE_BYTE_STRING_TYPE =
726 kOneByteStringTag | kThinStringTag | kNotInternalizedTag,
727
728 // Non-string names
729 SYMBOL_TYPE =
730 1 + (kIsNotInternalizedMask | kShortExternalStringMask |
731 kOneByteDataHintMask | kStringEncodingMask |
732 kStringRepresentationMask), // FIRST_NONSTRING_TYPE, LAST_NAME_TYPE
733
734 // Other primitives (cannot contain non-map-word pointers to heap objects).
735 HEAP_NUMBER_TYPE,
736 BIGINT_TYPE,
737 ODDBALL_TYPE, // LAST_PRIMITIVE_TYPE
738
739 // Objects allocated in their own spaces (never in new space).
740 MAP_TYPE,
741 CODE_TYPE,
742
743 // "Data", objects that cannot contain non-map-word pointers to heap
744 // objects.
745 MUTABLE_HEAP_NUMBER_TYPE,
746 FOREIGN_TYPE,
747 BYTE_ARRAY_TYPE,
748 BYTECODE_ARRAY_TYPE,
749 FREE_SPACE_TYPE,
750 FIXED_INT8_ARRAY_TYPE, // FIRST_FIXED_TYPED_ARRAY_TYPE
751 FIXED_UINT8_ARRAY_TYPE,
752 FIXED_INT16_ARRAY_TYPE,
753 FIXED_UINT16_ARRAY_TYPE,
754 FIXED_INT32_ARRAY_TYPE,
755 FIXED_UINT32_ARRAY_TYPE,
756 FIXED_FLOAT32_ARRAY_TYPE,
757 FIXED_FLOAT64_ARRAY_TYPE,
758 FIXED_UINT8_CLAMPED_ARRAY_TYPE,
759 FIXED_BIGINT64_ARRAY_TYPE,
760 FIXED_BIGUINT64_ARRAY_TYPE, // LAST_FIXED_TYPED_ARRAY_TYPE
761 FIXED_DOUBLE_ARRAY_TYPE,
762 FEEDBACK_METADATA_TYPE,
763 FILLER_TYPE, // LAST_DATA_TYPE
764
765 // Structs.
766 ACCESS_CHECK_INFO_TYPE,
767 ACCESSOR_INFO_TYPE,
768 ACCESSOR_PAIR_TYPE,
769 ALIASED_ARGUMENTS_ENTRY_TYPE,
770 ALLOCATION_MEMENTO_TYPE,
771 ALLOCATION_SITE_TYPE,
772 ASYNC_GENERATOR_REQUEST_TYPE,
773 DEBUG_INFO_TYPE,
774 FUNCTION_TEMPLATE_INFO_TYPE,
775 INTERCEPTOR_INFO_TYPE,
776 INTERPRETER_DATA_TYPE,
777 MODULE_INFO_ENTRY_TYPE,
778 MODULE_TYPE,
779 OBJECT_TEMPLATE_INFO_TYPE,
780 PROMISE_CAPABILITY_TYPE,
781 PROMISE_REACTION_TYPE,
782 PROTOTYPE_INFO_TYPE,
783 SCRIPT_TYPE,
784 STACK_FRAME_INFO_TYPE,
785 TUPLE2_TYPE,
786 TUPLE3_TYPE,
787 WASM_COMPILED_MODULE_TYPE,
788 WASM_DEBUG_INFO_TYPE,
789 WASM_EXPORTED_FUNCTION_DATA_TYPE,
790 WASM_SHARED_MODULE_DATA_TYPE,
791
792 CALLABLE_TASK_TYPE, // FIRST_MICROTASK_TYPE
793 CALLBACK_TASK_TYPE,
794 PROMISE_FULFILL_REACTION_JOB_TASK_TYPE,
795 PROMISE_REJECT_REACTION_JOB_TASK_TYPE,
796 PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE, // LAST_MICROTASK_TYPE
797
798 // FixedArrays.
799 FIXED_ARRAY_TYPE, // FIRST_FIXED_ARRAY_TYPE
800 BOILERPLATE_DESCRIPTION_TYPE,
801 DESCRIPTOR_ARRAY_TYPE,
802 HASH_TABLE_TYPE,
803 SCOPE_INFO_TYPE,
804 BLOCK_CONTEXT_TYPE, // FIRST_CONTEXT_TYPE
805 CATCH_CONTEXT_TYPE,
806 DEBUG_EVALUATE_CONTEXT_TYPE,
807 EVAL_CONTEXT_TYPE,
808 FUNCTION_CONTEXT_TYPE,
809 MODULE_CONTEXT_TYPE,
810 NATIVE_CONTEXT_TYPE,
811 SCRIPT_CONTEXT_TYPE,
812 WITH_CONTEXT_TYPE, // LAST_FIXED_ARRAY_TYPE, LAST_CONTEXT_TYPE
813
814 WEAK_FIXED_ARRAY_TYPE, // FIRST_WEAK_FIXED_ARRAY_TYPE
815 TRANSITION_ARRAY_TYPE, // LAST_WEAK_FIXED_ARRAY_TYPE
816
817 // Misc.
818 CALL_HANDLER_INFO_TYPE,
819 CELL_TYPE,
820 CODE_DATA_CONTAINER_TYPE,
821 FEEDBACK_CELL_TYPE,
822 FEEDBACK_VECTOR_TYPE,
823 LOAD_HANDLER_TYPE,
824 PROPERTY_ARRAY_TYPE,
825 PROPERTY_CELL_TYPE,
826 SHARED_FUNCTION_INFO_TYPE,
827 SMALL_ORDERED_HASH_MAP_TYPE,
828 SMALL_ORDERED_HASH_SET_TYPE,
829 STORE_HANDLER_TYPE,
830 WEAK_CELL_TYPE,
831 WEAK_ARRAY_LIST_TYPE,
832
833 // All the following types are subtypes of JSReceiver, which corresponds to
834 // objects in the JS sense. The first and the last type in this range are
835 // the two forms of function. This organization enables using the same
836 // compares for checking the JS_RECEIVER and the NONCALLABLE_JS_OBJECT range.
837 // Some of the following instance types are exposed in v8.h, so to not
838 // unnecessarily change the ABI when we introduce new instance types in the
839 // future, we leave some space between instance types.
840 JS_PROXY_TYPE = 0x0400, // FIRST_JS_RECEIVER_TYPE
841 JS_GLOBAL_OBJECT_TYPE, // FIRST_JS_OBJECT_TYPE
842 JS_GLOBAL_PROXY_TYPE,
843 JS_MODULE_NAMESPACE_TYPE,
844 // Like JS_API_OBJECT_TYPE, but requires access checks and/or has
845 // interceptors.
846 JS_SPECIAL_API_OBJECT_TYPE = 0x0410, // LAST_SPECIAL_RECEIVER_TYPE
847 JS_VALUE_TYPE, // LAST_CUSTOM_ELEMENTS_RECEIVER
848 // Like JS_OBJECT_TYPE, but created from API function.
849 JS_API_OBJECT_TYPE = 0x0420,
850 JS_OBJECT_TYPE,
851 JS_ARGUMENTS_TYPE,
852 JS_ARRAY_BUFFER_TYPE,
853 JS_ARRAY_ITERATOR_TYPE,
854 JS_ARRAY_TYPE,
855 JS_ASYNC_FROM_SYNC_ITERATOR_TYPE,
856 JS_ASYNC_GENERATOR_OBJECT_TYPE,
857 JS_CONTEXT_EXTENSION_OBJECT_TYPE,
858 JS_DATE_TYPE,
859 JS_ERROR_TYPE,
860 JS_GENERATOR_OBJECT_TYPE,
861 JS_MAP_TYPE,
862 JS_MAP_KEY_ITERATOR_TYPE,
863 JS_MAP_KEY_VALUE_ITERATOR_TYPE,
864 JS_MAP_VALUE_ITERATOR_TYPE,
865 JS_MESSAGE_OBJECT_TYPE,
866 JS_PROMISE_TYPE,
867 JS_REGEXP_TYPE,
868 JS_REGEXP_STRING_ITERATOR_TYPE,
869 JS_SET_TYPE,
870 JS_SET_KEY_VALUE_ITERATOR_TYPE,
871 JS_SET_VALUE_ITERATOR_TYPE,
872 JS_STRING_ITERATOR_TYPE,
873 JS_WEAK_MAP_TYPE,
874 JS_WEAK_SET_TYPE,
875
876 JS_TYPED_ARRAY_TYPE,
877 JS_DATA_VIEW_TYPE,
878
879 #ifdef V8_INTL_SUPPORT
880 JS_INTL_LOCALE_TYPE,
881 #endif // V8_INTL_SUPPORT
882
883 WASM_GLOBAL_TYPE,
884 WASM_INSTANCE_TYPE,
885 WASM_MEMORY_TYPE,
886 WASM_MODULE_TYPE,
887 WASM_TABLE_TYPE,
888 JS_BOUND_FUNCTION_TYPE,
889 JS_FUNCTION_TYPE, // LAST_JS_OBJECT_TYPE, LAST_JS_RECEIVER_TYPE
890
891 // Pseudo-types
892 FIRST_TYPE = 0x0,
893 LAST_TYPE = JS_FUNCTION_TYPE,
894 FIRST_NAME_TYPE = FIRST_TYPE,
895 LAST_NAME_TYPE = SYMBOL_TYPE,
896 FIRST_UNIQUE_NAME_TYPE = INTERNALIZED_STRING_TYPE,
897 LAST_UNIQUE_NAME_TYPE = SYMBOL_TYPE,
898 FIRST_NONSTRING_TYPE = SYMBOL_TYPE,
899 FIRST_PRIMITIVE_TYPE = FIRST_NAME_TYPE,
900 LAST_PRIMITIVE_TYPE = ODDBALL_TYPE,
901 FIRST_FUNCTION_TYPE = JS_BOUND_FUNCTION_TYPE,
902 LAST_FUNCTION_TYPE = JS_FUNCTION_TYPE,
903 // Boundaries for testing if given HeapObject is a subclass of FixedArray.
904 FIRST_FIXED_ARRAY_TYPE = FIXED_ARRAY_TYPE,
905 LAST_FIXED_ARRAY_TYPE = WITH_CONTEXT_TYPE,
906 // Boundaries for testing if given HeapObject is a subclass of WeakFixedArray.
907 FIRST_WEAK_FIXED_ARRAY_TYPE = WEAK_FIXED_ARRAY_TYPE,
908 LAST_WEAK_FIXED_ARRAY_TYPE = TRANSITION_ARRAY_TYPE,
909 // Boundaries for testing if given HeapObject is a Context
910 FIRST_CONTEXT_TYPE = BLOCK_CONTEXT_TYPE,
911 LAST_CONTEXT_TYPE = WITH_CONTEXT_TYPE,
912 // Boundaries for testing if given HeapObject is a subclass of Microtask.
913 FIRST_MICROTASK_TYPE = CALLABLE_TASK_TYPE,
914 LAST_MICROTASK_TYPE = PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE,
915 // Boundaries for testing for a fixed typed array.
916 FIRST_FIXED_TYPED_ARRAY_TYPE = FIXED_INT8_ARRAY_TYPE,
917 LAST_FIXED_TYPED_ARRAY_TYPE = FIXED_BIGUINT64_ARRAY_TYPE,
918 // Boundary for promotion to old space.
919 LAST_DATA_TYPE = FILLER_TYPE,
920 // Boundary for objects represented as JSReceiver (i.e. JSObject or JSProxy).
921 // Note that there is no range for JSObject or JSProxy, since their subtypes
922 // are not continuous in this enum! The enum ranges instead reflect the
923 // external class names, where proxies are treated as either ordinary objects,
924 // or functions.
925 FIRST_JS_RECEIVER_TYPE = JS_PROXY_TYPE,
926 LAST_JS_RECEIVER_TYPE = LAST_TYPE,
927 // Boundaries for testing the types represented as JSObject
928 FIRST_JS_OBJECT_TYPE = JS_GLOBAL_OBJECT_TYPE,
929 LAST_JS_OBJECT_TYPE = LAST_TYPE,
930 // Boundary for testing JSReceivers that need special property lookup handling
931 LAST_SPECIAL_RECEIVER_TYPE = JS_SPECIAL_API_OBJECT_TYPE,
932 // Boundary case for testing JSReceivers that may have elements while having
933 // an empty fixed array as elements backing store. This is true for string
934 // wrappers.
935 LAST_CUSTOM_ELEMENTS_RECEIVER = JS_VALUE_TYPE,
936
937 FIRST_SET_ITERATOR_TYPE = JS_SET_KEY_VALUE_ITERATOR_TYPE,
938 LAST_SET_ITERATOR_TYPE = JS_SET_VALUE_ITERATOR_TYPE,
939
940 FIRST_MAP_ITERATOR_TYPE = JS_MAP_KEY_ITERATOR_TYPE,
941 LAST_MAP_ITERATOR_TYPE = JS_MAP_VALUE_ITERATOR_TYPE,
942 };
943
944 STATIC_ASSERT((FIRST_NONSTRING_TYPE & kIsNotStringMask) != kStringTag);
945 STATIC_ASSERT(JS_OBJECT_TYPE == Internals::kJSObjectType);
946 STATIC_ASSERT(JS_API_OBJECT_TYPE == Internals::kJSApiObjectType);
947 STATIC_ASSERT(JS_SPECIAL_API_OBJECT_TYPE == Internals::kJSSpecialApiObjectType);
948 STATIC_ASSERT(FIRST_NONSTRING_TYPE == Internals::kFirstNonstringType);
949 STATIC_ASSERT(ODDBALL_TYPE == Internals::kOddballType);
950 STATIC_ASSERT(FOREIGN_TYPE == Internals::kForeignType);
951
952 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
953 InstanceType instance_type);
954
955 // Result of an abstract relational comparison of x and y, implemented according
956 // to ES6 section 7.2.11 Abstract Relational Comparison.
957 enum class ComparisonResult {
958 kLessThan, // x < y
959 kEqual, // x = y
960 kGreaterThan, // x > y
961 kUndefined // at least one of x or y was undefined or NaN
962 };
963
964 // (Returns false whenever {result} is kUndefined.)
965 bool ComparisonResultToBool(Operation op, ComparisonResult result);
966
967 class AbstractCode;
968 class AccessorPair;
969 class AccessCheckInfo;
970 class AllocationSite;
971 class ByteArray;
972 class Cell;
973 class ConsString;
974 class DependentCode;
975 class ElementsAccessor;
976 class EnumCache;
977 class FixedArrayBase;
978 class PropertyArray;
979 class FunctionLiteral;
980 class FunctionTemplateInfo;
981 class JSGlobalObject;
982 #ifdef V8_INTL_SUPPORT
983 class JSLocale;
984 #endif // V8_INTL_SUPPORT
985 class JSPromise;
986 class KeyAccumulator;
987 class LayoutDescriptor;
988 class LookupIterator;
989 class FieldType;
990 class Module;
991 class ModuleInfoEntry;
992 class ObjectHashTable;
993 class ObjectTemplateInfo;
994 class ObjectVisitor;
995 class PropertyCell;
996 class PropertyDescriptor;
997 class RootVisitor;
998 class SafepointEntry;
999 class SharedFunctionInfo;
1000 class StringStream;
1001 class FeedbackCell;
1002 class FeedbackMetadata;
1003 class FeedbackVector;
1004 class WeakCell;
1005 class TemplateInfo;
1006 class TransitionArray;
1007 class TemplateList;
1008 template <typename T>
1009 class ZoneForwardList;
1010
1011 // A template-ized version of the IsXXX functions.
1012 template <class C> inline bool Is(Object* obj);
1013
1014 #ifdef OBJECT_PRINT
1015 #define DECL_PRINTER(Name) void Name##Print(std::ostream& os); // NOLINT
1016 #else
1017 #define DECL_PRINTER(Name)
1018 #endif
1019
1020 #define OBJECT_TYPE_LIST(V) \
1021 V(Smi) \
1022 V(LayoutDescriptor) \
1023 V(HeapObject) \
1024 V(Primitive) \
1025 V(Number) \
1026 V(Numeric)
1027
1028 #define HEAP_OBJECT_ORDINARY_TYPE_LIST_BASE(V) \
1029 V(AbstractCode) \
1030 V(AccessCheckNeeded) \
1031 V(ArrayList) \
1032 V(BigInt) \
1033 V(BigIntWrapper) \
1034 V(BoilerplateDescription) \
1035 V(Boolean) \
1036 V(BooleanWrapper) \
1037 V(BreakPoint) \
1038 V(BreakPointInfo) \
1039 V(ByteArray) \
1040 V(BytecodeArray) \
1041 V(CallHandlerInfo) \
1042 V(Callable) \
1043 V(Cell) \
1044 V(ClassBoilerplate) \
1045 V(Code) \
1046 V(CodeDataContainer) \
1047 V(CompilationCacheTable) \
1048 V(ConsString) \
1049 V(ConstantElementsPair) \
1050 V(Constructor) \
1051 V(Context) \
1052 V(CoverageInfo) \
1053 V(DataHandler) \
1054 V(DeoptimizationData) \
1055 V(DependentCode) \
1056 V(DescriptorArray) \
1057 V(EnumCache) \
1058 V(External) \
1059 V(ExternalOneByteString) \
1060 V(ExternalString) \
1061 V(ExternalTwoByteString) \
1062 V(FeedbackCell) \
1063 V(FeedbackMetadata) \
1064 V(FeedbackVector) \
1065 V(Filler) \
1066 V(FixedArray) \
1067 V(FixedArrayBase) \
1068 V(FixedArrayExact) \
1069 V(FixedArrayOfWeakCells) \
1070 V(FixedBigInt64Array) \
1071 V(FixedBigUint64Array) \
1072 V(FixedDoubleArray) \
1073 V(FixedFloat32Array) \
1074 V(FixedFloat64Array) \
1075 V(FixedInt16Array) \
1076 V(FixedInt32Array) \
1077 V(FixedInt8Array) \
1078 V(FixedTypedArrayBase) \
1079 V(FixedUint16Array) \
1080 V(FixedUint32Array) \
1081 V(FixedUint8Array) \
1082 V(FixedUint8ClampedArray) \
1083 V(Foreign) \
1084 V(FrameArray) \
1085 V(FreeSpace) \
1086 V(Function) \
1087 V(GlobalDictionary) \
1088 V(HandlerTable) \
1089 V(HeapNumber) \
1090 V(InternalizedString) \
1091 V(JSArgumentsObject) \
1092 V(JSArray) \
1093 V(JSArrayBuffer) \
1094 V(JSArrayBufferView) \
1095 V(JSArrayIterator) \
1096 V(JSAsyncFromSyncIterator) \
1097 V(JSAsyncGeneratorObject) \
1098 V(JSBoundFunction) \
1099 V(JSCollection) \
1100 V(JSContextExtensionObject) \
1101 V(JSDataView) \
1102 V(JSDate) \
1103 V(JSError) \
1104 V(JSFunction) \
1105 V(JSGeneratorObject) \
1106 V(JSGlobalObject) \
1107 V(JSGlobalProxy) \
1108 V(JSMap) \
1109 V(JSMapIterator) \
1110 V(JSMessageObject) \
1111 V(JSModuleNamespace) \
1112 V(JSObject) \
1113 V(JSPromise) \
1114 V(JSProxy) \
1115 V(JSReceiver) \
1116 V(JSRegExp) \
1117 V(JSRegExpStringIterator) \
1118 V(JSSet) \
1119 V(JSSetIterator) \
1120 V(JSSloppyArgumentsObject) \
1121 V(JSStringIterator) \
1122 V(JSTypedArray) \
1123 V(JSValue) \
1124 V(JSWeakCollection) \
1125 V(JSWeakMap) \
1126 V(JSWeakSet) \
1127 V(LoadHandler) \
1128 V(Map) \
1129 V(MapCache) \
1130 V(Microtask) \
1131 V(ModuleInfo) \
1132 V(MutableHeapNumber) \
1133 V(Name) \
1134 V(NameDictionary) \
1135 V(NativeContext) \
1136 V(NormalizedMapCache) \
1137 V(NumberDictionary) \
1138 V(NumberWrapper) \
1139 V(ObjectHashSet) \
1140 V(ObjectHashTable) \
1141 V(Oddball) \
1142 V(OrderedHashMap) \
1143 V(OrderedHashSet) \
1144 V(PreParsedScopeData) \
1145 V(PromiseReactionJobTask) \
1146 V(PropertyArray) \
1147 V(PropertyCell) \
1148 V(PropertyDescriptorObject) \
1149 V(RegExpMatchInfo) \
1150 V(ScopeInfo) \
1151 V(ScriptContextTable) \
1152 V(ScriptWrapper) \
1153 V(SeqOneByteString) \
1154 V(SeqString) \
1155 V(SeqTwoByteString) \
1156 V(SharedFunctionInfo) \
1157 V(SimpleNumberDictionary) \
1158 V(SlicedString) \
1159 V(SloppyArgumentsElements) \
1160 V(SmallOrderedHashMap) \
1161 V(SmallOrderedHashSet) \
1162 V(SourcePositionTableWithFrameCache) \
1163 V(StoreHandler) \
1164 V(String) \
1165 V(StringSet) \
1166 V(StringTable) \
1167 V(StringWrapper) \
1168 V(Struct) \
1169 V(Symbol) \
1170 V(SymbolWrapper) \
1171 V(TemplateInfo) \
1172 V(TemplateList) \
1173 V(TemplateObjectDescription) \
1174 V(ThinString) \
1175 V(TransitionArray) \
1176 V(Undetectable) \
1177 V(UniqueName) \
1178 V(WasmGlobalObject) \
1179 V(WasmInstanceObject) \
1180 V(WasmMemoryObject) \
1181 V(WasmModuleObject) \
1182 V(WasmTableObject) \
1183 V(WeakCell) \
1184 V(WeakFixedArray) \
1185 V(WeakArrayList)
1186
1187 #ifdef V8_INTL_SUPPORT
1188 #define HEAP_OBJECT_ORDINARY_TYPE_LIST(V) \
1189 HEAP_OBJECT_ORDINARY_TYPE_LIST_BASE(V) \
1190 V(JSLocale)
1191 #else
1192 #define HEAP_OBJECT_ORDINARY_TYPE_LIST(V) HEAP_OBJECT_ORDINARY_TYPE_LIST_BASE(V)
1193 #endif // V8_INTL_SUPPORT
1194
1195 #define HEAP_OBJECT_TEMPLATE_TYPE_LIST(V) \
1196 V(Dictionary) \
1197 V(HashTable)
1198
1199 #define HEAP_OBJECT_TYPE_LIST(V) \
1200 HEAP_OBJECT_ORDINARY_TYPE_LIST(V) \
1201 HEAP_OBJECT_TEMPLATE_TYPE_LIST(V)
1202
1203 #define ODDBALL_LIST(V) \
1204 V(Undefined, undefined_value) \
1205 V(Null, null_value) \
1206 V(TheHole, the_hole_value) \
1207 V(Exception, exception) \
1208 V(Uninitialized, uninitialized_value) \
1209 V(True, true_value) \
1210 V(False, false_value) \
1211 V(ArgumentsMarker, arguments_marker) \
1212 V(OptimizedOut, optimized_out) \
1213 V(StaleRegister, stale_register)
1214
1215 // The element types selection for CreateListFromArrayLike.
1216 enum class ElementTypes { kAll, kStringAndSymbol };
1217
1218 // Object is the abstract superclass for all classes in the
1219 // object hierarchy.
1220 // Object does not use any virtual functions to avoid the
1221 // allocation of the C++ vtable.
1222 // Since both Smi and HeapObject are subclasses of Object no
1223 // data members can be present in Object.
1224 class Object {
1225 public:
1226 // Type testing.
IsObject()1227 bool IsObject() const { return true; }
1228
1229 #define IS_TYPE_FUNCTION_DECL(Type) INLINE(bool Is##Type() const);
1230 OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
1231 HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
1232 #undef IS_TYPE_FUNCTION_DECL
1233
1234 #define IS_TYPE_FUNCTION_DECL(Type, Value) \
1235 INLINE(bool Is##Type(Isolate* isolate) const);
1236 ODDBALL_LIST(IS_TYPE_FUNCTION_DECL)
1237 #undef IS_TYPE_FUNCTION_DECL
1238
1239 INLINE(bool IsNullOrUndefined(Isolate* isolate) const);
1240
1241 // A non-keyed store is of the form a.x = foo or a["x"] = foo whereas
1242 // a keyed store is of the form a[expression] = foo.
1243 enum StoreFromKeyed {
1244 MAY_BE_STORE_FROM_KEYED,
1245 CERTAINLY_NOT_STORE_FROM_KEYED
1246 };
1247
1248 enum class Conversion { kToNumber, kToNumeric };
1249
1250 #define RETURN_FAILURE(isolate, should_throw, call) \
1251 do { \
1252 if ((should_throw) == kDontThrow) { \
1253 return Just(false); \
1254 } else { \
1255 isolate->Throw(*isolate->factory()->call); \
1256 return Nothing<bool>(); \
1257 } \
1258 } while (false)
1259
1260 #define MAYBE_RETURN(call, value) \
1261 do { \
1262 if ((call).IsNothing()) return value; \
1263 } while (false)
1264
1265 #define MAYBE_RETURN_NULL(call) MAYBE_RETURN(call, MaybeHandle<Object>())
1266
1267 #define DECL_STRUCT_PREDICATE(NAME, Name, name) INLINE(bool Is##Name() const);
1268 STRUCT_LIST(DECL_STRUCT_PREDICATE)
1269 #undef DECL_STRUCT_PREDICATE
1270
1271 // ES6, #sec-isarray. NOT to be confused with %_IsArray.
1272 INLINE(
1273 V8_WARN_UNUSED_RESULT static Maybe<bool> IsArray(Handle<Object> object));
1274
1275 INLINE(bool IsSmallOrderedHashTable() const);
1276
1277 // Extract the number.
1278 inline double Number() const;
1279 INLINE(bool IsNaN() const);
1280 INLINE(bool IsMinusZero() const);
1281 V8_EXPORT_PRIVATE bool ToInt32(int32_t* value);
1282 inline bool ToUint32(uint32_t* value) const;
1283
1284 inline Representation OptimalRepresentation();
1285
1286 inline ElementsKind OptimalElementsKind();
1287
1288 inline bool FitsRepresentation(Representation representation);
1289
1290 // Checks whether two valid primitive encodings of a property name resolve to
1291 // the same logical property. E.g., the smi 1, the string "1" and the double
1292 // 1 all refer to the same property, so this helper will return true.
1293 inline bool KeyEquals(Object* other);
1294
1295 inline bool FilterKey(PropertyFilter filter);
1296
1297 Handle<FieldType> OptimalType(Isolate* isolate,
1298 Representation representation);
1299
1300 inline static Handle<Object> NewStorageFor(Isolate* isolate,
1301 Handle<Object> object,
1302 Representation representation);
1303
1304 inline static Handle<Object> WrapForRead(Isolate* isolate,
1305 Handle<Object> object,
1306 Representation representation);
1307
1308 // Returns true if the object is of the correct type to be used as a
1309 // implementation of a JSObject's elements.
1310 inline bool HasValidElements();
1311
1312 bool BooleanValue(); // ECMA-262 9.2.
1313
1314 // ES6 section 7.2.11 Abstract Relational Comparison
1315 V8_WARN_UNUSED_RESULT static Maybe<ComparisonResult> Compare(
1316 Handle<Object> x, Handle<Object> y);
1317
1318 // ES6 section 7.2.12 Abstract Equality Comparison
1319 V8_WARN_UNUSED_RESULT static Maybe<bool> Equals(Handle<Object> x,
1320 Handle<Object> y);
1321
1322 // ES6 section 7.2.13 Strict Equality Comparison
1323 bool StrictEquals(Object* that);
1324
1325 // ES6 section 7.1.13 ToObject
1326 // Convert to a JSObject if needed.
1327 // native_context is used when creating wrapper object.
1328 //
1329 // Passing a non-null method_name allows us to give a more informative
1330 // error message for those cases where ToObject is being called on
1331 // the receiver of a built-in method.
1332 V8_WARN_UNUSED_RESULT static inline MaybeHandle<JSReceiver> ToObject(
1333 Isolate* isolate, Handle<Object> object,
1334 const char* method_name = nullptr);
1335 V8_WARN_UNUSED_RESULT static MaybeHandle<JSReceiver> ToObject(
1336 Isolate* isolate, Handle<Object> object, Handle<Context> native_context,
1337 const char* method_name = nullptr);
1338
1339 // ES6 section 9.2.1.2, OrdinaryCallBindThis for sloppy callee.
1340 V8_WARN_UNUSED_RESULT static MaybeHandle<JSReceiver> ConvertReceiver(
1341 Isolate* isolate, Handle<Object> object);
1342
1343 // ES6 section 7.1.14 ToPropertyKey
1344 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Name> ToName(
1345 Isolate* isolate, Handle<Object> input);
1346
1347 // ES6 section 7.1.1 ToPrimitive
1348 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> ToPrimitive(
1349 Handle<Object> input, ToPrimitiveHint hint = ToPrimitiveHint::kDefault);
1350
1351 // ES6 section 7.1.3 ToNumber
1352 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> ToNumber(
1353 Handle<Object> input);
1354
1355 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> ToNumeric(
1356 Handle<Object> input);
1357
1358 // ES6 section 7.1.4 ToInteger
1359 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> ToInteger(
1360 Isolate* isolate, Handle<Object> input);
1361
1362 // ES6 section 7.1.5 ToInt32
1363 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> ToInt32(
1364 Isolate* isolate, Handle<Object> input);
1365
1366 // ES6 section 7.1.6 ToUint32
1367 V8_WARN_UNUSED_RESULT inline static MaybeHandle<Object> ToUint32(
1368 Isolate* isolate, Handle<Object> input);
1369
1370 // ES6 section 7.1.12 ToString
1371 V8_WARN_UNUSED_RESULT static inline MaybeHandle<String> ToString(
1372 Isolate* isolate, Handle<Object> input);
1373
1374 static Handle<String> NoSideEffectsToString(Isolate* isolate,
1375 Handle<Object> input);
1376
1377 // ES6 section 7.1.14 ToPropertyKey
1378 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> ToPropertyKey(
1379 Isolate* isolate, Handle<Object> value);
1380
1381 // ES6 section 7.1.15 ToLength
1382 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> ToLength(
1383 Isolate* isolate, Handle<Object> input);
1384
1385 // ES6 section 7.1.17 ToIndex
1386 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> ToIndex(
1387 Isolate* isolate, Handle<Object> input,
1388 MessageTemplate::Template error_index);
1389
1390 // ES6 section 7.3.9 GetMethod
1391 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> GetMethod(
1392 Handle<JSReceiver> receiver, Handle<Name> name);
1393
1394 // ES6 section 7.3.17 CreateListFromArrayLike
1395 V8_WARN_UNUSED_RESULT static MaybeHandle<FixedArray> CreateListFromArrayLike(
1396 Isolate* isolate, Handle<Object> object, ElementTypes element_types);
1397
1398 // Get length property and apply ToLength.
1399 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> GetLengthFromArrayLike(
1400 Isolate* isolate, Handle<Object> object);
1401
1402 // ES6 section 12.5.6 The typeof Operator
1403 static Handle<String> TypeOf(Isolate* isolate, Handle<Object> object);
1404
1405 // ES6 section 12.7 Additive Operators
1406 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> Add(Isolate* isolate,
1407 Handle<Object> lhs,
1408 Handle<Object> rhs);
1409
1410 // ES6 section 12.9 Relational Operators
1411 V8_WARN_UNUSED_RESULT static inline Maybe<bool> GreaterThan(Handle<Object> x,
1412 Handle<Object> y);
1413 V8_WARN_UNUSED_RESULT static inline Maybe<bool> GreaterThanOrEqual(
1414 Handle<Object> x, Handle<Object> y);
1415 V8_WARN_UNUSED_RESULT static inline Maybe<bool> LessThan(Handle<Object> x,
1416 Handle<Object> y);
1417 V8_WARN_UNUSED_RESULT static inline Maybe<bool> LessThanOrEqual(
1418 Handle<Object> x, Handle<Object> y);
1419
1420 // ES6 section 7.3.19 OrdinaryHasInstance (C, O).
1421 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> OrdinaryHasInstance(
1422 Isolate* isolate, Handle<Object> callable, Handle<Object> object);
1423
1424 // ES6 section 12.10.4 Runtime Semantics: InstanceofOperator(O, C)
1425 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> InstanceOf(
1426 Isolate* isolate, Handle<Object> object, Handle<Object> callable);
1427
1428 V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static MaybeHandle<Object>
1429 GetProperty(LookupIterator* it);
1430
1431 // ES6 [[Set]] (when passed kDontThrow)
1432 // Invariants for this and related functions (unless stated otherwise):
1433 // 1) When the result is Nothing, an exception is pending.
1434 // 2) When passed kThrowOnError, the result is never Just(false).
1435 // In some cases, an exception is thrown regardless of the ShouldThrow
1436 // argument. These cases are either in accordance with the spec or not
1437 // covered by it (eg., concerning API callbacks).
1438 V8_WARN_UNUSED_RESULT static Maybe<bool> SetProperty(
1439 LookupIterator* it, Handle<Object> value, LanguageMode language_mode,
1440 StoreFromKeyed store_mode);
1441 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> SetProperty(
1442 Handle<Object> object, Handle<Name> name, Handle<Object> value,
1443 LanguageMode language_mode,
1444 StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
1445 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> SetPropertyOrElement(
1446 Handle<Object> object, Handle<Name> name, Handle<Object> value,
1447 LanguageMode language_mode,
1448 StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
1449
1450 V8_WARN_UNUSED_RESULT static Maybe<bool> SetSuperProperty(
1451 LookupIterator* it, Handle<Object> value, LanguageMode language_mode,
1452 StoreFromKeyed store_mode);
1453
1454 V8_WARN_UNUSED_RESULT static Maybe<bool> CannotCreateProperty(
1455 Isolate* isolate, Handle<Object> receiver, Handle<Object> name,
1456 Handle<Object> value, ShouldThrow should_throw);
1457 V8_WARN_UNUSED_RESULT static Maybe<bool> WriteToReadOnlyProperty(
1458 LookupIterator* it, Handle<Object> value, ShouldThrow should_throw);
1459 V8_WARN_UNUSED_RESULT static Maybe<bool> WriteToReadOnlyProperty(
1460 Isolate* isolate, Handle<Object> receiver, Handle<Object> name,
1461 Handle<Object> value, ShouldThrow should_throw);
1462 V8_WARN_UNUSED_RESULT static Maybe<bool> RedefineIncompatibleProperty(
1463 Isolate* isolate, Handle<Object> name, Handle<Object> value,
1464 ShouldThrow should_throw);
1465 V8_WARN_UNUSED_RESULT static Maybe<bool> SetDataProperty(
1466 LookupIterator* it, Handle<Object> value);
1467 V8_WARN_UNUSED_RESULT static Maybe<bool> AddDataProperty(
1468 LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
1469 ShouldThrow should_throw, StoreFromKeyed store_mode);
1470 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> GetPropertyOrElement(
1471 Handle<Object> object, Handle<Name> name);
1472 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> GetPropertyOrElement(
1473 Handle<Object> receiver, Handle<Name> name, Handle<JSReceiver> holder);
1474 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> GetProperty(
1475 Handle<Object> object, Handle<Name> name);
1476
1477 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> GetPropertyWithAccessor(
1478 LookupIterator* it);
1479 V8_WARN_UNUSED_RESULT static Maybe<bool> SetPropertyWithAccessor(
1480 LookupIterator* it, Handle<Object> value, ShouldThrow should_throw);
1481
1482 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> GetPropertyWithDefinedGetter(
1483 Handle<Object> receiver, Handle<JSReceiver> getter);
1484 V8_WARN_UNUSED_RESULT static Maybe<bool> SetPropertyWithDefinedSetter(
1485 Handle<Object> receiver, Handle<JSReceiver> setter, Handle<Object> value,
1486 ShouldThrow should_throw);
1487
1488 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> GetElement(
1489 Isolate* isolate, Handle<Object> object, uint32_t index);
1490
1491 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> SetElement(
1492 Isolate* isolate, Handle<Object> object, uint32_t index,
1493 Handle<Object> value, LanguageMode language_mode);
1494
1495 // Returns the permanent hash code associated with this object. May return
1496 // undefined if not yet created.
1497 inline Object* GetHash();
1498
1499 // Returns the permanent hash code associated with this object depending on
1500 // the actual object type. May create and store a hash code if needed and none
1501 // exists.
1502 Smi* GetOrCreateHash(Isolate* isolate);
1503 static Smi* GetOrCreateHash(Isolate* isolate, Object* key);
1504
1505 // Checks whether this object has the same value as the given one. This
1506 // function is implemented according to ES5, section 9.12 and can be used
1507 // to implement the Harmony "egal" function.
1508 V8_EXPORT_PRIVATE bool SameValue(Object* other);
1509
1510 // Checks whether this object has the same value as the given one.
1511 // +0 and -0 are treated equal. Everything else is the same as SameValue.
1512 // This function is implemented according to ES6, section 7.2.4 and is used
1513 // by ES6 Map and Set.
1514 bool SameValueZero(Object* other);
1515
1516 // ES6 section 9.4.2.3 ArraySpeciesCreate (part of it)
1517 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> ArraySpeciesConstructor(
1518 Isolate* isolate, Handle<Object> original_array);
1519
1520 // ES6 section 7.3.20 SpeciesConstructor ( O, defaultConstructor )
1521 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> SpeciesConstructor(
1522 Isolate* isolate, Handle<JSReceiver> recv,
1523 Handle<JSFunction> default_ctor);
1524
1525 // Tries to convert an object to an array length. Returns true and sets the
1526 // output parameter if it succeeds.
1527 inline bool ToArrayLength(uint32_t* index) const;
1528
1529 // Tries to convert an object to an array index. Returns true and sets the
1530 // output parameter if it succeeds. Equivalent to ToArrayLength, but does not
1531 // allow kMaxUInt32.
1532 inline bool ToArrayIndex(uint32_t* index) const;
1533
1534 // Returns true if the result of iterating over the object is the same
1535 // (including observable effects) as simply accessing the properties between 0
1536 // and length.
1537 bool IterationHasObservableEffects();
1538
1539 DECL_VERIFIER(Object)
1540 #ifdef VERIFY_HEAP
1541 // Verify a pointer is a valid object pointer.
1542 static void VerifyPointer(Object* p);
1543 #endif
1544
1545 inline void VerifyApiCallResultType();
1546
1547 // Prints this object without details.
1548 void ShortPrint(FILE* out = stdout);
1549
1550 // Prints this object without details to a message accumulator.
1551 void ShortPrint(StringStream* accumulator);
1552
1553 void ShortPrint(std::ostream& os); // NOLINT
1554
1555 DECL_CAST(Object)
1556
1557 // Layout description.
1558 static const int kHeaderSize = 0; // Object does not take up any space.
1559
1560 #ifdef OBJECT_PRINT
1561 // For our gdb macros, we should perhaps change these in the future.
1562 void Print();
1563
1564 // Prints this object with details.
1565 void Print(std::ostream& os); // NOLINT
1566 #else
Print()1567 void Print() { ShortPrint(); }
Print(std::ostream & os)1568 void Print(std::ostream& os) { ShortPrint(os); } // NOLINT
1569 #endif
1570
1571 private:
1572 friend class LookupIterator;
1573 friend class StringStream;
1574
1575 // Return the map of the root of object's prototype chain.
1576 Map* GetPrototypeChainRootMap(Isolate* isolate) const;
1577
1578 // Returns a non-SMI for JSReceivers, but returns the hash code for
1579 // simple objects. This avoids a double lookup in the cases where
1580 // we know we will add the hash to the JSReceiver if it does not
1581 // already exist.
1582 //
1583 // Despite its size, this needs to be inlined for performance
1584 // reasons.
1585 static inline Object* GetSimpleHash(Object* object);
1586
1587 // Helper for SetProperty and SetSuperProperty.
1588 // Return value is only meaningful if [found] is set to true on return.
1589 V8_WARN_UNUSED_RESULT static Maybe<bool> SetPropertyInternal(
1590 LookupIterator* it, Handle<Object> value, LanguageMode language_mode,
1591 StoreFromKeyed store_mode, bool* found);
1592
1593 V8_WARN_UNUSED_RESULT static MaybeHandle<Name> ConvertToName(
1594 Isolate* isolate, Handle<Object> input);
1595 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> ConvertToPropertyKey(
1596 Isolate* isolate, Handle<Object> value);
1597 V8_WARN_UNUSED_RESULT static MaybeHandle<String> ConvertToString(
1598 Isolate* isolate, Handle<Object> input);
1599 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> ConvertToNumberOrNumeric(
1600 Isolate* isolate, Handle<Object> input, Conversion mode);
1601 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> ConvertToInteger(
1602 Isolate* isolate, Handle<Object> input);
1603 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> ConvertToInt32(
1604 Isolate* isolate, Handle<Object> input);
1605 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> ConvertToUint32(
1606 Isolate* isolate, Handle<Object> input);
1607 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> ConvertToLength(
1608 Isolate* isolate, Handle<Object> input);
1609 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> ConvertToIndex(
1610 Isolate* isolate, Handle<Object> input,
1611 MessageTemplate::Template error_index);
1612
1613 DISALLOW_IMPLICIT_CONSTRUCTORS(Object);
1614 };
1615
1616
1617 // In objects.h to be usable without objects-inl.h inclusion.
IsSmi()1618 bool Object::IsSmi() const { return HAS_SMI_TAG(this); }
IsHeapObject()1619 bool Object::IsHeapObject() const {
1620 DCHECK_EQ(!IsSmi(), Internals::HasHeapObjectTag(this));
1621 return !IsSmi();
1622 }
1623
1624 struct Brief {
BriefBrief1625 explicit Brief(const Object* const v) : value(v) {}
1626 const Object* value;
1627 };
1628
1629 struct MaybeObjectBrief {
MaybeObjectBriefMaybeObjectBrief1630 explicit MaybeObjectBrief(const MaybeObject* const v) : value(v) {}
1631 const MaybeObject* value;
1632 };
1633
1634 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, const Brief& v);
1635 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
1636 const MaybeObjectBrief& v);
1637
1638 // Smi represents integer Numbers that can be stored in 31 bits.
1639 // Smis are immediate which means they are NOT allocated in the heap.
1640 // The this pointer has the following format: [31 bit signed int] 0
1641 // For long smis it has the following format:
1642 // [32 bit signed int] [31 bits zero padding] 0
1643 // Smi stands for small integer.
1644 class Smi: public Object {
1645 public:
1646 // Returns the integer value.
value()1647 inline int value() const { return Internals::SmiValue(this); }
ToUint32Smi()1648 inline Smi* ToUint32Smi() {
1649 if (value() <= 0) return Smi::kZero;
1650 return Smi::FromInt(static_cast<uint32_t>(value()));
1651 }
1652
1653 // Convert a Smi object to an int.
1654 static inline int ToInt(const Object* object);
1655
1656 // Convert a value to a Smi object.
FromInt(int value)1657 static inline Smi* FromInt(int value) {
1658 DCHECK(Smi::IsValid(value));
1659 return reinterpret_cast<Smi*>(Internals::IntToSmi(value));
1660 }
1661
FromIntptr(intptr_t value)1662 static inline Smi* FromIntptr(intptr_t value) {
1663 DCHECK(Smi::IsValid(value));
1664 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
1665 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
1666 }
1667
1668 template <typename E,
1669 typename = typename std::enable_if<std::is_enum<E>::value>::type>
FromEnum(E value)1670 static inline Smi* FromEnum(E value) {
1671 STATIC_ASSERT(sizeof(E) <= sizeof(int));
1672 return FromInt(static_cast<int>(value));
1673 }
1674
1675 // Returns whether value can be represented in a Smi.
IsValid(intptr_t value)1676 static inline bool IsValid(intptr_t value) {
1677 bool result = Internals::IsValidSmi(value);
1678 DCHECK_EQ(result, value >= kMinValue && value <= kMaxValue);
1679 return result;
1680 }
1681
1682 DECL_CAST(Smi)
1683
1684 // Dispatched behavior.
1685 V8_EXPORT_PRIVATE void SmiPrint(std::ostream& os) const; // NOLINT
1686 DECL_VERIFIER(Smi)
1687
1688 static constexpr Smi* const kZero = nullptr;
1689 static const int kMinValue =
1690 (static_cast<unsigned int>(-1)) << (kSmiValueSize - 1);
1691 static const int kMaxValue = -(kMinValue + 1);
1692
1693 private:
1694 DISALLOW_IMPLICIT_CONSTRUCTORS(Smi);
1695 };
1696
1697
1698 // Heap objects typically have a map pointer in their first word. However,
1699 // during GC other data (e.g. mark bits, forwarding addresses) is sometimes
1700 // encoded in the first word. The class MapWord is an abstraction of the
1701 // value in a heap object's first word.
1702 class MapWord BASE_EMBEDDED {
1703 public:
1704 // Normal state: the map word contains a map pointer.
1705
1706 // Create a map word from a map pointer.
1707 static inline MapWord FromMap(const Map* map);
1708
1709 // View this map word as a map pointer.
1710 inline Map* ToMap() const;
1711
1712 // Scavenge collection: the map word of live objects in the from space
1713 // contains a forwarding address (a heap object pointer in the to space).
1714
1715 // True if this map word is a forwarding address for a scavenge
1716 // collection. Only valid during a scavenge collection (specifically,
1717 // when all map words are heap object pointers, i.e. not during a full GC).
1718 inline bool IsForwardingAddress() const;
1719
1720 // Create a map word from a forwarding address.
1721 static inline MapWord FromForwardingAddress(HeapObject* object);
1722
1723 // View this map word as a forwarding address.
1724 inline HeapObject* ToForwardingAddress();
1725
FromRawValue(uintptr_t value)1726 static inline MapWord FromRawValue(uintptr_t value) {
1727 return MapWord(value);
1728 }
1729
ToRawValue()1730 inline uintptr_t ToRawValue() {
1731 return value_;
1732 }
1733
1734 private:
1735 // HeapObject calls the private constructor and directly reads the value.
1736 friend class HeapObject;
1737
MapWord(uintptr_t value)1738 explicit MapWord(uintptr_t value) : value_(value) {}
1739
1740 uintptr_t value_;
1741 };
1742
1743
1744 // HeapObject is the superclass for all classes describing heap allocated
1745 // objects.
1746 class HeapObject: public Object {
1747 public:
1748 // [map]: Contains a map which contains the object's reflective
1749 // information.
1750 inline Map* map() const;
1751 inline void set_map(Map* value);
1752
1753 inline HeapObject** map_slot();
1754
1755 // The no-write-barrier version. This is OK if the object is white and in
1756 // new space, or if the value is an immortal immutable object, like the maps
1757 // of primitive (non-JS) objects like strings, heap numbers etc.
1758 inline void set_map_no_write_barrier(Map* value);
1759
1760 // Get the map using acquire load.
1761 inline Map* synchronized_map() const;
1762 inline MapWord synchronized_map_word() const;
1763
1764 // Set the map using release store
1765 inline void synchronized_set_map(Map* value);
1766 inline void synchronized_set_map_word(MapWord map_word);
1767
1768 // Initialize the map immediately after the object is allocated.
1769 // Do not use this outside Heap.
1770 inline void set_map_after_allocation(
1771 Map* value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
1772
1773 // During garbage collection, the map word of a heap object does not
1774 // necessarily contain a map pointer.
1775 inline MapWord map_word() const;
1776 inline void set_map_word(MapWord map_word);
1777
1778 // The Heap the object was allocated in. Used also to access Isolate.
1779 inline Heap* GetHeap() const;
1780
1781 // Convenience method to get current isolate.
1782 inline Isolate* GetIsolate() const;
1783
1784 #define IS_TYPE_FUNCTION_DECL(Type) INLINE(bool Is##Type() const);
1785 HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
1786 #undef IS_TYPE_FUNCTION_DECL
1787
1788 #define IS_TYPE_FUNCTION_DECL(Type, Value) \
1789 INLINE(bool Is##Type(Isolate* isolate) const);
1790 ODDBALL_LIST(IS_TYPE_FUNCTION_DECL)
1791 #undef IS_TYPE_FUNCTION_DECL
1792
1793 INLINE(bool IsNullOrUndefined(Isolate* isolate) const);
1794
1795 #define DECL_STRUCT_PREDICATE(NAME, Name, name) INLINE(bool Is##Name() const);
STRUCT_LIST(DECL_STRUCT_PREDICATE)1796 STRUCT_LIST(DECL_STRUCT_PREDICATE)
1797 #undef DECL_STRUCT_PREDICATE
1798
1799 // Converts an address to a HeapObject pointer.
1800 static inline HeapObject* FromAddress(Address address) {
1801 DCHECK_TAG_ALIGNED(address);
1802 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1803 }
1804
1805 // Returns the address of this HeapObject.
address()1806 inline Address address() const {
1807 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1808 }
1809
1810 // Iterates over pointers contained in the object (including the Map).
1811 // If it's not performance critical iteration use the non-templatized
1812 // version.
1813 void Iterate(ObjectVisitor* v);
1814
1815 template <typename ObjectVisitor>
1816 inline void IterateFast(ObjectVisitor* v);
1817
1818 // Iterates over all pointers contained in the object except the
1819 // first map pointer. The object type is given in the first
1820 // parameter. This function does not access the map pointer in the
1821 // object, and so is safe to call while the map pointer is modified.
1822 // If it's not performance critical iteration use the non-templatized
1823 // version.
1824 void IterateBody(ObjectVisitor* v);
1825 void IterateBody(Map* map, int object_size, ObjectVisitor* v);
1826
1827 template <typename ObjectVisitor>
1828 inline void IterateBodyFast(ObjectVisitor* v);
1829
1830 template <typename ObjectVisitor>
1831 inline void IterateBodyFast(Map* map, int object_size, ObjectVisitor* v);
1832
1833 // Returns true if the object contains a tagged value at given offset.
1834 // It is used for invalid slots filtering. If the offset points outside
1835 // of the object or to the map word, the result is UNDEFINED (!!!).
1836 bool IsValidSlot(Map* map, int offset);
1837
1838 // Returns the heap object's size in bytes
1839 inline int Size() const;
1840
1841 // Given a heap object's map pointer, returns the heap size in bytes
1842 // Useful when the map pointer field is used for other purposes.
1843 // GC internal.
1844 inline int SizeFromMap(Map* map) const;
1845
1846 // Returns the field at offset in obj, as a read/write Object* reference.
1847 // Does no checking, and is safe to use during GC, while maps are invalid.
1848 // Does not invoke write barrier, so should only be assigned to
1849 // during marking GC.
1850 static inline Object** RawField(const HeapObject* obj, int offset);
1851 static inline MaybeObject** RawMaybeWeakField(HeapObject* obj, int offset);
1852
1853 DECL_CAST(HeapObject)
1854
1855 // Return the write barrier mode for this. Callers of this function
1856 // must be able to present a reference to an DisallowHeapAllocation
1857 // object as a sign that they are not going to use this function
1858 // from code that allocates and thus invalidates the returned write
1859 // barrier mode.
1860 inline WriteBarrierMode GetWriteBarrierMode(
1861 const DisallowHeapAllocation& promise);
1862
1863 // Dispatched behavior.
1864 void HeapObjectShortPrint(std::ostream& os); // NOLINT
1865 #ifdef OBJECT_PRINT
1866 void PrintHeader(std::ostream& os, const char* id); // NOLINT
1867 #endif
1868 DECL_PRINTER(HeapObject)
1869 DECL_VERIFIER(HeapObject)
1870 #ifdef VERIFY_HEAP
1871 inline void VerifyObjectField(int offset);
1872 inline void VerifySmiField(int offset);
1873
1874 // Verify a pointer is a valid HeapObject pointer that points to object
1875 // areas in the heap.
1876 static void VerifyHeapPointer(Object* p);
1877 #endif
1878
1879 static inline AllocationAlignment RequiredAlignment(Map* map);
1880
1881 // Whether the object needs rehashing. That is the case if the object's
1882 // content depends on FLAG_hash_seed. When the object is deserialized into
1883 // a heap with a different hash seed, these objects need to adapt.
1884 inline bool NeedsRehashing() const;
1885
1886 // Rehashing support is not implemented for all objects that need rehashing.
1887 // With objects that need rehashing but cannot be rehashed, rehashing has to
1888 // be disabled.
1889 bool CanBeRehashed() const;
1890
1891 // Rehash the object based on the layout inferred from its map.
1892 void RehashBasedOnMap();
1893
1894 // Layout description.
1895 // First field in a heap object is map.
1896 static const int kMapOffset = Object::kHeaderSize;
1897 static const int kHeaderSize = kMapOffset + kPointerSize;
1898
1899 STATIC_ASSERT(kMapOffset == Internals::kHeapObjectMapOffset);
1900
1901 private:
1902 DISALLOW_IMPLICIT_CONSTRUCTORS(HeapObject);
1903 };
1904
1905
1906 template <int start_offset, int end_offset, int size>
1907 class FixedBodyDescriptor;
1908
1909
1910 template <int start_offset>
1911 class FlexibleBodyDescriptor;
1912
1913
1914 // The HeapNumber class describes heap allocated numbers that cannot be
1915 // represented in a Smi (small integer)
1916 class HeapNumber: public HeapObject {
1917 public:
1918 // [value]: number value.
1919 inline double value() const;
1920 inline void set_value(double value);
1921
1922 inline uint64_t value_as_bits() const;
1923 inline void set_value_as_bits(uint64_t bits);
1924
1925 DECL_CAST(HeapNumber)
1926
1927 V8_EXPORT_PRIVATE void HeapNumberPrint(std::ostream& os); // NOLINT
1928 DECL_VERIFIER(HeapNumber)
1929
1930 inline int get_exponent();
1931 inline int get_sign();
1932
1933 // Layout description.
1934 static const int kValueOffset = HeapObject::kHeaderSize;
1935 // IEEE doubles are two 32 bit words. The first is just mantissa, the second
1936 // is a mixture of sign, exponent and mantissa. The offsets of two 32 bit
1937 // words within double numbers are endian dependent and they are set
1938 // accordingly.
1939 #if defined(V8_TARGET_LITTLE_ENDIAN)
1940 static const int kMantissaOffset = kValueOffset;
1941 static const int kExponentOffset = kValueOffset + 4;
1942 #elif defined(V8_TARGET_BIG_ENDIAN)
1943 static const int kMantissaOffset = kValueOffset + 4;
1944 static const int kExponentOffset = kValueOffset;
1945 #else
1946 #error Unknown byte ordering
1947 #endif
1948
1949 static const int kSize = kValueOffset + kDoubleSize;
1950 static const uint32_t kSignMask = 0x80000000u;
1951 static const uint32_t kExponentMask = 0x7ff00000u;
1952 static const uint32_t kMantissaMask = 0xfffffu;
1953 static const int kMantissaBits = 52;
1954 static const int kExponentBits = 11;
1955 static const int kExponentBias = 1023;
1956 static const int kExponentShift = 20;
1957 static const int kInfinityOrNanExponent =
1958 (kExponentMask >> kExponentShift) - kExponentBias;
1959 static const int kMantissaBitsInTopWord = 20;
1960 static const int kNonMantissaBitsInTopWord = 12;
1961
1962 private:
1963 DISALLOW_IMPLICIT_CONSTRUCTORS(HeapNumber);
1964 };
1965
1966 enum EnsureElementsMode {
1967 DONT_ALLOW_DOUBLE_ELEMENTS,
1968 ALLOW_COPIED_DOUBLE_ELEMENTS,
1969 ALLOW_CONVERTED_DOUBLE_ELEMENTS
1970 };
1971
1972
1973 // Indicator for one component of an AccessorPair.
1974 enum AccessorComponent {
1975 ACCESSOR_GETTER,
1976 ACCESSOR_SETTER
1977 };
1978
1979 enum class GetKeysConversion {
1980 kKeepNumbers = static_cast<int>(v8::KeyConversionMode::kKeepNumbers),
1981 kConvertToString = static_cast<int>(v8::KeyConversionMode::kConvertToString)
1982 };
1983
1984 enum class KeyCollectionMode {
1985 kOwnOnly = static_cast<int>(v8::KeyCollectionMode::kOwnOnly),
1986 kIncludePrototypes =
1987 static_cast<int>(v8::KeyCollectionMode::kIncludePrototypes)
1988 };
1989
1990 enum class AllocationSiteUpdateMode { kUpdate, kCheckOnly };
1991
1992 class PropertyArray : public HeapObject {
1993 public:
1994 // [length]: length of the array.
1995 inline int length() const;
1996
1997 // Get the length using acquire loads.
1998 inline int synchronized_length() const;
1999
2000 // This is only used on a newly allocated PropertyArray which
2001 // doesn't have an existing hash.
2002 inline void initialize_length(int length);
2003
2004 inline void SetHash(int hash);
2005 inline int Hash() const;
2006
2007 inline Object* get(int index) const;
2008
2009 inline void set(int index, Object* value);
2010 // Setter with explicit barrier mode.
2011 inline void set(int index, Object* value, WriteBarrierMode mode);
2012
2013 // Gives access to raw memory which stores the array's data.
2014 inline Object** data_start();
2015
2016 // Garbage collection support.
SizeFor(int length)2017 static constexpr int SizeFor(int length) {
2018 return kHeaderSize + length * kPointerSize;
2019 }
2020
2021 DECL_CAST(PropertyArray)
2022 DECL_PRINTER(PropertyArray)
2023 DECL_VERIFIER(PropertyArray)
2024
2025 // Layout description.
2026 static const int kLengthAndHashOffset = HeapObject::kHeaderSize;
2027 static const int kHeaderSize = kLengthAndHashOffset + kPointerSize;
2028
2029 // Garbage collection support.
2030 typedef FlexibleBodyDescriptor<kHeaderSize> BodyDescriptor;
2031 // No weak fields.
2032 typedef BodyDescriptor BodyDescriptorWeak;
2033
2034 static const int kLengthFieldSize = 10;
2035 class LengthField : public BitField<int, 0, kLengthFieldSize> {};
2036 static const int kMaxLength = LengthField::kMax;
2037 class HashField : public BitField<int, kLengthFieldSize,
2038 kSmiValueSize - kLengthFieldSize - 1> {};
2039
2040 static const int kNoHashSentinel = 0;
2041
2042 private:
2043 DISALLOW_IMPLICIT_CONSTRUCTORS(PropertyArray);
2044 };
2045
2046 // JSReceiver includes types on which properties can be defined, i.e.,
2047 // JSObject and JSProxy.
2048 class JSReceiver: public HeapObject {
2049 public:
2050 // Returns true if there is no slow (ie, dictionary) backing store.
2051 inline bool HasFastProperties() const;
2052
2053 // Returns the properties array backing store if it
2054 // exists. Otherwise, returns an empty_property_array when there's a
2055 // Smi (hash code) or an empty_fixed_array for a fast properties
2056 // map.
2057 inline PropertyArray* property_array() const;
2058
2059 // Gets slow properties for non-global objects.
2060 inline NameDictionary* property_dictionary() const;
2061
2062 // Sets the properties backing store and makes sure any existing hash is moved
2063 // to the new properties store. To clear out the properties store, pass in the
2064 // empty_fixed_array(), the hash will be maintained in this case as well.
2065 void SetProperties(HeapObject* properties);
2066
2067 // There are five possible values for the properties offset.
2068 // 1) EmptyFixedArray/EmptyPropertyDictionary - This is the standard
2069 // placeholder.
2070 //
2071 // 2) Smi - This is the hash code of the object.
2072 //
2073 // 3) PropertyArray - This is similar to a FixedArray but stores
2074 // the hash code of the object in its length field. This is a fast
2075 // backing store.
2076 //
2077 // 4) NameDictionary - This is the dictionary-mode backing store.
2078 //
2079 // 4) GlobalDictionary - This is the backing store for the
2080 // GlobalObject.
2081 //
2082 // This is used only in the deoptimizer and heap. Please use the
2083 // above typed getters and setters to access the properties.
2084 DECL_ACCESSORS(raw_properties_or_hash, Object)
2085
2086 inline void initialize_properties();
2087
2088 // Deletes an existing named property in a normalized object.
2089 static void DeleteNormalizedProperty(Handle<JSReceiver> object, int entry);
2090
2091 DECL_CAST(JSReceiver)
2092
2093 // ES6 section 7.1.1 ToPrimitive
2094 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> ToPrimitive(
2095 Handle<JSReceiver> receiver,
2096 ToPrimitiveHint hint = ToPrimitiveHint::kDefault);
2097
2098 // ES6 section 7.1.1.1 OrdinaryToPrimitive
2099 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> OrdinaryToPrimitive(
2100 Handle<JSReceiver> receiver, OrdinaryToPrimitiveHint hint);
2101
2102 static MaybeHandle<Context> GetFunctionRealm(Handle<JSReceiver> receiver);
2103
2104 // Get the first non-hidden prototype.
2105 static inline MaybeHandle<Object> GetPrototype(Isolate* isolate,
2106 Handle<JSReceiver> receiver);
2107
2108 V8_WARN_UNUSED_RESULT static Maybe<bool> HasInPrototypeChain(
2109 Isolate* isolate, Handle<JSReceiver> object, Handle<Object> proto);
2110
2111 // Reads all enumerable own properties of source and adds them to
2112 // target, using either Set or CreateDataProperty depending on the
2113 // use_set argument. This only copies values not present in the
2114 // maybe_excluded_properties list.
2115 V8_WARN_UNUSED_RESULT static Maybe<bool> SetOrCopyDataProperties(
2116 Isolate* isolate, Handle<JSReceiver> target, Handle<Object> source,
2117 const ScopedVector<Handle<Object>>* excluded_properties = nullptr,
2118 bool use_set = true);
2119
2120 // Implementation of [[HasProperty]], ECMA-262 5th edition, section 8.12.6.
2121 V8_WARN_UNUSED_RESULT static Maybe<bool> HasProperty(LookupIterator* it);
2122 V8_WARN_UNUSED_RESULT static inline Maybe<bool> HasProperty(
2123 Handle<JSReceiver> object, Handle<Name> name);
2124 V8_WARN_UNUSED_RESULT static inline Maybe<bool> HasElement(
2125 Handle<JSReceiver> object, uint32_t index);
2126
2127 V8_WARN_UNUSED_RESULT static Maybe<bool> HasOwnProperty(
2128 Handle<JSReceiver> object, Handle<Name> name);
2129 V8_WARN_UNUSED_RESULT static inline Maybe<bool> HasOwnProperty(
2130 Handle<JSReceiver> object, uint32_t index);
2131
2132 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> GetProperty(
2133 Isolate* isolate, Handle<JSReceiver> receiver, const char* key);
2134 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> GetProperty(
2135 Handle<JSReceiver> receiver, Handle<Name> name);
2136 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> GetElement(
2137 Isolate* isolate, Handle<JSReceiver> receiver, uint32_t index);
2138
2139 // Implementation of ES6 [[Delete]]
2140 V8_WARN_UNUSED_RESULT static Maybe<bool> DeletePropertyOrElement(
2141 Handle<JSReceiver> object, Handle<Name> name,
2142 LanguageMode language_mode = LanguageMode::kSloppy);
2143 V8_WARN_UNUSED_RESULT static Maybe<bool> DeleteProperty(
2144 Handle<JSReceiver> object, Handle<Name> name,
2145 LanguageMode language_mode = LanguageMode::kSloppy);
2146 V8_WARN_UNUSED_RESULT static Maybe<bool> DeleteProperty(
2147 LookupIterator* it, LanguageMode language_mode);
2148 V8_WARN_UNUSED_RESULT static Maybe<bool> DeleteElement(
2149 Handle<JSReceiver> object, uint32_t index,
2150 LanguageMode language_mode = LanguageMode::kSloppy);
2151
2152 V8_WARN_UNUSED_RESULT static Object* DefineProperty(
2153 Isolate* isolate, Handle<Object> object, Handle<Object> name,
2154 Handle<Object> attributes);
2155 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> DefineProperties(
2156 Isolate* isolate, Handle<Object> object, Handle<Object> properties);
2157
2158 // "virtual" dispatcher to the correct [[DefineOwnProperty]] implementation.
2159 V8_WARN_UNUSED_RESULT static Maybe<bool> DefineOwnProperty(
2160 Isolate* isolate, Handle<JSReceiver> object, Handle<Object> key,
2161 PropertyDescriptor* desc, ShouldThrow should_throw);
2162
2163 // ES6 7.3.4 (when passed kDontThrow)
2164 V8_WARN_UNUSED_RESULT static Maybe<bool> CreateDataProperty(
2165 LookupIterator* it, Handle<Object> value, ShouldThrow should_throw);
2166
2167 // ES6 9.1.6.1
2168 V8_WARN_UNUSED_RESULT static Maybe<bool> OrdinaryDefineOwnProperty(
2169 Isolate* isolate, Handle<JSObject> object, Handle<Object> key,
2170 PropertyDescriptor* desc, ShouldThrow should_throw);
2171 V8_WARN_UNUSED_RESULT static Maybe<bool> OrdinaryDefineOwnProperty(
2172 LookupIterator* it, PropertyDescriptor* desc, ShouldThrow should_throw);
2173 // ES6 9.1.6.2
2174 V8_WARN_UNUSED_RESULT static Maybe<bool> IsCompatiblePropertyDescriptor(
2175 Isolate* isolate, bool extensible, PropertyDescriptor* desc,
2176 PropertyDescriptor* current, Handle<Name> property_name,
2177 ShouldThrow should_throw);
2178 // ES6 9.1.6.3
2179 // |it| can be NULL in cases where the ES spec passes |undefined| as the
2180 // receiver. Exactly one of |it| and |property_name| must be provided.
2181 V8_WARN_UNUSED_RESULT static Maybe<bool> ValidateAndApplyPropertyDescriptor(
2182 Isolate* isolate, LookupIterator* it, bool extensible,
2183 PropertyDescriptor* desc, PropertyDescriptor* current,
2184 ShouldThrow should_throw, Handle<Name> property_name);
2185
2186 V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<bool>
2187 GetOwnPropertyDescriptor(Isolate* isolate, Handle<JSReceiver> object,
2188 Handle<Object> key, PropertyDescriptor* desc);
2189 V8_WARN_UNUSED_RESULT static Maybe<bool> GetOwnPropertyDescriptor(
2190 LookupIterator* it, PropertyDescriptor* desc);
2191
2192 typedef PropertyAttributes IntegrityLevel;
2193
2194 // ES6 7.3.14 (when passed kDontThrow)
2195 // 'level' must be SEALED or FROZEN.
2196 V8_WARN_UNUSED_RESULT static Maybe<bool> SetIntegrityLevel(
2197 Handle<JSReceiver> object, IntegrityLevel lvl, ShouldThrow should_throw);
2198
2199 // ES6 7.3.15
2200 // 'level' must be SEALED or FROZEN.
2201 V8_WARN_UNUSED_RESULT static Maybe<bool> TestIntegrityLevel(
2202 Handle<JSReceiver> object, IntegrityLevel lvl);
2203
2204 // ES6 [[PreventExtensions]] (when passed kDontThrow)
2205 V8_WARN_UNUSED_RESULT static Maybe<bool> PreventExtensions(
2206 Handle<JSReceiver> object, ShouldThrow should_throw);
2207
2208 V8_WARN_UNUSED_RESULT static Maybe<bool> IsExtensible(
2209 Handle<JSReceiver> object);
2210
2211 // Returns the class name ([[Class]] property in the specification).
2212 V8_EXPORT_PRIVATE String* class_name();
2213
2214 // Returns the constructor name (the name (possibly, inferred name) of the
2215 // function that was used to instantiate the object).
2216 static Handle<String> GetConstructorName(Handle<JSReceiver> receiver);
2217
2218 Handle<Context> GetCreationContext();
2219
2220 V8_WARN_UNUSED_RESULT static inline Maybe<PropertyAttributes>
2221 GetPropertyAttributes(Handle<JSReceiver> object, Handle<Name> name);
2222 V8_WARN_UNUSED_RESULT static inline Maybe<PropertyAttributes>
2223 GetOwnPropertyAttributes(Handle<JSReceiver> object, Handle<Name> name);
2224 V8_WARN_UNUSED_RESULT static inline Maybe<PropertyAttributes>
2225 GetOwnPropertyAttributes(Handle<JSReceiver> object, uint32_t index);
2226
2227 V8_WARN_UNUSED_RESULT static inline Maybe<PropertyAttributes>
2228 GetElementAttributes(Handle<JSReceiver> object, uint32_t index);
2229 V8_WARN_UNUSED_RESULT static inline Maybe<PropertyAttributes>
2230 GetOwnElementAttributes(Handle<JSReceiver> object, uint32_t index);
2231
2232 V8_WARN_UNUSED_RESULT static Maybe<PropertyAttributes> GetPropertyAttributes(
2233 LookupIterator* it);
2234
2235 // Set the object's prototype (only JSReceiver and null are allowed values).
2236 V8_WARN_UNUSED_RESULT static Maybe<bool> SetPrototype(
2237 Handle<JSReceiver> object, Handle<Object> value, bool from_javascript,
2238 ShouldThrow should_throw);
2239
2240 inline static Handle<Object> GetDataProperty(Handle<JSReceiver> object,
2241 Handle<Name> name);
2242 static Handle<Object> GetDataProperty(LookupIterator* it);
2243
2244
2245 // Retrieves a permanent object identity hash code. The undefined value might
2246 // be returned in case no hash was created yet.
2247 Object* GetIdentityHash(Isolate* isolate);
2248
2249 // Retrieves a permanent object identity hash code. May create and store a
2250 // hash code if needed and none exists.
2251 static Smi* CreateIdentityHash(Isolate* isolate, JSReceiver* key);
2252 Smi* GetOrCreateIdentityHash(Isolate* isolate);
2253
2254 // Stores the hash code. The hash passed in must be masked with
2255 // JSReceiver::kHashMask.
2256 void SetIdentityHash(int masked_hash);
2257
2258 // ES6 [[OwnPropertyKeys]] (modulo return type)
2259 V8_WARN_UNUSED_RESULT static inline MaybeHandle<FixedArray> OwnPropertyKeys(
2260 Handle<JSReceiver> object);
2261
2262 V8_WARN_UNUSED_RESULT static MaybeHandle<FixedArray> GetOwnValues(
2263 Handle<JSReceiver> object, PropertyFilter filter,
2264 bool try_fast_path = true);
2265
2266 V8_WARN_UNUSED_RESULT static MaybeHandle<FixedArray> GetOwnEntries(
2267 Handle<JSReceiver> object, PropertyFilter filter,
2268 bool try_fast_path = true);
2269
2270 V8_WARN_UNUSED_RESULT static Handle<FixedArray> GetOwnElementIndices(
2271 Isolate* isolate, Handle<JSReceiver> receiver, Handle<JSObject> object);
2272
2273 static const int kHashMask = PropertyArray::HashField::kMask;
2274
2275 // Layout description.
2276 static const int kPropertiesOrHashOffset = HeapObject::kHeaderSize;
2277 static const int kHeaderSize = HeapObject::kHeaderSize + kPointerSize;
2278
2279 bool HasProxyInPrototype(Isolate* isolate);
2280
2281 bool HasComplexElements();
2282
2283 private:
2284 DISALLOW_IMPLICIT_CONSTRUCTORS(JSReceiver);
2285 };
2286
2287
2288 // The JSObject describes real heap allocated JavaScript objects with
2289 // properties.
2290 // Note that the map of JSObject changes during execution to enable inline
2291 // caching.
2292 class JSObject: public JSReceiver {
2293 public:
2294 static bool IsUnmodifiedApiObject(Object** o);
2295
2296 static V8_WARN_UNUSED_RESULT MaybeHandle<JSObject> New(
2297 Handle<JSFunction> constructor, Handle<JSReceiver> new_target,
2298 Handle<AllocationSite> site = Handle<AllocationSite>::null());
2299
2300 static MaybeHandle<Context> GetFunctionRealm(Handle<JSObject> object);
2301
2302 // [elements]: The elements (properties with names that are integers).
2303 //
2304 // Elements can be in two general modes: fast and slow. Each mode
2305 // corresponds to a set of object representations of elements that
2306 // have something in common.
2307 //
2308 // In the fast mode elements is a FixedArray and so each element can
2309 // be quickly accessed. This fact is used in the generated code. The
2310 // elements array can have one of three maps in this mode:
2311 // fixed_array_map, sloppy_arguments_elements_map or
2312 // fixed_cow_array_map (for copy-on-write arrays). In the latter case
2313 // the elements array may be shared by a few objects and so before
2314 // writing to any element the array must be copied. Use
2315 // EnsureWritableFastElements in this case.
2316 //
2317 // In the slow mode the elements is either a NumberDictionary, a
2318 // FixedArray parameter map for a (sloppy) arguments object.
2319 DECL_ACCESSORS(elements, FixedArrayBase)
2320 inline void initialize_elements();
2321 static inline void SetMapAndElements(Handle<JSObject> object,
2322 Handle<Map> map,
2323 Handle<FixedArrayBase> elements);
2324 inline ElementsKind GetElementsKind();
2325 ElementsAccessor* GetElementsAccessor();
2326 // Returns true if an object has elements of PACKED_SMI_ELEMENTS or
2327 // HOLEY_SMI_ELEMENTS ElementsKind.
2328 inline bool HasSmiElements();
2329 // Returns true if an object has elements of PACKED_ELEMENTS or
2330 // HOLEY_ELEMENTS ElementsKind.
2331 inline bool HasObjectElements();
2332 // Returns true if an object has elements of PACKED_SMI_ELEMENTS,
2333 // HOLEY_SMI_ELEMENTS, PACKED_ELEMENTS, or HOLEY_ELEMENTS.
2334 inline bool HasSmiOrObjectElements();
2335 // Returns true if an object has any of the "fast" elements kinds.
2336 inline bool HasFastElements();
2337 // Returns true if an object has any of the PACKED elements kinds.
2338 inline bool HasFastPackedElements();
2339 // Returns true if an object has elements of PACKED_DOUBLE_ELEMENTS or
2340 // HOLEY_DOUBLE_ELEMENTS ElementsKind.
2341 inline bool HasDoubleElements();
2342 // Returns true if an object has elements of HOLEY_SMI_ELEMENTS,
2343 // HOLEY_DOUBLE_ELEMENTS, or HOLEY_ELEMENTS ElementsKind.
2344 inline bool HasHoleyElements();
2345 inline bool HasSloppyArgumentsElements();
2346 inline bool HasStringWrapperElements();
2347 inline bool HasDictionaryElements();
2348
2349 inline bool HasFixedTypedArrayElements();
2350
2351 inline bool HasFixedUint8ClampedElements();
2352 inline bool HasFixedArrayElements();
2353 inline bool HasFixedInt8Elements();
2354 inline bool HasFixedUint8Elements();
2355 inline bool HasFixedInt16Elements();
2356 inline bool HasFixedUint16Elements();
2357 inline bool HasFixedInt32Elements();
2358 inline bool HasFixedUint32Elements();
2359 inline bool HasFixedFloat32Elements();
2360 inline bool HasFixedFloat64Elements();
2361 inline bool HasFixedBigInt64Elements();
2362 inline bool HasFixedBigUint64Elements();
2363
2364 inline bool HasFastArgumentsElements();
2365 inline bool HasSlowArgumentsElements();
2366 inline bool HasFastStringWrapperElements();
2367 inline bool HasSlowStringWrapperElements();
2368 bool HasEnumerableElements();
2369
2370 inline NumberDictionary* element_dictionary(); // Gets slow elements.
2371
2372 // Requires: HasFastElements().
2373 static void EnsureWritableFastElements(Handle<JSObject> object);
2374
2375 V8_WARN_UNUSED_RESULT static Maybe<bool> SetPropertyWithInterceptor(
2376 LookupIterator* it, ShouldThrow should_throw, Handle<Object> value);
2377
2378 // The API currently still wants DefineOwnPropertyIgnoreAttributes to convert
2379 // AccessorInfo objects to data fields. We allow FORCE_FIELD as an exception
2380 // to the default behavior that calls the setter.
2381 enum AccessorInfoHandling { FORCE_FIELD, DONT_FORCE_FIELD };
2382
2383 V8_WARN_UNUSED_RESULT static MaybeHandle<Object>
2384 DefineOwnPropertyIgnoreAttributes(
2385 LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
2386 AccessorInfoHandling handling = DONT_FORCE_FIELD);
2387
2388 V8_WARN_UNUSED_RESULT static Maybe<bool> DefineOwnPropertyIgnoreAttributes(
2389 LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
2390 ShouldThrow should_throw,
2391 AccessorInfoHandling handling = DONT_FORCE_FIELD);
2392
2393 V8_WARN_UNUSED_RESULT static MaybeHandle<Object>
2394 SetOwnPropertyIgnoreAttributes(Handle<JSObject> object, Handle<Name> name,
2395 Handle<Object> value,
2396 PropertyAttributes attributes);
2397
2398 V8_WARN_UNUSED_RESULT static MaybeHandle<Object>
2399 SetOwnElementIgnoreAttributes(Handle<JSObject> object, uint32_t index,
2400 Handle<Object> value,
2401 PropertyAttributes attributes);
2402
2403 // Equivalent to one of the above depending on whether |name| can be converted
2404 // to an array index.
2405 V8_WARN_UNUSED_RESULT static MaybeHandle<Object>
2406 DefinePropertyOrElementIgnoreAttributes(Handle<JSObject> object,
2407 Handle<Name> name,
2408 Handle<Object> value,
2409 PropertyAttributes attributes = NONE);
2410
2411 // Adds or reconfigures a property to attributes NONE. It will fail when it
2412 // cannot.
2413 V8_WARN_UNUSED_RESULT static Maybe<bool> CreateDataProperty(
2414 LookupIterator* it, Handle<Object> value,
2415 ShouldThrow should_throw = kDontThrow);
2416
2417 static void AddProperty(Handle<JSObject> object, Handle<Name> name,
2418 Handle<Object> value, PropertyAttributes attributes);
2419
2420 V8_WARN_UNUSED_RESULT static Maybe<bool> AddDataElement(
2421 Handle<JSObject> receiver, uint32_t index, Handle<Object> value,
2422 PropertyAttributes attributes, ShouldThrow should_throw);
2423 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> AddDataElement(
2424 Handle<JSObject> receiver, uint32_t index, Handle<Object> value,
2425 PropertyAttributes attributes);
2426
2427 // Extend the receiver with a single fast property appeared first in the
2428 // passed map. This also extends the property backing store if necessary.
2429 static void AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map);
2430
2431 // Migrates the given object to a map whose field representations are the
2432 // lowest upper bound of all known representations for that field.
2433 static void MigrateInstance(Handle<JSObject> instance);
2434
2435 // Migrates the given object only if the target map is already available,
2436 // or returns false if such a map is not yet available.
2437 static bool TryMigrateInstance(Handle<JSObject> instance);
2438
2439 // Sets the property value in a normalized object given (key, value, details).
2440 // Handles the special representation of JS global objects.
2441 static void SetNormalizedProperty(Handle<JSObject> object, Handle<Name> name,
2442 Handle<Object> value,
2443 PropertyDetails details);
2444 static void SetDictionaryElement(Handle<JSObject> object, uint32_t index,
2445 Handle<Object> value,
2446 PropertyAttributes attributes);
2447 static void SetDictionaryArgumentsElement(Handle<JSObject> object,
2448 uint32_t index,
2449 Handle<Object> value,
2450 PropertyAttributes attributes);
2451
2452 static void OptimizeAsPrototype(Handle<JSObject> object,
2453 bool enable_setup_mode = true);
2454 static void ReoptimizeIfPrototype(Handle<JSObject> object);
2455 static void MakePrototypesFast(Handle<Object> receiver,
2456 WhereToStart where_to_start, Isolate* isolate);
2457 static void LazyRegisterPrototypeUser(Handle<Map> user, Isolate* isolate);
2458 static void UpdatePrototypeUserRegistration(Handle<Map> old_map,
2459 Handle<Map> new_map,
2460 Isolate* isolate);
2461 static bool UnregisterPrototypeUser(Handle<Map> user, Isolate* isolate);
2462 static Map* InvalidatePrototypeChains(Map* map);
2463 static void InvalidatePrototypeValidityCell(JSGlobalObject* global);
2464
2465 // Updates prototype chain tracking information when an object changes its
2466 // map from |old_map| to |new_map|.
2467 static void NotifyMapChange(Handle<Map> old_map, Handle<Map> new_map,
2468 Isolate* isolate);
2469
2470 // Utility used by many Array builtins and runtime functions
2471 static inline bool PrototypeHasNoElements(Isolate* isolate, JSObject* object);
2472
2473 // Alternative implementation of FixedArrayOfWeakCells::NullCallback.
2474 class PrototypeRegistryCompactionCallback {
2475 public:
2476 static void Callback(Object* value, int old_index, int new_index);
2477 };
2478
2479 // Retrieve interceptors.
2480 inline InterceptorInfo* GetNamedInterceptor();
2481 inline InterceptorInfo* GetIndexedInterceptor();
2482
2483 // Used from JSReceiver.
2484 V8_WARN_UNUSED_RESULT static Maybe<PropertyAttributes>
2485 GetPropertyAttributesWithInterceptor(LookupIterator* it);
2486 V8_WARN_UNUSED_RESULT static Maybe<PropertyAttributes>
2487 GetPropertyAttributesWithFailedAccessCheck(LookupIterator* it);
2488
2489 // Defines an AccessorPair property on the given object.
2490 // TODO(mstarzinger): Rename to SetAccessor().
2491 static MaybeHandle<Object> DefineAccessor(Handle<JSObject> object,
2492 Handle<Name> name,
2493 Handle<Object> getter,
2494 Handle<Object> setter,
2495 PropertyAttributes attributes);
2496 static MaybeHandle<Object> DefineAccessor(LookupIterator* it,
2497 Handle<Object> getter,
2498 Handle<Object> setter,
2499 PropertyAttributes attributes);
2500
2501 // Defines an AccessorInfo property on the given object.
2502 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> SetAccessor(
2503 Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> info,
2504 PropertyAttributes attributes);
2505
2506 // The result must be checked first for exceptions. If there's no exception,
2507 // the output parameter |done| indicates whether the interceptor has a result
2508 // or not.
2509 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> GetPropertyWithInterceptor(
2510 LookupIterator* it, bool* done);
2511
2512 static void ValidateElements(JSObject* object);
2513
2514 // Makes sure that this object can contain HeapObject as elements.
2515 static inline void EnsureCanContainHeapObjectElements(Handle<JSObject> obj);
2516
2517 // Makes sure that this object can contain the specified elements.
2518 static inline void EnsureCanContainElements(
2519 Handle<JSObject> object,
2520 Object** elements,
2521 uint32_t count,
2522 EnsureElementsMode mode);
2523 static inline void EnsureCanContainElements(
2524 Handle<JSObject> object,
2525 Handle<FixedArrayBase> elements,
2526 uint32_t length,
2527 EnsureElementsMode mode);
2528 static void EnsureCanContainElements(
2529 Handle<JSObject> object,
2530 Arguments* arguments,
2531 uint32_t first_arg,
2532 uint32_t arg_count,
2533 EnsureElementsMode mode);
2534
2535 // Would we convert a fast elements array to dictionary mode given
2536 // an access at key?
2537 bool WouldConvertToSlowElements(uint32_t index);
2538
2539 static const uint32_t kMinAddedElementsCapacity = 16;
2540
2541 // Computes the new capacity when expanding the elements of a JSObject.
NewElementsCapacity(uint32_t old_capacity)2542 static uint32_t NewElementsCapacity(uint32_t old_capacity) {
2543 // (old_capacity + 50%) + kMinAddedElementsCapacity
2544 return old_capacity + (old_capacity >> 1) + kMinAddedElementsCapacity;
2545 }
2546
2547 // These methods do not perform access checks!
2548 template <AllocationSiteUpdateMode update_or_check =
2549 AllocationSiteUpdateMode::kUpdate>
2550 static bool UpdateAllocationSite(Handle<JSObject> object,
2551 ElementsKind to_kind);
2552
2553 // Lookup interceptors are used for handling properties controlled by host
2554 // objects.
2555 inline bool HasNamedInterceptor();
2556 inline bool HasIndexedInterceptor();
2557
2558 // Support functions for v8 api (needed for correct interceptor behavior).
2559 V8_WARN_UNUSED_RESULT static Maybe<bool> HasRealNamedProperty(
2560 Handle<JSObject> object, Handle<Name> name);
2561 V8_WARN_UNUSED_RESULT static Maybe<bool> HasRealElementProperty(
2562 Handle<JSObject> object, uint32_t index);
2563 V8_WARN_UNUSED_RESULT static Maybe<bool> HasRealNamedCallbackProperty(
2564 Handle<JSObject> object, Handle<Name> name);
2565
2566 // Get the header size for a JSObject. Used to compute the index of
2567 // embedder fields as well as the number of embedder fields.
2568 // The |function_has_prototype_slot| parameter is needed only for
2569 // JSFunction objects.
2570 static int GetHeaderSize(InstanceType instance_type,
2571 bool function_has_prototype_slot = false);
2572 static inline int GetHeaderSize(const Map* map);
2573 inline int GetHeaderSize() const;
2574
2575 static inline int GetEmbedderFieldCount(const Map* map);
2576 inline int GetEmbedderFieldCount() const;
2577 inline int GetEmbedderFieldOffset(int index);
2578 inline Object* GetEmbedderField(int index);
2579 inline void SetEmbedderField(int index, Object* value);
2580 inline void SetEmbedderField(int index, Smi* value);
2581 bool WasConstructedFromApiFunction();
2582
2583 // Returns a new map with all transitions dropped from the object's current
2584 // map and the ElementsKind set.
2585 static Handle<Map> GetElementsTransitionMap(Handle<JSObject> object,
2586 ElementsKind to_kind);
2587 static void TransitionElementsKind(Handle<JSObject> object,
2588 ElementsKind to_kind);
2589
2590 // Always use this to migrate an object to a new map.
2591 // |expected_additional_properties| is only used for fast-to-slow transitions
2592 // and ignored otherwise.
2593 static void MigrateToMap(Handle<JSObject> object, Handle<Map> new_map,
2594 int expected_additional_properties = 0);
2595
2596 // Forces a prototype without any of the checks that the regular SetPrototype
2597 // would do.
2598 static void ForceSetPrototype(Handle<JSObject> object, Handle<Object> proto);
2599
2600 // Convert the object to use the canonical dictionary
2601 // representation. If the object is expected to have additional properties
2602 // added this number can be indicated to have the backing store allocated to
2603 // an initial capacity for holding these properties.
2604 static void NormalizeProperties(Handle<JSObject> object,
2605 PropertyNormalizationMode mode,
2606 int expected_additional_properties,
2607 const char* reason);
2608
2609 // Convert and update the elements backing store to be a
2610 // NumberDictionary dictionary. Returns the backing after conversion.
2611 static Handle<NumberDictionary> NormalizeElements(Handle<JSObject> object);
2612
2613 void RequireSlowElements(NumberDictionary* dictionary);
2614
2615 // Transform slow named properties to fast variants.
2616 static void MigrateSlowToFast(Handle<JSObject> object,
2617 int unused_property_fields, const char* reason);
2618
2619 inline bool IsUnboxedDoubleField(FieldIndex index);
2620
2621 // Access fast-case object properties at index.
2622 static Handle<Object> FastPropertyAt(Handle<JSObject> object,
2623 Representation representation,
2624 FieldIndex index);
2625 inline Object* RawFastPropertyAt(FieldIndex index);
2626 inline double RawFastDoublePropertyAt(FieldIndex index);
2627 inline uint64_t RawFastDoublePropertyAsBitsAt(FieldIndex index);
2628
2629 inline void FastPropertyAtPut(FieldIndex index, Object* value);
2630 inline void RawFastPropertyAtPut(FieldIndex index, Object* value);
2631 inline void RawFastDoublePropertyAsBitsAtPut(FieldIndex index, uint64_t bits);
2632 inline void WriteToField(int descriptor, PropertyDetails details,
2633 Object* value);
2634
2635 // Access to in object properties.
2636 inline int GetInObjectPropertyOffset(int index);
2637 inline Object* InObjectPropertyAt(int index);
2638 inline Object* InObjectPropertyAtPut(int index,
2639 Object* value,
2640 WriteBarrierMode mode
2641 = UPDATE_WRITE_BARRIER);
2642
2643 // Set the object's prototype (only JSReceiver and null are allowed values).
2644 V8_WARN_UNUSED_RESULT static Maybe<bool> SetPrototype(
2645 Handle<JSObject> object, Handle<Object> value, bool from_javascript,
2646 ShouldThrow should_throw);
2647
2648 // Makes the object prototype immutable
2649 // Never called from JavaScript
2650 static void SetImmutableProto(Handle<JSObject> object);
2651
2652 // Initializes the body starting at |start_offset|. It is responsibility of
2653 // the caller to initialize object header. Fill the pre-allocated fields with
2654 // pre_allocated_value and the rest with filler_value.
2655 // Note: this call does not update write barrier, the caller is responsible
2656 // to ensure that |filler_value| can be collected without WB here.
2657 inline void InitializeBody(Map* map, int start_offset,
2658 Object* pre_allocated_value, Object* filler_value);
2659
2660 // Check whether this object references another object
2661 bool ReferencesObject(Object* obj);
2662
2663 V8_WARN_UNUSED_RESULT static Maybe<bool> TestIntegrityLevel(
2664 Handle<JSObject> object, IntegrityLevel lvl);
2665
2666 V8_WARN_UNUSED_RESULT static Maybe<bool> PreventExtensions(
2667 Handle<JSObject> object, ShouldThrow should_throw);
2668
2669 static bool IsExtensible(Handle<JSObject> object);
2670
2671 DECL_CAST(JSObject)
2672
2673 // Dispatched behavior.
2674 void JSObjectShortPrint(StringStream* accumulator);
2675 DECL_PRINTER(JSObject)
2676 DECL_VERIFIER(JSObject)
2677 #ifdef OBJECT_PRINT
2678 bool PrintProperties(std::ostream& os); // NOLINT
2679 void PrintElements(std::ostream& os); // NOLINT
2680 #endif
2681 #if defined(DEBUG) || defined(OBJECT_PRINT)
2682 void PrintTransitions(std::ostream& os); // NOLINT
2683 #endif
2684
2685 static void PrintElementsTransition(
2686 FILE* file, Handle<JSObject> object,
2687 ElementsKind from_kind, Handle<FixedArrayBase> from_elements,
2688 ElementsKind to_kind, Handle<FixedArrayBase> to_elements);
2689
2690 void PrintInstanceMigration(FILE* file, Map* original_map, Map* new_map);
2691
2692 #ifdef DEBUG
2693 // Structure for collecting spill information about JSObjects.
2694 class SpillInformation {
2695 public:
2696 void Clear();
2697 void Print();
2698 int number_of_objects_;
2699 int number_of_objects_with_fast_properties_;
2700 int number_of_objects_with_fast_elements_;
2701 int number_of_fast_used_fields_;
2702 int number_of_fast_unused_fields_;
2703 int number_of_slow_used_properties_;
2704 int number_of_slow_unused_properties_;
2705 int number_of_fast_used_elements_;
2706 int number_of_fast_unused_elements_;
2707 int number_of_slow_used_elements_;
2708 int number_of_slow_unused_elements_;
2709 };
2710
2711 void IncrementSpillStatistics(SpillInformation* info);
2712 #endif
2713
2714 #ifdef VERIFY_HEAP
2715 // If a GC was caused while constructing this object, the elements pointer
2716 // may point to a one pointer filler map. The object won't be rooted, but
2717 // our heap verification code could stumble across it.
2718 bool ElementsAreSafeToExamine();
2719 #endif
2720
2721 Object* SlowReverseLookup(Object* value);
2722
2723 // Maximal number of elements (numbered 0 .. kMaxElementCount - 1).
2724 // Also maximal value of JSArray's length property.
2725 static const uint32_t kMaxElementCount = 0xffffffffu;
2726
2727 // Constants for heuristics controlling conversion of fast elements
2728 // to slow elements.
2729
2730 // Maximal gap that can be introduced by adding an element beyond
2731 // the current elements length.
2732 static const uint32_t kMaxGap = 1024;
2733
2734 // Maximal length of fast elements array that won't be checked for
2735 // being dense enough on expansion.
2736 static const int kMaxUncheckedFastElementsLength = 5000;
2737
2738 // Same as above but for old arrays. This limit is more strict. We
2739 // don't want to be wasteful with long lived objects.
2740 static const int kMaxUncheckedOldFastElementsLength = 500;
2741
2742 // This constant applies only to the initial map of "global.Object" and
2743 // not to arbitrary other JSObject maps.
2744 static const int kInitialGlobalObjectUnusedPropertiesCount = 4;
2745
2746 static const int kMaxInstanceSize = 255 * kPointerSize;
2747
2748 // When extending the backing storage for property values, we increase
2749 // its size by more than the 1 entry necessary, so sequentially adding fields
2750 // to the same object requires fewer allocations and copies.
2751 static const int kFieldsAdded = 3;
2752 STATIC_ASSERT(kMaxNumberOfDescriptors + kFieldsAdded <=
2753 PropertyArray::kMaxLength);
2754
2755 // Layout description.
2756 static const int kElementsOffset = JSReceiver::kHeaderSize;
2757 static const int kHeaderSize = kElementsOffset + kPointerSize;
2758
2759 STATIC_ASSERT(kHeaderSize == Internals::kJSObjectHeaderSize);
2760 static const int kMaxInObjectProperties =
2761 (kMaxInstanceSize - kHeaderSize) >> kPointerSizeLog2;
2762 STATIC_ASSERT(kMaxInObjectProperties <= kMaxNumberOfDescriptors);
2763 // TODO(cbruni): Revisit calculation of the max supported embedder fields.
2764 static const int kMaxEmbedderFields =
2765 ((1 << kFirstInobjectPropertyOffsetBitCount) - 1 - kHeaderSize) >>
2766 kPointerSizeLog2;
2767 STATIC_ASSERT(kMaxEmbedderFields <= kMaxInObjectProperties);
2768
2769 class BodyDescriptor;
2770 // No weak fields.
2771 typedef BodyDescriptor BodyDescriptorWeak;
2772
2773 class FastBodyDescriptor;
2774 // No weak fields.
2775 typedef FastBodyDescriptor FastBodyDescriptorWeak;
2776
2777 // Gets the number of currently used elements.
2778 int GetFastElementsUsage();
2779
2780 static bool AllCanRead(LookupIterator* it);
2781 static bool AllCanWrite(LookupIterator* it);
2782
2783 private:
2784 friend class JSReceiver;
2785 friend class Object;
2786
2787 // Used from Object::GetProperty().
2788 V8_WARN_UNUSED_RESULT static MaybeHandle<Object>
2789 GetPropertyWithFailedAccessCheck(LookupIterator* it);
2790
2791 V8_WARN_UNUSED_RESULT static Maybe<bool> SetPropertyWithFailedAccessCheck(
2792 LookupIterator* it, Handle<Object> value, ShouldThrow should_throw);
2793
2794 V8_WARN_UNUSED_RESULT static Maybe<bool> DeletePropertyWithInterceptor(
2795 LookupIterator* it, ShouldThrow should_throw);
2796
2797 bool ReferencesObjectFromElements(FixedArray* elements,
2798 ElementsKind kind,
2799 Object* object);
2800
2801 // Helper for fast versions of preventExtensions, seal, and freeze.
2802 // attrs is one of NONE, SEALED, or FROZEN (depending on the operation).
2803 template <PropertyAttributes attrs>
2804 V8_WARN_UNUSED_RESULT static Maybe<bool> PreventExtensionsWithTransition(
2805 Handle<JSObject> object, ShouldThrow should_throw);
2806
2807 DISALLOW_IMPLICIT_CONSTRUCTORS(JSObject);
2808 };
2809
2810
2811 // JSAccessorPropertyDescriptor is just a JSObject with a specific initial
2812 // map. This initial map adds in-object properties for "get", "set",
2813 // "enumerable" and "configurable" properties, as assigned by the
2814 // FromPropertyDescriptor function for regular accessor properties.
2815 class JSAccessorPropertyDescriptor: public JSObject {
2816 public:
2817 // Offsets of object fields.
2818 static const int kGetOffset = JSObject::kHeaderSize;
2819 static const int kSetOffset = kGetOffset + kPointerSize;
2820 static const int kEnumerableOffset = kSetOffset + kPointerSize;
2821 static const int kConfigurableOffset = kEnumerableOffset + kPointerSize;
2822 static const int kSize = kConfigurableOffset + kPointerSize;
2823 // Indices of in-object properties.
2824 static const int kGetIndex = 0;
2825 static const int kSetIndex = 1;
2826 static const int kEnumerableIndex = 2;
2827 static const int kConfigurableIndex = 3;
2828
2829 private:
2830 DISALLOW_IMPLICIT_CONSTRUCTORS(JSAccessorPropertyDescriptor);
2831 };
2832
2833
2834 // JSDataPropertyDescriptor is just a JSObject with a specific initial map.
2835 // This initial map adds in-object properties for "value", "writable",
2836 // "enumerable" and "configurable" properties, as assigned by the
2837 // FromPropertyDescriptor function for regular data properties.
2838 class JSDataPropertyDescriptor: public JSObject {
2839 public:
2840 // Offsets of object fields.
2841 static const int kValueOffset = JSObject::kHeaderSize;
2842 static const int kWritableOffset = kValueOffset + kPointerSize;
2843 static const int kEnumerableOffset = kWritableOffset + kPointerSize;
2844 static const int kConfigurableOffset = kEnumerableOffset + kPointerSize;
2845 static const int kSize = kConfigurableOffset + kPointerSize;
2846 // Indices of in-object properties.
2847 static const int kValueIndex = 0;
2848 static const int kWritableIndex = 1;
2849 static const int kEnumerableIndex = 2;
2850 static const int kConfigurableIndex = 3;
2851
2852 private:
2853 DISALLOW_IMPLICIT_CONSTRUCTORS(JSDataPropertyDescriptor);
2854 };
2855
2856
2857 // JSIteratorResult is just a JSObject with a specific initial map.
2858 // This initial map adds in-object properties for "done" and "value",
2859 // as specified by ES6 section 25.1.1.3 The IteratorResult Interface
2860 class JSIteratorResult: public JSObject {
2861 public:
2862 DECL_ACCESSORS(value, Object)
2863
2864 DECL_ACCESSORS(done, Object)
2865
2866 // Offsets of object fields.
2867 static const int kValueOffset = JSObject::kHeaderSize;
2868 static const int kDoneOffset = kValueOffset + kPointerSize;
2869 static const int kSize = kDoneOffset + kPointerSize;
2870 // Indices of in-object properties.
2871 static const int kValueIndex = 0;
2872 static const int kDoneIndex = 1;
2873
2874 private:
2875 DISALLOW_IMPLICIT_CONSTRUCTORS(JSIteratorResult);
2876 };
2877
2878 // FreeSpace are fixed-size free memory blocks used by the heap and GC.
2879 // They look like heap objects (are heap object tagged and have a map) so that
2880 // the heap remains iterable. They have a size and a next pointer.
2881 // The next pointer is the raw address of the next FreeSpace object (or NULL)
2882 // in the free list.
2883 class FreeSpace: public HeapObject {
2884 public:
2885 // [size]: size of the free space including the header.
2886 inline int size() const;
2887 inline void set_size(int value);
2888
2889 inline int relaxed_read_size() const;
2890 inline void relaxed_write_size(int value);
2891
2892 inline int Size();
2893
2894 // Accessors for the next field.
2895 inline FreeSpace* next();
2896 inline void set_next(FreeSpace* next);
2897
2898 inline static FreeSpace* cast(HeapObject* obj);
2899
2900 // Dispatched behavior.
2901 DECL_PRINTER(FreeSpace)
2902 DECL_VERIFIER(FreeSpace)
2903
2904 // Layout description.
2905 // Size is smi tagged when it is stored.
2906 static const int kSizeOffset = HeapObject::kHeaderSize;
2907 static const int kNextOffset = POINTER_SIZE_ALIGN(kSizeOffset + kPointerSize);
2908 static const int kSize = kNextOffset + kPointerSize;
2909
2910 private:
2911 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeSpace);
2912 };
2913
2914 class PrototypeInfo;
2915
2916 // An abstract superclass, a marker class really, for simple structure classes.
2917 // It doesn't carry much functionality but allows struct classes to be
2918 // identified in the type system.
2919 class Struct: public HeapObject {
2920 public:
2921 inline void InitializeBody(int object_size);
2922 DECL_CAST(Struct)
2923 void BriefPrintDetails(std::ostream& os);
2924 };
2925
2926 class Tuple2 : public Struct {
2927 public:
2928 DECL_ACCESSORS(value1, Object)
2929 DECL_ACCESSORS(value2, Object)
2930
2931 DECL_CAST(Tuple2)
2932
2933 // Dispatched behavior.
2934 DECL_PRINTER(Tuple2)
2935 DECL_VERIFIER(Tuple2)
2936 void BriefPrintDetails(std::ostream& os);
2937
2938 static const int kValue1Offset = HeapObject::kHeaderSize;
2939 static const int kValue2Offset = kValue1Offset + kPointerSize;
2940 static const int kSize = kValue2Offset + kPointerSize;
2941
2942 private:
2943 DISALLOW_IMPLICIT_CONSTRUCTORS(Tuple2);
2944 };
2945
2946 class Tuple3 : public Tuple2 {
2947 public:
2948 DECL_ACCESSORS(value3, Object)
2949
2950 DECL_CAST(Tuple3)
2951
2952 // Dispatched behavior.
2953 DECL_PRINTER(Tuple3)
2954 DECL_VERIFIER(Tuple3)
2955 void BriefPrintDetails(std::ostream& os);
2956
2957 static const int kValue3Offset = Tuple2::kSize;
2958 static const int kSize = kValue3Offset + kPointerSize;
2959
2960 private:
2961 DISALLOW_IMPLICIT_CONSTRUCTORS(Tuple3);
2962 };
2963
2964 class AsyncGeneratorRequest : public Struct {
2965 public:
2966 // Holds an AsyncGeneratorRequest, or Undefined.
2967 DECL_ACCESSORS(next, Object)
2968 DECL_INT_ACCESSORS(resume_mode)
2969 DECL_ACCESSORS(value, Object)
2970 DECL_ACCESSORS(promise, Object)
2971
2972 static const int kNextOffset = Struct::kHeaderSize;
2973 static const int kResumeModeOffset = kNextOffset + kPointerSize;
2974 static const int kValueOffset = kResumeModeOffset + kPointerSize;
2975 static const int kPromiseOffset = kValueOffset + kPointerSize;
2976 static const int kSize = kPromiseOffset + kPointerSize;
2977
2978 DECL_CAST(AsyncGeneratorRequest)
2979 DECL_PRINTER(AsyncGeneratorRequest)
2980 DECL_VERIFIER(AsyncGeneratorRequest)
2981
2982 private:
2983 DISALLOW_IMPLICIT_CONSTRUCTORS(AsyncGeneratorRequest);
2984 };
2985
2986 // Container for metadata stored on each prototype map.
2987 class PrototypeInfo : public Struct {
2988 public:
2989 static const int UNREGISTERED = -1;
2990
2991 // [weak_cell]: A WeakCell containing this prototype. ICs cache the cell here.
2992 DECL_ACCESSORS(weak_cell, Object)
2993
2994 // [prototype_users]: FixedArrayOfWeakCells containing maps using this
2995 // prototype, or Smi(0) if uninitialized.
2996 DECL_ACCESSORS(prototype_users, Object)
2997
2998 // [object_create_map]: A field caching the map for Object.create(prototype).
2999 static inline void SetObjectCreateMap(Handle<PrototypeInfo> info,
3000 Handle<Map> map);
3001 inline Map* ObjectCreateMap();
3002 inline bool HasObjectCreateMap();
3003
3004 // [registry_slot]: Slot in prototype's user registry where this user
3005 // is stored. Returns UNREGISTERED if this prototype has not been registered.
3006 inline int registry_slot() const;
3007 inline void set_registry_slot(int slot);
3008
3009 // [bit_field]
3010 inline int bit_field() const;
3011 inline void set_bit_field(int bit_field);
3012
3013 DECL_BOOLEAN_ACCESSORS(should_be_fast_map)
3014
3015 DECL_CAST(PrototypeInfo)
3016
3017 // Dispatched behavior.
3018 DECL_PRINTER(PrototypeInfo)
3019 DECL_VERIFIER(PrototypeInfo)
3020
3021 static const int kWeakCellOffset = HeapObject::kHeaderSize;
3022 static const int kPrototypeUsersOffset = kWeakCellOffset + kPointerSize;
3023 static const int kRegistrySlotOffset = kPrototypeUsersOffset + kPointerSize;
3024 static const int kValidityCellOffset = kRegistrySlotOffset + kPointerSize;
3025 static const int kObjectCreateMap = kValidityCellOffset + kPointerSize;
3026 static const int kBitFieldOffset = kObjectCreateMap + kPointerSize;
3027 static const int kSize = kBitFieldOffset + kPointerSize;
3028
3029 // Bit field usage.
3030 static const int kShouldBeFastBit = 0;
3031
3032 private:
3033 DECL_ACCESSORS(object_create_map, Object)
3034
3035 DISALLOW_IMPLICIT_CONSTRUCTORS(PrototypeInfo);
3036 };
3037
3038 // List of builtin functions we want to identify to improve code
3039 // generation.
3040 //
3041 // Each entry has a name of a global object property holding an object
3042 // optionally followed by ".prototype", a name of a builtin function
3043 // on the object (the one the id is set for), and a label.
3044 //
3045 // Installation of ids for the selected builtin functions is handled
3046 // by the bootstrapper.
3047 #define FUNCTIONS_WITH_ID_LIST(V) \
3048 V(Array, isArray, ArrayIsArray) \
3049 V(Array.prototype, concat, ArrayConcat) \
3050 V(Array.prototype, every, ArrayEvery) \
3051 V(Array.prototype, fill, ArrayFill) \
3052 V(Array.prototype, filter, ArrayFilter) \
3053 V(Array.prototype, findIndex, ArrayFindIndex) \
3054 V(Array.prototype, forEach, ArrayForEach) \
3055 V(Array.prototype, includes, ArrayIncludes) \
3056 V(Array.prototype, indexOf, ArrayIndexOf) \
3057 V(Array.prototype, join, ArrayJoin) \
3058 V(Array.prototype, lastIndexOf, ArrayLastIndexOf) \
3059 V(Array.prototype, map, ArrayMap) \
3060 V(Array.prototype, pop, ArrayPop) \
3061 V(Array.prototype, push, ArrayPush) \
3062 V(Array.prototype, reverse, ArrayReverse) \
3063 V(Array.prototype, shift, ArrayShift) \
3064 V(Array.prototype, slice, ArraySlice) \
3065 V(Array.prototype, some, ArraySome) \
3066 V(Array.prototype, splice, ArraySplice) \
3067 V(Array.prototype, unshift, ArrayUnshift) \
3068 V(Date, now, DateNow) \
3069 V(Date.prototype, getDate, DateGetDate) \
3070 V(Date.prototype, getDay, DateGetDay) \
3071 V(Date.prototype, getFullYear, DateGetFullYear) \
3072 V(Date.prototype, getHours, DateGetHours) \
3073 V(Date.prototype, getMilliseconds, DateGetMilliseconds) \
3074 V(Date.prototype, getMinutes, DateGetMinutes) \
3075 V(Date.prototype, getMonth, DateGetMonth) \
3076 V(Date.prototype, getSeconds, DateGetSeconds) \
3077 V(Date.prototype, getTime, DateGetTime) \
3078 V(Function.prototype, apply, FunctionApply) \
3079 V(Function.prototype, bind, FunctionBind) \
3080 V(Function.prototype, call, FunctionCall) \
3081 V(Object, assign, ObjectAssign) \
3082 V(Object, create, ObjectCreate) \
3083 V(Object, is, ObjectIs) \
3084 V(Object.prototype, hasOwnProperty, ObjectHasOwnProperty) \
3085 V(Object.prototype, isPrototypeOf, ObjectIsPrototypeOf) \
3086 V(Object.prototype, toString, ObjectToString) \
3087 V(RegExp.prototype, compile, RegExpCompile) \
3088 V(RegExp.prototype, exec, RegExpExec) \
3089 V(RegExp.prototype, test, RegExpTest) \
3090 V(RegExp.prototype, toString, RegExpToString) \
3091 V(String.prototype, charCodeAt, StringCharCodeAt) \
3092 V(String.prototype, charAt, StringCharAt) \
3093 V(String.prototype, codePointAt, StringCodePointAt) \
3094 V(String.prototype, concat, StringConcat) \
3095 V(String.prototype, endsWith, StringEndsWith) \
3096 V(String.prototype, includes, StringIncludes) \
3097 V(String.prototype, indexOf, StringIndexOf) \
3098 V(String.prototype, lastIndexOf, StringLastIndexOf) \
3099 V(String.prototype, repeat, StringRepeat) \
3100 V(String.prototype, slice, StringSlice) \
3101 V(String.prototype, startsWith, StringStartsWith) \
3102 V(String.prototype, substr, StringSubstr) \
3103 V(String.prototype, substring, StringSubstring) \
3104 V(String.prototype, toLowerCase, StringToLowerCase) \
3105 V(String.prototype, toString, StringToString) \
3106 V(String.prototype, toUpperCase, StringToUpperCase) \
3107 V(String.prototype, trim, StringTrim) \
3108 V(String.prototype, trimLeft, StringTrimStart) \
3109 V(String.prototype, trimRight, StringTrimEnd) \
3110 V(String.prototype, valueOf, StringValueOf) \
3111 V(String, fromCharCode, StringFromCharCode) \
3112 V(String, fromCodePoint, StringFromCodePoint) \
3113 V(String, raw, StringRaw) \
3114 V(Math, random, MathRandom) \
3115 V(Math, floor, MathFloor) \
3116 V(Math, round, MathRound) \
3117 V(Math, ceil, MathCeil) \
3118 V(Math, abs, MathAbs) \
3119 V(Math, log, MathLog) \
3120 V(Math, log1p, MathLog1p) \
3121 V(Math, log2, MathLog2) \
3122 V(Math, log10, MathLog10) \
3123 V(Math, cbrt, MathCbrt) \
3124 V(Math, exp, MathExp) \
3125 V(Math, expm1, MathExpm1) \
3126 V(Math, sqrt, MathSqrt) \
3127 V(Math, pow, MathPow) \
3128 V(Math, max, MathMax) \
3129 V(Math, min, MathMin) \
3130 V(Math, cos, MathCos) \
3131 V(Math, cosh, MathCosh) \
3132 V(Math, sign, MathSign) \
3133 V(Math, sin, MathSin) \
3134 V(Math, sinh, MathSinh) \
3135 V(Math, tan, MathTan) \
3136 V(Math, tanh, MathTanh) \
3137 V(Math, acos, MathAcos) \
3138 V(Math, acosh, MathAcosh) \
3139 V(Math, asin, MathAsin) \
3140 V(Math, asinh, MathAsinh) \
3141 V(Math, atan, MathAtan) \
3142 V(Math, atan2, MathAtan2) \
3143 V(Math, atanh, MathAtanh) \
3144 V(Math, imul, MathImul) \
3145 V(Math, clz32, MathClz32) \
3146 V(Math, fround, MathFround) \
3147 V(Math, trunc, MathTrunc) \
3148 V(Number, isFinite, NumberIsFinite) \
3149 V(Number, isInteger, NumberIsInteger) \
3150 V(Number, isNaN, NumberIsNaN) \
3151 V(Number, isSafeInteger, NumberIsSafeInteger) \
3152 V(Number, parseFloat, NumberParseFloat) \
3153 V(Number, parseInt, NumberParseInt) \
3154 V(Number.prototype, toString, NumberToString) \
3155 V(Map.prototype, clear, MapClear) \
3156 V(Map.prototype, delete, MapDelete) \
3157 V(Map.prototype, entries, MapEntries) \
3158 V(Map.prototype, forEach, MapForEach) \
3159 V(Map.prototype, has, MapHas) \
3160 V(Map.prototype, keys, MapKeys) \
3161 V(Map.prototype, get, MapGet) \
3162 V(Map.prototype, set, MapSet) \
3163 V(Map.prototype, values, MapValues) \
3164 V(Set.prototype, add, SetAdd) \
3165 V(Set.prototype, clear, SetClear) \
3166 V(Set.prototype, delete, SetDelete) \
3167 V(Set.prototype, entries, SetEntries) \
3168 V(Set.prototype, forEach, SetForEach) \
3169 V(Set.prototype, has, SetHas) \
3170 V(Set.prototype, values, SetValues) \
3171 V(WeakMap.prototype, delete, WeakMapDelete) \
3172 V(WeakMap.prototype, has, WeakMapHas) \
3173 V(WeakMap.prototype, set, WeakMapSet) \
3174 V(WeakSet.prototype, add, WeakSetAdd) \
3175 V(WeakSet.prototype, delete, WeakSetDelete) \
3176 V(WeakSet.prototype, has, WeakSetHas)
3177
3178 #define ATOMIC_FUNCTIONS_WITH_ID_LIST(V) \
3179 V(Atomics, load, AtomicsLoad) \
3180 V(Atomics, store, AtomicsStore) \
3181 V(Atomics, exchange, AtomicsExchange) \
3182 V(Atomics, compareExchange, AtomicsCompareExchange) \
3183 V(Atomics, add, AtomicsAdd) \
3184 V(Atomics, sub, AtomicsSub) \
3185 V(Atomics, and, AtomicsAnd) \
3186 V(Atomics, or, AtomicsOr) \
3187 V(Atomics, xor, AtomicsXor)
3188
3189 enum BuiltinFunctionId {
3190 kInvalidBuiltinFunctionId = -1,
3191 kArrayConstructor,
3192 #define DECL_FUNCTION_ID(ignored1, ignore2, name) k##name,
3193 FUNCTIONS_WITH_ID_LIST(DECL_FUNCTION_ID)
3194 ATOMIC_FUNCTIONS_WITH_ID_LIST(DECL_FUNCTION_ID)
3195 #undef DECL_FUNCTION_ID
3196 // Fake id for a special case of Math.pow. Note, it continues the
3197 // list of math functions.
3198 kMathPowHalf,
3199 // These are manually assigned to special getters during bootstrapping.
3200 kArrayBufferByteLength,
3201 kArrayBufferIsView,
3202 kArrayEntries,
3203 kArrayKeys,
3204 kArrayValues,
3205 kArrayIteratorNext,
3206 kBigIntConstructor,
3207 kMapSize,
3208 kSetSize,
3209 kMapIteratorNext,
3210 kSetIteratorNext,
3211 kDataViewBuffer,
3212 kDataViewByteLength,
3213 kDataViewByteOffset,
3214 kFunctionHasInstance,
3215 kGlobalDecodeURI,
3216 kGlobalDecodeURIComponent,
3217 kGlobalEncodeURI,
3218 kGlobalEncodeURIComponent,
3219 kGlobalEscape,
3220 kGlobalUnescape,
3221 kGlobalIsFinite,
3222 kGlobalIsNaN,
3223 kNumberConstructor,
3224 kSymbolConstructor,
3225 kTypedArrayByteLength,
3226 kTypedArrayByteOffset,
3227 kTypedArrayEntries,
3228 kTypedArrayKeys,
3229 kTypedArrayLength,
3230 kTypedArrayToStringTag,
3231 kTypedArrayValues,
3232 kSharedArrayBufferByteLength,
3233 kStringConstructor,
3234 kStringIterator,
3235 kStringIteratorNext,
3236 kStringToLowerCaseIntl,
3237 kStringToUpperCaseIntl
3238 };
3239
3240 class JSGeneratorObject: public JSObject {
3241 public:
3242 // [function]: The function corresponding to this generator object.
3243 DECL_ACCESSORS(function, JSFunction)
3244
3245 // [context]: The context of the suspended computation.
3246 DECL_ACCESSORS(context, Context)
3247
3248 // [receiver]: The receiver of the suspended computation.
3249 DECL_ACCESSORS(receiver, Object)
3250
3251 // [input_or_debug_pos]
3252 // For executing generators: the most recent input value.
3253 // For suspended generators: debug information (bytecode offset).
3254 // There is currently no need to remember the most recent input value for a
3255 // suspended generator.
3256 DECL_ACCESSORS(input_or_debug_pos, Object)
3257
3258 // [resume_mode]: The most recent resume mode.
3259 enum ResumeMode { kNext, kReturn, kThrow };
3260 DECL_INT_ACCESSORS(resume_mode)
3261
3262 // [continuation]
3263 //
3264 // A positive value indicates a suspended generator. The special
3265 // kGeneratorExecuting and kGeneratorClosed values indicate that a generator
3266 // cannot be resumed.
3267 inline int continuation() const;
3268 inline void set_continuation(int continuation);
3269 inline bool is_closed() const;
3270 inline bool is_executing() const;
3271 inline bool is_suspended() const;
3272
3273 // For suspended generators: the source position at which the generator
3274 // is suspended.
3275 int source_position() const;
3276
3277 // [register_file]: Saved interpreter register file.
3278 DECL_ACCESSORS(register_file, FixedArray)
3279
3280 DECL_CAST(JSGeneratorObject)
3281
3282 // Dispatched behavior.
3283 DECL_PRINTER(JSGeneratorObject)
3284 DECL_VERIFIER(JSGeneratorObject)
3285
3286 // Magic sentinel values for the continuation.
3287 static const int kGeneratorExecuting = -2;
3288 static const int kGeneratorClosed = -1;
3289
3290 // Layout description.
3291 static const int kFunctionOffset = JSObject::kHeaderSize;
3292 static const int kContextOffset = kFunctionOffset + kPointerSize;
3293 static const int kReceiverOffset = kContextOffset + kPointerSize;
3294 static const int kInputOrDebugPosOffset = kReceiverOffset + kPointerSize;
3295 static const int kResumeModeOffset = kInputOrDebugPosOffset + kPointerSize;
3296 static const int kContinuationOffset = kResumeModeOffset + kPointerSize;
3297 static const int kRegisterFileOffset = kContinuationOffset + kPointerSize;
3298 static const int kSize = kRegisterFileOffset + kPointerSize;
3299
3300 private:
3301 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGeneratorObject);
3302 };
3303
3304 class JSAsyncGeneratorObject : public JSGeneratorObject {
3305 public:
3306 DECL_CAST(JSAsyncGeneratorObject)
3307
3308 // Dispatched behavior.
3309 DECL_VERIFIER(JSAsyncGeneratorObject)
3310
3311 // [queue]
3312 // Pointer to the head of a singly linked list of AsyncGeneratorRequest, or
3313 // undefined.
3314 DECL_ACCESSORS(queue, HeapObject)
3315
3316 // [is_awaiting]
3317 // Whether or not the generator is currently awaiting.
3318 DECL_INT_ACCESSORS(is_awaiting)
3319
3320 // Layout description.
3321 static const int kQueueOffset = JSGeneratorObject::kSize;
3322 static const int kIsAwaitingOffset = kQueueOffset + kPointerSize;
3323 static const int kSize = kIsAwaitingOffset + kPointerSize;
3324
3325 private:
3326 DISALLOW_IMPLICIT_CONSTRUCTORS(JSAsyncGeneratorObject);
3327 };
3328
3329 // JSBoundFunction describes a bound function exotic object.
3330 class JSBoundFunction : public JSObject {
3331 public:
3332 // [bound_target_function]: The wrapped function object.
3333 inline Object* raw_bound_target_function() const;
3334 DECL_ACCESSORS(bound_target_function, JSReceiver)
3335
3336 // [bound_this]: The value that is always passed as the this value when
3337 // calling the wrapped function.
3338 DECL_ACCESSORS(bound_this, Object)
3339
3340 // [bound_arguments]: A list of values whose elements are used as the first
3341 // arguments to any call to the wrapped function.
3342 DECL_ACCESSORS(bound_arguments, FixedArray)
3343
3344 static MaybeHandle<String> GetName(Isolate* isolate,
3345 Handle<JSBoundFunction> function);
3346 static Maybe<int> GetLength(Isolate* isolate,
3347 Handle<JSBoundFunction> function);
3348 static MaybeHandle<Context> GetFunctionRealm(
3349 Handle<JSBoundFunction> function);
3350
3351 DECL_CAST(JSBoundFunction)
3352
3353 // Dispatched behavior.
3354 DECL_PRINTER(JSBoundFunction)
3355 DECL_VERIFIER(JSBoundFunction)
3356
3357 // The bound function's string representation implemented according
3358 // to ES6 section 19.2.3.5 Function.prototype.toString ( ).
3359 static Handle<String> ToString(Handle<JSBoundFunction> function);
3360
3361 // Layout description.
3362 static const int kBoundTargetFunctionOffset = JSObject::kHeaderSize;
3363 static const int kBoundThisOffset = kBoundTargetFunctionOffset + kPointerSize;
3364 static const int kBoundArgumentsOffset = kBoundThisOffset + kPointerSize;
3365 static const int kSize = kBoundArgumentsOffset + kPointerSize;
3366
3367 private:
3368 DISALLOW_IMPLICIT_CONSTRUCTORS(JSBoundFunction);
3369 };
3370
3371
3372 // JSFunction describes JavaScript functions.
3373 class JSFunction: public JSObject {
3374 public:
3375 // [prototype_or_initial_map]:
3376 DECL_ACCESSORS(prototype_or_initial_map, Object)
3377
3378 // [shared]: The information about the function that
3379 // can be shared by instances.
3380 DECL_ACCESSORS(shared, SharedFunctionInfo)
3381
3382 static const int kLengthDescriptorIndex = 0;
3383 static const int kNameDescriptorIndex = 1;
3384 // Home object descriptor index when function has a [[HomeObject]] slot.
3385 static const int kMaybeHomeObjectDescriptorIndex = 2;
3386
3387 // [context]: The context for this function.
3388 inline Context* context();
3389 inline bool has_context() const;
3390 inline void set_context(Object* context);
3391 inline JSObject* global_proxy();
3392 inline Context* native_context();
3393
3394 static Handle<Object> GetName(Isolate* isolate, Handle<JSFunction> function);
3395 static Maybe<int> GetLength(Isolate* isolate, Handle<JSFunction> function);
3396 static Handle<Context> GetFunctionRealm(Handle<JSFunction> function);
3397
3398 // [code]: The generated code object for this function. Executed
3399 // when the function is invoked, e.g. foo() or new foo(). See
3400 // [[Call]] and [[Construct]] description in ECMA-262, section
3401 // 8.6.2, page 27.
3402 inline Code* code();
3403 inline void set_code(Code* code);
3404 inline void set_code_no_write_barrier(Code* code);
3405
3406 // Get the abstract code associated with the function, which will either be
3407 // a Code object or a BytecodeArray.
3408 inline AbstractCode* abstract_code();
3409
3410 // Tells whether or not this function is interpreted.
3411 //
3412 // Note: function->IsInterpreted() does not necessarily return the same value
3413 // as function->shared()->IsInterpreted() because the closure might have been
3414 // optimized.
3415 inline bool IsInterpreted();
3416
3417 // Tells whether or not this function checks its optimization marker in its
3418 // feedback vector.
3419 inline bool ChecksOptimizationMarker();
3420
3421 // Tells whether or not this function holds optimized code.
3422 //
3423 // Note: Returning false does not necessarily mean that this function hasn't
3424 // been optimized, as it may have optimized code on its feedback vector.
3425 inline bool IsOptimized();
3426
3427 // Tells whether or not this function has optimized code available to it,
3428 // either because it is optimized or because it has optimized code in its
3429 // feedback vector.
3430 inline bool HasOptimizedCode();
3431
3432 // Tells whether or not this function has a (non-zero) optimization marker.
3433 inline bool HasOptimizationMarker();
3434
3435 // Mark this function for lazy recompilation. The function will be recompiled
3436 // the next time it is executed.
3437 void MarkForOptimization(ConcurrencyMode mode);
3438
3439 // Tells whether or not the function is already marked for lazy recompilation.
3440 inline bool IsMarkedForOptimization();
3441 inline bool IsMarkedForConcurrentOptimization();
3442
3443 // Tells whether or not the function is on the concurrent recompilation queue.
3444 inline bool IsInOptimizationQueue();
3445
3446 // Clears the optimized code slot in the function's feedback vector.
3447 inline void ClearOptimizedCodeSlot(const char* reason);
3448
3449 // Sets the optimization marker in the function's feedback vector.
3450 inline void SetOptimizationMarker(OptimizationMarker marker);
3451
3452 // Clears the optimization marker in the function's feedback vector.
3453 inline void ClearOptimizationMarker();
3454
3455 // Completes inobject slack tracking on initial map if it is active.
3456 inline void CompleteInobjectSlackTrackingIfActive();
3457
3458 // [feedback_cell]: The FeedbackCell used to hold the FeedbackVector
3459 // eventually.
3460 DECL_ACCESSORS(feedback_cell, FeedbackCell)
3461
3462 // feedback_vector() can be used once the function is compiled.
3463 inline FeedbackVector* feedback_vector() const;
3464 inline bool has_feedback_vector() const;
3465 static void EnsureFeedbackVector(Handle<JSFunction> function);
3466
3467 // Unconditionally clear the type feedback vector.
3468 void ClearTypeFeedbackInfo();
3469
3470 inline bool has_prototype_slot() const;
3471
3472 // The initial map for an object created by this constructor.
3473 inline Map* initial_map();
3474 static void SetInitialMap(Handle<JSFunction> function, Handle<Map> map,
3475 Handle<Object> prototype);
3476 inline bool has_initial_map();
3477 static void EnsureHasInitialMap(Handle<JSFunction> function);
3478
3479 // Creates a map that matches the constructor's initial map, but with
3480 // [[prototype]] being new.target.prototype. Because new.target can be a
3481 // JSProxy, this can call back into JavaScript.
3482 static V8_WARN_UNUSED_RESULT MaybeHandle<Map> GetDerivedMap(
3483 Isolate* isolate, Handle<JSFunction> constructor,
3484 Handle<JSReceiver> new_target);
3485
3486 // Get and set the prototype property on a JSFunction. If the
3487 // function has an initial map the prototype is set on the initial
3488 // map. Otherwise, the prototype is put in the initial map field
3489 // until an initial map is needed.
3490 inline bool has_prototype();
3491 inline bool has_instance_prototype();
3492 inline Object* prototype();
3493 inline Object* instance_prototype();
3494 static void SetPrototype(Handle<JSFunction> function,
3495 Handle<Object> value);
3496
3497 // Returns if this function has been compiled to native code yet.
3498 inline bool is_compiled();
3499
GetHeaderSize(bool function_has_prototype_slot)3500 static int GetHeaderSize(bool function_has_prototype_slot) {
3501 return function_has_prototype_slot ? JSFunction::kSizeWithPrototype
3502 : JSFunction::kSizeWithoutPrototype;
3503 }
3504
3505 // Prints the name of the function using PrintF.
3506 void PrintName(FILE* out = stdout);
3507
3508 DECL_CAST(JSFunction)
3509
3510 // Calculate the instance size and in-object properties count.
3511 static bool CalculateInstanceSizeForDerivedClass(
3512 Handle<JSFunction> function, InstanceType instance_type,
3513 int requested_embedder_fields, int* instance_size,
3514 int* in_object_properties);
3515 static void CalculateInstanceSizeHelper(InstanceType instance_type,
3516 bool has_prototype_slot,
3517 int requested_embedder_fields,
3518 int requested_in_object_properties,
3519 int* instance_size,
3520 int* in_object_properties);
3521
3522 class BodyDescriptor;
3523
3524 // Dispatched behavior.
3525 DECL_PRINTER(JSFunction)
3526 DECL_VERIFIER(JSFunction)
3527
3528 // The function's name if it is configured, otherwise shared function info
3529 // debug name.
3530 static Handle<String> GetName(Handle<JSFunction> function);
3531
3532 // ES6 section 9.2.11 SetFunctionName
3533 // Because of the way this abstract operation is used in the spec,
3534 // it should never fail, but in practice it will fail if the generated
3535 // function name's length exceeds String::kMaxLength.
3536 static V8_WARN_UNUSED_RESULT bool SetName(Handle<JSFunction> function,
3537 Handle<Name> name,
3538 Handle<String> prefix);
3539
3540 // The function's displayName if it is set, otherwise name if it is
3541 // configured, otherwise shared function info
3542 // debug name.
3543 static Handle<String> GetDebugName(Handle<JSFunction> function);
3544
3545 // The function's string representation implemented according to
3546 // ES6 section 19.2.3.5 Function.prototype.toString ( ).
3547 static Handle<String> ToString(Handle<JSFunction> function);
3548
3549 // Layout description.
3550 #define JS_FUNCTION_FIELDS(V) \
3551 /* Pointer fields. */ \
3552 V(kSharedFunctionInfoOffset, kPointerSize) \
3553 V(kContextOffset, kPointerSize) \
3554 V(kFeedbackCellOffset, kPointerSize) \
3555 V(kEndOfStrongFieldsOffset, 0) \
3556 V(kCodeOffset, kPointerSize) \
3557 /* Size of JSFunction object without prototype field. */ \
3558 V(kSizeWithoutPrototype, 0) \
3559 V(kPrototypeOrInitialMapOffset, kPointerSize) \
3560 /* Size of JSFunction object with prototype field. */ \
3561 V(kSizeWithPrototype, 0)
3562
3563 DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, JS_FUNCTION_FIELDS)
3564
3565 private:
3566 DISALLOW_IMPLICIT_CONSTRUCTORS(JSFunction);
3567 };
3568
3569
3570 // JSGlobalProxy's prototype must be a JSGlobalObject or null,
3571 // and the prototype is hidden. JSGlobalProxy always delegates
3572 // property accesses to its prototype if the prototype is not null.
3573 //
3574 // A JSGlobalProxy can be reinitialized which will preserve its identity.
3575 //
3576 // Accessing a JSGlobalProxy requires security check.
3577
3578 class JSGlobalProxy : public JSObject {
3579 public:
3580 // [native_context]: the owner native context of this global proxy object.
3581 // It is null value if this object is not used by any context.
3582 DECL_ACCESSORS(native_context, Object)
3583
3584 DECL_CAST(JSGlobalProxy)
3585
3586 inline bool IsDetachedFrom(JSGlobalObject* global) const;
3587
3588 static int SizeWithEmbedderFields(int embedder_field_count);
3589
3590 // Dispatched behavior.
3591 DECL_PRINTER(JSGlobalProxy)
3592 DECL_VERIFIER(JSGlobalProxy)
3593
3594 // Layout description.
3595 static const int kNativeContextOffset = JSObject::kHeaderSize;
3596 static const int kSize = kNativeContextOffset + kPointerSize;
3597
3598 private:
3599 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalProxy);
3600 };
3601
3602
3603 // JavaScript global object.
3604 class JSGlobalObject : public JSObject {
3605 public:
3606 // [native context]: the natives corresponding to this global object.
3607 DECL_ACCESSORS(native_context, Context)
3608
3609 // [global proxy]: the global proxy object of the context
3610 DECL_ACCESSORS(global_proxy, JSObject)
3611
3612 // Gets global object properties.
3613 inline GlobalDictionary* global_dictionary();
3614 inline void set_global_dictionary(GlobalDictionary* dictionary);
3615
3616 static void InvalidatePropertyCell(Handle<JSGlobalObject> object,
3617 Handle<Name> name);
3618 // Ensure that the global object has a cell for the given property name.
3619 static Handle<PropertyCell> EnsureEmptyPropertyCell(
3620 Handle<JSGlobalObject> global, Handle<Name> name,
3621 PropertyCellType cell_type, int* entry_out = nullptr);
3622
3623 DECL_CAST(JSGlobalObject)
3624
3625 inline bool IsDetached();
3626
3627 // Dispatched behavior.
3628 DECL_PRINTER(JSGlobalObject)
3629 DECL_VERIFIER(JSGlobalObject)
3630
3631 // Layout description.
3632 static const int kNativeContextOffset = JSObject::kHeaderSize;
3633 static const int kGlobalProxyOffset = kNativeContextOffset + kPointerSize;
3634 static const int kHeaderSize = kGlobalProxyOffset + kPointerSize;
3635 static const int kSize = kHeaderSize;
3636
3637 private:
3638 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalObject);
3639 };
3640
3641
3642 // Representation for JS Wrapper objects, String, Number, Boolean, etc.
3643 class JSValue: public JSObject {
3644 public:
3645 // [value]: the object being wrapped.
3646 DECL_ACCESSORS(value, Object)
3647
3648 DECL_CAST(JSValue)
3649
3650 // Dispatched behavior.
3651 DECL_PRINTER(JSValue)
3652 DECL_VERIFIER(JSValue)
3653
3654 // Layout description.
3655 static const int kValueOffset = JSObject::kHeaderSize;
3656 static const int kSize = kValueOffset + kPointerSize;
3657
3658 private:
3659 DISALLOW_IMPLICIT_CONSTRUCTORS(JSValue);
3660 };
3661
3662
3663 class DateCache;
3664
3665 // Representation for JS date objects.
3666 class JSDate: public JSObject {
3667 public:
3668 static V8_WARN_UNUSED_RESULT MaybeHandle<JSDate> New(
3669 Handle<JSFunction> constructor, Handle<JSReceiver> new_target, double tv);
3670
3671 // If one component is NaN, all of them are, indicating a NaN time value.
3672 // [value]: the time value.
3673 DECL_ACCESSORS(value, Object)
3674 // [year]: caches year. Either undefined, smi, or NaN.
3675 DECL_ACCESSORS(year, Object)
3676 // [month]: caches month. Either undefined, smi, or NaN.
3677 DECL_ACCESSORS(month, Object)
3678 // [day]: caches day. Either undefined, smi, or NaN.
3679 DECL_ACCESSORS(day, Object)
3680 // [weekday]: caches day of week. Either undefined, smi, or NaN.
3681 DECL_ACCESSORS(weekday, Object)
3682 // [hour]: caches hours. Either undefined, smi, or NaN.
3683 DECL_ACCESSORS(hour, Object)
3684 // [min]: caches minutes. Either undefined, smi, or NaN.
3685 DECL_ACCESSORS(min, Object)
3686 // [sec]: caches seconds. Either undefined, smi, or NaN.
3687 DECL_ACCESSORS(sec, Object)
3688 // [cache stamp]: sample of the date cache stamp at the
3689 // moment when chached fields were cached.
3690 DECL_ACCESSORS(cache_stamp, Object)
3691
3692 DECL_CAST(JSDate)
3693
3694 // Returns the time value (UTC) identifying the current time.
3695 static double CurrentTimeValue(Isolate* isolate);
3696
3697 // Returns the date field with the specified index.
3698 // See FieldIndex for the list of date fields.
3699 static Object* GetField(Object* date, Smi* index);
3700
3701 static Handle<Object> SetValue(Handle<JSDate> date, double v);
3702
3703 void SetValue(Object* value, bool is_value_nan);
3704
3705 // Dispatched behavior.
3706 DECL_PRINTER(JSDate)
3707 DECL_VERIFIER(JSDate)
3708
3709 // The order is important. It must be kept in sync with date macros
3710 // in macros.py.
3711 enum FieldIndex {
3712 kDateValue,
3713 kYear,
3714 kMonth,
3715 kDay,
3716 kWeekday,
3717 kHour,
3718 kMinute,
3719 kSecond,
3720 kFirstUncachedField,
3721 kMillisecond = kFirstUncachedField,
3722 kDays,
3723 kTimeInDay,
3724 kFirstUTCField,
3725 kYearUTC = kFirstUTCField,
3726 kMonthUTC,
3727 kDayUTC,
3728 kWeekdayUTC,
3729 kHourUTC,
3730 kMinuteUTC,
3731 kSecondUTC,
3732 kMillisecondUTC,
3733 kDaysUTC,
3734 kTimeInDayUTC,
3735 kTimezoneOffset
3736 };
3737
3738 // Layout description.
3739 static const int kValueOffset = JSObject::kHeaderSize;
3740 static const int kYearOffset = kValueOffset + kPointerSize;
3741 static const int kMonthOffset = kYearOffset + kPointerSize;
3742 static const int kDayOffset = kMonthOffset + kPointerSize;
3743 static const int kWeekdayOffset = kDayOffset + kPointerSize;
3744 static const int kHourOffset = kWeekdayOffset + kPointerSize;
3745 static const int kMinOffset = kHourOffset + kPointerSize;
3746 static const int kSecOffset = kMinOffset + kPointerSize;
3747 static const int kCacheStampOffset = kSecOffset + kPointerSize;
3748 static const int kSize = kCacheStampOffset + kPointerSize;
3749
3750 private:
3751 inline Object* DoGetField(FieldIndex index);
3752
3753 Object* GetUTCField(FieldIndex index, double value, DateCache* date_cache);
3754
3755 // Computes and caches the cacheable fields of the date.
3756 inline void SetCachedFields(int64_t local_time_ms, DateCache* date_cache);
3757
3758
3759 DISALLOW_IMPLICIT_CONSTRUCTORS(JSDate);
3760 };
3761
3762
3763 // Representation of message objects used for error reporting through
3764 // the API. The messages are formatted in JavaScript so this object is
3765 // a real JavaScript object. The information used for formatting the
3766 // error messages are not directly accessible from JavaScript to
3767 // prevent leaking information to user code called during error
3768 // formatting.
3769 class JSMessageObject: public JSObject {
3770 public:
3771 // [type]: the type of error message.
3772 inline int type() const;
3773 inline void set_type(int value);
3774
3775 // [arguments]: the arguments for formatting the error message.
3776 DECL_ACCESSORS(argument, Object)
3777
3778 // [script]: the script from which the error message originated.
3779 DECL_ACCESSORS(script, Object)
3780
3781 // [stack_frames]: an array of stack frames for this error object.
3782 DECL_ACCESSORS(stack_frames, Object)
3783
3784 // [start_position]: the start position in the script for the error message.
3785 inline int start_position() const;
3786 inline void set_start_position(int value);
3787
3788 // [end_position]: the end position in the script for the error message.
3789 inline int end_position() const;
3790 inline void set_end_position(int value);
3791
3792 // Returns the line number for the error message (1-based), or
3793 // Message::kNoLineNumberInfo if the line cannot be determined.
3794 int GetLineNumber() const;
3795
3796 // Returns the offset of the given position within the containing line.
3797 int GetColumnNumber() const;
3798
3799 // Returns the source code line containing the given source
3800 // position, or the empty string if the position is invalid.
3801 Handle<String> GetSourceLine() const;
3802
3803 inline int error_level() const;
3804 inline void set_error_level(int level);
3805
3806 DECL_CAST(JSMessageObject)
3807
3808 // Dispatched behavior.
3809 DECL_PRINTER(JSMessageObject)
3810 DECL_VERIFIER(JSMessageObject)
3811
3812 // Layout description.
3813 static const int kTypeOffset = JSObject::kHeaderSize;
3814 static const int kArgumentsOffset = kTypeOffset + kPointerSize;
3815 static const int kScriptOffset = kArgumentsOffset + kPointerSize;
3816 static const int kStackFramesOffset = kScriptOffset + kPointerSize;
3817 static const int kStartPositionOffset = kStackFramesOffset + kPointerSize;
3818 static const int kEndPositionOffset = kStartPositionOffset + kPointerSize;
3819 static const int kErrorLevelOffset = kEndPositionOffset + kPointerSize;
3820 static const int kSize = kErrorLevelOffset + kPointerSize;
3821
3822 typedef FixedBodyDescriptor<HeapObject::kMapOffset,
3823 kStackFramesOffset + kPointerSize,
3824 kSize> BodyDescriptor;
3825 // No weak fields.
3826 typedef BodyDescriptor BodyDescriptorWeak;
3827 };
3828
3829 class AllocationSite: public Struct {
3830 public:
3831 static const uint32_t kMaximumArrayBytesToPretransition = 8 * 1024;
3832 static const double kPretenureRatio;
3833 static const int kPretenureMinimumCreated = 100;
3834
3835 // Values for pretenure decision field.
3836 enum PretenureDecision {
3837 kUndecided = 0,
3838 kDontTenure = 1,
3839 kMaybeTenure = 2,
3840 kTenure = 3,
3841 kZombie = 4,
3842 kLastPretenureDecisionValue = kZombie
3843 };
3844
3845 const char* PretenureDecisionName(PretenureDecision decision);
3846
3847 // Contains either a Smi-encoded bitfield or a boilerplate. If it's a Smi the
3848 // AllocationSite is for a constructed Array.
3849 DECL_ACCESSORS(transition_info_or_boilerplate, Object)
3850 DECL_ACCESSORS(boilerplate, JSObject)
3851 DECL_INT_ACCESSORS(transition_info)
3852
3853 // nested_site threads a list of sites that represent nested literals
3854 // walked in a particular order. So [[1, 2], 1, 2] will have one
3855 // nested_site, but [[1, 2], 3, [4]] will have a list of two.
3856 DECL_ACCESSORS(nested_site, Object)
3857
3858 // Bitfield containing pretenuring information.
3859 DECL_INT_ACCESSORS(pretenure_data)
3860
3861 DECL_INT_ACCESSORS(pretenure_create_count)
3862 DECL_ACCESSORS(dependent_code, DependentCode)
3863
3864 // heap->allocation_site_list() points to the last AllocationSite which form
3865 // a linked list through the weak_next property. The GC might remove elements
3866 // from the list by updateing weak_next.
3867 DECL_ACCESSORS(weak_next, Object)
3868
3869 inline void Initialize();
3870
3871 // This method is expensive, it should only be called for reporting.
3872 bool IsNested();
3873
3874 // transition_info bitfields, for constructed array transition info.
3875 class ElementsKindBits: public BitField<ElementsKind, 0, 15> {};
3876 class UnusedBits: public BitField<int, 15, 14> {};
3877 class DoNotInlineBit: public BitField<bool, 29, 1> {};
3878
3879 // Bitfields for pretenure_data
3880 class MementoFoundCountBits: public BitField<int, 0, 26> {};
3881 class PretenureDecisionBits: public BitField<PretenureDecision, 26, 3> {};
3882 class DeoptDependentCodeBit: public BitField<bool, 29, 1> {};
3883 STATIC_ASSERT(PretenureDecisionBits::kMax >= kLastPretenureDecisionValue);
3884
3885 // Increments the mementos found counter and returns true when the first
3886 // memento was found for a given allocation site.
3887 inline bool IncrementMementoFoundCount(int increment = 1);
3888
3889 inline void IncrementMementoCreateCount();
3890
3891 PretenureFlag GetPretenureMode() const;
3892
3893 void ResetPretenureDecision();
3894
3895 inline PretenureDecision pretenure_decision() const;
3896 inline void set_pretenure_decision(PretenureDecision decision);
3897
3898 inline bool deopt_dependent_code() const;
3899 inline void set_deopt_dependent_code(bool deopt);
3900
3901 inline int memento_found_count() const;
3902 inline void set_memento_found_count(int count);
3903
3904 inline int memento_create_count() const;
3905 inline void set_memento_create_count(int count);
3906
3907 // The pretenuring decision is made during gc, and the zombie state allows
3908 // us to recognize when an allocation site is just being kept alive because
3909 // a later traversal of new space may discover AllocationMementos that point
3910 // to this AllocationSite.
3911 inline bool IsZombie() const;
3912
3913 inline bool IsMaybeTenure() const;
3914
3915 inline void MarkZombie();
3916
3917 inline bool MakePretenureDecision(PretenureDecision current_decision,
3918 double ratio,
3919 bool maximum_size_scavenge);
3920
3921 inline bool DigestPretenuringFeedback(bool maximum_size_scavenge);
3922
3923 inline ElementsKind GetElementsKind() const;
3924 inline void SetElementsKind(ElementsKind kind);
3925
3926 inline bool CanInlineCall() const;
3927 inline void SetDoNotInlineCall();
3928
3929 inline bool PointsToLiteral() const;
3930
3931 template <AllocationSiteUpdateMode update_or_check =
3932 AllocationSiteUpdateMode::kUpdate>
3933 static bool DigestTransitionFeedback(Handle<AllocationSite> site,
3934 ElementsKind to_kind);
3935
3936 DECL_PRINTER(AllocationSite)
3937 DECL_VERIFIER(AllocationSite)
3938
3939 DECL_CAST(AllocationSite)
3940 static inline bool ShouldTrack(ElementsKind boilerplate_elements_kind);
3941 static bool ShouldTrack(ElementsKind from, ElementsKind to);
3942 static inline bool CanTrack(InstanceType type);
3943
3944 static const int kTransitionInfoOrBoilerplateOffset = HeapObject::kHeaderSize;
3945 static const int kNestedSiteOffset =
3946 kTransitionInfoOrBoilerplateOffset + kPointerSize;
3947 static const int kPretenureDataOffset = kNestedSiteOffset + kPointerSize;
3948 static const int kPretenureCreateCountOffset =
3949 kPretenureDataOffset + kPointerSize;
3950 static const int kDependentCodeOffset =
3951 kPretenureCreateCountOffset + kPointerSize;
3952 static const int kWeakNextOffset = kDependentCodeOffset + kPointerSize;
3953 static const int kSize = kWeakNextOffset + kPointerSize;
3954
3955 // During mark compact we need to take special care for the dependent code
3956 // field.
3957 static const int kPointerFieldsBeginOffset =
3958 kTransitionInfoOrBoilerplateOffset;
3959 static const int kPointerFieldsEndOffset = kWeakNextOffset;
3960
3961 // Ignores weakness.
3962 typedef FixedBodyDescriptor<HeapObject::kHeaderSize, kSize, kSize>
3963 BodyDescriptor;
3964
3965 // Respects weakness.
3966 typedef FixedBodyDescriptor<kPointerFieldsBeginOffset,
3967 kPointerFieldsEndOffset, kSize>
3968 BodyDescriptorWeak;
3969
3970 private:
3971 inline bool PretenuringDecisionMade() const;
3972
3973 DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationSite);
3974 };
3975
3976
3977 class AllocationMemento: public Struct {
3978 public:
3979 static const int kAllocationSiteOffset = HeapObject::kHeaderSize;
3980 static const int kSize = kAllocationSiteOffset + kPointerSize;
3981
3982 DECL_ACCESSORS(allocation_site, Object)
3983
3984 inline bool IsValid() const;
3985 inline AllocationSite* GetAllocationSite() const;
3986 inline Address GetAllocationSiteUnchecked() const;
3987
3988 DECL_PRINTER(AllocationMemento)
3989 DECL_VERIFIER(AllocationMemento)
3990
3991 DECL_CAST(AllocationMemento)
3992
3993 private:
3994 DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationMemento);
3995 };
3996
3997
3998 // Utility superclass for stack-allocated objects that must be updated
3999 // on gc. It provides two ways for the gc to update instances, either
4000 // iterating or updating after gc.
4001 class Relocatable BASE_EMBEDDED {
4002 public:
4003 explicit inline Relocatable(Isolate* isolate);
4004 inline virtual ~Relocatable();
IterateInstance(RootVisitor * v)4005 virtual void IterateInstance(RootVisitor* v) {}
PostGarbageCollection()4006 virtual void PostGarbageCollection() { }
4007
4008 static void PostGarbageCollectionProcessing(Isolate* isolate);
4009 static int ArchiveSpacePerThread();
4010 static char* ArchiveState(Isolate* isolate, char* to);
4011 static char* RestoreState(Isolate* isolate, char* from);
4012 static void Iterate(Isolate* isolate, RootVisitor* v);
4013 static void Iterate(RootVisitor* v, Relocatable* top);
4014 static char* Iterate(RootVisitor* v, char* t);
4015
4016 private:
4017 Isolate* isolate_;
4018 Relocatable* prev_;
4019 };
4020
4021
4022 // The Oddball describes objects null, undefined, true, and false.
4023 class Oddball: public HeapObject {
4024 public:
4025 // [to_number_raw]: Cached raw to_number computed at startup.
4026 inline double to_number_raw() const;
4027 inline void set_to_number_raw(double value);
4028 inline void set_to_number_raw_as_bits(uint64_t bits);
4029
4030 // [to_string]: Cached to_string computed at startup.
4031 DECL_ACCESSORS(to_string, String)
4032
4033 // [to_number]: Cached to_number computed at startup.
4034 DECL_ACCESSORS(to_number, Object)
4035
4036 // [typeof]: Cached type_of computed at startup.
4037 DECL_ACCESSORS(type_of, String)
4038
4039 inline byte kind() const;
4040 inline void set_kind(byte kind);
4041
4042 // ES6 section 7.1.3 ToNumber for Boolean, Null, Undefined.
4043 V8_WARN_UNUSED_RESULT static inline Handle<Object> ToNumber(
4044 Handle<Oddball> input);
4045
4046 DECL_CAST(Oddball)
4047
4048 // Dispatched behavior.
4049 DECL_VERIFIER(Oddball)
4050
4051 // Initialize the fields.
4052 static void Initialize(Isolate* isolate, Handle<Oddball> oddball,
4053 const char* to_string, Handle<Object> to_number,
4054 const char* type_of, byte kind);
4055
4056 // Layout description.
4057 static const int kToNumberRawOffset = HeapObject::kHeaderSize;
4058 static const int kToStringOffset = kToNumberRawOffset + kDoubleSize;
4059 static const int kToNumberOffset = kToStringOffset + kPointerSize;
4060 static const int kTypeOfOffset = kToNumberOffset + kPointerSize;
4061 static const int kKindOffset = kTypeOfOffset + kPointerSize;
4062 static const int kSize = kKindOffset + kPointerSize;
4063
4064 static const byte kFalse = 0;
4065 static const byte kTrue = 1;
4066 static const byte kNotBooleanMask = static_cast<byte>(~1);
4067 static const byte kTheHole = 2;
4068 static const byte kNull = 3;
4069 static const byte kArgumentsMarker = 4;
4070 static const byte kUndefined = 5;
4071 static const byte kUninitialized = 6;
4072 static const byte kOther = 7;
4073 static const byte kException = 8;
4074 static const byte kOptimizedOut = 9;
4075 static const byte kStaleRegister = 10;
4076 static const byte kSelfReferenceMarker = 10;
4077
4078 typedef FixedBodyDescriptor<kToStringOffset, kTypeOfOffset + kPointerSize,
4079 kSize> BodyDescriptor;
4080 // No weak fields.
4081 typedef BodyDescriptor BodyDescriptorWeak;
4082
4083 STATIC_ASSERT(kToNumberRawOffset == HeapNumber::kValueOffset);
4084 STATIC_ASSERT(kKindOffset == Internals::kOddballKindOffset);
4085 STATIC_ASSERT(kNull == Internals::kNullOddballKind);
4086 STATIC_ASSERT(kUndefined == Internals::kUndefinedOddballKind);
4087
4088 private:
4089 DISALLOW_IMPLICIT_CONSTRUCTORS(Oddball);
4090 };
4091
4092
4093 class Cell: public HeapObject {
4094 public:
4095 // [value]: value of the cell.
DECL_ACCESSORS(value,Object)4096 DECL_ACCESSORS(value, Object)
4097
4098 DECL_CAST(Cell)
4099
4100 static inline Cell* FromValueAddress(Address value) {
4101 Object* result = FromAddress(value - kValueOffset);
4102 return static_cast<Cell*>(result);
4103 }
4104
ValueAddress()4105 inline Address ValueAddress() {
4106 return address() + kValueOffset;
4107 }
4108
4109 // Dispatched behavior.
4110 DECL_PRINTER(Cell)
4111 DECL_VERIFIER(Cell)
4112
4113 // Layout description.
4114 static const int kValueOffset = HeapObject::kHeaderSize;
4115 static const int kSize = kValueOffset + kPointerSize;
4116
4117 typedef FixedBodyDescriptor<kValueOffset,
4118 kValueOffset + kPointerSize,
4119 kSize> BodyDescriptor;
4120 // No weak fields.
4121 typedef BodyDescriptor BodyDescriptorWeak;
4122
4123 private:
4124 DISALLOW_IMPLICIT_CONSTRUCTORS(Cell);
4125 };
4126
4127 // This is a special cell used to maintain both the link between a
4128 // closure and it's feedback vector, as well as a way to count the
4129 // number of closures created for a certain function per native
4130 // context. There's at most one FeedbackCell for each function in
4131 // a native context.
4132 class FeedbackCell : public Struct {
4133 public:
4134 // [value]: value of the cell.
4135 DECL_ACCESSORS(value, HeapObject)
4136
4137 DECL_CAST(FeedbackCell)
4138
4139 // Dispatched behavior.
4140 DECL_PRINTER(FeedbackCell)
4141 DECL_VERIFIER(FeedbackCell)
4142
4143 static const int kValueOffset = HeapObject::kHeaderSize;
4144 static const int kSize = kValueOffset + kPointerSize;
4145
4146 typedef FixedBodyDescriptor<kValueOffset, kValueOffset + kPointerSize, kSize>
4147 BodyDescriptor;
4148 // No weak fields.
4149 typedef BodyDescriptor BodyDescriptorWeak;
4150
4151 private:
4152 DISALLOW_IMPLICIT_CONSTRUCTORS(FeedbackCell);
4153 };
4154
4155 class PropertyCell : public HeapObject {
4156 public:
4157 // [name]: the name of the global property.
4158 DECL_ACCESSORS(name, Name)
4159 // [property_details]: details of the global property.
4160 DECL_ACCESSORS(property_details_raw, Object)
4161 // [value]: value of the global property.
4162 DECL_ACCESSORS(value, Object)
4163 // [dependent_code]: dependent code that depends on the type of the global
4164 // property.
4165 DECL_ACCESSORS(dependent_code, DependentCode)
4166
4167 inline PropertyDetails property_details();
4168 inline void set_property_details(PropertyDetails details);
4169
4170 PropertyCellConstantType GetConstantType();
4171
4172 // Computes the new type of the cell's contents for the given value, but
4173 // without actually modifying the details.
4174 static PropertyCellType UpdatedType(Handle<PropertyCell> cell,
4175 Handle<Object> value,
4176 PropertyDetails details);
4177 // Prepares property cell at given entry for receiving given value.
4178 // As a result the old cell could be invalidated and/or dependent code could
4179 // be deoptimized. Returns the prepared property cell.
4180 static Handle<PropertyCell> PrepareForValue(
4181 Handle<GlobalDictionary> dictionary, int entry, Handle<Object> value,
4182 PropertyDetails details);
4183
4184 static Handle<PropertyCell> InvalidateEntry(
4185 Handle<GlobalDictionary> dictionary, int entry);
4186
4187 static void SetValueWithInvalidation(Handle<PropertyCell> cell,
4188 Handle<Object> new_value);
4189
4190 DECL_CAST(PropertyCell)
4191
4192 // Dispatched behavior.
4193 DECL_PRINTER(PropertyCell)
4194 DECL_VERIFIER(PropertyCell)
4195
4196 // Layout description.
4197 static const int kDetailsOffset = HeapObject::kHeaderSize;
4198 static const int kNameOffset = kDetailsOffset + kPointerSize;
4199 static const int kValueOffset = kNameOffset + kPointerSize;
4200 static const int kDependentCodeOffset = kValueOffset + kPointerSize;
4201 static const int kSize = kDependentCodeOffset + kPointerSize;
4202
4203 typedef FixedBodyDescriptor<kNameOffset, kSize, kSize> BodyDescriptor;
4204 // No weak fields.
4205 typedef BodyDescriptor BodyDescriptorWeak;
4206
4207 private:
4208 DISALLOW_IMPLICIT_CONSTRUCTORS(PropertyCell);
4209 };
4210
4211
4212 class WeakCell : public HeapObject {
4213 public:
4214 inline Object* value() const;
4215
4216 // This should not be called by anyone except GC.
4217 inline void clear();
4218
4219 // This should not be called by anyone except allocator.
4220 inline void initialize(HeapObject* value);
4221
4222 inline bool cleared() const;
4223
4224 DECL_CAST(WeakCell)
4225
4226 DECL_PRINTER(WeakCell)
4227 DECL_VERIFIER(WeakCell)
4228
4229 // Layout description.
4230 static const int kValueOffset = HeapObject::kHeaderSize;
4231 static const int kSize = kValueOffset + kPointerSize;
4232
4233 typedef FixedBodyDescriptor<kValueOffset, kSize, kSize> BodyDescriptor;
4234
4235 private:
4236 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakCell);
4237 };
4238
4239
4240 // The JSProxy describes EcmaScript Harmony proxies
4241 class JSProxy: public JSReceiver {
4242 public:
4243 V8_WARN_UNUSED_RESULT static MaybeHandle<JSProxy> New(Isolate* isolate,
4244 Handle<Object>,
4245 Handle<Object>);
4246
4247 // [handler]: The handler property.
4248 DECL_ACCESSORS(handler, Object)
4249 // [target]: The target property.
4250 DECL_ACCESSORS(target, Object)
4251
4252 static MaybeHandle<Context> GetFunctionRealm(Handle<JSProxy> proxy);
4253
4254 DECL_CAST(JSProxy)
4255
4256 INLINE(bool IsRevoked() const);
4257 static void Revoke(Handle<JSProxy> proxy);
4258
4259 // ES6 9.5.1
4260 static MaybeHandle<Object> GetPrototype(Handle<JSProxy> receiver);
4261
4262 // ES6 9.5.2
4263 V8_WARN_UNUSED_RESULT static Maybe<bool> SetPrototype(
4264 Handle<JSProxy> proxy, Handle<Object> value, bool from_javascript,
4265 ShouldThrow should_throw);
4266 // ES6 9.5.3
4267 V8_WARN_UNUSED_RESULT static Maybe<bool> IsExtensible(Handle<JSProxy> proxy);
4268
4269 // ES6, #sec-isarray. NOT to be confused with %_IsArray.
4270 V8_WARN_UNUSED_RESULT static Maybe<bool> IsArray(Handle<JSProxy> proxy);
4271
4272 // ES6 9.5.4 (when passed kDontThrow)
4273 V8_WARN_UNUSED_RESULT static Maybe<bool> PreventExtensions(
4274 Handle<JSProxy> proxy, ShouldThrow should_throw);
4275
4276 // ES6 9.5.5
4277 V8_WARN_UNUSED_RESULT static Maybe<bool> GetOwnPropertyDescriptor(
4278 Isolate* isolate, Handle<JSProxy> proxy, Handle<Name> name,
4279 PropertyDescriptor* desc);
4280
4281 // ES6 9.5.6
4282 V8_WARN_UNUSED_RESULT static Maybe<bool> DefineOwnProperty(
4283 Isolate* isolate, Handle<JSProxy> object, Handle<Object> key,
4284 PropertyDescriptor* desc, ShouldThrow should_throw);
4285
4286 // ES6 9.5.7
4287 V8_WARN_UNUSED_RESULT static Maybe<bool> HasProperty(Isolate* isolate,
4288 Handle<JSProxy> proxy,
4289 Handle<Name> name);
4290
4291 // This function never returns false.
4292 // It returns either true or throws.
4293 V8_WARN_UNUSED_RESULT static Maybe<bool> CheckHasTrap(
4294 Isolate* isolate, Handle<Name> name, Handle<JSReceiver> target);
4295
4296 // ES6 9.5.8
4297 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> GetProperty(
4298 Isolate* isolate, Handle<JSProxy> proxy, Handle<Name> name,
4299 Handle<Object> receiver, bool* was_found);
4300
4301 enum AccessKind { kGet, kSet };
4302
4303 static MaybeHandle<Object> CheckGetSetTrapResult(Isolate* isolate,
4304 Handle<Name> name,
4305 Handle<JSReceiver> target,
4306 Handle<Object> trap_result,
4307 AccessKind access_kind);
4308
4309 // ES6 9.5.9
4310 V8_WARN_UNUSED_RESULT static Maybe<bool> SetProperty(
4311 Handle<JSProxy> proxy, Handle<Name> name, Handle<Object> value,
4312 Handle<Object> receiver, LanguageMode language_mode);
4313
4314 // ES6 9.5.10 (when passed LanguageMode::kSloppy)
4315 V8_WARN_UNUSED_RESULT static Maybe<bool> DeletePropertyOrElement(
4316 Handle<JSProxy> proxy, Handle<Name> name, LanguageMode language_mode);
4317
4318 // ES6 9.5.12
4319 V8_WARN_UNUSED_RESULT static Maybe<bool> OwnPropertyKeys(
4320 Isolate* isolate, Handle<JSReceiver> receiver, Handle<JSProxy> proxy,
4321 PropertyFilter filter, KeyAccumulator* accumulator);
4322
4323 V8_WARN_UNUSED_RESULT static Maybe<PropertyAttributes> GetPropertyAttributes(
4324 LookupIterator* it);
4325
4326 // Dispatched behavior.
4327 DECL_PRINTER(JSProxy)
4328 DECL_VERIFIER(JSProxy)
4329
4330 static const int kMaxIterationLimit = 100 * 1024;
4331
4332 // Layout description.
4333 static const int kTargetOffset = JSReceiver::kHeaderSize;
4334 static const int kHandlerOffset = kTargetOffset + kPointerSize;
4335 static const int kSize = kHandlerOffset + kPointerSize;
4336
4337 // kTargetOffset aliases with the elements of JSObject. The fact that
4338 // JSProxy::target is a Javascript value which cannot be confused with an
4339 // elements backing store is exploited by loading from this offset from an
4340 // unknown JSReceiver.
4341 STATIC_ASSERT(JSObject::kElementsOffset == JSProxy::kTargetOffset);
4342
4343 typedef FixedBodyDescriptor<JSReceiver::kPropertiesOrHashOffset, kSize, kSize>
4344 BodyDescriptor;
4345 // No weak fields.
4346 typedef BodyDescriptor BodyDescriptorWeak;
4347
4348 static Maybe<bool> SetPrivateSymbol(Isolate* isolate, Handle<JSProxy> proxy,
4349 Handle<Symbol> private_name,
4350 PropertyDescriptor* desc,
4351 ShouldThrow should_throw);
4352
4353 private:
4354 DISALLOW_IMPLICIT_CONSTRUCTORS(JSProxy);
4355 };
4356
4357 // JSProxyRevocableResult is just a JSObject with a specific initial map.
4358 // This initial map adds in-object properties for "proxy" and "revoke".
4359 // See https://tc39.github.io/ecma262/#sec-proxy.revocable
4360 class JSProxyRevocableResult : public JSObject {
4361 public:
4362 // Offsets of object fields.
4363 static const int kProxyOffset = JSObject::kHeaderSize;
4364 static const int kRevokeOffset = kProxyOffset + kPointerSize;
4365 static const int kSize = kRevokeOffset + kPointerSize;
4366 // Indices of in-object properties.
4367 static const int kProxyIndex = 0;
4368 static const int kRevokeIndex = 1;
4369
4370 private:
4371 DISALLOW_IMPLICIT_CONSTRUCTORS(JSProxyRevocableResult);
4372 };
4373
4374 // The [Async-from-Sync Iterator] object
4375 // (proposal-async-iteration/#sec-async-from-sync-iterator-objects)
4376 // An object which wraps an ordinary Iterator and converts it to behave
4377 // according to the Async Iterator protocol.
4378 // (See https://tc39.github.io/proposal-async-iteration/#sec-iteration)
4379 class JSAsyncFromSyncIterator : public JSObject {
4380 public:
4381 DECL_CAST(JSAsyncFromSyncIterator)
4382 DECL_PRINTER(JSAsyncFromSyncIterator)
4383 DECL_VERIFIER(JSAsyncFromSyncIterator)
4384
4385 // Async-from-Sync Iterator instances are ordinary objects that inherit
4386 // properties from the %AsyncFromSyncIteratorPrototype% intrinsic object.
4387 // Async-from-Sync Iterator instances are initially created with the internal
4388 // slots listed in Table 4.
4389 // (proposal-async-iteration/#table-async-from-sync-iterator-internal-slots)
4390 DECL_ACCESSORS(sync_iterator, JSReceiver)
4391
4392 // The "next" method is loaded during GetIterator, and is not reloaded for
4393 // subsequent "next" invocations.
4394 DECL_ACCESSORS(next, Object)
4395
4396 // Offsets of object fields.
4397 static const int kSyncIteratorOffset = JSObject::kHeaderSize;
4398 static const int kNextOffset = kSyncIteratorOffset + kPointerSize;
4399 static const int kSize = kNextOffset + kPointerSize;
4400
4401 private:
4402 DISALLOW_IMPLICIT_CONSTRUCTORS(JSAsyncFromSyncIterator);
4403 };
4404
4405 class JSStringIterator : public JSObject {
4406 public:
4407 // Dispatched behavior.
4408 DECL_PRINTER(JSStringIterator)
4409 DECL_VERIFIER(JSStringIterator)
4410
4411 DECL_CAST(JSStringIterator)
4412
4413 // [string]: the [[IteratedString]] inobject property.
4414 DECL_ACCESSORS(string, String)
4415
4416 // [index]: The [[StringIteratorNextIndex]] inobject property.
4417 inline int index() const;
4418 inline void set_index(int value);
4419
4420 static const int kStringOffset = JSObject::kHeaderSize;
4421 static const int kNextIndexOffset = kStringOffset + kPointerSize;
4422 static const int kSize = kNextIndexOffset + kPointerSize;
4423
4424 private:
4425 DISALLOW_IMPLICIT_CONSTRUCTORS(JSStringIterator);
4426 };
4427
4428 // Foreign describes objects pointing from JavaScript to C structures.
4429 class Foreign: public HeapObject {
4430 public:
4431 // [address]: field containing the address.
4432 inline Address foreign_address();
4433
4434 static inline bool IsNormalized(Object* object);
4435
4436 DECL_CAST(Foreign)
4437
4438 // Dispatched behavior.
4439 DECL_PRINTER(Foreign)
4440 DECL_VERIFIER(Foreign)
4441
4442 // Layout description.
4443
4444 static const int kForeignAddressOffset = HeapObject::kHeaderSize;
4445 static const int kSize = kForeignAddressOffset + kPointerSize;
4446
4447 STATIC_ASSERT(kForeignAddressOffset == Internals::kForeignAddressOffset);
4448
4449 class BodyDescriptor;
4450 // No weak fields.
4451 typedef BodyDescriptor BodyDescriptorWeak;
4452
4453 private:
4454 friend class Factory;
4455 friend class SerializerDeserializer;
4456 friend class StartupSerializer;
4457
4458 inline void set_foreign_address(Address value);
4459
4460 DISALLOW_IMPLICIT_CONSTRUCTORS(Foreign);
4461 };
4462
4463 // Support for JavaScript accessors: A pair of a getter and a setter. Each
4464 // accessor can either be
4465 // * a JavaScript function or proxy: a real accessor
4466 // * a FunctionTemplateInfo: a real (lazy) accessor
4467 // * undefined: considered an accessor by the spec, too, strangely enough
4468 // * null: an accessor which has not been set
4469 class AccessorPair: public Struct {
4470 public:
4471 DECL_ACCESSORS(getter, Object)
4472 DECL_ACCESSORS(setter, Object)
4473
4474 DECL_CAST(AccessorPair)
4475
4476 static Handle<AccessorPair> Copy(Handle<AccessorPair> pair);
4477
4478 inline Object* get(AccessorComponent component);
4479 inline void set(AccessorComponent component, Object* value);
4480
4481 // Note: Returns undefined if the component is not set.
4482 static Handle<Object> GetComponent(Handle<AccessorPair> accessor_pair,
4483 AccessorComponent component);
4484
4485 // Set both components, skipping arguments which are a JavaScript null.
4486 inline void SetComponents(Object* getter, Object* setter);
4487
4488 inline bool Equals(AccessorPair* pair);
4489 inline bool Equals(Object* getter_value, Object* setter_value);
4490
4491 inline bool ContainsAccessor();
4492
4493 // Dispatched behavior.
4494 DECL_PRINTER(AccessorPair)
4495 DECL_VERIFIER(AccessorPair)
4496
4497 static const int kGetterOffset = HeapObject::kHeaderSize;
4498 static const int kSetterOffset = kGetterOffset + kPointerSize;
4499 static const int kSize = kSetterOffset + kPointerSize;
4500
4501 private:
4502 // Strangely enough, in addition to functions and harmony proxies, the spec
4503 // requires us to consider undefined as a kind of accessor, too:
4504 // var obj = {};
4505 // Object.defineProperty(obj, "foo", {get: undefined});
4506 // assertTrue("foo" in obj);
4507 inline bool IsJSAccessor(Object* obj);
4508
4509 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorPair);
4510 };
4511
4512 class StackFrameInfo : public Struct {
4513 public:
4514 DECL_INT_ACCESSORS(line_number)
4515 DECL_INT_ACCESSORS(column_number)
4516 DECL_INT_ACCESSORS(script_id)
4517 DECL_ACCESSORS(script_name, Object)
4518 DECL_ACCESSORS(script_name_or_source_url, Object)
4519 DECL_ACCESSORS(function_name, Object)
4520 DECL_BOOLEAN_ACCESSORS(is_eval)
4521 DECL_BOOLEAN_ACCESSORS(is_constructor)
4522 DECL_BOOLEAN_ACCESSORS(is_wasm)
4523 DECL_INT_ACCESSORS(flag)
4524 DECL_INT_ACCESSORS(id)
4525
4526 DECL_CAST(StackFrameInfo)
4527
4528 // Dispatched behavior.
4529 DECL_PRINTER(StackFrameInfo)
4530 DECL_VERIFIER(StackFrameInfo)
4531
4532 static const int kLineNumberIndex = Struct::kHeaderSize;
4533 static const int kColumnNumberIndex = kLineNumberIndex + kPointerSize;
4534 static const int kScriptIdIndex = kColumnNumberIndex + kPointerSize;
4535 static const int kScriptNameIndex = kScriptIdIndex + kPointerSize;
4536 static const int kScriptNameOrSourceUrlIndex =
4537 kScriptNameIndex + kPointerSize;
4538 static const int kFunctionNameIndex =
4539 kScriptNameOrSourceUrlIndex + kPointerSize;
4540 static const int kFlagIndex = kFunctionNameIndex + kPointerSize;
4541 static const int kIdIndex = kFlagIndex + kPointerSize;
4542 static const int kSize = kIdIndex + kPointerSize;
4543
4544 private:
4545 // Bit position in the flag, from least significant bit position.
4546 static const int kIsEvalBit = 0;
4547 static const int kIsConstructorBit = 1;
4548 static const int kIsWasmBit = 2;
4549
4550 DISALLOW_IMPLICIT_CONSTRUCTORS(StackFrameInfo);
4551 };
4552
4553 class SourcePositionTableWithFrameCache : public Tuple2 {
4554 public:
4555 DECL_ACCESSORS(source_position_table, ByteArray)
4556 DECL_ACCESSORS(stack_frame_cache, SimpleNumberDictionary)
4557
4558 DECL_CAST(SourcePositionTableWithFrameCache)
4559
4560 static const int kSourcePositionTableIndex = Struct::kHeaderSize;
4561 static const int kStackFrameCacheIndex =
4562 kSourcePositionTableIndex + kPointerSize;
4563 static const int kSize = kStackFrameCacheIndex + kPointerSize;
4564
4565 private:
4566 DISALLOW_IMPLICIT_CONSTRUCTORS(SourcePositionTableWithFrameCache);
4567 };
4568
4569 // BooleanBit is a helper class for setting and getting a bit in an integer.
4570 class BooleanBit : public AllStatic {
4571 public:
get(int value,int bit_position)4572 static inline bool get(int value, int bit_position) {
4573 return (value & (1 << bit_position)) != 0;
4574 }
4575
set(int value,int bit_position,bool v)4576 static inline int set(int value, int bit_position, bool v) {
4577 if (v) {
4578 value |= (1 << bit_position);
4579 } else {
4580 value &= ~(1 << bit_position);
4581 }
4582 return value;
4583 }
4584 };
4585
4586
4587 } // NOLINT, false-positive due to second-order macros.
4588 } // NOLINT, false-positive due to second-order macros.
4589
4590 #include "src/objects/object-macros-undef.h"
4591
4592 #endif // V8_OBJECTS_H_
4593