js-objects.h 54.1 KB
Newer Older
1 2 3 4 5 6 7
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_OBJECTS_JS_OBJECTS_H_
#define V8_OBJECTS_JS_OBJECTS_H_

8
#include "src/objects/embedder-data-slot.h"
9 10
// TODO(jkummerow): Consider forward-declaring instead.
#include "src/objects/internal-index.h"
11
#include "src/objects/objects.h"
12
#include "src/objects/property-array.h"
13 14 15 16 17 18 19

// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"

namespace v8 {
namespace internal {

20 21 22 23
// Enum for functions that offer a second mode that does not cause allocations.
// Used in conjunction with LookupIterator and unboxed double fields.
enum class AllocationPolicy { kAllocationAllowed, kAllocationDisallowed };

24
enum InstanceType : uint16_t;
25 26
class JSGlobalObject;
class JSGlobalProxy;
27 28
class LookupIterator;
class PropertyKey;
29
class NativeContext;
30
class IsCompiledScope;
31

32 33
#include "torque-generated/src/objects/js-objects-tq.inc"

34 35
// JSReceiver includes types on which properties can be defined, i.e.,
// 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 43 44 45

  // Returns the properties array backing store if it
  // exists. Otherwise, returns an empty_property_array when there's a
  // Smi (hash code) or an empty_fixed_array for a fast properties
  // map.
46
  DECL_GETTER(property_array, PropertyArray)
47

48 49
  // Gets slow properties for non-global objects (if
  // v8_enable_swiss_name_dictionary is not set).
50
  DECL_GETTER(property_dictionary, NameDictionary)
51

52 53
  // Gets slow properties for non-global objects (if
  // v8_enable_swiss_name_dictionary is set).
54
  DECL_GETTER(property_dictionary_swiss, SwissNameDictionary)
55

56 57 58
  // Sets the properties backing store and makes sure any existing hash is moved
  // to the new properties store. To clear out the properties store, pass in the
  // empty_fixed_array(), the hash will be maintained in this case as well.
59
  void SetProperties(HeapObject properties);
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78

  // There are five possible values for the properties offset.
  // 1) EmptyFixedArray/EmptyPropertyDictionary - This is the standard
  // placeholder.
  //
  // 2) Smi - This is the hash code of the object.
  //
  // 3) PropertyArray - This is similar to a FixedArray but stores
  // the hash code of the object in its length field. This is a fast
  // backing store.
  //
  // 4) NameDictionary - This is the dictionary-mode backing store.
  //
  // 4) GlobalDictionary - This is the backing store for the
  // GlobalObject.
  //
  // This is used only in the deoptimizer and heap. Please use the
  // above typed getters and setters to access the properties.
  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 85
  static void DeleteNormalizedProperty(Handle<JSReceiver> object,
                                       InternalIndex entry);
86 87 88

  // ES6 section 7.1.1 ToPrimitive
  V8_WARN_UNUSED_RESULT static MaybeHandle<Object> ToPrimitive(
89
      Isolate* isolate, Handle<JSReceiver> receiver,
90 91 92 93
      ToPrimitiveHint hint = ToPrimitiveHint::kDefault);

  // ES6 section 7.1.1.1 OrdinaryToPrimitive
  V8_WARN_UNUSED_RESULT static MaybeHandle<Object> OrdinaryToPrimitive(
94 95
      Isolate* isolate, Handle<JSReceiver> receiver,
      OrdinaryToPrimitiveHint hint);
96

97 98
  static MaybeHandle<NativeContext> GetFunctionRealm(
      Handle<JSReceiver> receiver);
99 100
  V8_EXPORT_PRIVATE static MaybeHandle<NativeContext> GetContextForMicrotask(
      Handle<JSReceiver> receiver);
101 102

  // Get the first non-hidden prototype.
103 104
  static inline MaybeHandle<HeapObject> GetPrototype(
      Isolate* isolate, Handle<JSReceiver> receiver);
105 106 107 108 109 110 111 112 113 114

  V8_WARN_UNUSED_RESULT static Maybe<bool> HasInPrototypeChain(
      Isolate* isolate, Handle<JSReceiver> object, Handle<Object> proto);

  // Reads all enumerable own properties of source and adds them to
  // target, using either Set or CreateDataProperty depending on the
  // use_set argument. This only copies values not present in the
  // maybe_excluded_properties list.
  V8_WARN_UNUSED_RESULT static Maybe<bool> SetOrCopyDataProperties(
      Isolate* isolate, Handle<JSReceiver> target, Handle<Object> source,
115
      PropertiesEnumerationMode mode,
116
      const base::ScopedVector<Handle<Object>>* excluded_properties = nullptr,
117 118 119
      bool use_set = true);

