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