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 : class NativeContext;
23 :
24 : // JSReceiver includes types on which properties can be defined, i.e.,
25 : // JSObject and JSProxy.
26 : class 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.
285 : class 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 1309980 : 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 : template <typename Dictionary>
801 : static void ApplyAttributesToDictionary(Isolate* isolate, ReadOnlyRoots roots,
802 : Handle<Dictionary> dictionary,
803 : const PropertyAttributes attributes);
804 :
805 : private:
806 : friend class JSReceiver;
807 : friend class Object;
808 :
809 : // Used from Object::GetProperty().
810 : V8_WARN_UNUSED_RESULT static MaybeHandle<Object>
811 : GetPropertyWithFailedAccessCheck(LookupIterator* it);
812 :
813 : V8_WARN_UNUSED_RESULT static Maybe<bool> SetPropertyWithFailedAccessCheck(
814 : LookupIterator* it, Handle<Object> value,
815 : Maybe<ShouldThrow> should_throw);
816 :
817 : V8_WARN_UNUSED_RESULT static Maybe<bool> DeletePropertyWithInterceptor(
818 : LookupIterator* it, ShouldThrow should_throw);
819 :
820 : bool ReferencesObjectFromElements(FixedArray elements, ElementsKind kind,
821 : Object object);
822 :
823 : // Helper for fast versions of preventExtensions, seal, and freeze.
824 : // attrs is one of NONE, SEALED, or FROZEN (depending on the operation).
825 : template <PropertyAttributes attrs>
826 : V8_WARN_UNUSED_RESULT static Maybe<bool> PreventExtensionsWithTransition(
827 : Handle<JSObject> object, ShouldThrow should_throw);
828 :
829 : OBJECT_CONSTRUCTORS(JSObject, JSReceiver);
830 : };
831 :
832 : // JSAccessorPropertyDescriptor is just a JSObject with a specific initial
833 : // map. This initial map adds in-object properties for "get", "set",
834 : // "enumerable" and "configurable" properties, as assigned by the
835 : // FromPropertyDescriptor function for regular accessor properties.
836 : class JSAccessorPropertyDescriptor : public JSObject {
837 : public:
838 : // Layout description.
839 : DEFINE_FIELD_OFFSET_CONSTANTS(
840 : JSObject::kHeaderSize,
841 : TORQUE_GENERATED_JSACCESSOR_PROPERTY_DESCRIPTOR_FIELDS)
842 :
843 : // Indices of in-object properties.
844 : static const int kGetIndex = 0;
845 : static const int kSetIndex = 1;
846 : static const int kEnumerableIndex = 2;
847 : static const int kConfigurableIndex = 3;
848 :
849 : private:
850 : DISALLOW_IMPLICIT_CONSTRUCTORS(JSAccessorPropertyDescriptor);
851 : };
852 :
853 : // JSDataPropertyDescriptor is just a JSObject with a specific initial map.
854 : // This initial map adds in-object properties for "value", "writable",
855 : // "enumerable" and "configurable" properties, as assigned by the
856 : // FromPropertyDescriptor function for regular data properties.
857 : class JSDataPropertyDescriptor : public JSObject {
858 : public:
859 : DEFINE_FIELD_OFFSET_CONSTANTS(
860 : JSObject::kHeaderSize, TORQUE_GENERATED_JSDATA_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<NativeContext> 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,
935 : TORQUE_GENERATED_JSBOUND_FUNCTION_FIELDS)
936 :
937 : OBJECT_CONSTRUCTORS(JSBoundFunction, JSObject);
938 : };
939 :
940 : // JSFunction describes JavaScript functions.
941 : class JSFunction : public JSObject {
942 : public:
943 : // [prototype_or_initial_map]:
944 : DECL_ACCESSORS(prototype_or_initial_map, Object)
945 :
946 : // [shared]: The information about the function that
947 : // can be shared by instances.
948 : DECL_ACCESSORS(shared, SharedFunctionInfo)
949 :
950 : static const int kLengthDescriptorIndex = 0;
951 : static const int kNameDescriptorIndex = 1;
952 : // Home object descriptor index when function has a [[HomeObject]] slot.
953 : static const int kMaybeHomeObjectDescriptorIndex = 2;
954 :
955 : // [context]: The context for this function.
956 : inline Context context();
957 : inline bool has_context() const;
958 : inline void set_context(Object context);
959 : inline JSGlobalProxy global_proxy();
960 : inline NativeContext native_context();
961 : inline int length();
962 :
963 : static Handle<Object> GetName(Isolate* isolate, Handle<JSFunction> function);
964 : static Handle<NativeContext> GetFunctionRealm(Handle<JSFunction> function);
965 :
966 : // [code]: The generated code object for this function. Executed
967 : // when the function is invoked, e.g. foo() or new foo(). See
968 : // [[Call]] and [[Construct]] description in ECMA-262, section
969 : // 8.6.2, page 27.
970 : inline Code code() const;
971 : inline void set_code(Code code);
972 : inline void set_code_no_write_barrier(Code code);
973 :
974 : // Get the abstract code associated with the function, which will either be
975 : // a Code object or a BytecodeArray.
976 : inline AbstractCode abstract_code();
977 :
978 : // Tells whether or not this function is interpreted.
979 : //
980 : // Note: function->IsInterpreted() does not necessarily return the same value
981 : // as function->shared()->IsInterpreted() because the closure might have been
982 : // optimized.
983 : inline bool IsInterpreted();
984 :
985 : // Tells whether or not this function checks its optimization marker in its
986 : // feedback vector.
987 : inline bool ChecksOptimizationMarker();
988 :
989 : // Tells whether or not this function holds optimized code.
990 : //
991 : // Note: Returning false does not necessarily mean that this function hasn't
992 : // been optimized, as it may have optimized code on its feedback vector.
993 : inline bool IsOptimized();
994 :
995 : // Tells whether or not this function has optimized code available to it,
996 : // either because it is optimized or because it has optimized code in its
997 : // feedback vector.
998 : inline bool HasOptimizedCode();
999 :
1000 : // Tells whether or not this function has a (non-zero) optimization marker.
1001 : inline bool HasOptimizationMarker();
1002 :
1003 : // Mark this function for lazy recompilation. The function will be recompiled
1004 : // the next time it is executed.
1005 : void MarkForOptimization(ConcurrencyMode mode);
1006 :
1007 : // Tells whether or not the function is already marked for lazy recompilation.
1008 : inline bool IsMarkedForOptimization();
1009 : inline bool IsMarkedForConcurrentOptimization();
1010 :
1011 : // Tells whether or not the function is on the concurrent recompilation queue.
1012 : inline bool IsInOptimizationQueue();
1013 :
1014 : // Clears the optimized code slot in the function's feedback vector.
1015 : inline void ClearOptimizedCodeSlot(const char* reason);
1016 :
1017 : // Sets the optimization marker in the function's feedback vector.
1018 : inline void SetOptimizationMarker(OptimizationMarker marker);
1019 :
1020 : // Clears the optimization marker in the function's feedback vector.
1021 : inline void ClearOptimizationMarker();
1022 :
1023 : // If slack tracking is active, it computes instance size of the initial map
1024 : // with minimum permissible object slack. If it is not active, it simply
1025 : // returns the initial map's instance size.
1026 : int ComputeInstanceSizeWithMinSlack(Isolate* isolate);
1027 :
1028 : // Completes inobject slack tracking on initial map if it is active.
1029 : inline void CompleteInobjectSlackTrackingIfActive();
1030 :
1031 : // [raw_feedback_cell]: Gives raw access to the FeedbackCell used to hold the
1032 : /// FeedbackVector eventually. Generally this shouldn't be used to get the
1033 : // feedback_vector, instead use feedback_vector() which correctly deals with
1034 : // the JSFunction's bytecode being flushed.
1035 : DECL_ACCESSORS(raw_feedback_cell, FeedbackCell)
1036 :
1037 : // Functions related to feedback vector. feedback_vector() can be used once
1038 : // the function has feedback vectors allocated. feedback vectors may not be
1039 : // available after compile when lazily allocating feedback vectors.
1040 : inline FeedbackVector feedback_vector() const;
1041 : inline bool has_feedback_vector() const;
1042 : V8_EXPORT_PRIVATE static void EnsureFeedbackVector(
1043 : Handle<JSFunction> function);
1044 :
1045 : // Functions related to clousre feedback cell array that holds feedback cells
1046 : // used to create closures from this function. We allocate closure feedback
1047 : // cell arrays after compile, when we want to allocate feedback vectors
1048 : // lazily.
1049 : inline bool has_closure_feedback_cell_array() const;
1050 : inline ClosureFeedbackCellArray closure_feedback_cell_array() const;
1051 : static void EnsureClosureFeedbackCellArray(Handle<JSFunction> function);
1052 :
1053 : // Initializes the feedback cell of |function|. In lite mode, this would be
1054 : // initialized to the closure feedback cell array that holds the feedback
1055 : // cells for create closure calls from this function. In the regular mode,
1056 : // this allocates feedback vector.
1057 : static void InitializeFeedbackCell(Handle<JSFunction> function);
1058 :
1059 : // Unconditionally clear the type feedback vector.
1060 : void ClearTypeFeedbackInfo();
1061 :
1062 : // Resets function to clear compiled data after bytecode has been flushed.
1063 : inline bool NeedsResetDueToFlushedBytecode();
1064 : inline void ResetIfBytecodeFlushed();
1065 :
1066 : inline bool has_prototype_slot() const;
1067 :
1068 : // The initial map for an object created by this constructor.
1069 : inline Map initial_map();
1070 : static void SetInitialMap(Handle<JSFunction> function, Handle<Map> map,
1071 : Handle<HeapObject> prototype);
1072 : inline bool has_initial_map();
1073 : V8_EXPORT_PRIVATE static void EnsureHasInitialMap(
1074 : Handle<JSFunction> function);
1075 :
1076 : // Creates a map that matches the constructor's initial map, but with
1077 : // [[prototype]] being new.target.prototype. Because new.target can be a
1078 : // JSProxy, this can call back into JavaScript.
1079 : static V8_WARN_UNUSED_RESULT MaybeHandle<Map> GetDerivedMap(
1080 : Isolate* isolate, Handle<JSFunction> constructor,
1081 : Handle<JSReceiver> new_target);
1082 :
1083 : // Get and set the prototype property on a JSFunction. If the
1084 : // function has an initial map the prototype is set on the initial
1085 : // map. Otherwise, the prototype is put in the initial map field
1086 : // until an initial map is needed.
1087 : inline bool has_prototype();
1088 : inline bool has_instance_prototype();
1089 : inline Object prototype();
1090 : inline HeapObject instance_prototype();
1091 : inline bool has_prototype_property();
1092 : inline bool PrototypeRequiresRuntimeLookup();
1093 : static void SetPrototype(Handle<JSFunction> function, Handle<Object> value);
1094 :
1095 : // Returns if this function has been compiled to native code yet.
1096 : inline bool is_compiled() const;
1097 :
1098 : static int GetHeaderSize(bool function_has_prototype_slot) {
1099 : return function_has_prototype_slot ? JSFunction::kSizeWithPrototype
1100 480472 : : JSFunction::kSizeWithoutPrototype;
1101 : }
1102 :
1103 : // Prints the name of the function using PrintF.
1104 : void PrintName(FILE* out = stdout);
1105 :
1106 : DECL_CAST(JSFunction)
1107 :
1108 : // Calculate the instance size and in-object properties count.
1109 : static V8_WARN_UNUSED_RESULT int CalculateExpectedNofProperties(
1110 : Isolate* isolate, Handle<JSFunction> function);
1111 : static void CalculateInstanceSizeHelper(InstanceType instance_type,
1112 : bool has_prototype_slot,
1113 : int requested_embedder_fields,
1114 : int requested_in_object_properties,
1115 : int* instance_size,
1116 : int* in_object_properties);
1117 :
1118 : // Dispatched behavior.
1119 : DECL_PRINTER(JSFunction)
1120 : DECL_VERIFIER(JSFunction)
1121 :
1122 : // The function's name if it is configured, otherwise shared function info
1123 : // debug name.
1124 : static Handle<String> GetName(Handle<JSFunction> function);
1125 :
1126 : // ES6 section 9.2.11 SetFunctionName
1127 : // Because of the way this abstract operation is used in the spec,
1128 : // it should never fail, but in practice it will fail if the generated
1129 : // function name's length exceeds String::kMaxLength.
1130 : static V8_WARN_UNUSED_RESULT bool SetName(Handle<JSFunction> function,
1131 : Handle<Name> name,
1132 : Handle<String> prefix);
1133 :
1134 : // The function's displayName if it is set, otherwise name if it is
1135 : // configured, otherwise shared function info
1136 : // debug name.
1137 : static Handle<String> GetDebugName(Handle<JSFunction> function);
1138 :
1139 : // The function's string representation implemented according to
1140 : // ES6 section 19.2.3.5 Function.prototype.toString ( ).
1141 : static Handle<String> ToString(Handle<JSFunction> function);
1142 :
1143 : DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
1144 : TORQUE_GENERATED_JSFUNCTION_FIELDS)
1145 :
1146 : static constexpr int kSizeWithoutPrototype = kPrototypeOrInitialMapOffset;
1147 : static constexpr int kSizeWithPrototype = kSize;
1148 :
1149 : OBJECT_CONSTRUCTORS(JSFunction, JSObject);
1150 : };
1151 :
1152 : // JSGlobalProxy's prototype must be a JSGlobalObject or null,
1153 : // and the prototype is hidden. JSGlobalProxy always delegates
1154 : // property accesses to its prototype if the prototype is not null.
1155 : //
1156 : // A JSGlobalProxy can be reinitialized which will preserve its identity.
1157 : //
1158 : // Accessing a JSGlobalProxy requires security check.
1159 :
1160 : class JSGlobalProxy : public JSObject {
1161 : public:
1162 : // [native_context]: the owner native context of this global proxy object.
1163 : // It is null value if this object is not used by any context.
1164 : DECL_ACCESSORS(native_context, Object)
1165 :
1166 : DECL_CAST(JSGlobalProxy)
1167 :
1168 : inline bool IsDetachedFrom(JSGlobalObject global) const;
1169 :
1170 : static int SizeWithEmbedderFields(int embedder_field_count);
1171 :
1172 : // Dispatched behavior.
1173 : DECL_PRINTER(JSGlobalProxy)
1174 : DECL_VERIFIER(JSGlobalProxy)
1175 :
1176 : // Layout description.
1177 : DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
1178 : TORQUE_GENERATED_JSGLOBAL_PROXY_FIELDS)
1179 :
1180 : OBJECT_CONSTRUCTORS(JSGlobalProxy, JSObject);
1181 : };
1182 :
1183 : // JavaScript global object.
1184 : class JSGlobalObject : public JSObject {
1185 : public:
1186 : // [native context]: the natives corresponding to this global object.
1187 : DECL_ACCESSORS(native_context, NativeContext)
1188 :
1189 : // [global proxy]: the global proxy object of the context
1190 : DECL_ACCESSORS(global_proxy, JSGlobalProxy)
1191 :
1192 : // Gets global object properties.
1193 : inline GlobalDictionary global_dictionary();
1194 : inline void set_global_dictionary(GlobalDictionary dictionary);
1195 :
1196 : static void InvalidatePropertyCell(Handle<JSGlobalObject> object,
1197 : Handle<Name> name);
1198 : // Ensure that the global object has a cell for the given property name.
1199 : static Handle<PropertyCell> EnsureEmptyPropertyCell(
1200 : Handle<JSGlobalObject> global, Handle<Name> name,
1201 : PropertyCellType cell_type, int* entry_out = nullptr);
1202 :
1203 : DECL_CAST(JSGlobalObject)
1204 :
1205 : inline bool IsDetached();
1206 :
1207 : // Dispatched behavior.
1208 : DECL_PRINTER(JSGlobalObject)
1209 : DECL_VERIFIER(JSGlobalObject)
1210 :
1211 : // Layout description.
1212 : #define JS_GLOBAL_OBJECT_FIELDS(V) \
1213 : V(kNativeContextOffset, kTaggedSize) \
1214 : V(kGlobalProxyOffset, kTaggedSize) \
1215 : /* Header size. */ \
1216 : V(kHeaderSize, 0) \
1217 : V(kSize, 0)
1218 :
1219 : DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, JS_GLOBAL_OBJECT_FIELDS)
1220 : #undef JS_GLOBAL_OBJECT_FIELDS
1221 :
1222 : OBJECT_CONSTRUCTORS(JSGlobalObject, JSObject);
1223 : };
1224 :
1225 : // Representation for JS Wrapper objects, String, Number, Boolean, etc.
1226 : class JSValue : public JSObject {
1227 : public:
1228 : // [value]: the object being wrapped.
1229 : DECL_ACCESSORS(value, Object)
1230 :
1231 : DECL_CAST(JSValue)
1232 :
1233 : // Dispatched behavior.
1234 : DECL_PRINTER(JSValue)
1235 : DECL_VERIFIER(JSValue)
1236 :
1237 : // Layout description.
1238 : DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
1239 : TORQUE_GENERATED_JSVALUE_FIELDS)
1240 :
1241 : OBJECT_CONSTRUCTORS(JSValue, JSObject);
1242 : };
1243 :
1244 : class DateCache;
1245 :
1246 : // Representation for JS date objects.
1247 : class JSDate : public JSObject {
1248 : public:
1249 : static V8_WARN_UNUSED_RESULT MaybeHandle<JSDate> New(
1250 : Handle<JSFunction> constructor, Handle<JSReceiver> new_target, double tv);
1251 :
1252 : // If one component is NaN, all of them are, indicating a NaN time value.
1253 : // [value]: the time value.
1254 : DECL_ACCESSORS(value, Object)
1255 : // [year]: caches year. Either undefined, smi, or NaN.
1256 : DECL_ACCESSORS(year, Object)
1257 : // [month]: caches month. Either undefined, smi, or NaN.
1258 : DECL_ACCESSORS(month, Object)
1259 : // [day]: caches day. Either undefined, smi, or NaN.
1260 : DECL_ACCESSORS(day, Object)
1261 : // [weekday]: caches day of week. Either undefined, smi, or NaN.
1262 : DECL_ACCESSORS(weekday, Object)
1263 : // [hour]: caches hours. Either undefined, smi, or NaN.
1264 : DECL_ACCESSORS(hour, Object)
1265 : // [min]: caches minutes. Either undefined, smi, or NaN.
1266 : DECL_ACCESSORS(min, Object)
1267 : // [sec]: caches seconds. Either undefined, smi, or NaN.
1268 : DECL_ACCESSORS(sec, Object)
1269 : // [cache stamp]: sample of the date cache stamp at the
1270 : // moment when chached fields were cached.
1271 : DECL_ACCESSORS(cache_stamp, Object)
1272 :
1273 : DECL_CAST(JSDate)
1274 :
1275 : // Returns the time value (UTC) identifying the current time.
1276 : static double CurrentTimeValue(Isolate* isolate);
1277 :
1278 : // Returns the date field with the specified index.
1279 : // See FieldIndex for the list of date fields.
1280 : // Arguments and result are raw Address values because this is called
1281 : // via ExternalReference.
1282 : // {raw_date} is a tagged Object pointer.
1283 : // {smi_index} is a tagged Smi.
1284 : // The return value is a tagged Object pointer.
1285 : static Address GetField(Address raw_date, Address smi_index);
1286 :
1287 : static Handle<Object> SetValue(Handle<JSDate> date, double v);
1288 :
1289 : void SetValue(Object value, bool is_value_nan);
1290 :
1291 : // Dispatched behavior.
1292 : DECL_PRINTER(JSDate)
1293 : DECL_VERIFIER(JSDate)
1294 :
1295 : // The order is important. It must be kept in sync with date macros
1296 : // in macros.py.
1297 : enum FieldIndex {
1298 : kDateValue,
1299 : kYear,
1300 : kMonth,
1301 : kDay,
1302 : kWeekday,
1303 : kHour,
1304 : kMinute,
1305 : kSecond,
1306 : kFirstUncachedField,
1307 : kMillisecond = kFirstUncachedField,
1308 : kDays,
1309 : kTimeInDay,
1310 : kFirstUTCField,
1311 : kYearUTC = kFirstUTCField,
1312 : kMonthUTC,
1313 : kDayUTC,
1314 : kWeekdayUTC,
1315 : kHourUTC,
1316 : kMinuteUTC,
1317 : kSecondUTC,
1318 : kMillisecondUTC,
1319 : kDaysUTC,
1320 : kTimeInDayUTC,
1321 : kTimezoneOffset
1322 : };
1323 :
1324 : DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
1325 : TORQUE_GENERATED_JSDATE_FIELDS)
1326 :
1327 : private:
1328 : inline Object DoGetField(FieldIndex index);
1329 :
1330 : Object GetUTCField(FieldIndex index, double value, DateCache* date_cache);
1331 :
1332 : // Computes and caches the cacheable fields of the date.
1333 : inline void SetCachedFields(int64_t local_time_ms, DateCache* date_cache);
1334 :
1335 : OBJECT_CONSTRUCTORS(JSDate, JSObject);
1336 : };
1337 :
1338 : // Representation of message objects used for error reporting through
1339 : // the API. The messages are formatted in JavaScript so this object is
1340 : // a real JavaScript object. The information used for formatting the
1341 : // error messages are not directly accessible from JavaScript to
1342 : // prevent leaking information to user code called during error
1343 : // formatting.
1344 : class JSMessageObject : public JSObject {
1345 : public:
1346 : // [type]: the type of error message.
1347 : inline MessageTemplate type() const;
1348 : inline void set_type(MessageTemplate value);
1349 :
1350 : // [arguments]: the arguments for formatting the error message.
1351 : DECL_ACCESSORS(argument, Object)
1352 :
1353 : // [script]: the script from which the error message originated.
1354 : DECL_ACCESSORS(script, Script)
1355 :
1356 : // [stack_frames]: an array of stack frames for this error object.
1357 : DECL_ACCESSORS(stack_frames, Object)
1358 :
1359 : // [start_position]: the start position in the script for the error message.
1360 : inline int start_position() const;
1361 : inline void set_start_position(int value);
1362 :
1363 : // [end_position]: the end position in the script for the error message.
1364 : inline int end_position() const;
1365 : inline void set_end_position(int value);
1366 :
1367 : // Returns the line number for the error message (1-based), or
1368 : // Message::kNoLineNumberInfo if the line cannot be determined.
1369 : V8_EXPORT_PRIVATE int GetLineNumber() const;
1370 :
1371 : // Returns the offset of the given position within the containing line.
1372 : V8_EXPORT_PRIVATE int GetColumnNumber() const;
1373 :
1374 : // Returns the source code line containing the given source
1375 : // position, or the empty string if the position is invalid.
1376 : Handle<String> GetSourceLine() const;
1377 :
1378 : inline int error_level() const;
1379 : inline void set_error_level(int level);
1380 :
1381 : DECL_CAST(JSMessageObject)
1382 :
1383 : // Dispatched behavior.
1384 : DECL_PRINTER(JSMessageObject)
1385 : DECL_VERIFIER(JSMessageObject)
1386 :
1387 : DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
1388 : TORQUE_GENERATED_JSMESSAGE_OBJECT_FIELDS)
1389 : // TODO(v8:8989): [torque] Support marker constants.
1390 : static const int kPointerFieldsEndOffset = kStartPositionOffset;
1391 :
1392 : using BodyDescriptor = FixedBodyDescriptor<HeapObject::kMapOffset,
1393 : kPointerFieldsEndOffset, kSize>;
1394 :
1395 : OBJECT_CONSTRUCTORS(JSMessageObject, JSObject);
1396 : };
1397 :
1398 : // The [Async-from-Sync Iterator] object
1399 : // (proposal-async-iteration/#sec-async-from-sync-iterator-objects)
1400 : // An object which wraps an ordinary Iterator and converts it to behave
1401 : // according to the Async Iterator protocol.
1402 : // (See https://tc39.github.io/proposal-async-iteration/#sec-iteration)
1403 : class JSAsyncFromSyncIterator : public JSObject {
1404 : public:
1405 : DECL_CAST(JSAsyncFromSyncIterator)
1406 : DECL_PRINTER(JSAsyncFromSyncIterator)
1407 : DECL_VERIFIER(JSAsyncFromSyncIterator)
1408 :
1409 : // Async-from-Sync Iterator instances are ordinary objects that inherit
1410 : // properties from the %AsyncFromSyncIteratorPrototype% intrinsic object.
1411 : // Async-from-Sync Iterator instances are initially created with the internal
1412 : // slots listed in Table 4.
1413 : // (proposal-async-iteration/#table-async-from-sync-iterator-internal-slots)
1414 : DECL_ACCESSORS(sync_iterator, JSReceiver)
1415 :
1416 : // The "next" method is loaded during GetIterator, and is not reloaded for
1417 : // subsequent "next" invocations.
1418 : DECL_ACCESSORS(next, Object)
1419 :
1420 : DEFINE_FIELD_OFFSET_CONSTANTS(
1421 : JSObject::kHeaderSize, TORQUE_GENERATED_JSASYNC_FROM_SYNC_ITERATOR_FIELDS)
1422 :
1423 : OBJECT_CONSTRUCTORS(JSAsyncFromSyncIterator, JSObject);
1424 : };
1425 :
1426 : class JSStringIterator : public JSObject {
1427 : public:
1428 : // Dispatched behavior.
1429 : DECL_PRINTER(JSStringIterator)
1430 : DECL_VERIFIER(JSStringIterator)
1431 :
1432 : DECL_CAST(JSStringIterator)
1433 :
1434 : // [string]: the [[IteratedString]] inobject property.
1435 : DECL_ACCESSORS(string, String)
1436 :
1437 : // [index]: The [[StringIteratorNextIndex]] inobject property.
1438 : inline int index() const;
1439 : inline void set_index(int value);
1440 :
1441 : DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
1442 : TORQUE_GENERATED_JSSTRING_ITERATOR_FIELDS)
1443 :
1444 : OBJECT_CONSTRUCTORS(JSStringIterator, JSObject);
1445 : };
1446 :
1447 : } // namespace internal
1448 : } // namespace v8
1449 :
1450 : #include "src/objects/object-macros-undef.h"
1451 :
1452 : #endif // V8_OBJECTS_JS_OBJECTS_H_
|