  // Implementation of [[HasProperty]], ECMA-262 5th edition, section 8.12.6.
120 121
  V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<bool> HasProperty(
      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 133 134 135 136 137 138 139

  V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> GetProperty(
      Isolate* isolate, Handle<JSReceiver> receiver, const char* key);
  V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> GetProperty(
      Isolate* isolate, Handle<JSReceiver> receiver, Handle<Name> name);
  V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> GetElement(
      Isolate* isolate, Handle<JSReceiver> receiver, uint32_t index);

  // Implementation of ES6 [[Delete]]
140 141 142 143
  V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<bool>
  DeletePropertyOrElement(Handle<JSReceiver> object, Handle<Name> name,
                          LanguageMode language_mode = LanguageMode::kSloppy);
  V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<bool> DeleteProperty(
144 145 146 147 148 149 150 151
      Handle<JSReceiver> object, Handle<Name> name,
      LanguageMode language_mode = LanguageMode::kSloppy);
  V8_WARN_UNUSED_RESULT static Maybe<bool> DeleteProperty(
      LookupIterator* it, LanguageMode language_mode);
  V8_WARN_UNUSED_RESULT static Maybe<bool> DeleteElement(
      Handle<JSReceiver> object, uint32_t index,
      LanguageMode language_mode = LanguageMode::kSloppy);

152 153 154 155
  V8_WARN_UNUSED_RESULT static Object DefineProperty(Isolate* isolate,
                                                     Handle<Object> object,
                                                     Handle<Object> name,
                                                     Handle<Object> attributes);
156 157 158 159 160 161
  V8_WARN_UNUSED_RESULT static MaybeHandle<Object> DefineProperties(
      Isolate* isolate, Handle<Object> object, Handle<Object> properties);

  // "virtual" dispatcher to the correct [[DefineOwnProperty]] implementation.
  V8_WARN_UNUSED_RESULT static Maybe<bool> DefineOwnProperty(
      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 166 167 168
  // false with an error when it cannot but didn't throw, or a Nothing if
  // it throws.
  V8_WARN_UNUSED_RESULT static Maybe<bool> CheckPrivateNameStore(
      LookupIterator* it, bool is_define);
169

170 171 172 173 174 175
  // Check if a data property can be created on the object. It will fail with
  // an error when it cannot.
  V8_WARN_UNUSED_RESULT static Maybe<bool> CheckIfCanDefine(
      Isolate* isolate, LookupIterator* it, Handle<Object> value,
      Maybe<ShouldThrow> should_throw);

176 177 178
  // ES6 7.3.4 (when passed kDontThrow)
  V8_WARN_UNUSED_RESULT static Maybe<bool> CreateDataProperty(
      Isolate* isolate, Handle<JSReceiver> object, Handle<Name> key,
179
      Handle<Object> value, Maybe<ShouldThrow> should_throw);
180
  V8_WARN_UNUSED_RESULT static Maybe<bool> CreateDataProperty(
181 182
      LookupIterator* it, Handle<Object> value,
      Maybe<ShouldThrow> should_throw);
183

184 185 186 187 188 189 190
  // Add private fields to the receiver, ignoring extensibility and the
  // traps. The caller should check that the private field does not already
  // exist on the receiver before calling this method.
  V8_WARN_UNUSED_RESULT static Maybe<bool> AddPrivateField(
      LookupIterator* it, Handle<Object> value,
      Maybe<ShouldThrow> should_throw);

191 192 193
  // ES6 9.1.6.1
  V8_WARN_UNUSED_RESULT static Maybe<bool> OrdinaryDefineOwnProperty(
      Isolate* isolate, Handle<JSObject> object, Handle<Object> key,
194
      PropertyDescriptor* desc, Maybe<ShouldThrow> should_throw);
195 196 197
  V8_WARN_UNUSED_RESULT static Maybe<bool> OrdinaryDefineOwnProperty(
      Isolate* isolate, Handle<JSObject> object, const PropertyKey& key,
      PropertyDescriptor* desc, Maybe<ShouldThrow> should_throw);
198
  V8_WARN_UNUSED_RESULT static Maybe<bool> OrdinaryDefineOwnProperty(
199 200
      LookupIterator* it, PropertyDescriptor* desc,
      Maybe<ShouldThrow> should_throw);
201 202 203 204
  // ES6 9.1.6.2
  V8_WARN_UNUSED_RESULT static Maybe<bool> IsCompatiblePropertyDescriptor(
      Isolate* isolate, bool extensible, PropertyDescriptor* desc,
      PropertyDescriptor* current, Handle<Name> property_name,
205
      Maybe<ShouldThrow> should_throw);
206 207 208 209 210 211
  // ES6 9.1.6.3
  // |it| can be NULL in cases where the ES spec passes |undefined| as the
  // receiver. Exactly one of |it| and |property_name| must be provided.
  V8_WARN_UNUSED_RESULT static Maybe<bool> ValidateAndApplyPropertyDescriptor(
      Isolate* isolate, LookupIterator* it, bool extensible,
      PropertyDescriptor* desc, PropertyDescriptor* current,
212
      Maybe<ShouldThrow> should_throw, Handle<Name> property_name);
213 214 215 216 217 218 219

  V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<bool>
  GetOwnPropertyDescriptor(Isolate* isolate, Handle<JSReceiver> object,
                           Handle<Object> key, PropertyDescriptor* desc);
  V8_WARN_UNUSED_RESULT static Maybe<bool> GetOwnPropertyDescriptor(
      LookupIterator* it, PropertyDescriptor* desc);

220
  using IntegrityLevel = PropertyAttributes;
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238

  // ES6 7.3.14 (when passed kDontThrow)
  // 'level' must be SEALED or FROZEN.
  V8_WARN_UNUSED_RESULT static Maybe<bool> SetIntegrityLevel(
      Handle<JSReceiver> object, IntegrityLevel lvl, ShouldThrow should_throw);

  // ES6 7.3.15
  // 'level' must be SEALED or FROZEN.
  V8_WARN_UNUSED_RESULT static Maybe<bool> TestIntegrityLevel(
      Handle<JSReceiver> object, IntegrityLevel lvl);

  // ES6 [[PreventExtensions]] (when passed kDontThrow)
  V8_WARN_UNUSED_RESULT static Maybe<bool> PreventExtensions(
      Handle<JSReceiver> object, ShouldThrow should_throw);

  V8_WARN_UNUSED_RESULT static Maybe<bool> IsExtensible(
      Handle<JSReceiver> object);

239
  // Returns the class name.
240
  V8_EXPORT_PRIVATE String class_name();
241 242 243

  // Returns the constructor (the function that was used to instantiate the
  // object).
244 245
  static MaybeHandle<JSFunction> GetConstructor(Isolate* isolate,
                                                Handle<JSReceiver> receiver);
246

247 248 249 250
  // Returns the constructor name (the (possibly inferred) name of the function
  // that was used to instantiate the object), if any. If a FunctionTemplate is
  // used to instantiate the object, the class_name of the FunctionTemplate is
  // returned instead.
251 252
  static Handle<String> GetConstructorName(Isolate* isolate,
                                           Handle<JSReceiver> receiver);
253

254
  V8_EXPORT_PRIVATE MaybeHandle<NativeContext> GetCreationContext();
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271

  V8_WARN_UNUSED_RESULT static inline Maybe<PropertyAttributes>
  GetPropertyAttributes(Handle<JSReceiver> object, Handle<Name> name);
  V8_WARN_UNUSED_RESULT static inline Maybe<PropertyAttributes>
  GetOwnPropertyAttributes(Handle<JSReceiver> object, Handle<Name> name);
  V8_WARN_UNUSED_RESULT static inline Maybe<PropertyAttributes>
  GetOwnPropertyAttributes(Handle<JSReceiver> object, uint32_t index);

  V8_WARN_UNUSED_RESULT static inline Maybe<PropertyAttributes>
  GetElementAttributes(Handle<JSReceiver> object, uint32_t index);
  V8_WARN_UNUSED_RESULT static inline Maybe<PropertyAttributes>
  GetOwnElementAttributes(Handle<JSReceiver> object, uint32_t index);

  V8_WARN_UNUSED_RESULT static Maybe<PropertyAttributes> GetPropertyAttributes(
      LookupIterator* it);

  // Set the object's prototype (only JSReceiver and null are allowed values).
272
  V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<bool> SetPrototype(
273 274
      Isolate* isolate, Handle<JSReceiver> object, Handle<Object> value,
      bool from_javascript, ShouldThrow should_throw);
275

276 277
  inline static Handle<Object> GetDataProperty(Isolate* isolate,
                                               Handle<JSReceiver> object,
278
                                               Handle<Name> name);
279 280 281
  V8_EXPORT_PRIVATE static Handle<Object> GetDataProperty(
      LookupIterator* it, AllocationPolicy allocation_policy =
                              AllocationPolicy::kAllocationAllowed);
282 283 284

  // Retrieves a permanent object identity hash code. The undefined value might
  // be returned in case no hash was created yet.
285
  V8_EXPORT_PRIVATE Object GetIdentityHash();
286 287 288

  // Retrieves a permanent object identity hash code. May create and store a
  // hash code if needed and none exists.
289
  static Smi CreateIdentityHash(Isolate* isolate, JSReceiver key);
290
  V8_EXPORT_PRIVATE Smi GetOrCreateIdentityHash(Isolate* isolate);
291 292 293

  // Stores the hash code. The hash passed in must be masked with
  // JSReceiver::kHashMask.
294
  V8_EXPORT_PRIVATE void SetIdentityHash(int masked_hash);
295 296 297

  // ES6 [[OwnPropertyKeys]] (modulo return type)
  V8_WARN_UNUSED_RESULT static inline MaybeHandle<FixedArray> OwnPropertyKeys(
298
      Isolate* isolate, Handle<JSReceiver> object);
299 300

  V8_WARN_UNUSED_RESULT static MaybeHandle<FixedArray> GetOwnValues(
301
      Isolate* isolate, Handle<JSReceiver> object, PropertyFilter filter,
302 303 304
      bool try_fast_path = true);

  V8_WARN_UNUSED_RESULT static MaybeHandle<FixedArray> GetOwnEntries(
305
      Isolate* isolate, Handle<JSReceiver> object, PropertyFilter filter,
306 307 308 309 310 311
      bool try_fast_path = true);

  static const int kHashMask = PropertyArray::HashField::kMask;

  bool HasProxyInPrototype(Isolate* isolate);

312
  // TC39 "Dynamic Code Brand Checks"
313
  bool IsCodeLike(Isolate* isolate) const;
314

315 316 317 318 319 320
 private:
  // Hide generated accessors; custom accessors are called
  // "raw_properties_or_hash".
  DECL_ACCESSORS(properties_or_hash, Object)

  TQ_OBJECT_CONSTRUCTORS(JSReceiver)
321 322 323 324 325 326
};

// The JSObject describes real heap allocated JavaScript objects with
// properties.
// Note that the map of JSObject changes during execution to enable inline
// caching.
327
class JSObject : public TorqueGeneratedJSObject<JSObject, JSReceiver> {
328
 public:
329
  static bool IsUnmodifiedApiObject(FullObjectSlot o);
330

331
  V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT MaybeHandle<JSObject> New(
332 333 334 335 336 337 338 339
      Handle<JSFunction> constructor, Handle<JSReceiver> new_target,
      Handle<AllocationSite> site);

  // 9.1.12 ObjectCreate ( proto [ , internalSlotsList ] )
  // Notice: This is NOT 19.1.2.2 Object.create ( O, Properties )
  static V8_WARN_UNUSED_RESULT MaybeHandle<JSObject> ObjectCreate(
      Isolate* isolate, Handle<Object> prototype);

340 341 342 343 344 345 346 347
  DECL_ACCESSORS(elements, FixedArrayBase)
  DECL_RELAXED_GETTER(elements, FixedArrayBase)

  // Acquire/release semantics on this field are explicitly forbidden to avoid
  // confusion, since the default setter uses relaxed semantics. If
  // acquire/release semantics ever become necessary, the default setter should
  // be reverted to non-atomic behavior, and setters with explicit tags
  // introduced and used when required.
348
  FixedArrayBase elements(PtrComprCageBase cage_base,
349 350 351 352
                          AcquireLoadTag tag) const = delete;
  void set_elements(FixedArrayBase value, ReleaseStoreTag tag,
                    WriteBarrierMode mode = UPDATE_WRITE_BARRIER) = delete;

353 354 355
  inline void initialize_elements();
  static inline void SetMapAndElements(Handle<JSObject> object, Handle<Map> map,
                                       Handle<FixedArrayBase> elements);
356 357 358
  DECL_GETTER(GetElementsKind, ElementsKind)
  DECL_GETTER(GetElementsAccessor, ElementsAccessor*)

359 360
  // Returns true if an object has elements of PACKED_SMI_ELEMENTS or
  // HOLEY_SMI_ELEMENTS ElementsKind.
361
  DECL_GETTER(HasSmiElements, bool)
362 363
  // Returns true if an object has elements of PACKED_ELEMENTS or
  // HOLEY_ELEMENTS ElementsKind.
364
  DECL_GETTER(HasObjectElements, bool)
365 366
  // Returns true if an object has elements of PACKED_SMI_ELEMENTS,
  // HOLEY_SMI_ELEMENTS, PACKED_ELEMENTS, or HOLEY_ELEMENTS.
367
  DECL_GETTER(HasSmiOrObjectElements, bool)
368
  // Returns true if an object has any of the "fast" elements kinds.
369
  DECL_GETTER(HasFastElements, bool)
370
  // Returns true if an object has any of the PACKED elements kinds.
371
  DECL_GETTER(HasFastPackedElements, bool)
372 373
  // Returns true if an object has elements of PACKED_DOUBLE_ELEMENTS or
  // HOLEY_DOUBLE_ELEMENTS ElementsKind.
374
  DECL_GETTER(HasDoubleElements, bool)
375 376
  // Returns true if an object has elements of HOLEY_SMI_ELEMENTS,
  // HOLEY_DOUBLE_ELEMENTS, or HOLEY_ELEMENTS ElementsKind.
377 378 379 380
  DECL_GETTER(HasHoleyElements, bool)
  DECL_GETTER(HasSloppyArgumentsElements, bool)
  DECL_GETTER(HasStringWrapperElements, bool)
  DECL_GETTER(HasDictionaryElements, bool)
381

382
  // Returns true if an object has elements of PACKED_ELEMENTS
383
  DECL_GETTER(HasPackedElements, bool)
384
  DECL_GETTER(HasAnyNonextensibleElements, bool)
385
  DECL_GETTER(HasSealedElements, bool)
386
  DECL_GETTER(HasSharedArrayElements, bool)
387
  DECL_GETTER(HasNonextensibleElements, bool)
388

389
  DECL_GETTER(HasTypedArrayOrRabGsabTypedArrayElements, bool)
390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407

  DECL_GETTER(HasFixedUint8ClampedElements, bool)
  DECL_GETTER(HasFixedArrayElements, bool)
  DECL_GETTER(HasFixedInt8Elements, bool)
  DECL_GETTER(HasFixedUint8Elements, bool)
  DECL_GETTER(HasFixedInt16Elements, bool)
  DECL_GETTER(HasFixedUint16Elements, bool)
  DECL_GETTER(HasFixedInt32Elements, bool)
  DECL_GETTER(HasFixedUint32Elements, bool)
  DECL_GETTER(HasFixedFloat32Elements, bool)
  DECL_GETTER(HasFixedFloat64Elements, bool)
  DECL_GETTER(HasFixedBigInt64Elements, bool)
  DECL_GETTER(HasFixedBigUint64Elements, bool)

  DECL_GETTER(HasFastArgumentsElements, bool)
  DECL_GETTER(HasSlowArgumentsElements, bool)
  DECL_GETTER(HasFastStringWrapperElements, bool)
  DECL_GETTER(HasSlowStringWrapperElements, bool)
408 409
  bool HasEnumerableElements();

410 411
  // Gets slow elements.
  DECL_GETTER(element_dictionary, NumberDictionary)
412 413 414 415 416

  // Requires: HasFastElements().
  static void EnsureWritableFastElements(Handle<JSObject> object);

  V8_WARN_UNUSED_RESULT static Maybe<bool> SetPropertyWithInterceptor(
417 418
      LookupIterator* it, Maybe<ShouldThrow> should_throw,
      Handle<Object> value);
419 420 421 422 423 424 425 426 427

  // The API currently still wants DefineOwnPropertyIgnoreAttributes to convert
  // AccessorInfo objects to data fields. We allow FORCE_FIELD as an exception
  // to the default behavior that calls the setter.
  enum AccessorInfoHandling { FORCE_FIELD, DONT_FORCE_FIELD };

  V8_WARN_UNUSED_RESULT static MaybeHandle<Object>
  DefineOwnPropertyIgnoreAttributes(
      LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
428 429
      AccessorInfoHandling handling = DONT_FORCE_FIELD,
      EnforceDefineSemantics semantics = EnforceDefineSemantics::kSet);
430 431 432

  V8_WARN_UNUSED_RESULT static Maybe<bool> DefineOwnPropertyIgnoreAttributes(
      LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
433
      Maybe<ShouldThrow> should_throw,
434
      AccessorInfoHandling handling = DONT_FORCE_FIELD,
435 436
      EnforceDefineSemantics semantics = EnforceDefineSemantics::kSet,
      StoreOrigin store_origin = StoreOrigin::kNamed);
437

438
  V8_WARN_UNUSED_RESULT static MaybeHandle<Object> V8_EXPORT_PRIVATE
439 440 441 442 443
  SetOwnPropertyIgnoreAttributes(Handle<JSObject> object, Handle<Name> name,
                                 Handle<Object> value,
                                 PropertyAttributes attributes);

  V8_WARN_UNUSED_RESULT static MaybeHandle<Object>
444
  SetOwnElementIgnoreAttributes(Handle<JSObject> object, size_t index,
445 446 447 448 449
                                Handle<Object> value,
                                PropertyAttributes attributes);

  // Equivalent to one of the above depending on whether |name| can be converted
  // to an array index.
450
  V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static MaybeHandle<Object>
451 452 453 454 455 456 457 458 459
  DefinePropertyOrElementIgnoreAttributes(Handle<JSObject> object,
                                          Handle<Name> name,
                                          Handle<Object> value,
                                          PropertyAttributes attributes = NONE);

  // Adds or reconfigures a property to attributes NONE. It will fail when it
  // cannot.
  V8_WARN_UNUSED_RESULT static Maybe<bool> CreateDataProperty(
      LookupIterator* it, Handle<Object> value,
460
      Maybe<ShouldThrow> should_throw = Just(kDontThrow));
461

462 463 464 465 466
  V8_EXPORT_PRIVATE static void AddProperty(Isolate* isolate,
                                            Handle<JSObject> object,
                                            Handle<Name> name,
                                            Handle<Object> value,
                                            PropertyAttributes attributes);
467

468 469 470 471 472
  // {name} must be a UTF-8 encoded, null-terminated string.
  static void AddProperty(Isolate* isolate, Handle<JSObject> object,
                          const char* name, Handle<Object> value,
                          PropertyAttributes attributes);

473 474 475
  V8_EXPORT_PRIVATE static Maybe<bool> AddDataElement(
      Handle<JSObject> receiver, uint32_t index, Handle<Object> value,
      PropertyAttributes attributes);
476 477 478 479 480 481 482

  // Extend the receiver with a single fast property appeared first in the
  // passed map. This also extends the property backing store if necessary.
  static void AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map);

  // Migrates the given object to a map whose field representations are the
  // lowest upper bound of all known representations for that field.
483
  static void MigrateInstance(Isolate* isolate, Handle<JSObject> instance);
484 485 486

  // Migrates the given object only if the target map is already available,
  // or returns false if such a map is not yet available.
487
  static bool TryMigrateInstance(Isolate* isolate, Handle<JSObject> instance);
488 489 490 491 492 493

  // Sets the property value in a normalized object given (key, value, details).
  // Handles the special representation of JS global objects.
  static void SetNormalizedProperty(Handle<JSObject> object, Handle<Name> name,
                                    Handle<Object> value,
                                    PropertyDetails details);
494
  static void SetNormalizedElement(Handle<JSObject> object, uint32_t index,
495
                                   Handle<Object> value,
496
                                   PropertyDetails details);
497 498 499 500 501 502 503 504 505 506 507

  static void OptimizeAsPrototype(Handle<JSObject> object,
                                  bool enable_setup_mode = true);
  static void ReoptimizeIfPrototype(Handle<JSObject> object);
  static void MakePrototypesFast(Handle<Object> receiver,
                                 WhereToStart where_to_start, Isolate* isolate);
  static void LazyRegisterPrototypeUser(Handle<Map> user, Isolate* isolate);
  static void UpdatePrototypeUserRegistration(Handle<Map> old_map,
                                              Handle<Map> new_map,
                                              Isolate* isolate);
  static bool UnregisterPrototypeUser(Handle<Map> user, Isolate* isolate);
508
  static Map InvalidatePrototypeChains(Map map);
509
  static void InvalidatePrototypeValidityCell(JSGlobalObject global);
510 511 512 513 514 515 516

  // Updates prototype chain tracking information when an object changes its
  // map from |old_map| to |new_map|.
  static void NotifyMapChange(Handle<Map> old_map, Handle<Map> new_map,
                              Isolate* isolate);

  // Utility used by many Array builtins and runtime functions
517
  static inline bool PrototypeHasNoElements(Isolate* isolate, JSObject object);
518 519

  // To be passed to PrototypeUsers::Compact.
520
  static void PrototypeRegistryCompactionCallback(HeapObject value,
521 522 523
                                                  int old_index, int new_index);

  // Retrieve interceptors.
524 525
  DECL_GETTER(GetNamedInterceptor, InterceptorInfo)
  DECL_GETTER(GetIndexedInterceptor, InterceptorInfo)
526 527 528 529 530 531 532 533

  // Used from JSReceiver.
  V8_WARN_UNUSED_RESULT static Maybe<PropertyAttributes>
  GetPropertyAttributesWithInterceptor(LookupIterator* it);
  V8_WARN_UNUSED_RESULT static Maybe<PropertyAttributes>
  GetPropertyAttributesWithFailedAccessCheck(LookupIterator* it);

  // Defines an AccessorPair property on the given object.
534 535 536
  V8_EXPORT_PRIVATE static MaybeHandle<Object> DefineAccessor(
      Handle<JSObject> object, Handle<Name> name, Handle<Object> getter,
      Handle<Object> setter, PropertyAttributes attributes);
537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552
  static MaybeHandle<Object> DefineAccessor(LookupIterator* it,
                                            Handle<Object> getter,
                                            Handle<Object> setter,
                                            PropertyAttributes attributes);

  // Defines an AccessorInfo property on the given object.
  V8_WARN_UNUSED_RESULT static MaybeHandle<Object> SetAccessor(
      Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> info,
      PropertyAttributes attributes);

  // The result must be checked first for exceptions. If there's no exception,
  // the output parameter |done| indicates whether the interceptor has a result
  // or not.
  V8_WARN_UNUSED_RESULT static MaybeHandle<Object> GetPropertyWithInterceptor(
      LookupIterator* it, bool* done);

553
  static void ValidateElements(JSObject object);
554 555 556 557 558

  // Makes sure that this object can contain HeapObject as elements.
  static inline void EnsureCanContainHeapObjectElements(Handle<JSObject> obj);

  // Makes sure that this object can contain the specified elements.
559 560
  // TSlot here is either ObjectSlot or FullObjectSlot.
  template <typename TSlot>
561
  static inline void EnsureCanContainElements(Handle<JSObject> object,
562
                                              TSlot elements, uint32_t count,
563 564 565 566 567 568
                                              EnsureElementsMode mode);
  static inline void EnsureCanContainElements(Handle<JSObject> object,
                                              Handle<FixedArrayBase> elements,
                                              uint32_t length,
                                              EnsureElementsMode mode);
  static void EnsureCanContainElements(Handle<JSObject> object,
569
                                       JavaScriptArguments* arguments,
570
                                       uint32_t arg_count,
571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592
                                       EnsureElementsMode mode);

  // Would we convert a fast elements array to dictionary mode given
  // an access at key?
  bool WouldConvertToSlowElements(uint32_t index);

  static const uint32_t kMinAddedElementsCapacity = 16;

  // Computes the new capacity when expanding the elements of a JSObject.
  static uint32_t NewElementsCapacity(uint32_t old_capacity) {
    // (old_capacity + 50%) + kMinAddedElementsCapacity
    return old_capacity + (old_capacity >> 1) + kMinAddedElementsCapacity;
  }

  // These methods do not perform access checks!
  template <AllocationSiteUpdateMode update_or_check =
                AllocationSiteUpdateMode::kUpdate>
  static bool UpdateAllocationSite(Handle<JSObject> object,
                                   ElementsKind to_kind);

  // Lookup interceptors are used for handling properties controlled by host
  // objects.
593 594
  DECL_GETTER(HasNamedInterceptor, bool)
  DECL_GETTER(HasIndexedInterceptor, bool)
595 596 597

  // Support functions for v8 api (needed for correct interceptor behavior).
  V8_WARN_UNUSED_RESULT static Maybe<bool> HasRealNamedProperty(
598
      Isolate* isolate, Handle<JSObject> object, Handle<Name> name);
599
  V8_WARN_UNUSED_RESULT static Maybe<bool> HasRealElementProperty(
600
      Isolate* isolate, Handle<JSObject> object, uint32_t index);
601
  V8_WARN_UNUSED_RESULT static Maybe<bool> HasRealNamedCallbackProperty(
602
      Isolate* isolate, Handle<JSObject> object, Handle<Name> name);
603 604 605 606 607

  // Get the header size for a JSObject.  Used to compute the index of
  // embedder fields as well as the number of embedder fields.
  // The |function_has_prototype_slot| parameter is needed only for
  // JSFunction objects.
608 609
  static V8_EXPORT_PRIVATE int GetHeaderSize(
      InstanceType instance_type, bool function_has_prototype_slot = false);
610
  static inline int GetHeaderSize(Map map);
611

612 613 614
  static inline bool MayHaveEmbedderFields(Map map);
  inline bool MayHaveEmbedderFields() const;

615
  static inline int GetEmbedderFieldsStartOffset(Map map);
616 617
  inline int GetEmbedderFieldsStartOffset();

618
  static inline int GetEmbedderFieldCount(Map map);
619 620
  inline int GetEmbedderFieldCount() const;
  inline int GetEmbedderFieldOffset(int index);
621 622
  inline Object GetEmbedderField(int index);
  inline void SetEmbedderField(int index, Object value);
623
  inline void SetEmbedderField(int index, Smi value);
624

625 626 627
  // Returns true if this object is an Api object which can, if unmodified, be
  // dropped during minor GC because the embedder can recreate it again later.
  inline bool IsDroppableApiObject() const;
628 629 630 631 632

  // Returns a new map with all transitions dropped from the object's current
  // map and the ElementsKind set.
  static Handle<Map> GetElementsTransitionMap(Handle<JSObject> object,
                                              ElementsKind to_kind);
633 634
  V8_EXPORT_PRIVATE static void TransitionElementsKind(Handle<JSObject> object,
                                                       ElementsKind to_kind);
635 636 637 638

  // Always use this to migrate an object to a new map.
  // |expected_additional_properties| is only used for fast-to-slow transitions
  // and ignored otherwise.
639
  V8_EXPORT_PRIVATE static void MigrateToMap(
640
      Isolate* isolate, Handle<JSObject> object, Handle<Map> new_map,
641
      int expected_additional_properties = 0);
642 643 644

  // Forces a prototype without any of the checks that the regular SetPrototype
  // would do.
645
  static void ForceSetPrototype(Isolate* isolate, Handle<JSObject> object,
646
                                Handle<HeapObject> proto);
647 648 649 650 651

  // Convert the object to use the canonical dictionary
  // representation. If the object is expected to have additional properties
  // added this number can be indicated to have the backing store allocated to
  // an initial capacity for holding these properties.
652
  V8_EXPORT_PRIVATE static void NormalizeProperties(
653
      Isolate* isolate, Handle<JSObject> object, PropertyNormalizationMode mode,
654 655 656 657 658 659 660 661 662
      int expected_additional_properties, bool use_cache, const char* reason);

  V8_EXPORT_PRIVATE static void NormalizeProperties(
      Isolate* isolate, Handle<JSObject> object, PropertyNormalizationMode mode,
      int expected_additional_properties, const char* reason) {
    const bool kUseCache = true;
    NormalizeProperties(isolate, object, mode, expected_additional_properties,
                        kUseCache, reason);
  }
663 664 665

  // Convert and update the elements backing store to be a
  // NumberDictionary dictionary.  Returns the backing after conversion.
666 667
  V8_EXPORT_PRIVATE static Handle<NumberDictionary> NormalizeElements(
      Handle<JSObject> object);
668

669
  void RequireSlowElements(NumberDictionary dictionary);
670 671

  // Transform slow named properties to fast variants.
672 673 674
  V8_EXPORT_PRIVATE static void MigrateSlowToFast(Handle<JSObject> object,
                                                  int unused_property_fields,
                                                  const char* reason);
675

676
  // Access property in dictionary mode object at the given dictionary index.
677 678
  static Handle<Object> DictionaryPropertyAt(Isolate* isolate,
                                             Handle<JSObject> object,
679
                                             InternalIndex dict_index);
680 681 682 683 684 685
  // Same as above, but it will return {} if we would be reading out of the
  // bounds of the object or if the dictionary is pending allocation. Use this
  // version for concurrent access.
  static base::Optional<Object> DictionaryPropertyAt(Handle<JSObject> object,
                                                     InternalIndex dict_index,
                                                     Heap* heap);
686

687
  // Access fast-case object properties at index.
688 689
  static Handle<Object> FastPropertyAt(Isolate* isolate,
                                       Handle<JSObject> object,
690 691
                                       Representation representation,
                                       FieldIndex index);
692 693 694 695
  static Handle<Object> FastPropertyAt(Isolate* isolate,
                                       Handle<JSObject> object,
                                       Representation representation,
                                       FieldIndex index, SeqCstAccessTag tag);
696
  inline Object RawFastPropertyAt(FieldIndex index) const;
697 698
  inline Object RawFastPropertyAt(PtrComprCageBase cage_base,
                                  FieldIndex index) const;
699 700 701
  inline Object RawFastPropertyAt(FieldIndex index, SeqCstAccessTag tag) const;
  inline Object RawFastPropertyAt(PtrComprCageBase cage_base, FieldIndex index,
                                  SeqCstAccessTag tag) const;
702 703 704 705 706

  // See comment in the body of the method to understand the conditions
  // in which this method is meant to be used, and what guarantees it
  // provides against invalid reads from another thread during object
  // mutation.
707 708
  inline base::Optional<Object> RawInobjectPropertyAt(
      PtrComprCageBase cage_base, Map original_map, FieldIndex index) const;
709

710 711
  inline void FastPropertyAtPut(FieldIndex index, Object value,
                                WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
712 713
  inline void FastPropertyAtPut(FieldIndex index, Object value,
                                SeqCstAccessTag tag);
714 715 716
  inline void RawFastInobjectPropertyAtPut(
      FieldIndex index, Object value,
      WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
717 718
  inline void RawFastInobjectPropertyAtPut(FieldIndex index, Object value,
                                           SeqCstAccessTag tag);
719
  inline void WriteToField(InternalIndex descriptor, PropertyDetails details,
720
                           Object value);
721

722 723 724 725 726 727
  inline Object RawFastPropertyAtSwap(FieldIndex index, Object value,
                                      SeqCstAccessTag tag);
  inline Object RawFastPropertyAtSwap(PtrComprCageBase cage_base,
                                      FieldIndex index, Object value,
                                      SeqCstAccessTag tag);

728 729
  // Access to in object properties.
  inline int GetInObjectPropertyOffset(int index);
730 731 732
  inline Object InObjectPropertyAt(int index);
  inline Object InObjectPropertyAtPut(
      int index, Object value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
733 734 735

  // Set the object's prototype (only JSReceiver and null are allowed values).
  V8_WARN_UNUSED_RESULT static Maybe<bool> SetPrototype(
736 737
      Isolate* isolate, Handle<JSObject> object, Handle<Object> value,
      bool from_javascript, ShouldThrow should_throw);
738 739 740 741 742 743 744

  // Makes the object prototype immutable
  // Never called from JavaScript
  static void SetImmutableProto(Handle<JSObject> object);

  // Initializes the body starting at |start_offset|. It is responsibility of
  // the caller to initialize object header. Fill the pre-allocated fields with
745
  // undefined_value and the rest with filler_map.
746
  // Note: this call does not update write barrier, the caller is responsible
747
  // to ensure that |filler_map| can be collected without WB here.
748
  inline void InitializeBody(Map map, int start_offset,
749 750
                             bool is_slack_tracking_in_progress,
                             MapWord filler_map, Object undefined_value);
751 752

  // Check whether this object references another object
753
  bool ReferencesObject(Object obj);
754 755 756 757 758 759 760 761 762

  V8_WARN_UNUSED_RESULT static Maybe<bool> TestIntegrityLevel(
      Handle<JSObject> object, IntegrityLevel lvl);

  V8_WARN_UNUSED_RESULT static Maybe<bool> PreventExtensions(
      Handle<JSObject> object, ShouldThrow should_throw);

  static bool IsExtensible(Handle<JSObject> object);

763 764 765 766
  static MaybeHandle<Object> ReadFromOptionsBag(Handle<Object> options,
                                                Handle<String> option_name,
                                                Isolate* isolate);

767 768 769 770 771
  // Dispatched behavior.
  void JSObjectShortPrint(StringStream* accumulator);
  DECL_PRINTER(JSObject)
  DECL_VERIFIER(JSObject)
#ifdef OBJECT_PRINT
772 773
  bool PrintProperties(std::ostream& os);
  void PrintElements(std::ostream& os);
774 775
#endif
#if defined(DEBUG) || defined(OBJECT_PRINT)
776
  void PrintTransitions(std::ostream& os);
777 778 779 780 781 782 783 784
#endif

  static void PrintElementsTransition(FILE* file, Handle<JSObject> object,
                                      ElementsKind from_kind,
                                      Handle<FixedArrayBase> from_elements,
                                      ElementsKind to_kind,
                                      Handle<FixedArrayBase> to_elements);

785
  void PrintInstanceMigration(FILE* file, Map original_map, Map new_map);
786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812

#ifdef DEBUG
  // Structure for collecting spill information about JSObjects.
  class SpillInformation {
   public:
    void Clear();
    void Print();
    int number_of_objects_;
    int number_of_objects_with_fast_properties_;
    int number_of_objects_with_fast_elements_;
    int number_of_fast_used_fields_;
    int number_of_fast_unused_fields_;
    int number_of_slow_used_properties_;
    int number_of_slow_unused_properties_;
    int number_of_fast_used_elements_;
    int number_of_fast_unused_elements_;
    int number_of_slow_used_elements_;
    int number_of_slow_unused_elements_;
  };

  void IncrementSpillStatistics(Isolate* isolate, SpillInformation* info);
#endif

#ifdef VERIFY_HEAP
  // If a GC was caused while constructing this object, the elements pointer
  // may point to a one pointer filler map. The object won't be rooted, but
  // our heap verification code could stumble across it.
813 814
  V8_EXPORT_PRIVATE bool ElementsAreSafeToExamine(
      PtrComprCageBase cage_base) const;
815 816
#endif

817
  Object SlowReverseLookup(Object value);
818 819 820

  // Maximal number of elements (numbered 0 .. kMaxElementCount - 1).
  // Also maximal value of JSArray's length property.
821 822
  static constexpr uint32_t kMaxElementCount = kMaxUInt32;
  static constexpr uint32_t kMaxElementIndex = kMaxElementCount - 1;
823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842

  // Constants for heuristics controlling conversion of fast elements
  // to slow elements.

  // Maximal gap that can be introduced by adding an element beyond
  // the current elements length.
  static const uint32_t kMaxGap = 1024;

  // Maximal length of fast elements array that won't be checked for
  // being dense enough on expansion.
  static const int kMaxUncheckedFastElementsLength = 5000;

  // Same as above but for old arrays. This limit is more strict. We
  // don't want to be wasteful with long lived objects.
  static const int kMaxUncheckedOldFastElementsLength = 500;

  // This constant applies only to the initial map of "global.Object" and
  // not to arbitrary other JSObject maps.
  static const int kInitialGlobalObjectUnusedPropertiesCount = 4;

843
  static const int kMaxInstanceSize = 255 * kTaggedSize;
844

845 846
  static const int kMapCacheSize = 128;

847 848 849 850
  // When extending the backing storage for property values, we increase
  // its size by more than the 1 entry necessary, so sequentially adding fields
  // to the same object requires fewer allocations and copies.
  static const int kFieldsAdded = 3;
851
  static_assert(kMaxNumberOfDescriptors + kFieldsAdded <=
852 853
                PropertyArray::kMaxLength);

854
  static_assert(kHeaderSize == Internals::kJSObjectHeaderSize);
855
  static const int kMaxInObjectProperties =
856
      (kMaxInstanceSize - kHeaderSize) >> kTaggedSizeLog2;
857
  static_assert(kMaxInObjectProperties <= kMaxNumberOfDescriptors);
858 859 860

  static const int kMaxFirstInobjectPropertyOffset =
      (1 << kFirstInobjectPropertyOffsetBitCount) - 1;
861
  static const int kMaxEmbedderFields =
862
      (kMaxFirstInobjectPropertyOffset - kHeaderSize) / kEmbedderDataSlotSize;
863
  static_assert(kHeaderSize +
864 865
                    kMaxEmbedderFields * kEmbedderDataSlotSizeInTaggedSlots <=
                kMaxInstanceSize);
866 867 868 869 870 871 872 873 874 875 876

  class BodyDescriptor;

  class FastBodyDescriptor;

  // Gets the number of currently used elements.
  int GetFastElementsUsage();

  static bool AllCanRead(LookupIterator* it);
  static bool AllCanWrite(LookupIterator* it);

877 878 879 880 881
  template <typename Dictionary>
  static void ApplyAttributesToDictionary(Isolate* isolate, ReadOnlyRoots roots,
                                          Handle<Dictionary> dictionary,
                                          const PropertyAttributes attributes);

882 883 884 885 886 887 888 889 890
 private:
  friend class JSReceiver;
  friend class Object;

  // Used from Object::GetProperty().
  V8_WARN_UNUSED_RESULT static MaybeHandle<Object>
  GetPropertyWithFailedAccessCheck(LookupIterator* it);

  V8_WARN_UNUSED_RESULT static Maybe<bool> SetPropertyWithFailedAccessCheck(
891 892
      LookupIterator* it, Handle<Object> value,
      Maybe<ShouldThrow> should_throw);
893 894 895 896

  V8_WARN_UNUSED_RESULT static Maybe<bool> DeletePropertyWithInterceptor(
      LookupIterator* it, ShouldThrow should_throw);

897
  bool ReferencesObjectFromElements(FixedArray elements, ElementsKind kind,
898
                                    Object object);
899 900 901 902 903 904 905

  // Helper for fast versions of preventExtensions, seal, and freeze.
  // attrs is one of NONE, SEALED, or FROZEN (depending on the operation).
  template <PropertyAttributes attrs>
  V8_WARN_UNUSED_RESULT static Maybe<bool> PreventExtensionsWithTransition(
      Handle<JSObject> object, ShouldThrow should_throw);

906
  TQ_OBJECT_CONSTRUCTORS(JSObject)
907 908
};

909 910 911 912 913 914 915 916 917 918 919 920 921 922
// A JSObject created through the public api which wraps an external pointer.
// See v8::External.
class JSExternalObject
    : public TorqueGeneratedJSExternalObject<JSExternalObject, JSObject> {
 public:
  inline void AllocateExternalPointerEntries(Isolate* isolate);

  // [value]: field containing the pointer value.
  DECL_GETTER(value, void*)

  inline void set_value(Isolate* isolate, void* value);

  static constexpr int kEndOfTaggedFieldsOffset = JSObject::kHeaderSize;

923 924
  DECL_PRINTER(JSExternalObject)

925 926 927 928 929 930
  class BodyDescriptor;

 private:
  TQ_OBJECT_CONSTRUCTORS(JSExternalObject)
};

931 932 933 934 935
// An abstract superclass for JSObjects that may contain EmbedderDataSlots.
class JSObjectWithEmbedderSlots
    : public TorqueGeneratedJSObjectWithEmbedderSlots<JSObjectWithEmbedderSlots,
                                                      JSObject> {
 public:
936
  static_assert(kHeaderSize == JSObject::kHeaderSize);
937 938 939
  TQ_OBJECT_CONSTRUCTORS(JSObjectWithEmbedderSlots)
};

940 941 942 943 944 945 946 947
// An abstract superclass for JSObjects that may have elements while having an
// empty fixed array as elements backing store. It doesn't carry any
// functionality but allows function classes to be identified in the type
// system.
class JSCustomElementsObject
    : public TorqueGeneratedJSCustomElementsObject<JSCustomElementsObject,
                                                   JSObject> {
 public:
948
  static_assert(kHeaderSize == JSObject::kHeaderSize);
949 950 951 952 953 954
  TQ_OBJECT_CONSTRUCTORS(JSCustomElementsObject)
};

// An abstract superclass for JSObjects that require non-standard element
// access. It doesn't carry any functionality but allows function classes to be
// identified in the type system.
955 956
// These may also contain EmbedderDataSlots, but can't currently inherit from
// JSObjectWithEmbedderSlots due to instance_type constraints.
957 958 959 960
class JSSpecialObject
    : public TorqueGeneratedJSSpecialObject<JSSpecialObject,
                                            JSCustomElementsObject> {
 public:
961
  static_assert(kHeaderSize == JSObject::kHeaderSize);
962 963 964
  TQ_OBJECT_CONSTRUCTORS(JSSpecialObject)
};

965 966 967 968 969 970
// JSAccessorPropertyDescriptor is just a JSObject with a specific initial
// map. This initial map adds in-object properties for "get", "set",
// "enumerable" and "configurable" properties, as assigned by the
// FromPropertyDescriptor function for regular accessor properties.
class JSAccessorPropertyDescriptor : public JSObject {
 public:
971
  // Layout description.
972 973 974 975 976 977 978 979 980 981 982
#define JS_ACCESSOR_PROPERTY_DESCRIPTOR_FIELDS(V) \
  V(kGetOffset, kTaggedSize)                      \
  V(kSetOffset, kTaggedSize)                      \
  V(kEnumerableOffset, kTaggedSize)               \
  V(kConfigurableOffset, kTaggedSize)             \
  /* Total size. */                               \
  V(kSize, 0)

  DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
                                JS_ACCESSOR_PROPERTY_DESCRIPTOR_FIELDS)
#undef JS_ACCESSOR_PROPERTY_DESCRIPTOR_FIELDS
983

984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999
  // Indices of in-object properties.
  static const int kGetIndex = 0;
  static const int kSetIndex = 1;
  static const int kEnumerableIndex = 2;
  static const int kConfigurableIndex = 3;

 private:
  DISALLOW_IMPLICIT_CONSTRUCTORS(JSAccessorPropertyDescriptor);
};

// JSDataPropertyDescriptor is just a JSObject with a specific initial map.
// This initial map adds in-object properties for "value", "writable",
// "enumerable" and "configurable" properties, as assigned by the
// FromPropertyDescriptor function for regular data properties.
class JSDataPropertyDescriptor : public JSObject {
 public:
1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011
  // Layout description.
#define JS_DATA_PROPERTY_DESCRIPTOR_FIELDS(V) \
  V(kValueOffset, kTaggedSize)                \
  V(kWritableOffset, kTaggedSize)             \
  V(kEnumerableOffset, kTaggedSize)           \
  V(kConfigurableOffset, kTaggedSize)         \
  /* Total size. */                           \
  V(kSize, 0)

  DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
                                JS_DATA_PROPERTY_DESCRIPTOR_FIELDS)
#undef JS_DATA_PROPERTY_DESCRIPTOR_FIELDS
1012

1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024
  // Indices of in-object properties.
  static const int kValueIndex = 0;
  static const int kWritableIndex = 1;
  static const int kEnumerableIndex = 2;
  static const int kConfigurableIndex = 3;

 private:
  DISALLOW_IMPLICIT_CONSTRUCTORS(JSDataPropertyDescriptor);
};

// JSIteratorResult is just a JSObject with a specific initial map.
// This initial map adds in-object properties for "done" and "value",
1025
// as specified by ES6 section 25.1.1.3 The IteratorResult Interface.
1026 1027 1028 1029 1030 1031
class JSIteratorResult : public JSObject {
 public:
  DECL_ACCESSORS(value, Object)

  DECL_ACCESSORS(done, Object)

1032
  // Layout description.
1033 1034 1035 1036 1037 1038
#define JS_ITERATOR_RESULT_FIELDS(V) \
  V(kValueOffset, kTaggedSize)       \
  V(kDoneOffset, kTaggedSize)        \
  /* Total size. */                  \
  V(kSize, 0)

1039
  DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
1040 1041
                                JS_ITERATOR_RESULT_FIELDS)
#undef JS_ITERATOR_RESULT_FIELDS
1042

1043 1044 1045 1046
  // Indices of in-object properties.
  static const int kValueIndex = 0;
  static const int kDoneIndex = 1;

1047
  DECL_CAST(JSIteratorResult)
1048 1049

  OBJECT_CONSTRUCTORS(JSIteratorResult, JSObject);
1050 1051 1052 1053 1054 1055 1056 1057 1058 1059
};

// JSGlobalProxy's prototype must be a JSGlobalObject or null,
// and the prototype is hidden. JSGlobalProxy always delegates
// property accesses to its prototype if the prototype is not null.
//
// A JSGlobalProxy can be reinitialized which will preserve its identity.
//
// Accessing a JSGlobalProxy requires security check.

1060
class JSGlobalProxy
1061
    : public TorqueGeneratedJSGlobalProxy<JSGlobalProxy, JSSpecialObject> {
1062
 public:
1063
  inline bool IsDetachedFrom(JSGlobalObject global) const;
1064
  V8_EXPORT_PRIVATE bool IsDetached() const;
1065 1066 1067 1068 1069 1070 1071

  static int SizeWithEmbedderFields(int embedder_field_count);

  // Dispatched behavior.
  DECL_PRINTER(JSGlobalProxy)
  DECL_VERIFIER(JSGlobalProxy)

1072
  TQ_OBJECT_CONSTRUCTORS(JSGlobalProxy)
1073 1074 1075
};

// JavaScript global object.
1076 1077
class JSGlobalObject
    : public TorqueGeneratedJSGlobalObject<JSGlobalObject, JSSpecialObject> {
1078
 public:
1079
  DECL_RELEASE_ACQUIRE_ACCESSORS(global_dictionary, GlobalDictionary)
1080 1081 1082 1083 1084 1085

  static void InvalidatePropertyCell(Handle<JSGlobalObject> object,
                                     Handle<Name> name);

  inline bool IsDetached();

1086 1087 1088 1089
  // May be called by the concurrent GC when the global object is not
  // fully initialized.
  DECL_GETTER(native_context_unchecked, Object)

1090 1091 1092 1093
  // Dispatched behavior.
  DECL_PRINTER(JSGlobalObject)
  DECL_VERIFIER(JSGlobalObject)

1094
  TQ_OBJECT_CONSTRUCTORS(JSGlobalObject)
1095 1096 1097
};

// Representation for JS Wrapper objects, String, Number, Boolean, etc.
1098
class JSPrimitiveWrapper
1099 1100
    : public TorqueGeneratedJSPrimitiveWrapper<JSPrimitiveWrapper,
                                               JSCustomElementsObject> {
1101 1102
 public:
  // Dispatched behavior.
1103
  DECL_PRINTER(JSPrimitiveWrapper)
1104

1105
  TQ_OBJECT_CONSTRUCTORS(JSPrimitiveWrapper)
1106 1107 1108 1109 1110
};

class DateCache;

// Representation for JS date objects.
1111
class JSDate : public TorqueGeneratedJSDate<JSDate, JSObject> {
1112 1113 1114 1115 1116 1117 1118 1119 1120
 public:
  static V8_WARN_UNUSED_RESULT MaybeHandle<JSDate> New(
      Handle<JSFunction> constructor, Handle<JSReceiver> new_target, double tv);

