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