1 // Copyright 2018 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_JS_OBJECTS_H_ 6 #define V8_OBJECTS_JS_OBJECTS_H_ 7 8 #include "src/objects/embedder-data-slot.h" 9 // TODO(jkummerow): Consider forward-declaring instead. 10 #include "src/objects/internal-index.h" 11 #include "src/objects/objects.h" 12 #include "src/objects/property-array.h" 13 14 // Has to be the last include (doesn't have include guards): 15 #include "src/objects/object-macros.h" 16 17 namespace v8 { 18 namespace internal { 19 20 // Enum for functions that offer a second mode that does not cause allocations. 21 // Used in conjunction with LookupIterator and unboxed double fields. 22 enum class AllocationPolicy { kAllocationAllowed, kAllocationDisallowed }; 23 24 enum InstanceType : uint16_t; 25 class JSGlobalObject; 26 class JSGlobalProxy; 27 class LookupIterator; 28 class PropertyKey; 29 class NativeContext; 30 class IsCompiledScope; 31 32 #include "torque-generated/src/objects/js-objects-tq.inc" 33 34 // JSReceiver includes types on which properties can be defined, i.e., 35 // JSObject and JSProxy. 36 class JSReceiver : public TorqueGeneratedJSReceiver<JSReceiver, HeapObject> { 37 public: 38 NEVER_READ_ONLY_SPACE 39 // Returns true if there is no slow (ie, dictionary) backing store. 40 DECL_GETTER(HasFastProperties, bool) 41 42 // Returns the properties array backing store if it 43 // exists. Otherwise, returns an empty_property_array when there's a 44 // Smi (hash code) or an empty_fixed_array for a fast properties 45 // map. 46 DECL_GETTER(property_array, PropertyArray) 47 48 // Gets slow properties for non-global objects (if 49 // v8_enable_swiss_name_dictionary is not set). 50 DECL_GETTER(property_dictionary, NameDictionary) 51 52 // Gets slow properties for non-global objects (if 53 // v8_enable_swiss_name_dictionary is set). 54 DECL_GETTER(property_dictionary_swiss, SwissNameDictionary) 55 56 // Sets the properties backing store and makes sure any existing hash is moved 57 // to the new properties store. To clear out the properties store, pass in the 58 // empty_fixed_array(), the hash will be maintained in this case as well. 59 void SetProperties(HeapObject properties); 60 61 // There are five possible values for the properties offset. 62 // 1) EmptyFixedArray/EmptyPropertyDictionary - This is the standard 63 // placeholder. 64 // 65 // 2) Smi - This is the hash code of the object. 66 // 67 // 3) PropertyArray - This is similar to a FixedArray but stores 68 // the hash code of the object in its length field. This is a fast 69 // backing store. 70 // 71 // 4) NameDictionary - This is the dictionary-mode backing store. 72 // 73 // 4) GlobalDictionary - This is the backing store for the 74 // GlobalObject. 75 // 76 // This is used only in the deoptimizer and heap. Please use the 77 // above typed getters and setters to access the properties. 78 DECL_ACCESSORS(raw_properties_or_hash, Object) 79 DECL_RELAXED_ACCESSORS(raw_properties_or_hash, Object) 80 81 inline void initialize_properties(Isolate* isolate); 82 83 // Deletes an existing named property in a normalized object. 84 static void DeleteNormalizedProperty(Handle<JSReceiver> object, 85 InternalIndex entry); 86 87 // ES6 section 7.1.1 ToPrimitive 88 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> ToPrimitive( 89 Isolate* isolate, Handle<JSReceiver> receiver, 90 ToPrimitiveHint hint = ToPrimitiveHint::kDefault); 91 92 // ES6 section 7.1.1.1 OrdinaryToPrimitive 93 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> OrdinaryToPrimitive( 94 Isolate* isolate, Handle<JSReceiver> receiver, 95 OrdinaryToPrimitiveHint hint); 96 97 static MaybeHandle<NativeContext> GetFunctionRealm( 98 Handle<JSReceiver> receiver); 99 V8_EXPORT_PRIVATE static MaybeHandle<NativeContext> GetContextForMicrotask( 100 Handle<JSReceiver> receiver); 101 102 // Get the first non-hidden prototype. 103 static inline MaybeHandle<HeapObject> GetPrototype( 104 Isolate* isolate, Handle<JSReceiver> receiver); 105 106 V8_WARN_UNUSED_RESULT static Maybe<bool> HasInPrototypeChain( 107 Isolate* isolate, Handle<JSReceiver> object, Handle<Object> proto); 108 109 // Reads all enumerable own properties of source and adds them to 110 // target, using either Set or CreateDataProperty depending on the 111 // use_set argument. This only copies values not present in the 112 // maybe_excluded_properties list. 113 V8_WARN_UNUSED_RESULT static Maybe<bool> SetOrCopyDataProperties( 114 Isolate* isolate, Handle<JSReceiver> target, Handle<Object> source, 115 PropertiesEnumerationMode mode, 116 const base::ScopedVector<Handle<Object>>* excluded_properties = nullptr, 117 bool use_set = true); 118 119 // Implementation of [[HasProperty]], ECMA-262 5th edition, section 8.12.6. 120 V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<bool> HasProperty( 121 LookupIterator* it); 122 V8_WARN_UNUSED_RESULT static inline Maybe<bool> HasProperty( 123 Isolate* isolate, Handle<JSReceiver> object, Handle<Name> name); 124 V8_WARN_UNUSED_RESULT static inline Maybe<bool> HasElement( 125 Isolate* isolate, Handle<JSReceiver> object, uint32_t index); 126 127 V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<bool> HasOwnProperty( 128 Isolate* isolate, Handle<JSReceiver> object, Handle<Name> name); 129 V8_WARN_UNUSED_RESULT static inline Maybe<bool> HasOwnProperty( 130 Isolate* isolate, Handle<JSReceiver> object, uint32_t index); 131 132 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> GetProperty( 133 Isolate* isolate, Handle<JSReceiver> receiver, const char* key); 134 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> GetProperty( 135 Isolate* isolate, Handle<JSReceiver> receiver, Handle<Name> name); 136 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> GetElement( 137 Isolate* isolate, Handle<JSReceiver> receiver, uint32_t index); 138 139 // Implementation of ES6 [[Delete]] 140 V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<bool> 141 DeletePropertyOrElement(Handle<JSReceiver> object, Handle<Name> name, 142 LanguageMode language_mode = LanguageMode::kSloppy); 143 V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<bool> DeleteProperty( 144 Handle<JSReceiver> object, Handle<Name> name, 145 LanguageMode language_mode = LanguageMode::kSloppy); 146 V8_WARN_UNUSED_RESULT static Maybe<bool> DeleteProperty( 147 LookupIterator* it, LanguageMode language_mode); 148 V8_WARN_UNUSED_RESULT static Maybe<bool> DeleteElement( 149 Handle<JSReceiver> object, uint32_t index, 150 LanguageMode language_mode = LanguageMode::kSloppy); 151 152 V8_WARN_UNUSED_RESULT static Object DefineProperty(Isolate* isolate, 153 Handle<Object> object, 154 Handle<Object> name, 155 Handle<Object> attributes); 156 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> DefineProperties( 157 Isolate* isolate, Handle<Object> object, Handle<Object> properties); 158 159 // "virtual" dispatcher to the correct [[DefineOwnProperty]] implementation. 160 V8_WARN_UNUSED_RESULT static Maybe<bool> DefineOwnProperty( 161 Isolate* isolate, Handle<JSReceiver> object, Handle<Object> key, 162 PropertyDescriptor* desc, Maybe<ShouldThrow> should_throw); 163 164 // Check if private name property can be store on the object. It will return 165 // false with an error when it cannot. 166 V8_WARN_UNUSED_RESULT static bool CheckPrivateNameStore(LookupIterator* it, 167 bool is_define); 168 169 // Check if a data property can be created on the object. It will fail with 170 // an error when it cannot. 171 V8_WARN_UNUSED_RESULT static Maybe<bool> CheckIfCanDefine( 172 Isolate* isolate, LookupIterator* it, Handle<Object> value, 173 Maybe<ShouldThrow> should_throw); 174 175 // ES6 7.3.4 (when passed kDontThrow) 176 V8_WARN_UNUSED_RESULT static Maybe<bool> CreateDataProperty( 177 Isolate* isolate, Handle<JSReceiver> object, Handle<Name> key, 178 Handle<Object> value, Maybe<ShouldThrow> should_throw); 179 V8_WARN_UNUSED_RESULT static Maybe<bool> CreateDataProperty( 180 LookupIterator* it, Handle<Object> value, 181 Maybe<ShouldThrow> should_throw); 182 183 // Add private fields to the receiver, ignoring extensibility and the 184 // traps. The caller should check that the private field does not already 185 // exist on the receiver before calling this method. 186 V8_WARN_UNUSED_RESULT static Maybe<bool> AddPrivateField( 187 LookupIterator* it, Handle<Object> value, 188 Maybe<ShouldThrow> should_throw); 189 190 // ES6 9.1.6.1 191 V8_WARN_UNUSED_RESULT static Maybe<bool> OrdinaryDefineOwnProperty( 192 Isolate* isolate, Handle<JSObject> object, Handle<Object> key, 193 PropertyDescriptor* desc, Maybe<ShouldThrow> should_throw); 194 V8_WARN_UNUSED_RESULT static Maybe<bool> OrdinaryDefineOwnProperty( 195 Isolate* isolate, Handle<JSObject> object, const PropertyKey& key, 196 PropertyDescriptor* desc, Maybe<ShouldThrow> should_throw); 197 V8_WARN_UNUSED_RESULT static Maybe<bool> OrdinaryDefineOwnProperty( 198 LookupIterator* it, PropertyDescriptor* desc, 199 Maybe<ShouldThrow> should_throw); 200 // ES6 9.1.6.2 201 V8_WARN_UNUSED_RESULT static Maybe<bool> IsCompatiblePropertyDescriptor( 202 Isolate* isolate, bool extensible, PropertyDescriptor* desc, 203 PropertyDescriptor* current, Handle<Name> property_name, 204 Maybe<ShouldThrow> should_throw); 205 // ES6 9.1.6.3 206 // |it| can be NULL in cases where the ES spec passes |undefined| as the 207 // receiver. Exactly one of |it| and |property_name| must be provided. 208 V8_WARN_UNUSED_RESULT static Maybe<bool> ValidateAndApplyPropertyDescriptor( 209 Isolate* isolate, LookupIterator* it, bool extensible, 210 PropertyDescriptor* desc, PropertyDescriptor* current, 211 Maybe<ShouldThrow> should_throw, Handle<Name> property_name); 212 213 V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<bool> 214 GetOwnPropertyDescriptor(Isolate* isolate, Handle<JSReceiver> object, 215 Handle<Object> key, PropertyDescriptor* desc); 216 V8_WARN_UNUSED_RESULT static Maybe<bool> GetOwnPropertyDescriptor( 217 LookupIterator* it, PropertyDescriptor* desc); 218 219 using IntegrityLevel = PropertyAttributes; 220 221 // ES6 7.3.14 (when passed kDontThrow) 222 // 'level' must be SEALED or FROZEN. 223 V8_WARN_UNUSED_RESULT static Maybe<bool> SetIntegrityLevel( 224 Handle<JSReceiver> object, IntegrityLevel lvl, ShouldThrow should_throw); 225 226 // ES6 7.3.15 227 // 'level' must be SEALED or FROZEN. 228 V8_WARN_UNUSED_RESULT static Maybe<bool> TestIntegrityLevel( 229 Handle<JSReceiver> object, IntegrityLevel lvl); 230 231 // ES6 [[PreventExtensions]] (when passed kDontThrow) 232 V8_WARN_UNUSED_RESULT static Maybe<bool> PreventExtensions( 233 Handle<JSReceiver> object, ShouldThrow should_throw); 234 235 V8_WARN_UNUSED_RESULT static Maybe<bool> IsExtensible( 236 Handle<JSReceiver> object); 237 238 // Returns the class name. 239 V8_EXPORT_PRIVATE String class_name(); 240 241 // Returns the constructor (the function that was used to instantiate the 242 // object). 243 static MaybeHandle<JSFunction> GetConstructor(Isolate* isolate, 244 Handle<JSReceiver> receiver); 245 246 // Returns the constructor name (the (possibly inferred) name of the function 247 // that was used to instantiate the object), if any. If a FunctionTemplate is 248 // used to instantiate the object, the class_name of the FunctionTemplate is 249 // returned instead. 250 static Handle<String> GetConstructorName(Isolate* isolate, 251 Handle<JSReceiver> receiver); 252 253 V8_EXPORT_PRIVATE MaybeHandle<NativeContext> GetCreationContext(); 254 255 V8_WARN_UNUSED_RESULT static inline Maybe<PropertyAttributes> 256 GetPropertyAttributes(Handle<JSReceiver> object, Handle<Name> name); 257 V8_WARN_UNUSED_RESULT static inline Maybe<PropertyAttributes> 258 GetOwnPropertyAttributes(Handle<JSReceiver> object, Handle<Name> name); 259 V8_WARN_UNUSED_RESULT static inline Maybe<PropertyAttributes> 260 GetOwnPropertyAttributes(Handle<JSReceiver> object, uint32_t index); 261 262 V8_WARN_UNUSED_RESULT static inline Maybe<PropertyAttributes> 263 GetElementAttributes(Handle<JSReceiver> object, uint32_t index); 264 V8_WARN_UNUSED_RESULT static inline Maybe<PropertyAttributes> 265 GetOwnElementAttributes(Handle<JSReceiver> object, uint32_t index); 266 267 V8_WARN_UNUSED_RESULT static Maybe<PropertyAttributes> GetPropertyAttributes( 268 LookupIterator* it); 269 270 // Set the object's prototype (only JSReceiver and null are allowed values). 271 V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<bool> SetPrototype( 272 Isolate* isolate, Handle<JSReceiver> object, Handle<Object> value, 273 bool from_javascript, ShouldThrow should_throw); 274 275 inline static Handle<Object> GetDataProperty(Isolate* isolate, 276 Handle<JSReceiver> object, 277 Handle<Name> name); 278 V8_EXPORT_PRIVATE static Handle<Object> GetDataProperty( 279 LookupIterator* it, AllocationPolicy allocation_policy = 280 AllocationPolicy::kAllocationAllowed); 281 282 // Retrieves a permanent object identity hash code. The undefined value might 283 // be returned in case no hash was created yet. 284 V8_EXPORT_PRIVATE Object GetIdentityHash(); 285 286 // Retrieves a permanent object identity hash code. May create and store a 287 // hash code if needed and none exists. 288 static Smi CreateIdentityHash(Isolate* isolate, JSReceiver key); 289 V8_EXPORT_PRIVATE Smi GetOrCreateIdentityHash(Isolate* isolate); 290 291 // Stores the hash code. The hash passed in must be masked with 292 // JSReceiver::kHashMask. 293 V8_EXPORT_PRIVATE void SetIdentityHash(int masked_hash); 294 295 // ES6 [[OwnPropertyKeys]] (modulo return type) 296 V8_WARN_UNUSED_RESULT static inline MaybeHandle<FixedArray> OwnPropertyKeys( 297 Handle<JSReceiver> object); 298 299 V8_WARN_UNUSED_RESULT static MaybeHandle<FixedArray> GetOwnValues( 300 Handle<JSReceiver> object, PropertyFilter filter, 301 bool try_fast_path = true); 302 303 V8_WARN_UNUSED_RESULT static MaybeHandle<FixedArray> GetOwnEntries( 304 Handle<JSReceiver> object, PropertyFilter filter, 305 bool try_fast_path = true); 306 307 static const int kHashMask = PropertyArray::HashField::kMask; 308 309 bool HasProxyInPrototype(Isolate* isolate); 310 311 // TC39 "Dynamic Code Brand Checks" 312 bool IsCodeLike(Isolate* isolate) const; 313 314 private: 315 // Hide generated accessors; custom accessors are called 316 // "raw_properties_or_hash". 317 DECL_ACCESSORS(properties_or_hash, Object) 318 319 TQ_OBJECT_CONSTRUCTORS(JSReceiver) 320 }; 321 322 // The JSObject describes real heap allocated JavaScript objects with 323 // properties. 324 // Note that the map of JSObject changes during execution to enable inline 325 // caching. 326 class JSObject : public TorqueGeneratedJSObject<JSObject, JSReceiver> { 327 public: 328 static bool IsUnmodifiedApiObject(FullObjectSlot o); 329 330 V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT MaybeHandle<JSObject> New( 331 Handle<JSFunction> constructor, Handle<JSReceiver> new_target, 332 Handle<AllocationSite> site); 333 334 // 9.1.12 ObjectCreate ( proto [ , internalSlotsList ] ) 335 // Notice: This is NOT 19.1.2.2 Object.create ( O, Properties ) 336 static V8_WARN_UNUSED_RESULT MaybeHandle<JSObject> ObjectCreate( 337 Isolate* isolate, Handle<Object> prototype); 338 339 DECL_ACCESSORS(elements, FixedArrayBase) 340 DECL_RELAXED_GETTER(elements, FixedArrayBase) 341 342 // Acquire/release semantics on this field are explicitly forbidden to avoid 343 // confusion, since the default setter uses relaxed semantics. If 344 // acquire/release semantics ever become necessary, the default setter should 345 // be reverted to non-atomic behavior, and setters with explicit tags 346 // introduced and used when required. 347 FixedArrayBase elements(PtrComprCageBase cage_base, 348 AcquireLoadTag tag) const = delete; 349 void set_elements(FixedArrayBase value, ReleaseStoreTag tag, 350 WriteBarrierMode mode = UPDATE_WRITE_BARRIER) = delete; 351 352 inline void initialize_elements(); 353 static inline void SetMapAndElements(Handle<JSObject> object, Handle<Map> map, 354 Handle<FixedArrayBase> elements); 355 DECL_GETTER(GetElementsKind, ElementsKind) 356 DECL_GETTER(GetElementsAccessor, ElementsAccessor*) 357 358 // Returns true if an object has elements of PACKED_SMI_ELEMENTS or 359 // HOLEY_SMI_ELEMENTS ElementsKind. 360 DECL_GETTER(HasSmiElements, bool) 361 // Returns true if an object has elements of PACKED_ELEMENTS or 362 // HOLEY_ELEMENTS ElementsKind. 363 DECL_GETTER(HasObjectElements, bool) 364 // Returns true if an object has elements of PACKED_SMI_ELEMENTS, 365 // HOLEY_SMI_ELEMENTS, PACKED_ELEMENTS, or HOLEY_ELEMENTS. 366 DECL_GETTER(HasSmiOrObjectElements, bool) 367 // Returns true if an object has any of the "fast" elements kinds. 368 DECL_GETTER(HasFastElements, bool) 369 // Returns true if an object has any of the PACKED elements kinds. 370 DECL_GETTER(HasFastPackedElements, bool) 371 // Returns true if an object has elements of PACKED_DOUBLE_ELEMENTS or 372 // HOLEY_DOUBLE_ELEMENTS ElementsKind. 373 DECL_GETTER(HasDoubleElements, bool) 374 // Returns true if an object has elements of HOLEY_SMI_ELEMENTS, 375 // HOLEY_DOUBLE_ELEMENTS, or HOLEY_ELEMENTS ElementsKind. 376 DECL_GETTER(HasHoleyElements, bool) 377 DECL_GETTER(HasSloppyArgumentsElements, bool) 378 DECL_GETTER(HasStringWrapperElements, bool) 379 DECL_GETTER(HasDictionaryElements, bool) 380 381 // Returns true if an object has elements of PACKED_ELEMENTS 382 DECL_GETTER(HasPackedElements, bool) 383 DECL_GETTER(HasAnyNonextensibleElements, bool) 384 DECL_GETTER(HasSealedElements, bool) 385 DECL_GETTER(HasNonextensibleElements, bool) 386 387 DECL_GETTER(HasTypedArrayOrRabGsabTypedArrayElements, bool) 388 389 DECL_GETTER(HasFixedUint8ClampedElements, bool) 390 DECL_GETTER(HasFixedArrayElements, bool) 391 DECL_GETTER(HasFixedInt8Elements, bool) 392 DECL_GETTER(HasFixedUint8Elements, bool) 393 DECL_GETTER(HasFixedInt16Elements, bool) 394 DECL_GETTER(HasFixedUint16Elements, bool) 395 DECL_GETTER(HasFixedInt32Elements, bool) 396 DECL_GETTER(HasFixedUint32Elements, bool) 397 DECL_GETTER(HasFixedFloat32Elements, bool) 398 DECL_GETTER(HasFixedFloat64Elements, bool) 399 DECL_GETTER(HasFixedBigInt64Elements, bool) 400 DECL_GETTER(HasFixedBigUint64Elements, bool) 401 402 DECL_GETTER(HasFastArgumentsElements, bool) 403 DECL_GETTER(HasSlowArgumentsElements, bool) 404 DECL_GETTER(HasFastStringWrapperElements, bool) 405 DECL_GETTER(HasSlowStringWrapperElements, bool) 406 bool HasEnumerableElements(); 407 408 // Gets slow elements. 409 DECL_GETTER(element_dictionary, NumberDictionary) 410 411 // Requires: HasFastElements(). 412 static void EnsureWritableFastElements(Handle<JSObject> object); 413 414 V8_WARN_UNUSED_RESULT static Maybe<bool> SetPropertyWithInterceptor( 415 LookupIterator* it, Maybe<ShouldThrow> should_throw, 416 Handle<Object> value); 417 418 // The API currently still wants DefineOwnPropertyIgnoreAttributes to convert 419 // AccessorInfo objects to data fields. We allow FORCE_FIELD as an exception 420 // to the default behavior that calls the setter. 421 enum AccessorInfoHandling { FORCE_FIELD, DONT_FORCE_FIELD }; 422 423 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> 424 DefineOwnPropertyIgnoreAttributes( 425 LookupIterator* it, Handle<Object> value, PropertyAttributes attributes, 426 AccessorInfoHandling handling = DONT_FORCE_FIELD, 427 EnforceDefineSemantics semantics = EnforceDefineSemantics::kSet); 428 429 V8_WARN_UNUSED_RESULT static Maybe<bool> DefineOwnPropertyIgnoreAttributes( 430 LookupIterator* it, Handle<Object> value, PropertyAttributes attributes, 431 Maybe<ShouldThrow> should_throw, 432 AccessorInfoHandling handling = DONT_FORCE_FIELD, 433 EnforceDefineSemantics semantics = EnforceDefineSemantics::kSet, 434 StoreOrigin store_origin = StoreOrigin::kNamed); 435 436 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> V8_EXPORT_PRIVATE 437 SetOwnPropertyIgnoreAttributes(Handle<JSObject> object, Handle<Name> name, 438 Handle<Object> value, 439 PropertyAttributes attributes); 440 441 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> 442 SetOwnElementIgnoreAttributes(Handle<JSObject> object, size_t index, 443 Handle<Object> value, 444 PropertyAttributes attributes); 445 446 // Equivalent to one of the above depending on whether |name| can be converted 447 // to an array index. 448 V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static MaybeHandle<Object> 449 DefinePropertyOrElementIgnoreAttributes(Handle<JSObject> object, 450 Handle<Name> name, 451 Handle<Object> value, 452 PropertyAttributes attributes = NONE); 453 454 // Adds or reconfigures a property to attributes NONE. It will fail when it 455 // cannot. 456 V8_WARN_UNUSED_RESULT static Maybe<bool> CreateDataProperty( 457 LookupIterator* it, Handle<Object> value, 458 Maybe<ShouldThrow> should_throw = Just(kDontThrow)); 459 460 V8_EXPORT_PRIVATE static void AddProperty(Isolate* isolate, 461 Handle<JSObject> object, 462 Handle<Name> name, 463 Handle<Object> value, 464 PropertyAttributes attributes); 465 466 // {name} must be a UTF-8 encoded, null-terminated string. 467 static void AddProperty(Isolate* isolate, Handle<JSObject> object, 468 const char* name, Handle<Object> value, 469 PropertyAttributes attributes); 470 471 V8_EXPORT_PRIVATE static Maybe<bool> AddDataElement( 472 Handle<JSObject> receiver, uint32_t index, Handle<Object> value, 473 PropertyAttributes attributes); 474 475 // Extend the receiver with a single fast property appeared first in the 476 // passed map. This also extends the property backing store if necessary. 477 static void AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map); 478 479 // Migrates the given object to a map whose field representations are the 480 // lowest upper bound of all known representations for that field. 481 static void MigrateInstance(Isolate* isolate, Handle<JSObject> instance); 482 483 // Migrates the given object only if the target map is already available, 484 // or returns false if such a map is not yet available. 485 static bool TryMigrateInstance(Isolate* isolate, Handle<JSObject> instance); 486 487 // Sets the property value in a normalized object given (key, value, details). 488 // Handles the special representation of JS global objects. 489 static void SetNormalizedProperty(Handle<JSObject> object, Handle<Name> name, 490 Handle<Object> value, 491 PropertyDetails details); 492 static void SetNormalizedElement(Handle<JSObject> object, uint32_t index, 493 Handle<Object> value, 494 PropertyDetails details); 495 496 static void OptimizeAsPrototype(Handle<JSObject> object, 497 bool enable_setup_mode = true); 498 static void ReoptimizeIfPrototype(Handle<JSObject> object); 499 static void MakePrototypesFast(Handle<Object> receiver, 500 WhereToStart where_to_start, Isolate* isolate); 501 static void LazyRegisterPrototypeUser(Handle<Map> user, Isolate* isolate); 502 static void UpdatePrototypeUserRegistration(Handle<Map> old_map, 503 Handle<Map> new_map, 504 Isolate* isolate); 505 static bool UnregisterPrototypeUser(Handle<Map> user, Isolate* isolate); 506 static Map InvalidatePrototypeChains(Map map); 507 static void InvalidatePrototypeValidityCell(JSGlobalObject global); 508 509 // Updates prototype chain tracking information when an object changes its 510 // map from |old_map| to |new_map|. 511 static void NotifyMapChange(Handle<Map> old_map, Handle<Map> new_map, 512 Isolate* isolate); 513 514 // Utility used by many Array builtins and runtime functions 515 static inline bool PrototypeHasNoElements(Isolate* isolate, JSObject object); 516 517 // To be passed to PrototypeUsers::Compact. 518 static void PrototypeRegistryCompactionCallback(HeapObject value, 519 int old_index, int new_index); 520 521 // Retrieve interceptors. 522 DECL_GETTER(GetNamedInterceptor, InterceptorInfo) 523 DECL_GETTER(GetIndexedInterceptor, InterceptorInfo) 524 525 // Used from JSReceiver. 526 V8_WARN_UNUSED_RESULT static Maybe<PropertyAttributes> 527 GetPropertyAttributesWithInterceptor(LookupIterator* it); 528 V8_WARN_UNUSED_RESULT static Maybe<PropertyAttributes> 529 GetPropertyAttributesWithFailedAccessCheck(LookupIterator* it); 530 531 // Defines an AccessorPair property on the given object. 532 V8_EXPORT_PRIVATE static MaybeHandle<Object> DefineAccessor( 533 Handle<JSObject> object, Handle<Name> name, Handle<Object> getter, 534 Handle<Object> setter, PropertyAttributes attributes); 535 static MaybeHandle<Object> DefineAccessor(LookupIterator* it, 536 Handle<Object> getter, 537 Handle<Object> setter, 538 PropertyAttributes attributes); 539 540 // Defines an AccessorInfo property on the given object. 541 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> SetAccessor( 542 Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> info, 543 PropertyAttributes attributes); 544 545 // The result must be checked first for exceptions. If there's no exception, 546 // the output parameter |done| indicates whether the interceptor has a result 547 // or not. 548 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> GetPropertyWithInterceptor( 549 LookupIterator* it, bool* done); 550 551 static void ValidateElements(JSObject object); 552 553 // Makes sure that this object can contain HeapObject as elements. 554 static inline void EnsureCanContainHeapObjectElements(Handle<JSObject> obj); 555 556 // Makes sure that this object can contain the specified elements. 557 // TSlot here is either ObjectSlot or FullObjectSlot. 558 template <typename TSlot> 559 static inline void EnsureCanContainElements(Handle<JSObject> object, 560 TSlot elements, uint32_t count, 561 EnsureElementsMode mode); 562 static inline void EnsureCanContainElements(Handle<JSObject> object, 563 Handle<FixedArrayBase> elements, 564 uint32_t length, 565 EnsureElementsMode mode); 566 static void EnsureCanContainElements(Handle<JSObject> object, 567 JavaScriptArguments* arguments, 568 uint32_t arg_count, 569 EnsureElementsMode mode); 570 571 // Would we convert a fast elements array to dictionary mode given 572 // an access at key? 573 bool WouldConvertToSlowElements(uint32_t index); 574 575 static const uint32_t kMinAddedElementsCapacity = 16; 576 577 // Computes the new capacity when expanding the elements of a JSObject. NewElementsCapacity(uint32_t old_capacity)578 static uint32_t NewElementsCapacity(uint32_t old_capacity) { 579 // (old_capacity + 50%) + kMinAddedElementsCapacity 580 return old_capacity + (old_capacity >> 1) + kMinAddedElementsCapacity; 581 } 582 583 // These methods do not perform access checks! 584 template <AllocationSiteUpdateMode update_or_check = 585 AllocationSiteUpdateMode::kUpdate> 586 static bool UpdateAllocationSite(Handle<JSObject> object, 587 ElementsKind to_kind); 588 589 // Lookup interceptors are used for handling properties controlled by host 590 // objects. 591 DECL_GETTER(HasNamedInterceptor, bool) 592 DECL_GETTER(HasIndexedInterceptor, bool) 593 594 // Support functions for v8 api (needed for correct interceptor behavior). 595 V8_WARN_UNUSED_RESULT static Maybe<bool> HasRealNamedProperty( 596 Isolate* isolate, Handle<JSObject> object, Handle<Name> name); 597 V8_WARN_UNUSED_RESULT static Maybe<bool> HasRealElementProperty( 598 Isolate* isolate, Handle<JSObject> object, uint32_t index); 599 V8_WARN_UNUSED_RESULT static Maybe<bool> HasRealNamedCallbackProperty( 600 Isolate* isolate, Handle<JSObject> object, Handle<Name> name); 601 602 // Get the header size for a JSObject. Used to compute the index of 603 // embedder fields as well as the number of embedder fields. 604 // The |function_has_prototype_slot| parameter is needed only for 605 // JSFunction objects. 606 static V8_EXPORT_PRIVATE int GetHeaderSize( 607 InstanceType instance_type, bool function_has_prototype_slot = false); 608 static inline int GetHeaderSize(Map map); 609 610 static inline bool MayHaveEmbedderFields(Map map); 611 inline bool MayHaveEmbedderFields() const; 612 613 static inline int GetEmbedderFieldsStartOffset(Map map); 614 inline int GetEmbedderFieldsStartOffset(); 615 616 static inline int GetEmbedderFieldCount(Map map); 617 inline int GetEmbedderFieldCount() const; 618 inline int GetEmbedderFieldOffset(int index); 619 inline Object GetEmbedderField(int index); 620 inline void SetEmbedderField(int index, Object value); 621 inline void SetEmbedderField(int index, Smi value); 622 623 // Returns true if this object is an Api object which can, if unmodified, be 624 // dropped during minor GC because the embedder can recreate it again later. 625 inline bool IsDroppableApiObject() const; 626 627 // Returns a new map with all transitions dropped from the object's current 628 // map and the ElementsKind set. 629 static Handle<Map> GetElementsTransitionMap(Handle<JSObject> object, 630 ElementsKind to_kind); 631 V8_EXPORT_PRIVATE static void TransitionElementsKind(Handle<JSObject> object, 632 ElementsKind to_kind); 633 634 // Always use this to migrate an object to a new map. 635 // |expected_additional_properties| is only used for fast-to-slow transitions 636 // and ignored otherwise. 637 V8_EXPORT_PRIVATE static void MigrateToMap( 638 Isolate* isolate, Handle<JSObject> object, Handle<Map> new_map, 639 int expected_additional_properties = 0); 640 641 // Forces a prototype without any of the checks that the regular SetPrototype 642 // would do. 643 static void ForceSetPrototype(Isolate* isolate, Handle<JSObject> object, 644 Handle<HeapObject> proto); 645 646 // Convert the object to use the canonical dictionary 647 // representation. If the object is expected to have additional properties 648 // added this number can be indicated to have the backing store allocated to 649 // an initial capacity for holding these properties. 650 V8_EXPORT_PRIVATE static void NormalizeProperties( 651 Isolate* isolate, Handle<JSObject> object, PropertyNormalizationMode mode, 652 int expected_additional_properties, const char* reason); 653 654 // Convert and update the elements backing store to be a 655 // NumberDictionary dictionary. Returns the backing after conversion. 656 V8_EXPORT_PRIVATE static Handle<NumberDictionary> NormalizeElements( 657 Handle<JSObject> object); 658 659 void RequireSlowElements(NumberDictionary dictionary); 660 661 // Transform slow named properties to fast variants. 662 V8_EXPORT_PRIVATE static void MigrateSlowToFast(Handle<JSObject> object, 663 int unused_property_fields, 664 const char* reason); 665 666 // Access property in dictionary mode object at the given dictionary index. 667 static Handle<Object> DictionaryPropertyAt(Isolate* isolate, 668 Handle<JSObject> object, 669 InternalIndex dict_index); 670 // Same as above, but it will return {} if we would be reading out of the 671 // bounds of the object or if the dictionary is pending allocation. Use this 672 // version for concurrent access. 673 static base::Optional<Object> DictionaryPropertyAt(Handle<JSObject> object, 674 InternalIndex dict_index, 675 Heap* heap); 676 677 // Access fast-case object properties at index. 678 static Handle<Object> FastPropertyAt(Isolate* isolate, 679 Handle<JSObject> object, 680 Representation representation, 681 FieldIndex index); 682 static Handle<Object> FastPropertyAt(Isolate* isolate, 683 Handle<JSObject> object, 684 Representation representation, 685 FieldIndex index, SeqCstAccessTag tag); 686 inline Object RawFastPropertyAt(FieldIndex index) const; 687 inline Object RawFastPropertyAt(PtrComprCageBase cage_base, 688 FieldIndex index) const; 689 inline Object RawFastPropertyAt(FieldIndex index, SeqCstAccessTag tag) const; 690 inline Object RawFastPropertyAt(PtrComprCageBase cage_base, FieldIndex index, 691 SeqCstAccessTag tag) const; 692 693 // See comment in the body of the method to understand the conditions 694 // in which this method is meant to be used, and what guarantees it 695 // provides against invalid reads from another thread during object 696 // mutation. 697 inline base::Optional<Object> RawInobjectPropertyAt( 698 PtrComprCageBase cage_base, Map original_map, FieldIndex index) const; 699 700 inline void FastPropertyAtPut(FieldIndex index, Object value, 701 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); 702 inline void FastPropertyAtPut(FieldIndex index, Object value, 703 SeqCstAccessTag tag); 704 inline void RawFastInobjectPropertyAtPut( 705 FieldIndex index, Object value, 706 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); 707 inline void RawFastInobjectPropertyAtPut(FieldIndex index, Object value, 708 SeqCstAccessTag tag); 709 inline void WriteToField(InternalIndex descriptor, PropertyDetails details, 710 Object value); 711 712 inline Object RawFastPropertyAtSwap(FieldIndex index, Object value, 713 SeqCstAccessTag tag); 714 inline Object RawFastPropertyAtSwap(PtrComprCageBase cage_base, 715 FieldIndex index, Object value, 716 SeqCstAccessTag tag); 717 718 // Access to in object properties. 719 inline int GetInObjectPropertyOffset(int index); 720 inline Object InObjectPropertyAt(int index); 721 inline Object InObjectPropertyAtPut( 722 int index, Object value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER); 723 724 // Set the object's prototype (only JSReceiver and null are allowed values). 725 V8_WARN_UNUSED_RESULT static Maybe<bool> SetPrototype( 726 Isolate* isolate, Handle<JSObject> object, Handle<Object> value, 727 bool from_javascript, ShouldThrow should_throw); 728 729 // Makes the object prototype immutable 730 // Never called from JavaScript 731 static void SetImmutableProto(Handle<JSObject> object); 732 733 // Initializes the body starting at |start_offset|. It is responsibility of 734 // the caller to initialize object header. Fill the pre-allocated fields with 735 // undefined_value and the rest with filler_map. 736 // Note: this call does not update write barrier, the caller is responsible 737 // to ensure that |filler_map| can be collected without WB here. 738 inline void InitializeBody(Map map, int start_offset, 739 bool is_slack_tracking_in_progress, 740 MapWord filler_map, Object undefined_value); 741 742 // Check whether this object references another object 743 bool ReferencesObject(Object obj); 744 745 V8_WARN_UNUSED_RESULT static Maybe<bool> TestIntegrityLevel( 746 Handle<JSObject> object, IntegrityLevel lvl); 747 748 V8_WARN_UNUSED_RESULT static Maybe<bool> PreventExtensions( 749 Handle<JSObject> object, ShouldThrow should_throw); 750 751 static bool IsExtensible(Handle<JSObject> object); 752 753 static MaybeHandle<Object> ReadFromOptionsBag(Handle<Object> options, 754 Handle<String> option_name, 755 Isolate* isolate); 756 757 // Dispatched behavior. 758 void JSObjectShortPrint(StringStream* accumulator); 759 DECL_PRINTER(JSObject) 760 DECL_VERIFIER(JSObject) 761 #ifdef OBJECT_PRINT 762 bool PrintProperties(std::ostream& os); 763 void PrintElements(std::ostream& os); 764 #endif 765 #if defined(DEBUG) || defined(OBJECT_PRINT) 766 void PrintTransitions(std::ostream& os); 767 #endif 768 769 static void PrintElementsTransition(FILE* file, Handle<JSObject> object, 770 ElementsKind from_kind, 771 Handle<FixedArrayBase> from_elements, 772 ElementsKind to_kind, 773 Handle<FixedArrayBase> to_elements); 774 775 void PrintInstanceMigration(FILE* file, Map original_map, Map new_map); 776 777 #ifdef DEBUG 778 // Structure for collecting spill information about JSObjects. 779 class SpillInformation { 780 public: 781 void Clear(); 782 void Print(); 783 int number_of_objects_; 784 int number_of_objects_with_fast_properties_; 785 int number_of_objects_with_fast_elements_; 786 int number_of_fast_used_fields_; 787 int number_of_fast_unused_fields_; 788 int number_of_slow_used_properties_; 789 int number_of_slow_unused_properties_; 790 int number_of_fast_used_elements_; 791 int number_of_fast_unused_elements_; 792 int number_of_slow_used_elements_; 793 int number_of_slow_unused_elements_; 794 }; 795 796 void IncrementSpillStatistics(Isolate* isolate, SpillInformation* info); 797 #endif 798 799 #ifdef VERIFY_HEAP 800 // If a GC was caused while constructing this object, the elements pointer 801 // may point to a one pointer filler map. The object won't be rooted, but 802 // our heap verification code could stumble across it. 803 V8_EXPORT_PRIVATE bool ElementsAreSafeToExamine( 804 PtrComprCageBase cage_base) const; 805 #endif 806 807 Object SlowReverseLookup(Object value); 808 809 // Maximal number of elements (numbered 0 .. kMaxElementCount - 1). 810 // Also maximal value of JSArray's length property. 811 static constexpr uint32_t kMaxElementCount = kMaxUInt32; 812 static constexpr uint32_t kMaxElementIndex = kMaxElementCount - 1; 813 814 // Constants for heuristics controlling conversion of fast elements 815 // to slow elements. 816 817 // Maximal gap that can be introduced by adding an element beyond 818 // the current elements length. 819 static const uint32_t kMaxGap = 1024; 820 821 // Maximal length of fast elements array that won't be checked for 822 // being dense enough on expansion. 823 static const int kMaxUncheckedFastElementsLength = 5000; 824 825 // Same as above but for old arrays. This limit is more strict. We 826 // don't want to be wasteful with long lived objects. 827 static const int kMaxUncheckedOldFastElementsLength = 500; 828 829 // This constant applies only to the initial map of "global.Object" and 830 // not to arbitrary other JSObject maps. 831 static const int kInitialGlobalObjectUnusedPropertiesCount = 4; 832 833 static const int kMaxInstanceSize = 255 * kTaggedSize; 834 835 static const int kMapCacheSize = 128; 836 837 // When extending the backing storage for property values, we increase 838 // its size by more than the 1 entry necessary, so sequentially adding fields 839 // to the same object requires fewer allocations and copies. 840 static const int kFieldsAdded = 3; 841 STATIC_ASSERT(kMaxNumberOfDescriptors + kFieldsAdded <= 842 PropertyArray::kMaxLength); 843 844 STATIC_ASSERT(kHeaderSize == Internals::kJSObjectHeaderSize); 845 static const int kMaxInObjectProperties = 846 (kMaxInstanceSize - kHeaderSize) >> kTaggedSizeLog2; 847 STATIC_ASSERT(kMaxInObjectProperties <= kMaxNumberOfDescriptors); 848 849 static const int kMaxFirstInobjectPropertyOffset = 850 (1 << kFirstInobjectPropertyOffsetBitCount) - 1; 851 static const int kMaxEmbedderFields = 852 (kMaxFirstInobjectPropertyOffset - kHeaderSize) / kEmbedderDataSlotSize; 853 STATIC_ASSERT(kHeaderSize + 854 kMaxEmbedderFields * kEmbedderDataSlotSizeInTaggedSlots <= 855 kMaxInstanceSize); 856 857 class BodyDescriptor; 858 859 class FastBodyDescriptor; 860 861 // Gets the number of currently used elements. 862 int GetFastElementsUsage(); 863 864 static bool AllCanRead(LookupIterator* it); 865 static bool AllCanWrite(LookupIterator* it); 866 867 template <typename Dictionary> 868 static void ApplyAttributesToDictionary(Isolate* isolate, ReadOnlyRoots roots, 869 Handle<Dictionary> dictionary, 870 const PropertyAttributes attributes); 871 872 private: 873 friend class JSReceiver; 874 friend class Object; 875 876 // Used from Object::GetProperty(). 877 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> 878 GetPropertyWithFailedAccessCheck(LookupIterator* it); 879 880 V8_WARN_UNUSED_RESULT static Maybe<bool> SetPropertyWithFailedAccessCheck( 881 LookupIterator* it, Handle<Object> value, 882 Maybe<ShouldThrow> should_throw); 883 884 V8_WARN_UNUSED_RESULT static Maybe<bool> DeletePropertyWithInterceptor( 885 LookupIterator* it, ShouldThrow should_throw); 886 887 bool ReferencesObjectFromElements(FixedArray elements, ElementsKind kind, 888 Object object); 889 890 // Helper for fast versions of preventExtensions, seal, and freeze. 891 // attrs is one of NONE, SEALED, or FROZEN (depending on the operation). 892 template <PropertyAttributes attrs> 893 V8_WARN_UNUSED_RESULT static Maybe<bool> PreventExtensionsWithTransition( 894 Handle<JSObject> object, ShouldThrow should_throw); 895 896 TQ_OBJECT_CONSTRUCTORS(JSObject) 897 }; 898 899 // A JSObject created through the public api which wraps an external pointer. 900 // See v8::External. 901 class JSExternalObject 902 : public TorqueGeneratedJSExternalObject<JSExternalObject, JSObject> { 903 public: 904 inline void AllocateExternalPointerEntries(Isolate* isolate); 905 906 // [value]: field containing the pointer value. 907 DECL_GETTER(value, void*) 908 909 inline void set_value(Isolate* isolate, void* value); 910 911 static constexpr int kEndOfTaggedFieldsOffset = JSObject::kHeaderSize; 912 913 class BodyDescriptor; 914 915 private: 916 TQ_OBJECT_CONSTRUCTORS(JSExternalObject) 917 }; 918 919 // An abstract superclass for JSObjects that may contain EmbedderDataSlots. 920 class JSObjectWithEmbedderSlots 921 : public TorqueGeneratedJSObjectWithEmbedderSlots<JSObjectWithEmbedderSlots, 922 JSObject> { 923 public: 924 STATIC_ASSERT(kHeaderSize == JSObject::kHeaderSize); 925 TQ_OBJECT_CONSTRUCTORS(JSObjectWithEmbedderSlots) 926 }; 927 928 // An abstract superclass for JSObjects that may have elements while having an 929 // empty fixed array as elements backing store. It doesn't carry any 930 // functionality but allows function classes to be identified in the type 931 // system. 932 class JSCustomElementsObject 933 : public TorqueGeneratedJSCustomElementsObject<JSCustomElementsObject, 934 JSObject> { 935 public: 936 STATIC_ASSERT(kHeaderSize == JSObject::kHeaderSize); 937 TQ_OBJECT_CONSTRUCTORS(JSCustomElementsObject) 938 }; 939 940 // An abstract superclass for JSObjects that require non-standard element 941 // access. It doesn't carry any functionality but allows function classes to be 942 // identified in the type system. 943 // These may also contain EmbedderDataSlots, but can't currently inherit from 944 // JSObjectWithEmbedderSlots due to instance_type constraints. 945 class JSSpecialObject 946 : public TorqueGeneratedJSSpecialObject<JSSpecialObject, 947 JSCustomElementsObject> { 948 public: 949 STATIC_ASSERT(kHeaderSize == JSObject::kHeaderSize); 950 TQ_OBJECT_CONSTRUCTORS(JSSpecialObject) 951 }; 952 953 // JSAccessorPropertyDescriptor is just a JSObject with a specific initial 954 // map. This initial map adds in-object properties for "get", "set", 955 // "enumerable" and "configurable" properties, as assigned by the 956 // FromPropertyDescriptor function for regular accessor properties. 957 class JSAccessorPropertyDescriptor : public JSObject { 958 public: 959 // Layout description. 960 #define JS_ACCESSOR_PROPERTY_DESCRIPTOR_FIELDS(V) \ 961 V(kGetOffset, kTaggedSize) \ 962 V(kSetOffset, kTaggedSize) \ 963 V(kEnumerableOffset, kTaggedSize) \ 964 V(kConfigurableOffset, kTaggedSize) \ 965 /* Total size. */ \ 966 V(kSize, 0) 967 968 DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, 969 JS_ACCESSOR_PROPERTY_DESCRIPTOR_FIELDS) 970 #undef JS_ACCESSOR_PROPERTY_DESCRIPTOR_FIELDS 971 972 // Indices of in-object properties. 973 static const int kGetIndex = 0; 974 static const int kSetIndex = 1; 975 static const int kEnumerableIndex = 2; 976 static const int kConfigurableIndex = 3; 977 978 private: 979 DISALLOW_IMPLICIT_CONSTRUCTORS(JSAccessorPropertyDescriptor); 980 }; 981 982 // JSDataPropertyDescriptor is just a JSObject with a specific initial map. 983 // This initial map adds in-object properties for "value", "writable", 984 // "enumerable" and "configurable" properties, as assigned by the 985 // FromPropertyDescriptor function for regular data properties. 986 class JSDataPropertyDescriptor : public JSObject { 987 public: 988 // Layout description. 989 #define JS_DATA_PROPERTY_DESCRIPTOR_FIELDS(V) \ 990 V(kValueOffset, kTaggedSize) \ 991 V(kWritableOffset, kTaggedSize) \ 992 V(kEnumerableOffset, kTaggedSize) \ 993 V(kConfigurableOffset, kTaggedSize) \ 994 /* Total size. */ \ 995 V(kSize, 0) 996 997 DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, 998 JS_DATA_PROPERTY_DESCRIPTOR_FIELDS) 999 #undef JS_DATA_PROPERTY_DESCRIPTOR_FIELDS 1000 1001 // Indices of in-object properties. 1002 static const int kValueIndex = 0; 1003 static const int kWritableIndex = 1; 1004 static const int kEnumerableIndex = 2; 1005 static const int kConfigurableIndex = 3; 1006 1007 private: 1008 DISALLOW_IMPLICIT_CONSTRUCTORS(JSDataPropertyDescriptor); 1009 }; 1010 1011 // JSIteratorResult is just a JSObject with a specific initial map. 1012 // This initial map adds in-object properties for "done" and "value", 1013 // as specified by ES6 section 25.1.1.3 The IteratorResult Interface. 1014 class JSIteratorResult : public JSObject { 1015 public: 1016 DECL_ACCESSORS(value, Object) 1017 1018 DECL_ACCESSORS(done, Object) 1019 1020 // Layout description. 1021 #define JS_ITERATOR_RESULT_FIELDS(V) \ 1022 V(kValueOffset, kTaggedSize) \ 1023 V(kDoneOffset, kTaggedSize) \ 1024 /* Total size. */ \ 1025 V(kSize, 0) 1026 1027 DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, 1028 JS_ITERATOR_RESULT_FIELDS) 1029 #undef JS_ITERATOR_RESULT_FIELDS 1030 1031 // Indices of in-object properties. 1032 static const int kValueIndex = 0; 1033 static const int kDoneIndex = 1; 1034 1035 DECL_CAST(JSIteratorResult) 1036 1037 OBJECT_CONSTRUCTORS(JSIteratorResult, JSObject); 1038 }; 1039 1040 // JSGlobalProxy's prototype must be a JSGlobalObject or null, 1041 // and the prototype is hidden. JSGlobalProxy always delegates 1042 // property accesses to its prototype if the prototype is not null. 1043 // 1044 // A JSGlobalProxy can be reinitialized which will preserve its identity. 1045 // 1046 // Accessing a JSGlobalProxy requires security check. 1047 1048 class JSGlobalProxy 1049 : public TorqueGeneratedJSGlobalProxy<JSGlobalProxy, JSSpecialObject> { 1050 public: 1051 inline bool IsDetachedFrom(JSGlobalObject global) const; 1052 V8_EXPORT_PRIVATE bool IsDetached() const; 1053 1054 static int SizeWithEmbedderFields(int embedder_field_count); 1055 1056 // Dispatched behavior. 1057 DECL_PRINTER(JSGlobalProxy) 1058 DECL_VERIFIER(JSGlobalProxy) 1059 1060 TQ_OBJECT_CONSTRUCTORS(JSGlobalProxy) 1061 }; 1062 1063 // JavaScript global object. 1064 class JSGlobalObject 1065 : public TorqueGeneratedJSGlobalObject<JSGlobalObject, JSSpecialObject> { 1066 public: 1067 DECL_RELEASE_ACQUIRE_ACCESSORS(global_dictionary, GlobalDictionary) 1068 1069 static void InvalidatePropertyCell(Handle<JSGlobalObject> object, 1070 Handle<Name> name); 1071 1072 inline bool IsDetached(); 1073 1074 // May be called by the concurrent GC when the global object is not 1075 // fully initialized. 1076 DECL_GETTER(native_context_unchecked, Object) 1077 1078 // Dispatched behavior. 1079 DECL_PRINTER(JSGlobalObject) 1080 DECL_VERIFIER(JSGlobalObject) 1081 1082 TQ_OBJECT_CONSTRUCTORS(JSGlobalObject) 1083 }; 1084 1085 // Representation for JS Wrapper objects, String, Number, Boolean, etc. 1086 class JSPrimitiveWrapper 1087 : public TorqueGeneratedJSPrimitiveWrapper<JSPrimitiveWrapper, 1088 JSCustomElementsObject> { 1089 public: 1090 // Dispatched behavior. 1091 DECL_PRINTER(JSPrimitiveWrapper) 1092 1093 TQ_OBJECT_CONSTRUCTORS(JSPrimitiveWrapper) 1094 }; 1095 1096 class DateCache; 1097 1098 // Representation for JS date objects. 1099 class JSDate : public TorqueGeneratedJSDate<JSDate, JSObject> { 1100 public: 1101 static V8_WARN_UNUSED_RESULT MaybeHandle<JSDate> New( 1102 Handle<JSFunction> constructor, Handle<JSReceiver> new_target, double tv); 1103 1104 // Returns the time value (UTC) identifying the current time. 1105 static double CurrentTimeValue(Isolate* isolate); 1106 1107 // Returns the date field with the specified index. 1108 // See FieldIndex for the list of date fields. 1109 // Arguments and result are raw Address values because this is called 1110 // via ExternalReference. 1111 // {raw_date} is a tagged Object pointer. 1112 // {smi_index} is a tagged Smi. 1113 // The return value is a tagged Object pointer. 1114 static Address GetField(Isolate* isolate, Address raw_date, 1115 Address smi_index); 1116 1117 static Handle<Object> SetValue(Handle<JSDate> date, double v); 1118 1119 void SetValue(Object value, bool is_value_nan); 1120 1121 // Dispatched behavior. 1122 DECL_PRINTER(JSDate) 1123 DECL_VERIFIER(JSDate) 1124 1125 // The order is important. It must be kept in sync with date macros 1126 // in macros.py. 1127 enum FieldIndex { 1128 kDateValue, 1129 kYear, 1130 kMonth, 1131 kDay, 1132 kWeekday, 1133 kHour, 1134 kMinute, 1135 kSecond, 1136 kFirstUncachedField, 1137 kMillisecond = kFirstUncachedField, 1138 kDays, 1139 kTimeInDay, 1140 kFirstUTCField, 1141 kYearUTC = kFirstUTCField, 1142 kMonthUTC, 1143 kDayUTC, 1144 kWeekdayUTC, 1145 kHourUTC, 1146 kMinuteUTC, 1147 kSecondUTC, 1148 kMillisecondUTC, 1149 kDaysUTC, 1150 kTimeInDayUTC, 1151 kTimezoneOffset 1152 }; 1153 1154 private: 1155 Object DoGetField(Isolate* isolate, FieldIndex index); 1156 Object GetUTCField(FieldIndex index, double value, DateCache* date_cache); 1157 1158 // Computes and caches the cacheable fields of the date. 1159 inline void SetCachedFields(int64_t local_time_ms, DateCache* date_cache); 1160 1161 TQ_OBJECT_CONSTRUCTORS(JSDate) 1162 }; 1163 1164 // Representation of message objects used for error reporting through 1165 // the API. The messages are formatted in JavaScript so this object is 1166 // a real JavaScript object. The information used for formatting the 1167 // error messages are not directly accessible from JavaScript to 1168 // prevent leaking information to user code called during error 1169 // formatting. 1170 class JSMessageObject 1171 : public TorqueGeneratedJSMessageObject<JSMessageObject, JSObject> { 1172 public: 1173 // [type]: the type of error message. 1174 inline MessageTemplate type() const; 1175 inline void set_type(MessageTemplate value); 1176 1177 // Initializes the source positions in the object if possible. Does nothing if 1178 // called more than once. If called when stack space is exhausted, then the 1179 // source positions will be not be set and calling it again when there is more 1180 // stack space will not have any effect. 1181 static void EnsureSourcePositionsAvailable(Isolate* isolate, 1182 Handle<JSMessageObject> message); 1183 1184 // Gets the start and end positions for the message. 1185 // EnsureSourcePositionsAvailable must have been called before calling these. 1186 inline int GetStartPosition() const; 1187 inline int GetEndPosition() const; 1188 1189 // Returns the line number for the error message (1-based), or 1190 // Message::kNoLineNumberInfo if the line cannot be determined. 1191 // EnsureSourcePositionsAvailable must have been called before calling this. 1192 V8_EXPORT_PRIVATE int GetLineNumber() const; 1193 1194 // Returns the offset of the given position within the containing line. 1195 // EnsureSourcePositionsAvailable must have been called before calling this. 1196 V8_EXPORT_PRIVATE int GetColumnNumber() const; 1197 1198 // Returns the source code 1199 V8_EXPORT_PRIVATE String GetSource() const; 1200 1201 // Returns the source code line containing the given source 1202 // position, or the empty string if the position is invalid. 1203 // EnsureSourcePositionsAvailable must have been called before calling this. 1204 Handle<String> GetSourceLine() const; 1205 1206 DECL_INT_ACCESSORS(error_level) 1207 1208 // Dispatched behavior. 1209 DECL_PRINTER(JSMessageObject) 1210 1211 // TODO(v8:8989): [torque] Support marker constants. 1212 static const int kPointerFieldsEndOffset = kStartPositionOffset; 1213 1214 using BodyDescriptor = 1215 FixedBodyDescriptor<HeapObject::kMapOffset, kPointerFieldsEndOffset, 1216 kHeaderSize>; 1217 1218 private: 1219 friend class Factory; 1220 1221 inline bool DidEnsureSourcePositionsAvailable() const; 1222 1223 // [shared]: optional SharedFunctionInfo that can be used to reconstruct the 1224 // source position if not available when the message was generated. 1225 DECL_ACCESSORS(shared_info, HeapObject) 1226 1227 // [bytecode_offset]: optional offset using along with |shared| to generation 1228 // source positions. 1229 DECL_ACCESSORS(bytecode_offset, Smi) 1230 1231 // [start_position]: the start position in the script for the error message. 1232 DECL_INT_ACCESSORS(start_position) 1233 1234 // [end_position]: the end position in the script for the error message. 1235 DECL_INT_ACCESSORS(end_position) 1236 1237 DECL_INT_ACCESSORS(raw_type) 1238 1239 // Hide generated accessors; custom accessors are named "raw_type". 1240 DECL_INT_ACCESSORS(message_type) 1241 1242 TQ_OBJECT_CONSTRUCTORS(JSMessageObject) 1243 }; 1244 1245 // The [Async-from-Sync Iterator] object 1246 // (proposal-async-iteration/#sec-async-from-sync-iterator-objects) 1247 // An object which wraps an ordinary Iterator and converts it to behave 1248 // according to the Async Iterator protocol. 1249 // (See https://tc39.github.io/proposal-async-iteration/#sec-iteration) 1250 class JSAsyncFromSyncIterator 1251 : public TorqueGeneratedJSAsyncFromSyncIterator<JSAsyncFromSyncIterator, 1252 JSObject> { 1253 public: 1254 DECL_PRINTER(JSAsyncFromSyncIterator) 1255 1256 // Async-from-Sync Iterator instances are ordinary objects that inherit 1257 // properties from the %AsyncFromSyncIteratorPrototype% intrinsic object. 1258 // Async-from-Sync Iterator instances are initially created with the internal 1259 // slots listed in Table 4. 1260 // (proposal-async-iteration/#table-async-from-sync-iterator-internal-slots) 1261 1262 TQ_OBJECT_CONSTRUCTORS(JSAsyncFromSyncIterator) 1263 }; 1264 1265 class JSStringIterator 1266 : public TorqueGeneratedJSStringIterator<JSStringIterator, JSObject> { 1267 public: 1268 // Dispatched behavior. 1269 DECL_PRINTER(JSStringIterator) 1270 DECL_VERIFIER(JSStringIterator) 1271 1272 TQ_OBJECT_CONSTRUCTORS(JSStringIterator) 1273 }; 1274 1275 } // namespace internal 1276 } // namespace v8 1277 1278 #include "src/objects/object-macros-undef.h" 1279 1280 #endif // V8_OBJECTS_JS_OBJECTS_H_ 1281