  // Returns the time value (UTC) identifying the current time.
  static double CurrentTimeValue(Isolate* isolate);

  // Returns the date field with the specified index.
  // See FieldIndex for the list of date fields.
1121 1122 1123 1124 1125
  // Arguments and result are raw Address values because this is called
  // via ExternalReference.
  // {raw_date} is a tagged Object pointer.
  // {smi_index} is a tagged Smi.
  // The return value is a tagged Object pointer.
1126 1127
  static Address GetField(Isolate* isolate, Address raw_date,
                          Address smi_index);
1128 1129 1130

  static Handle<Object> SetValue(Handle<JSDate> date, double v);

1131
  void SetValue(Object value, bool is_value_nan);
1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166

  // Dispatched behavior.
  DECL_PRINTER(JSDate)
  DECL_VERIFIER(JSDate)

  // The order is important. It must be kept in sync with date macros
  // in macros.py.
  enum FieldIndex {
    kDateValue,
    kYear,
    kMonth,
    kDay,
    kWeekday,
    kHour,
    kMinute,
    kSecond,
    kFirstUncachedField,
    kMillisecond = kFirstUncachedField,
    kDays,
    kTimeInDay,
    kFirstUTCField,
    kYearUTC = kFirstUTCField,
    kMonthUTC,
    kDayUTC,
    kWeekdayUTC,
    kHourUTC,
    kMinuteUTC,
    kSecondUTC,
    kMillisecondUTC,
    kDaysUTC,
    kTimeInDayUTC,
    kTimezoneOffset
  };

