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.h"
9#include "src/objects/embedder-data-slot.h"
10#include "src/objects/property-array.h"
11#include "torque-generated/class-definitions-from-dsl.h"
12
13// Has to be the last include (doesn't have include guards):
14#include "src/objects/object-macros.h"
15
16namespace v8 {
17namespace internal {
18
19enum InstanceType : uint16_t;
20class JSGlobalObject;
21class JSGlobalProxy;
22class NativeContext;
23
24// JSReceiver includes types on which properties can be defined, i.e.,
25// JSObject and JSProxy.
26class JSReceiver : public HeapObject {
27 public:
28 NEVER_READ_ONLY_SPACE
29 // Returns true if there is no slow (ie, dictionary) backing store.
30 inline bool HasFastProperties() const;
31
32 // Returns the properties array backing store if it
33 // exists. Otherwise, returns an empty_property_array when there's a
34 // Smi (hash code) or an empty_fixed_array for a fast properties
35 // map.
36 inline PropertyArray property_array() const;
37
38 // Gets slow properties for non-global objects.
39 inline NameDictionary property_dictionary() const;
40
41 // Sets the properties backing store and makes sure any existing hash is moved
42 // to the new properties store. To clear out the properties store, pass in the
43 // empty_fixed_array(), the hash will be maintained in this case as well.
44 void SetProperties(HeapObject properties);
45
46 // There are five possible values for the properties offset.
47 // 1) EmptyFixedArray/EmptyPropertyDictionary - This is the standard
48 // placeholder.
49 //
50 // 2) Smi - This is the hash code of the object.
51 //
52 // 3) PropertyArray - This is similar to a FixedArray but stores
53 // the hash code of the object in its length field. This is a fast
54 // backing store.
55 //
56 // 4) NameDictionary - This is the dictionary-mode backing store.
57 //
58 // 4) GlobalDictionary - This is the backing store for the
59 // GlobalObject.
60 //
61 // This is used only in the deoptimizer and heap. Please use the
62 // above typed getters and setters to access the properties.
63 DECL_ACCESSORS(raw_properties_or_hash, Object)
64
65 inline void initialize_properties();
66
67 // Deletes an existing named property in a normalized object.
68 static void DeleteNormalizedProperty(Handle<JSReceiver> object, int entry);
69
70 DECL_CAST(JSReceiver)
71
72 // ES6 section 7.1.1 ToPrimitive
73 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> ToPrimitive(
74 Handle<JSReceiver> receiver,
75 ToPrimitiveHint hint = ToPrimitiveHint::kDefault);
76
77 // ES6 section 7.1.1.1 OrdinaryToPrimitive
78 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> OrdinaryToPrimitive(
79 Handle<JSReceiver> receiver, OrdinaryToPrimitiveHint hint);
80
81 static MaybeHandle<NativeContext> GetFunctionRealm(
82 Handle<JSReceiver> receiver);
83 V8_EXPORT_PRIVATE static MaybeHandle<NativeContext> GetContextForMicrotask(
84 Handle<JSReceiver> receiver);
85
86 // Get the first non-hidden prototype.
87 static inline MaybeHandle<HeapObject> GetPrototype(
88 Isolate* isolate, Handle<JSReceiver> receiver);
89
90 V8_WARN_UNUSED_RESULT static Maybe<bool> HasInPrototypeChain(
91 Isolate* isolate, Handle<JSReceiver> object, Handle<Object> proto);
92
93 // Reads all enumerable own properties of source and adds them to
94 // target, using either Set or CreateDataProperty depending on the
95 // use_set argument. This only copies values not present in the
96 // maybe_excluded_properties list.
97 V8_WARN_UNUSED_RESULT static Maybe<bool> SetOrCopyDataProperties(
98 Isolate* isolate, Handle<JSReceiver> target, Handle<Object> source,
99 const ScopedVector<Handle<Object>>* excluded_properties = nullptr,
100 bool use_set = true);
101
102 // Implementation of [[HasProperty]], ECMA-262 5th edition, section 8.12.6.
103 V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<bool> HasProperty(
104 LookupIterator* it);
105 V8_WARN_UNUSED_RESULT static inline Maybe<bool> HasProperty(
106 Handle<JSReceiver> object, Handle<Name> name);
107 V8_WARN_UNUSED_RESULT static inline Maybe<bool> HasElement(
108 Handle<JSReceiver> object, uint32_t index);
109
110 V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<bool> HasOwnProperty(
111 Handle<JSReceiver> object, Handle<Name> name);
112 V8_WARN_UNUSED_RESULT static inline Maybe<bool> HasOwnProperty(
113 Handle<JSReceiver> object, uint32_t index);
114
115 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> GetProperty(
116 Isolate* isolate, Handle<JSReceiver> receiver, const char* key);
117 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> GetProperty(
118 Isolate* isolate, Handle<JSReceiver> receiver, Handle<Name> name);
119 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> GetElement(
120 Isolate* isolate, Handle<JSReceiver> receiver, uint32_t index);
121
122 // Implementation of ES6 [[Delete]]
123 V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<bool>
124 DeletePropertyOrElement(Handle<JSReceiver> object, Handle<Name> name,
125 LanguageMode language_mode = LanguageMode::kSloppy);
126 V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<bool> DeleteProperty(
127 Handle<JSReceiver> object, Handle<Name> name,
128 LanguageMode language_mode = LanguageMode::kSloppy);
129 V8_WARN_UNUSED_RESULT static Maybe<bool> DeleteProperty(
130 LookupIterator* it, LanguageMode language_mode);
131 V8_WARN_UNUSED_RESULT static Maybe<bool> DeleteElement(
132 Handle<JSReceiver> object, uint32_t index,
133 LanguageMode language_mode = LanguageMode::kSloppy);
134
135 V8_WARN_UNUSED_RESULT static Object DefineProperty(Isolate* isolate,
136 Handle<Object> object,
137 Handle<Object> name,
138 Handle<Object> attributes);
139 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> DefineProperties(
140 Isolate* isolate, Handle<Object> object, Handle<Object> properties);
141
142 // "virtual" dispatcher to the correct [[DefineOwnProperty]] implementation.
143 V8_WARN_UNUSED_RESULT static Maybe<bool> DefineOwnProperty(
144 Isolate* isolate, Handle<JSReceiver> object, Handle<Object> key,
145 PropertyDescriptor* desc, Maybe<ShouldThrow> should_throw);
146
147 // ES6 7.3.4 (when passed kDontThrow)
148 V8_WARN_UNUSED_RESULT static Maybe<bool> CreateDataProperty(
149 Isolate* isolate, Handle<JSReceiver> object, Handle<Name> key,
150 Handle<Object> value, Maybe<ShouldThrow> should_throw);
151 V8_WARN_UNUSED_RESULT static Maybe<bool> CreateDataProperty(
152 LookupIterator* it, Handle<Object> value,
153 Maybe<ShouldThrow> should_throw);
154
155 // ES6 9.1.6.1
156 V8_WARN_UNUSED_RESULT static Maybe<bool> OrdinaryDefineOwnProperty(
157 Isolate* isolate, Handle<JSObject> object, Handle<Object> key,
158 PropertyDescriptor* desc, Maybe<ShouldThrow> should_throw);
159 V8_WARN_UNUSED_RESULT static Maybe<bool> OrdinaryDefineOwnProperty(
160 LookupIterator* it, PropertyDescriptor* desc,
161 Maybe<ShouldThrow> should_throw);
162 // ES6 9.1.6.2
163 V8_WARN_UNUSED_RESULT static Maybe<bool> IsCompatiblePropertyDescriptor(
164 Isolate* isolate, bool extensible, PropertyDescriptor* desc,
165 PropertyDescriptor* current, Handle<Name> property_name,
166 Maybe<ShouldThrow> should_throw);
167 // ES6 9.1.6.3
168 // |it| can be NULL in cases where the ES spec passes |undefined| as the
169 // receiver. Exactly one of |it| and |property_name| must be provided.
170 V8_WARN_UNUSED_RESULT static Maybe<bool> ValidateAndApplyPropertyDescriptor(
171 Isolate* isolate, LookupIterator* it, bool extensible,
172 PropertyDescriptor* desc, PropertyDescriptor* current,
173 Maybe<ShouldThrow> should_throw, Handle<Name> property_name);
174
175 V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<bool>
176 GetOwnPropertyDescriptor(Isolate* isolate, Handle<JSReceiver> object,
177 Handle<Object> key, PropertyDescriptor* desc);
178 V8_WARN_UNUSED_RESULT static Maybe<bool> GetOwnPropertyDescriptor(
179 LookupIterator* it, PropertyDescriptor* desc);
180
181 using IntegrityLevel = PropertyAttributes;
182
183 // ES6 7.3.14 (when passed kDontThrow)
184 // 'level' must be SEALED or FROZEN.
185 V8_WARN_UNUSED_RESULT static Maybe<bool> SetIntegrityLevel(
186 Handle<JSReceiver> object, IntegrityLevel lvl, ShouldThrow should_throw);
187
188 // ES6 7.3.15
189 // 'level' must be SEALED or FROZEN.
190 V8_WARN_UNUSED_RESULT static Maybe<bool> TestIntegrityLevel(
191 Handle<JSReceiver> object, IntegrityLevel lvl);
192
193 // ES6 [[PreventExtensions]] (when passed kDontThrow)
194 V8_WARN_UNUSED_RESULT static Maybe<bool> PreventExtensions(
195 Handle<JSReceiver> object, ShouldThrow should_throw);
196
197 V8_WARN_UNUSED_RESULT static Maybe<bool> IsExtensible(
198 Handle<JSReceiver> object);
199
200 // Returns the class name ([[Class]] property in the specification).
201 V8_EXPORT_PRIVATE String class_name();
202
203 // Returns the constructor (the function that was used to instantiate the
204 // object).
205 static MaybeHandle<JSFunction> GetConstructor(Handle<JSReceiver> receiver);
206
207 // Returns the constructor name (the name (possibly, inferred name) of the
208 // function that was used to instantiate the object).
209 static Handle<String> GetConstructorName(Handle<JSReceiver> receiver);
210
211 V8_EXPORT_PRIVATE Handle<NativeContext> GetCreationContext();
212
213 V8_WARN_UNUSED_RESULT static inline Maybe<PropertyAttributes>
214 GetPropertyAttributes(Handle<JSReceiver> object, Handle<Name> name);
215 V8_WARN_UNUSED_RESULT static inline Maybe<PropertyAttributes>
216 GetOwnPropertyAttributes(Handle<JSReceiver> object, Handle<Name> name);
217 V8_WARN_UNUSED_RESULT static inline Maybe<PropertyAttributes>
218 GetOwnPropertyAttributes(Handle<JSReceiver> object, uint32_t index);
219
220 V8_WARN_UNUSED_RESULT static inline Maybe<PropertyAttributes>
221 GetElementAttributes(Handle<JSReceiver> object, uint32_t index);
222 V8_WARN_UNUSED_RESULT static inline Maybe<PropertyAttributes>
223 GetOwnElementAttributes(Handle<JSReceiver> object, uint32_t index);
224
225 V8_WARN_UNUSED_RESULT static Maybe<PropertyAttributes> GetPropertyAttributes(
226 LookupIterator* it);
227
228 // Set the object's prototype (only JSReceiver and null are allowed values).
229 V8_WARN_UNUSED_RESULT static Maybe<bool> SetPrototype(
230 Handle<JSReceiver> object, Handle<Object> value, bool from_javascript,
231 ShouldThrow should_throw);
232
233 inline static Handle<Object> GetDataProperty(Handle<JSReceiver> object,
234 Handle<Name> name);
235 V8_EXPORT_PRIVATE static Handle<Object> GetDataProperty(LookupIterator* it);
236
237 // Retrieves a permanent object identity hash code. The undefined value might
238 // be returned in case no hash was created yet.
239 V8_EXPORT_PRIVATE Object GetIdentityHash();
240
241 // Retrieves a permanent object identity hash code. May create and store a
242 // hash code if needed and none exists.
243 static Smi CreateIdentityHash(Isolate* isolate, JSReceiver key);
244 V8_EXPORT_PRIVATE Smi GetOrCreateIdentityHash(Isolate* isolate);
245
246 // Stores the hash code. The hash passed in must be masked with
247 // JSReceiver::kHashMask.
248 V8_EXPORT_PRIVATE void SetIdentityHash(int masked_hash);
249
250 // ES6 [[OwnPropertyKeys]] (modulo return type)
251 V8_WARN_UNUSED_RESULT static inline MaybeHandle<FixedArray> OwnPropertyKeys(
252 Handle<JSReceiver> object);
253
254 V8_WARN_UNUSED_RESULT static MaybeHandle<FixedArray> GetOwnValues(
255 Handle<JSReceiver> object, PropertyFilter filter,
256 bool try_fast_path = true);
257
258 V8_WARN_UNUSED_RESULT static MaybeHandle<FixedArray> GetOwnEntries(
259 Handle<JSReceiver> object, PropertyFilter filter,
260 bool try_fast_path = true);
261
262 V8_WARN_UNUSED_RESULT static Handle<FixedArray> GetOwnElementIndices(
263 Isolate* isolate, Handle<JSReceiver> receiver, Handle<JSObject> object);
264
265 static const int kHashMask = PropertyArray::HashField::kMask;
266
267 DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize,
268 TORQUE_GENERATED_JSRECEIVER_FIELDS)
269 static const int kHeaderSize = kSize;
270
271 bool HasProxyInPrototype(Isolate* isolate);
272
273 bool HasComplexElements();
274
275 V8_WARN_UNUSED_RESULT static MaybeHandle<FixedArray> GetPrivateEntries(
276 Isolate* isolate, Handle<JSReceiver> receiver);
277
278 OBJECT_CONSTRUCTORS(JSReceiver, HeapObject);
279};
280
281// The JSObject describes real heap allocated JavaScript objects with
282// properties.
283// Note that the map of JSObject changes during execution to enable inline
284// caching.
285class JSObject : public JSReceiver {
286 public:
287 static bool IsUnmodifiedApiObject(FullObjectSlot o);
288
289 V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT MaybeHandle<JSObject> New(
290 Handle<JSFunction> constructor, Handle<JSReceiver> new_target,
291 Handle<AllocationSite> site);
292
293 static MaybeHandle<NativeContext> GetFunctionRealm(Handle<JSObject> object);
294
295 // 9.1.12 ObjectCreate ( proto [ , internalSlotsList ] )
296 // Notice: This is NOT 19.1.2.2 Object.create ( O, Properties )
297 static V8_WARN_UNUSED_RESULT MaybeHandle<JSObject> ObjectCreate(
298 Isolate* isolate, Handle<Object> prototype);
299
300 // [elements]: The elements (properties with names that are integers).
301 //
302 // Elements can be in two general modes: fast and slow. Each mode
303 // corresponds to a set of object representations of elements that
304 // have something in common.
305 //
306 // In the fast mode elements is a FixedArray and so each element can be
307 // quickly accessed. The elements array can have one of several maps in this
308 // mode: fixed_array_map, fixed_double_array_map,
309 // sloppy_arguments_elements_map or fixed_cow_array_map (for copy-on-write
310 // arrays). In the latter case the elements array may be shared by a few
311 // objects and so before writing to any element the array must be copied. Use
312 // EnsureWritableFastElements in this case.
313 //
314 // In the slow mode the elements is either a NumberDictionary or a
315 // FixedArray parameter map for a (sloppy) arguments object.
316 DECL_ACCESSORS(elements, FixedArrayBase)
317 inline void initialize_elements();
318 static inline void SetMapAndElements(Handle<JSObject> object, Handle<Map> map,
319 Handle<FixedArrayBase> elements);
320 inline ElementsKind GetElementsKind() const;
321 V8_EXPORT_PRIVATE ElementsAccessor* GetElementsAccessor();
322 // Returns true if an object has elements of PACKED_SMI_ELEMENTS or
323 // HOLEY_SMI_ELEMENTS ElementsKind.
324 inline bool HasSmiElements();
325 // Returns true if an object has elements of PACKED_ELEMENTS or
326 // HOLEY_ELEMENTS ElementsKind.
327 inline bool HasObjectElements();
328 // Returns true if an object has elements of PACKED_SMI_ELEMENTS,
329 // HOLEY_SMI_ELEMENTS, PACKED_ELEMENTS, or HOLEY_ELEMENTS.
330 inline bool HasSmiOrObjectElements();
331 // Returns true if an object has any of the "fast" elements kinds.
332 inline bool HasFastElements();
333 // Returns true if an object has any of the PACKED elements kinds.
334 inline bool HasFastPackedElements();
335 // Returns true if an object has elements of PACKED_DOUBLE_ELEMENTS or
336 // HOLEY_DOUBLE_ELEMENTS ElementsKind.
337 inline bool HasDoubleElements();
338 // Returns true if an object has elements of HOLEY_SMI_ELEMENTS,
339 // HOLEY_DOUBLE_ELEMENTS, or HOLEY_ELEMENTS ElementsKind.
340 inline bool HasHoleyElements();
341 inline bool HasSloppyArgumentsElements();
342 inline bool HasStringWrapperElements();
343 inline bool HasDictionaryElements();
344
345 // Returns true if an object has elements of PACKED_ELEMENTS
346 inline bool HasPackedElements();
347 inline bool HasFrozenOrSealedElements();
348
349 inline bool HasFixedTypedArrayElements();
350
351 inline bool HasFixedUint8ClampedElements();
352 inline bool HasFixedArrayElements();
353 inline bool HasFixedInt8Elements();
354 inline bool HasFixedUint8Elements();
355 inline bool HasFixedInt16Elements();
356 inline bool HasFixedUint16Elements();
357 inline bool HasFixedInt32Elements();
358 inline bool HasFixedUint32Elements();
359 inline bool HasFixedFloat32Elements();
360 inline bool HasFixedFloat64Elements();
361 inline bool HasFixedBigInt64Elements();
362 inline bool HasFixedBigUint64Elements();
363
364 inline bool HasFastArgumentsElements();
365 inline bool HasSlowArgumentsElements();
366 inline bool HasFastStringWrapperElements();
367 inline bool HasSlowStringWrapperElements();
368 bool HasEnumerableElements();
369
370 inline NumberDictionary element_dictionary(); // Gets slow elements.
371
372 // Requires: HasFastElements().
373 static void EnsureWritableFastElements(Handle<JSObject> object);
374
375 V8_WARN_UNUSED_RESULT static Maybe<bool> SetPropertyWithInterceptor(
376 LookupIterator* it, Maybe<ShouldThrow> should_throw,
377 Handle<Object> value);
378
379 // The API currently still wants DefineOwnPropertyIgnoreAttributes to convert
380 // AccessorInfo objects to data fields. We allow FORCE_FIELD as an exception
381 // to the default behavior that calls the setter.
382 enum AccessorInfoHandling { FORCE_FIELD, DONT_FORCE_FIELD };
383
384 V8_WARN_UNUSED_RESULT static MaybeHandle<Object>
385 DefineOwnPropertyIgnoreAttributes(
386 LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
387 AccessorInfoHandling handling = DONT_FORCE_FIELD);
388
389 V8_WARN_UNUSED_RESULT static Maybe<bool> DefineOwnPropertyIgnoreAttributes(
390 LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
391 Maybe<ShouldThrow> should_throw,
392 AccessorInfoHandling handling = DONT_FORCE_FIELD);
393
394 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> V8_EXPORT_PRIVATE
395 SetOwnPropertyIgnoreAttributes(Handle<JSObject> object, Handle<Name> name,
396 Handle<Object> value,
397 PropertyAttributes attributes);
398
399 V8_WARN_UNUSED_RESULT static MaybeHandle<Object>
400 SetOwnElementIgnoreAttributes(Handle<JSObject> object, uint32_t index,
401 Handle<Object> value,
402 PropertyAttributes attributes);
403
404 // Equivalent to one of the above depending on whether |name| can be converted
405 // to an array index.
406 V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static MaybeHandle<Object>
407 DefinePropertyOrElementIgnoreAttributes(Handle<JSObject> object,
408 Handle<Name> name,
409 Handle<Object> value,
410 PropertyAttributes attributes = NONE);
411
412 // Adds or reconfigures a property to attributes NONE. It will fail when it
413 // cannot.
414 V8_WARN_UNUSED_RESULT static Maybe<bool> CreateDataProperty(
415 LookupIterator* it, Handle<Object> value,
416 Maybe<ShouldThrow> should_throw = Just(kDontThrow));
417
418 V8_EXPORT_PRIVATE static void AddProperty(Isolate* isolate,
419 Handle<JSObject> object,
420 Handle<Name> name,
421 Handle<Object> value,
422 PropertyAttributes attributes);
423
424 // {name} must be a UTF-8 encoded, null-terminated string.
425 static void AddProperty(Isolate* isolate, Handle<JSObject> object,
426 const char* name, Handle<Object> value,
427 PropertyAttributes attributes);
428
429 V8_EXPORT_PRIVATE static void AddDataElement(Handle<JSObject> receiver,
430 uint32_t index,
431 Handle<Object> value,
432 PropertyAttributes attributes);
433
434 // Extend the receiver with a single fast property appeared first in the
435 // passed map. This also extends the property backing store if necessary.
436 static void AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map);
437
438 // Migrates the given object to a map whose field representations are the
439 // lowest upper bound of all known representations for that field.
440 static void MigrateInstance(Handle<JSObject> instance);
441
442 // Migrates the given object only if the target map is already available,
443 // or returns false if such a map is not yet available.
444 static bool TryMigrateInstance(Handle<JSObject> instance);
445
446 // Sets the property value in a normalized object given (key, value, details).
447 // Handles the special representation of JS global objects.
448 static void SetNormalizedProperty(Handle<JSObject> object, Handle<Name> name,
449 Handle<Object> value,
450 PropertyDetails details);
451 static void SetDictionaryElement(Handle<JSObject> object, uint32_t index,
452 Handle<Object> value,
453 PropertyAttributes attributes);
454 static void SetDictionaryArgumentsElement(Handle<JSObject> object,
455 uint32_t index,
456 Handle<Object> value,
457 PropertyAttributes attributes);
458
459 static void OptimizeAsPrototype(Handle<JSObject> object,
460 bool enable_setup_mode = true);
461 static void ReoptimizeIfPrototype(Handle<JSObject> object);
462 static void MakePrototypesFast(Handle<Object> receiver,
463 WhereToStart where_to_start, Isolate* isolate);
464 static void LazyRegisterPrototypeUser(Handle<Map> user, Isolate* isolate);
465 static void UpdatePrototypeUserRegistration(Handle<Map> old_map,
466 Handle<Map> new_map,
467 Isolate* isolate);
468 static bool UnregisterPrototypeUser(Handle<Map> user, Isolate* isolate);
469 static Map InvalidatePrototypeChains(Map map);
470 static void InvalidatePrototypeValidityCell(JSGlobalObject global);
471
472 // Updates prototype chain tracking information when an object changes its
473 // map from |old_map| to |new_map|.
474 static void NotifyMapChange(Handle<Map> old_map, Handle<Map> new_map,
475 Isolate* isolate);
476
477 // Utility used by many Array builtins and runtime functions
478 static inline bool PrototypeHasNoElements(Isolate* isolate, JSObject object);
479
480 // To be passed to PrototypeUsers::Compact.
481 static void PrototypeRegistryCompactionCallback(HeapObject value,
482 int old_index, int new_index);
483
484 // Retrieve interceptors.
485 inline InterceptorInfo GetNamedInterceptor();
486 inline InterceptorInfo GetIndexedInterceptor();
487
488 // Used from JSReceiver.
489 V8_WARN_UNUSED_RESULT static Maybe<PropertyAttributes>
490 GetPropertyAttributesWithInterceptor(LookupIterator* it);
491 V8_WARN_UNUSED_RESULT static Maybe<PropertyAttributes>
492 GetPropertyAttributesWithFailedAccessCheck(LookupIterator* it);
493
494 // Defines an AccessorPair property on the given object.
495 // TODO(mstarzinger): Rename to SetAccessor().
496 V8_EXPORT_PRIVATE static MaybeHandle<Object> DefineAccessor(
497 Handle<JSObject> object, Handle<Name> name, Handle<Object> getter,
498 Handle<Object> setter, PropertyAttributes attributes);
499 static MaybeHandle<Object> DefineAccessor(LookupIterator* it,
500 Handle<Object> getter,
501 Handle<Object> setter,
502 PropertyAttributes attributes);
503
504 // Defines an AccessorInfo property on the given object.
505 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> SetAccessor(
506 Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> info,
507 PropertyAttributes attributes);
508
509 // The result must be checked first for exceptions. If there's no exception,
510 // the output parameter |done| indicates whether the interceptor has a result
511 // or not.
512 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> GetPropertyWithInterceptor(
513 LookupIterator* it, bool* done);
514
515 static void ValidateElements(JSObject object);
516
517 // Makes sure that this object can contain HeapObject as elements.
518 static inline void EnsureCanContainHeapObjectElements(Handle<JSObject> obj);
519
520 // Makes sure that this object can contain the specified elements.
521 // TSlot here is either ObjectSlot or FullObjectSlot.
522 template <typename TSlot>
523 static inline void EnsureCanContainElements(Handle<JSObject> object,
524 TSlot elements, uint32_t count,
525 EnsureElementsMode mode);
526 static inline void EnsureCanContainElements(Handle<JSObject> object,
527 Handle<FixedArrayBase> elements,
528 uint32_t length,
529 EnsureElementsMode mode);
530 static void EnsureCanContainElements(Handle<JSObject> object,
531 Arguments* arguments, uint32_t first_arg,
532 uint32_t arg_count,
533 EnsureElementsMode mode);
534
535 // Would we convert a fast elements array to dictionary mode given
536 // an access at key?
537 bool WouldConvertToSlowElements(uint32_t index);
538
539 static const uint32_t kMinAddedElementsCapacity = 16;
540
541 // Computes the new capacity when expanding the elements of a JSObject.
542 static uint32_t NewElementsCapacity(uint32_t old_capacity) {
543 // (old_capacity + 50%) + kMinAddedElementsCapacity
544 return old_capacity + (old_capacity >> 1) + kMinAddedElementsCapacity;
545 }
546
547 // These methods do not perform access checks!
548 template <AllocationSiteUpdateMode update_or_check =
549 AllocationSiteUpdateMode::kUpdate>
550 static bool UpdateAllocationSite(Handle<JSObject> object,
551 ElementsKind to_kind);
552
553 // Lookup interceptors are used for handling properties controlled by host
554 // objects.
555 inline bool HasNamedInterceptor();
556 inline bool HasIndexedInterceptor();
557
558 // Support functions for v8 api (needed for correct interceptor behavior).
559 V8_WARN_UNUSED_RESULT static Maybe<bool> HasRealNamedProperty(
560 Handle<JSObject> object, Handle<Name> name);
561 V8_WARN_UNUSED_RESULT static Maybe<bool> HasRealElementProperty(
562 Handle<JSObject> object, uint32_t index);
563 V8_WARN_UNUSED_RESULT static Maybe<bool> HasRealNamedCallbackProperty(
564 Handle<JSObject> object, Handle<Name> name);
565
566 // Get the header size for a JSObject. Used to compute the index of
567 // embedder fields as well as the number of embedder fields.
568 // The |function_has_prototype_slot| parameter is needed only for
569 // JSFunction objects.
570 static int GetHeaderSize(InstanceType instance_type,
571 bool function_has_prototype_slot = false);
572 static inline int GetHeaderSize(const Map map);
573 inline int GetHeaderSize() const;
574
575 static inline int GetEmbedderFieldsStartOffset(const Map map);
576 inline int GetEmbedderFieldsStartOffset();
577
578 static inline int GetEmbedderFieldCount(const Map map);
579 inline int GetEmbedderFieldCount() const;
580 inline int GetEmbedderFieldOffset(int index);
581 inline Object GetEmbedderField(int index);
582 inline void SetEmbedderField(int index, Object value);
583 inline void SetEmbedderField(int index, Smi value);
584
585 // Returns true when the object is potentially a wrapper that gets special
586 // garbage collection treatment.
587 // TODO(mlippautz): Make check exact and replace the pattern match in
588 // Heap::TracePossibleWrapper.
589 bool IsApiWrapper();
590
591 // Same as IsApiWrapper() but also allow dropping the wrapper on minor GCs.
592 bool IsDroppableApiWrapper();
593
594 // Returns a new map with all transitions dropped from the object's current
595 // map and the ElementsKind set.
596 static Handle<Map> GetElementsTransitionMap(Handle<JSObject> object,
597 ElementsKind to_kind);
598 V8_EXPORT_PRIVATE static void TransitionElementsKind(Handle<JSObject> object,
599 ElementsKind to_kind);
600
601 // Always use this to migrate an object to a new map.
602 // |expected_additional_properties| is only used for fast-to-slow transitions
603 // and ignored otherwise.
604 V8_EXPORT_PRIVATE static void MigrateToMap(
605 Handle<JSObject> object, Handle<Map> new_map,
606 int expected_additional_properties = 0);
607
608 // Forces a prototype without any of the checks that the regular SetPrototype
609 // would do.
610 static void ForceSetPrototype(Handle<JSObject> object,
611 Handle<HeapObject> proto);
612
613 // Convert the object to use the canonical dictionary
614 // representation. If the object is expected to have additional properties
615 // added this number can be indicated to have the backing store allocated to
616 // an initial capacity for holding these properties.
617 V8_EXPORT_PRIVATE static void NormalizeProperties(
618 Handle<JSObject> object, PropertyNormalizationMode mode,
619 int expected_additional_properties, const char* reason);
620
621 // Convert and update the elements backing store to be a
622 // NumberDictionary dictionary. Returns the backing after conversion.
623 V8_EXPORT_PRIVATE static Handle<NumberDictionary> NormalizeElements(
624 Handle<JSObject> object);
625
626 void RequireSlowElements(NumberDictionary dictionary);
627
628 // Transform slow named properties to fast variants.
629 V8_EXPORT_PRIVATE static void MigrateSlowToFast(Handle<JSObject> object,
630 int unused_property_fields,
631 const char* reason);
632
633 inline bool IsUnboxedDoubleField(FieldIndex index);
634
635 // Access fast-case object properties at index.
636 static Handle<Object> FastPropertyAt(Handle<JSObject> object,
637 Representation representation,
638 FieldIndex index);
639 inline Object RawFastPropertyAt(FieldIndex index);
640 inline double RawFastDoublePropertyAt(FieldIndex index);
641 inline uint64_t RawFastDoublePropertyAsBitsAt(FieldIndex index);
642
643 inline void FastPropertyAtPut(FieldIndex index, Object value);
644 inline void RawFastPropertyAtPut(FieldIndex index, Object value);
645 inline void RawFastDoublePropertyAsBitsAtPut(FieldIndex index, uint64_t bits);
646 inline void WriteToField(int descriptor, PropertyDetails details,
647 Object value);
648
649 // Access to in object properties.
650 inline int GetInObjectPropertyOffset(int index);
651 inline Object InObjectPropertyAt(int index);
652 inline Object InObjectPropertyAtPut(
653 int index, Object value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
654
655 // Set the object's prototype (only JSReceiver and null are allowed values).
656 V8_WARN_UNUSED_RESULT static Maybe<bool> SetPrototype(
657 Handle<JSObject> object, Handle<Object> value, bool from_javascript,
658 ShouldThrow should_throw);
659
660 // Makes the object prototype immutable
661 // Never called from JavaScript
662 static void SetImmutableProto(Handle<JSObject> object);
663
664 // Initializes the body starting at |start_offset|. It is responsibility of
665 // the caller to initialize object header. Fill the pre-allocated fields with
666 // pre_allocated_value and the rest with filler_value.
667 // Note: this call does not update write barrier, the caller is responsible
668 // to ensure that |filler_value| can be collected without WB here.
669 inline void InitializeBody(Map map, int start_offset,
670 Object pre_allocated_value, Object filler_value);
671
672 // Check whether this object references another object
673 bool ReferencesObject(Object obj);
674
675 V8_WARN_UNUSED_RESULT static Maybe<bool> TestIntegrityLevel(
676 Handle<JSObject> object, IntegrityLevel lvl);
677
678 V8_WARN_UNUSED_RESULT static Maybe<bool> PreventExtensions(
679 Handle<JSObject> object, ShouldThrow should_throw);
680
681 static bool IsExtensible(Handle<JSObject> object);
682
683 DECL_CAST(JSObject)
684
685 // Dispatched behavior.
686 void JSObjectShortPrint(StringStream* accumulator);
687 DECL_PRINTER(JSObject)
688 DECL_VERIFIER(JSObject)
689#ifdef OBJECT_PRINT
690 bool PrintProperties(std::ostream& os); // NOLINT
691 void PrintElements(std::ostream& os); // NOLINT
692#endif
693#if defined(DEBUG) || defined(OBJECT_PRINT)
694 void PrintTransitions(std::ostream& os); // NOLINT
695#endif
696
697 static void PrintElementsTransition(FILE* file, Handle<JSObject> object,
698 ElementsKind from_kind,
699 Handle<FixedArrayBase> from_elements,
700 ElementsKind to_kind,
701 Handle<FixedArrayBase> to_elements);
702
703 void PrintInstanceMigration(FILE* file, Map original_map, Map new_map);
704
705#ifdef DEBUG
706 // Structure for collecting spill information about JSObjects.
707 class SpillInformation {
708 public:
709 void Clear();
710 void Print();
711 int number_of_objects_;
712 int number_of_objects_with_fast_properties_;
713 int number_of_objects_with_fast_elements_;
714 int number_of_fast_used_fields_;
715 int number_of_fast_unused_fields_;
716 int number_of_slow_used_properties_;
717 int number_of_slow_unused_properties_;
718 int number_of_fast_used_elements_;
719 int number_of_fast_unused_elements_;
720 int number_of_slow_used_elements_;
721 int number_of_slow_unused_elements_;
722 };
723
724 void IncrementSpillStatistics(Isolate* isolate, SpillInformation* info);
725#endif
726
727#ifdef VERIFY_HEAP
728 // If a GC was caused while constructing this object, the elements pointer
729 // may point to a one pointer filler map. The object won't be rooted, but
730 // our heap verification code could stumble across it.
731 V8_EXPORT_PRIVATE bool ElementsAreSafeToExamine() const;
732#endif
733
734 Object SlowReverseLookup(Object value);
735
736 // Maximal number of elements (numbered 0 .. kMaxElementCount - 1).
737 // Also maximal value of JSArray's length property.
738 static const uint32_t kMaxElementCount = 0xffffffffu;
739
740 // Constants for heuristics controlling conversion of fast elements
741 // to slow elements.
742
743 // Maximal gap that can be introduced by adding an element beyond
744 // the current elements length.
745 static const uint32_t kMaxGap = 1024;
746
747 // Maximal length of fast elements array that won't be checked for
748 // being dense enough on expansion.
749 static const int kMaxUncheckedFastElementsLength = 5000;
750
751 // Same as above but for old arrays. This limit is more strict. We
752 // don't want to be wasteful with long lived objects.
753 static const int kMaxUncheckedOldFastElementsLength = 500;
754
755 // This constant applies only to the initial map of "global.Object" and
756 // not to arbitrary other JSObject maps.
757 static const int kInitialGlobalObjectUnusedPropertiesCount = 4;
758
759 static const int kMaxInstanceSize = 255 * kTaggedSize;
760
761 // When extending the backing storage for property values, we increase
762 // its size by more than the 1 entry necessary, so sequentially adding fields
763 // to the same object requires fewer allocations and copies.
764 static const int kFieldsAdded = 3;
765 STATIC_ASSERT(kMaxNumberOfDescriptors + kFieldsAdded <=
766 PropertyArray::kMaxLength);
767
768// Layout description.
769#define JS_OBJECT_FIELDS(V) \
770 V(kElementsOffset, kTaggedSize) \
771 /* Header size. */ \
772 V(kHeaderSize, 0)
773
774 DEFINE_FIELD_OFFSET_CONSTANTS(JSReceiver::kHeaderSize, JS_OBJECT_FIELDS)
775#undef JS_OBJECT_FIELDS
776
777 STATIC_ASSERT(kHeaderSize == Internals::kJSObjectHeaderSize);
778 static const int kMaxInObjectProperties =
779 (kMaxInstanceSize - kHeaderSize) >> kTaggedSizeLog2;
780 STATIC_ASSERT(kMaxInObjectProperties <= kMaxNumberOfDescriptors);
781
782 static const int kMaxFirstInobjectPropertyOffset =
783 (1 << kFirstInobjectPropertyOffsetBitCount) - 1;
784 static const int kMaxEmbedderFields =
785 (kMaxFirstInobjectPropertyOffset - kHeaderSize) / kEmbedderDataSlotSize;
786 STATIC_ASSERT(kHeaderSize +
787 kMaxEmbedderFields * kEmbedderDataSlotSizeInTaggedSlots <=
788 kMaxInstanceSize);
789
790 class BodyDescriptor;
791
792 class FastBodyDescriptor;
793
794 // Gets the number of currently used elements.
795 int GetFastElementsUsage();
796
797 static bool AllCanRead(LookupIterator* it);
798 static bool AllCanWrite(LookupIterator* it);
799
800 private:
801 friend class JSReceiver;
802 friend class Object;
803
804 // Used from Object::GetProperty().
805 V8_WARN_UNUSED_RESULT static MaybeHandle<Object>
806 GetPropertyWithFailedAccessCheck(LookupIterator* it);
807
808 V8_WARN_UNUSED_RESULT static Maybe<bool> SetPropertyWithFailedAccessCheck(
809 LookupIterator* it, Handle<Object> value,
810 Maybe<ShouldThrow> should_throw);
811
812 V8_WARN_UNUSED_RESULT static Maybe<bool> DeletePropertyWithInterceptor(
813 LookupIterator* it, ShouldThrow should_throw);
814
815 bool ReferencesObjectFromElements(FixedArray elements, ElementsKind kind,
816 Object object);
817
818 // Helper for fast versions of preventExtensions, seal, and freeze.
819 // attrs is one of NONE, SEALED, or FROZEN (depending on the operation).
820 template <PropertyAttributes attrs>
821 V8_WARN_UNUSED_RESULT static Maybe<bool> PreventExtensionsWithTransition(
822 Handle<JSObject> object, ShouldThrow should_throw);
823
824 OBJECT_CONSTRUCTORS(JSObject, JSReceiver);
825};
826
827// JSAccessorPropertyDescriptor is just a JSObject with a specific initial
828// map. This initial map adds in-object properties for "get", "set",
829// "enumerable" and "configurable" properties, as assigned by the
830// FromPropertyDescriptor function for regular accessor properties.
831class JSAccessorPropertyDescriptor : public JSObject {
832 public:
833 // Layout description.
834 DEFINE_FIELD_OFFSET_CONSTANTS(
835 JSObject::kHeaderSize,
836 TORQUE_GENERATED_JSACCESSOR_PROPERTY_DESCRIPTOR_FIELDS)
837
838 // Indices of in-object properties.
839 static const int kGetIndex = 0;
840 static const int kSetIndex = 1;
841 static const int kEnumerableIndex = 2;
842 static const int kConfigurableIndex = 3;
843
844 private:
845 DISALLOW_IMPLICIT_CONSTRUCTORS(JSAccessorPropertyDescriptor);
846};
847
848// JSDataPropertyDescriptor is just a JSObject with a specific initial map.
849// This initial map adds in-object properties for "value", "writable",
850// "enumerable" and "configurable" properties, as assigned by the
851// FromPropertyDescriptor function for regular data properties.
852class JSDataPropertyDescriptor : public JSObject {
853 public:
854 DEFINE_FIELD_OFFSET_CONSTANTS(
855 JSObject::kHeaderSize, TORQUE_GENERATED_JSDATA_PROPERTY_DESCRIPTOR_FIELDS)
856
857 // Indices of in-object properties.
858 static const int kValueIndex = 0;
859 static const int kWritableIndex = 1;
860 static const int kEnumerableIndex = 2;
861 static const int kConfigurableIndex = 3;
862
863 private:
864 DISALLOW_IMPLICIT_CONSTRUCTORS(JSDataPropertyDescriptor);
865};
866
867// JSIteratorResult is just a JSObject with a specific initial map.
868// This initial map adds in-object properties for "done" and "value",
869// as specified by ES6 section 25.1.1.3 The IteratorResult Interface
870class JSIteratorResult : public JSObject {
871 public:
872 DECL_ACCESSORS(value, Object)
873
874 DECL_ACCESSORS(done, Object)
875
876 // Layout description.
877#define JS_ITERATOR_RESULT_FIELDS(V) \
878 V(kValueOffset, kTaggedSize) \
879 V(kDoneOffset, kTaggedSize) \
880 /* Total size. */ \
881 V(kSize, 0)
882
883 DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
884 JS_ITERATOR_RESULT_FIELDS)
885#undef JS_ITERATOR_RESULT_FIELDS
886
887 // Indices of in-object properties.
888 static const int kValueIndex = 0;
889 static const int kDoneIndex = 1;
890
891 DECL_CAST(JSIteratorResult)
892
893 OBJECT_CONSTRUCTORS(JSIteratorResult, JSObject);
894};
895
896// JSBoundFunction describes a bound function exotic object.
897class JSBoundFunction : public JSObject {
898 public:
899 // [bound_target_function]: The wrapped function object.
900 inline Object raw_bound_target_function() const;
901 DECL_ACCESSORS(bound_target_function, JSReceiver)
902
903 // [bound_this]: The value that is always passed as the this value when
904 // calling the wrapped function.
905 DECL_ACCESSORS(bound_this, Object)
906
907 // [bound_arguments]: A list of values whose elements are used as the first
908 // arguments to any call to the wrapped function.
909 DECL_ACCESSORS(bound_arguments, FixedArray)
910
911 static MaybeHandle<String> GetName(Isolate* isolate,
912 Handle<JSBoundFunction> function);
913 static Maybe<int> GetLength(Isolate* isolate,
914 Handle<JSBoundFunction> function);
915 static MaybeHandle<NativeContext> GetFunctionRealm(
916 Handle<JSBoundFunction> function);
917
918 DECL_CAST(JSBoundFunction)
919
920 // Dispatched behavior.
921 DECL_PRINTER(JSBoundFunction)
922 DECL_VERIFIER(JSBoundFunction)
923
924 // The bound function's string representation implemented according
925 // to ES6 section 19.2.3.5 Function.prototype.toString ( ).
926 static Handle<String> ToString(Handle<JSBoundFunction> function);
927
928 // Layout description.
929 DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
930 TORQUE_GENERATED_JSBOUND_FUNCTION_FIELDS)
931
932 OBJECT_CONSTRUCTORS(JSBoundFunction, JSObject);
933};
934
935// JSFunction describes JavaScript functions.
936class JSFunction : public JSObject {
937 public:
938 // [prototype_or_initial_map]:
939 DECL_ACCESSORS(prototype_or_initial_map, Object)
940
941 // [shared]: The information about the function that
942 // can be shared by instances.
943 DECL_ACCESSORS(shared, SharedFunctionInfo)
944
945 static const int kLengthDescriptorIndex = 0;
946 static const int kNameDescriptorIndex = 1;
947 // Home object descriptor index when function has a [[HomeObject]] slot.
948 static const int kMaybeHomeObjectDescriptorIndex = 2;
949
950 // [context]: The context for this function.
951 inline Context context();
952 inline bool has_context() const;
953 inline void set_context(Object context);
954 inline JSGlobalProxy global_proxy();
955 inline NativeContext native_context();
956 inline int length();
957
958 static Handle<Object> GetName(Isolate* isolate, Handle<JSFunction> function);
959 static Handle<NativeContext> GetFunctionRealm(Handle<JSFunction> function);
960
961 // [code]: The generated code object for this function. Executed
962 // when the function is invoked, e.g. foo() or new foo(). See
963 // [[Call]] and [[Construct]] description in ECMA-262, section
964 // 8.6.2, page 27.
965 inline Code code() const;
966 inline void set_code(Code code);
967 inline void set_code_no_write_barrier(Code code);
968
969 // Get the abstract code associated with the function, which will either be
970 // a Code object or a BytecodeArray.
971 inline AbstractCode abstract_code();
972
973 // Tells whether or not this function is interpreted.
974 //
975 // Note: function->IsInterpreted() does not necessarily return the same value
976 // as function->shared()->IsInterpreted() because the closure might have been
977 // optimized.
978 inline bool IsInterpreted();
979
980 // Tells whether or not this function checks its optimization marker in its
981 // feedback vector.
982 inline bool ChecksOptimizationMarker();
983
984 // Tells whether or not this function holds optimized code.
985 //
986 // Note: Returning false does not necessarily mean that this function hasn't
987 // been optimized, as it may have optimized code on its feedback vector.
988 inline bool IsOptimized();
989
990 // Tells whether or not this function has optimized code available to it,
991 // either because it is optimized or because it has optimized code in its
992 // feedback vector.
993 inline bool HasOptimizedCode();
994
995 // Tells whether or not this function has a (non-zero) optimization marker.
996 inline bool HasOptimizationMarker();
997
998 // Mark this function for lazy recompilation. The function will be recompiled
999 // the next time it is executed.
1000 void MarkForOptimization(ConcurrencyMode mode);
1001
1002 // Tells whether or not the function is already marked for lazy recompilation.
1003 inline bool IsMarkedForOptimization();
1004 inline bool IsMarkedForConcurrentOptimization();
1005
1006 // Tells whether or not the function is on the concurrent recompilation queue.
1007 inline bool IsInOptimizationQueue();
1008
1009 // Clears the optimized code slot in the function's feedback vector.
1010 inline void ClearOptimizedCodeSlot(const char* reason);
1011
1012 // Sets the optimization marker in the function's feedback vector.
1013 inline void SetOptimizationMarker(OptimizationMarker marker);
1014
1015 // Clears the optimization marker in the function's feedback vector.
1016 inline void ClearOptimizationMarker();
1017
1018 // If slack tracking is active, it computes instance size of the initial map
1019 // with minimum permissible object slack. If it is not active, it simply
1020 // returns the initial map's instance size.
1021 int ComputeInstanceSizeWithMinSlack(Isolate* isolate);
1022
1023 // Completes inobject slack tracking on initial map if it is active.
1024 inline void CompleteInobjectSlackTrackingIfActive();
1025
1026 // [raw_feedback_cell]: Gives raw access to the FeedbackCell used to hold the
1027 /// FeedbackVector eventually. Generally this shouldn't be used to get the
1028 // feedback_vector, instead use feedback_vector() which correctly deals with
1029 // the JSFunction's bytecode being flushed.
1030 DECL_ACCESSORS(raw_feedback_cell, FeedbackCell)
1031
1032 // Functions related to feedback vector. feedback_vector() can be used once
1033 // the function has feedback vectors allocated. feedback vectors may not be
1034 // available after compile when lazily allocating feedback vectors.
1035 inline FeedbackVector feedback_vector() const;
1036 inline bool has_feedback_vector() const;
1037 V8_EXPORT_PRIVATE static void EnsureFeedbackVector(
1038 Handle<JSFunction> function);
1039
1040 // Functions related to clousre feedback cell array that holds feedback cells
1041 // used to create closures from this function. We allocate closure feedback
1042 // cell arrays after compile, when we want to allocate feedback vectors
1043 // lazily.
1044 inline bool has_closure_feedback_cell_array() const;
1045 inline ClosureFeedbackCellArray closure_feedback_cell_array() const;
1046 static void EnsureClosureFeedbackCellArray(Handle<JSFunction> function);
1047
1048 // Initializes the feedback cell of |function|. In lite mode, this would be
1049 // initialized to the closure feedback cell array that holds the feedback
1050 // cells for create closure calls from this function. In the regular mode,
1051 // this allocates feedback vector.
1052 static void InitializeFeedbackCell(Handle<JSFunction> function);
1053
1054 // Unconditionally clear the type feedback vector.
1055 void ClearTypeFeedbackInfo();
1056
1057 // Resets function to clear compiled data after bytecode has been flushed.
1058 inline bool NeedsResetDueToFlushedBytecode();
1059 inline void ResetIfBytecodeFlushed();
1060
1061 inline bool has_prototype_slot() const;
1062
1063 // The initial map for an object created by this constructor.
1064 inline Map initial_map();
1065 static void SetInitialMap(Handle<JSFunction> function, Handle<Map> map,
1066 Handle<HeapObject> prototype);
1067 inline bool has_initial_map();
1068 V8_EXPORT_PRIVATE static void EnsureHasInitialMap(
1069 Handle<JSFunction> function);
1070
1071 // Creates a map that matches the constructor's initial map, but with
1072 // [[prototype]] being new.target.prototype. Because new.target can be a
1073 // JSProxy, this can call back into JavaScript.
1074 static V8_WARN_UNUSED_RESULT MaybeHandle<Map> GetDerivedMap(
1075 Isolate* isolate, Handle<JSFunction> constructor,
1076 Handle<JSReceiver> new_target);
1077
1078 // Get and set the prototype property on a JSFunction. If the
1079 // function has an initial map the prototype is set on the initial
1080 // map. Otherwise, the prototype is put in the initial map field
1081 // until an initial map is needed.
1082 inline bool has_prototype();
1083 inline bool has_instance_prototype();
1084 inline Object prototype();
1085 inline HeapObject instance_prototype();
1086 inline bool has_prototype_property();
1087 inline bool PrototypeRequiresRuntimeLookup();
1088 static void SetPrototype(Handle<JSFunction> function, Handle<Object> value);
1089
1090 // Returns if this function has been compiled to native code yet.
1091 inline bool is_compiled() const;
1092
1093 static int GetHeaderSize(bool function_has_prototype_slot) {
1094 return function_has_prototype_slot ? JSFunction::kSizeWithPrototype
1095 : JSFunction::kSizeWithoutPrototype;
1096 }
1097
1098 // Prints the name of the function using PrintF.
1099 void PrintName(FILE* out = stdout);
1100
1101 DECL_CAST(JSFunction)
1102
1103 // Calculate the instance size and in-object properties count.
1104 static V8_WARN_UNUSED_RESULT int CalculateExpectedNofProperties(
1105 Isolate* isolate, Handle<JSFunction> function);
1106 static void CalculateInstanceSizeHelper(InstanceType instance_type,
1107 bool has_prototype_slot,
1108 int requested_embedder_fields,
1109 int requested_in_object_properties,
1110 int* instance_size,
1111 int* in_object_properties);
1112
1113 // Dispatched behavior.
1114 DECL_PRINTER(JSFunction)
1115 DECL_VERIFIER(JSFunction)
1116
1117 // The function's name if it is configured, otherwise shared function info
1118 // debug name.
1119 static Handle<String> GetName(Handle<JSFunction> function);
1120
1121 // ES6 section 9.2.11 SetFunctionName
1122 // Because of the way this abstract operation is used in the spec,
1123 // it should never fail, but in practice it will fail if the generated
1124 // function name's length exceeds String::kMaxLength.
1125 static V8_WARN_UNUSED_RESULT bool SetName(Handle<JSFunction> function,
1126 Handle<Name> name,
1127 Handle<String> prefix);
1128
1129 // The function's displayName if it is set, otherwise name if it is
1130 // configured, otherwise shared function info
1131 // debug name.
1132 static Handle<String> GetDebugName(Handle<JSFunction> function);
1133
1134 // The function's string representation implemented according to
1135 // ES6 section 19.2.3.5 Function.prototype.toString ( ).
1136 static Handle<String> ToString(Handle<JSFunction> function);
1137
1138 DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
1139 TORQUE_GENERATED_JSFUNCTION_FIELDS)
1140
1141 static constexpr int kSizeWithoutPrototype = kPrototypeOrInitialMapOffset;
1142 static constexpr int kSizeWithPrototype = kSize;
1143
1144 OBJECT_CONSTRUCTORS(JSFunction, JSObject);
1145};
1146
1147// JSGlobalProxy's prototype must be a JSGlobalObject or null,
1148// and the prototype is hidden. JSGlobalProxy always delegates
1149// property accesses to its prototype if the prototype is not null.
1150//
1151// A JSGlobalProxy can be reinitialized which will preserve its identity.
1152//
1153// Accessing a JSGlobalProxy requires security check.
1154
1155class JSGlobalProxy : public JSObject {
1156 public:
1157 // [native_context]: the owner native context of this global proxy object.
1158 // It is null value if this object is not used by any context.
1159 DECL_ACCESSORS(native_context, Object)
1160
1161 DECL_CAST(JSGlobalProxy)
1162
1163 inline bool IsDetachedFrom(JSGlobalObject global) const;
1164
1165 static int SizeWithEmbedderFields(int embedder_field_count);
1166
1167 // Dispatched behavior.
1168 DECL_PRINTER(JSGlobalProxy)
1169 DECL_VERIFIER(JSGlobalProxy)
1170
1171 // Layout description.
1172 DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
1173 TORQUE_GENERATED_JSGLOBAL_PROXY_FIELDS)
1174
1175 OBJECT_CONSTRUCTORS(JSGlobalProxy, JSObject);
1176};
1177
1178// JavaScript global object.
1179class JSGlobalObject : public JSObject {
1180 public:
1181 // [native context]: the natives corresponding to this global object.
1182 DECL_ACCESSORS(native_context, NativeContext)
1183
1184 // [global proxy]: the global proxy object of the context
1185 DECL_ACCESSORS(global_proxy, JSGlobalProxy)
1186
1187 // Gets global object properties.
1188 inline GlobalDictionary global_dictionary();
1189 inline void set_global_dictionary(GlobalDictionary dictionary);
1190
1191 static void InvalidatePropertyCell(Handle<JSGlobalObject> object,
1192 Handle<Name> name);
1193 // Ensure that the global object has a cell for the given property name.
1194 static Handle<PropertyCell> EnsureEmptyPropertyCell(
1195 Handle<JSGlobalObject> global, Handle<Name> name,
1196 PropertyCellType cell_type, int* entry_out = nullptr);
1197
1198 DECL_CAST(JSGlobalObject)
1199
1200 inline bool IsDetached();
1201
1202 // Dispatched behavior.
1203 DECL_PRINTER(JSGlobalObject)
1204 DECL_VERIFIER(JSGlobalObject)
1205
1206 // Layout description.
1207#define JS_GLOBAL_OBJECT_FIELDS(V) \
1208 V(kNativeContextOffset, kTaggedSize) \
1209 V(kGlobalProxyOffset, kTaggedSize) \
1210 /* Header size. */ \
1211 V(kHeaderSize, 0) \
1212 V(kSize, 0)
1213
1214 DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, JS_GLOBAL_OBJECT_FIELDS)
1215#undef JS_GLOBAL_OBJECT_FIELDS
1216
1217 OBJECT_CONSTRUCTORS(JSGlobalObject, JSObject);
1218};
1219
1220// Representation for JS Wrapper objects, String, Number, Boolean, etc.
1221class JSValue : public JSObject {
1222 public:
1223 // [value]: the object being wrapped.
1224 DECL_ACCESSORS(value, Object)
1225
1226 DECL_CAST(JSValue)
1227
1228 // Dispatched behavior.
1229 DECL_PRINTER(JSValue)
1230 DECL_VERIFIER(JSValue)
1231
1232 // Layout description.
1233 DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
1234 TORQUE_GENERATED_JSVALUE_FIELDS)
1235
1236 OBJECT_CONSTRUCTORS(JSValue, JSObject);
1237};
1238
1239class DateCache;
1240
1241// Representation for JS date objects.
1242class JSDate : public JSObject {
1243 public:
1244 static V8_WARN_UNUSED_RESULT MaybeHandle<JSDate> New(
1245 Handle<JSFunction> constructor, Handle<JSReceiver> new_target, double tv);
1246
1247 // If one component is NaN, all of them are, indicating a NaN time value.
1248 // [value]: the time value.
1249 DECL_ACCESSORS(value, Object)
1250 // [year]: caches year. Either undefined, smi, or NaN.
1251 DECL_ACCESSORS(year, Object)
1252 // [month]: caches month. Either undefined, smi, or NaN.
1253 DECL_ACCESSORS(month, Object)
1254 // [day]: caches day. Either undefined, smi, or NaN.
1255 DECL_ACCESSORS(day, Object)
1256 // [weekday]: caches day of week. Either undefined, smi, or NaN.
1257 DECL_ACCESSORS(weekday, Object)
1258 // [hour]: caches hours. Either undefined, smi, or NaN.
1259 DECL_ACCESSORS(hour, Object)
1260 // [min]: caches minutes. Either undefined, smi, or NaN.
1261 DECL_ACCESSORS(min, Object)
1262 // [sec]: caches seconds. Either undefined, smi, or NaN.
1263 DECL_ACCESSORS(sec, Object)
1264 // [cache stamp]: sample of the date cache stamp at the
1265 // moment when chached fields were cached.
1266 DECL_ACCESSORS(cache_stamp, Object)
1267
1268 DECL_CAST(JSDate)
1269
1270 // Returns the time value (UTC) identifying the current time.
1271 static double CurrentTimeValue(Isolate* isolate);
1272
1273 // Returns the date field with the specified index.
1274 // See FieldIndex for the list of date fields.
1275 // Arguments and result are raw Address values because this is called
1276 // via ExternalReference.
1277 // {raw_date} is a tagged Object pointer.
1278 // {smi_index} is a tagged Smi.
1279 // The return value is a tagged Object pointer.
1280 static Address GetField(Address raw_date, Address smi_index);
1281
1282 static Handle<Object> SetValue(Handle<JSDate> date, double v);
1283
1284 void SetValue(Object value, bool is_value_nan);
1285
1286 // Dispatched behavior.
1287 DECL_PRINTER(JSDate)
1288 DECL_VERIFIER(JSDate)
1289
1290 // The order is important. It must be kept in sync with date macros
1291 // in macros.py.
1292 enum FieldIndex {
1293 kDateValue,
1294 kYear,
1295 kMonth,
1296 kDay,
1297 kWeekday,
1298 kHour,
1299 kMinute,
1300 kSecond,
1301 kFirstUncachedField,
1302 kMillisecond = kFirstUncachedField,
1303 kDays,
1304 kTimeInDay,
1305 kFirstUTCField,
1306 kYearUTC = kFirstUTCField,
1307 kMonthUTC,
1308 kDayUTC,
1309 kWeekdayUTC,
1310 kHourUTC,
1311 kMinuteUTC,
1312 kSecondUTC,
1313 kMillisecondUTC,
1314 kDaysUTC,
1315 kTimeInDayUTC,
1316 kTimezoneOffset
1317 };
1318
1319 DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
1320 TORQUE_GENERATED_JSDATE_FIELDS)
1321
1322 private:
1323 inline Object DoGetField(FieldIndex index);
1324
1325 Object GetUTCField(FieldIndex index, double value, DateCache* date_cache);
1326
1327 // Computes and caches the cacheable fields of the date.
1328 inline void SetCachedFields(int64_t local_time_ms, DateCache* date_cache);
1329
1330 OBJECT_CONSTRUCTORS(JSDate, JSObject);
1331};
1332
1333// Representation of message objects used for error reporting through
1334// the API. The messages are formatted in JavaScript so this object is
1335// a real JavaScript object. The information used for formatting the
1336// error messages are not directly accessible from JavaScript to
1337// prevent leaking information to user code called during error
1338// formatting.
1339class JSMessageObject : public JSObject {
1340 public:
1341 // [type]: the type of error message.
1342 inline MessageTemplate type() const;
1343 inline void set_type(MessageTemplate value);
1344
1345 // [arguments]: the arguments for formatting the error message.
1346 DECL_ACCESSORS(argument, Object)
1347
1348 // [script]: the script from which the error message originated.
1349 DECL_ACCESSORS(script, Script)
1350
1351 // [stack_frames]: an array of stack frames for this error object.
1352 DECL_ACCESSORS(stack_frames, Object)
1353
1354 // [start_position]: the start position in the script for the error message.
1355 inline int start_position() const;
1356 inline void set_start_position(int value);
1357
1358 // [end_position]: the end position in the script for the error message.
1359 inline int end_position() const;
1360 inline void set_end_position(int value);
1361
1362 // Returns the line number for the error message (1-based), or
1363 // Message::kNoLineNumberInfo if the line cannot be determined.
1364 V8_EXPORT_PRIVATE int GetLineNumber() const;
1365
1366 // Returns the offset of the given position within the containing line.
1367 V8_EXPORT_PRIVATE int GetColumnNumber() const;
1368
1369 // Returns the source code line containing the given source
1370 // position, or the empty string if the position is invalid.
1371 Handle<String> GetSourceLine() const;
1372
1373 inline int error_level() const;
1374 inline void set_error_level(int level);
1375
1376 DECL_CAST(JSMessageObject)
1377
1378 // Dispatched behavior.
1379 DECL_PRINTER(JSMessageObject)
1380 DECL_VERIFIER(JSMessageObject)
1381
1382 DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
1383 TORQUE_GENERATED_JSMESSAGE_OBJECT_FIELDS)
1384 // TODO(v8:8989): [torque] Support marker constants.
1385 static const int kPointerFieldsEndOffset = kStartPositionOffset;
1386
1387 using BodyDescriptor = FixedBodyDescriptor<HeapObject::kMapOffset,
1388 kPointerFieldsEndOffset, kSize>;
1389
1390 OBJECT_CONSTRUCTORS(JSMessageObject, JSObject);
1391};
1392
1393// The [Async-from-Sync Iterator] object
1394// (proposal-async-iteration/#sec-async-from-sync-iterator-objects)
1395// An object which wraps an ordinary Iterator and converts it to behave
1396// according to the Async Iterator protocol.
1397// (See https://tc39.github.io/proposal-async-iteration/#sec-iteration)
1398class JSAsyncFromSyncIterator : public JSObject {
1399 public:
1400 DECL_CAST(JSAsyncFromSyncIterator)
1401 DECL_PRINTER(JSAsyncFromSyncIterator)
1402 DECL_VERIFIER(JSAsyncFromSyncIterator)
1403
1404 // Async-from-Sync Iterator instances are ordinary objects that inherit
1405 // properties from the %AsyncFromSyncIteratorPrototype% intrinsic object.
1406 // Async-from-Sync Iterator instances are initially created with the internal
1407 // slots listed in Table 4.
1408 // (proposal-async-iteration/#table-async-from-sync-iterator-internal-slots)
1409 DECL_ACCESSORS(sync_iterator, JSReceiver)
1410
1411 // The "next" method is loaded during GetIterator, and is not reloaded for
1412 // subsequent "next" invocations.
1413 DECL_ACCESSORS(next, Object)
1414
1415 DEFINE_FIELD_OFFSET_CONSTANTS(
1416 JSObject::kHeaderSize, TORQUE_GENERATED_JSASYNC_FROM_SYNC_ITERATOR_FIELDS)
1417
1418 OBJECT_CONSTRUCTORS(JSAsyncFromSyncIterator, JSObject);
1419};
1420
1421class JSStringIterator : public JSObject {
1422 public:
1423 // Dispatched behavior.
1424 DECL_PRINTER(JSStringIterator)
1425 DECL_VERIFIER(JSStringIterator)
1426
1427 DECL_CAST(JSStringIterator)
1428
1429 // [string]: the [[IteratedString]] inobject property.
1430 DECL_ACCESSORS(string, String)
1431
1432 // [index]: The [[StringIteratorNextIndex]] inobject property.
1433 inline int index() const;
1434 inline void set_index(int value);
1435
1436 DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
1437 TORQUE_GENERATED_JSSTRING_ITERATOR_FIELDS)
1438
1439 OBJECT_CONSTRUCTORS(JSStringIterator, JSObject);
1440};
1441
1442} // namespace internal
1443} // namespace v8
1444
1445#include "src/objects/object-macros-undef.h"
1446
1447#endif // V8_OBJECTS_JS_OBJECTS_H_
1448