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