 private:
1167
  Object DoGetField(Isolate* isolate, FieldIndex index);
1168
  Object GetUTCField(FieldIndex index, double value, DateCache* date_cache);
1169 1170 1171 1172

  // Computes and caches the cacheable fields of the date.
  inline void SetCachedFields(int64_t local_time_ms, DateCache* date_cache);

1173
  TQ_OBJECT_CONSTRUCTORS(JSDate)
1174 1175 1176 1177 1178 1179 1180 1181
};

// Representation of message objects used for error reporting through
// the API. The messages are formatted in JavaScript so this object is
// a real JavaScript object. The information used for formatting the
// error messages are not directly accessible from JavaScript to
// prevent leaking information to user code called during error
// formatting.
1182 1183
class JSMessageObject
    : public TorqueGeneratedJSMessageObject<JSMessageObject, JSObject> {
1184 1185
 public:
  // [type]: the type of error message.
1186 1187
  inline MessageTemplate type() const;
  inline void set_type(MessageTemplate value);
1188

1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199
  // Initializes the source positions in the object if possible. Does nothing if
  // called more than once. If called when stack space is exhausted, then the
  // source positions will be not be set and calling it again when there is more
  // stack space will not have any effect.
  static void EnsureSourcePositionsAvailable(Isolate* isolate,
                                             Handle<JSMessageObject> message);

  // Gets the start and end positions for the message.
  // EnsureSourcePositionsAvailable must have been called before calling these.
  inline int GetStartPosition() const;
  inline int GetEndPosition() const;
1200 1201 1202

  // Returns the line number for the error message (1-based), or
  // Message::kNoLineNumberInfo if the line cannot be determined.
1203
  // EnsureSourcePositionsAvailable must have been called before calling this.
1204
  V8_EXPORT_PRIVATE int GetLineNumber() const;
1205 1206

  // Returns the offset of the given position within the containing line.
1207
  // EnsureSourcePositionsAvailable must have been called before calling this.
1208
  V8_EXPORT_PRIVATE int GetColumnNumber() const;
1209

1210 1211 1212
  // Returns the source code
  V8_EXPORT_PRIVATE String GetSource() const;

1213 1214
  // Returns the source code line containing the given source
  // position, or the empty string if the position is invalid.
1215
  // EnsureSourcePositionsAvailable must have been called before calling this.
1216 1217
  Handle<String> GetSourceLine() const;

1218
  DECL_INT_ACCESSORS(error_level)
1219 1220 1221 1222

  // Dispatched behavior.
  DECL_PRINTER(JSMessageObject)

1223 1224
  // TODO(v8:8989): [torque] Support marker constants.
  static const int kPointerFieldsEndOffset = kStartPositionOffset;
1225

1226 1227 1228
  using BodyDescriptor =
      FixedBodyDescriptor<HeapObject::kMapOffset, kPointerFieldsEndOffset,
                          kHeaderSize>;
1229

1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243
 private:
  friend class Factory;

  inline bool DidEnsureSourcePositionsAvailable() const;

  // [shared]: optional SharedFunctionInfo that can be used to reconstruct the
  // source position if not available when the message was generated.
  DECL_ACCESSORS(shared_info, HeapObject)

  // [bytecode_offset]: optional offset using along with |shared| to generation
  // source positions.
  DECL_ACCESSORS(bytecode_offset, Smi)

  // [start_position]: the start position in the script for the error message.
1244
  DECL_INT_ACCESSORS(start_position)
1245 1246

  // [end_position]: the end position in the script for the error message.
1247 1248 1249 1250
  DECL_INT_ACCESSORS(end_position)

  DECL_INT_ACCESSORS(raw_type)

1251 1252 1253 1254
  // Hide generated accessors; custom accessors are named "raw_type".
  DECL_INT_ACCESSORS(message_type)

  TQ_OBJECT_CONSTRUCTORS(JSMessageObject)
1255 1256 1257 1258 1259 1260 1261
};

// The [Async-from-Sync Iterator] object
// (proposal-async-iteration/#sec-async-from-sync-iterator-objects)
// An object which wraps an ordinary Iterator and converts it to behave
// according to the Async Iterator protocol.
// (See https://tc39.github.io/proposal-async-iteration/#sec-iteration)
1262 1263 1264
class JSAsyncFromSyncIterator
    : public TorqueGeneratedJSAsyncFromSyncIterator<JSAsyncFromSyncIterator,
                                                    JSObject> {
1265 1266 1267 1268 1269 1270 1271 1272 1273
 public:
  DECL_PRINTER(JSAsyncFromSyncIterator)

  // Async-from-Sync Iterator instances are ordinary objects that inherit
  // properties from the %AsyncFromSyncIteratorPrototype% intrinsic object.
  // Async-from-Sync Iterator instances are initially created with the internal
  // slots listed in Table 4.
  // (proposal-async-iteration/#table-async-from-sync-iterator-internal-slots)

1274
  TQ_OBJECT_CONSTRUCTORS(JSAsyncFromSyncIterator)
1275 1276
};

1277 1278
class JSStringIterator
    : public TorqueGeneratedJSStringIterator<JSStringIterator, JSObject> {
1279 1280 1281 1282 1283
 public:
  // Dispatched behavior.
  DECL_PRINTER(JSStringIterator)
  DECL_VERIFIER(JSStringIterator)

1284
  TQ_OBJECT_CONSTRUCTORS(JSStringIterator)
1285 1286 1287 1288 1289 1290 1291 1292
};

}  // namespace internal
}  // namespace v8

#include "src/objects/object-macros-undef.h"

#endif  // V8_OBJECTS_JS_OBJECTS_H_