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<Object> GetPrototype(Isolate* isolate,
88 : 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_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_WARN_UNUSED_RESULT static Maybe<bool> DeletePropertyOrElement(
124 : Handle<JSReceiver> object, Handle<Name> name,
125 : LanguageMode language_mode = LanguageMode::kSloppy);
126 : 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 : typedef PropertyAttributes IntegrityLevel;
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 : 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 : 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 : 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 : Smi GetOrCreateIdentityHash(Isolate* isolate);
245 :
246 : // Stores the hash code. The hash passed in must be masked with
247 : // JSReceiver::kHashMask.
248 : 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 : 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
307 : // be quickly accessed. This fact is used in the generated code. The
308 : // elements array can have one of three maps in this mode:
309 : // fixed_array_map, sloppy_arguments_elements_map or
310 : // fixed_cow_array_map (for copy-on-write arrays). In the latter case
311 : // the elements array may be shared by a few objects and so before
312 : // writing to any element the array must be copied. Use
313 : // EnsureWritableFastElements in this case.
314 : //
315 : // In the slow mode the elements is either a NumberDictionary, a
316 : // FixedArray parameter map for a (sloppy) arguments object.
317 : DECL_ACCESSORS(elements, FixedArrayBase)
318 : inline void initialize_elements();
319 : static inline void SetMapAndElements(Handle<JSObject> object, Handle<Map> map,
320 : Handle<FixedArrayBase> elements);
321 : inline ElementsKind GetElementsKind() const;
322 : ElementsAccessor* GetElementsAccessor();
323 : // Returns true if an object has elements of PACKED_SMI_ELEMENTS or
324 : // HOLEY_SMI_ELEMENTS ElementsKind.
325 : inline bool HasSmiElements();
326 : // Returns true if an object has elements of PACKED_ELEMENTS or
327 : // HOLEY_ELEMENTS ElementsKind.
328 : inline bool HasObjectElements();
329 : // Returns true if an object has elements of PACKED_SMI_ELEMENTS,
330 : // HOLEY_SMI_ELEMENTS, PACKED_ELEMENTS, or HOLEY_ELEMENTS.
331 : inline bool HasSmiOrObjectElements();
332 : // Returns true if an object has any of the "fast" elements kinds.
333 : inline bool HasFastElements();
334 : // Returns true if an object has any of the PACKED elements kinds.
335 : inline bool HasFastPackedElements();
336 : // Returns true if an object has elements of PACKED_DOUBLE_ELEMENTS or
337 : // HOLEY_DOUBLE_ELEMENTS ElementsKind.
338 : inline bool HasDoubleElements();
339 : // Returns true if an object has elements of HOLEY_SMI_ELEMENTS,
340 : // HOLEY_DOUBLE_ELEMENTS, or HOLEY_ELEMENTS ElementsKind.
341 : inline bool HasHoleyElements();
342 : inline bool HasSloppyArgumentsElements();
343 : inline bool HasStringWrapperElements();
344 : inline bool HasDictionaryElements();
345 : // Returns true if an object has elements of PACKED_ELEMENTS
346 : inline bool HasPackedElements();
347 :
348 : inline bool HasFixedTypedArrayElements();
349 :
350 : inline bool HasFixedUint8ClampedElements();
351 : inline bool HasFixedArrayElements();
352 : inline bool HasFixedInt8Elements();
353 : inline bool HasFixedUint8Elements();
354 : inline bool HasFixedInt16Elements();
355 : inline bool HasFixedUint16Elements();
356 : inline bool HasFixedInt32Elements();
357 : inline bool HasFixedUint32Elements();
358 : inline bool HasFixedFloat32Elements();
359 : inline bool HasFixedFloat64Elements();
360 : inline bool HasFixedBigInt64Elements();
361 : inline bool HasFixedBigUint64Elements();
362 :
363 : inline bool HasFastArgumentsElements();
364 : inline bool HasSlowArgumentsElements();
365 : inline bool HasFastStringWrapperElements();
366 : inline bool HasSlowStringWrapperElements();
367 : bool HasEnumerableElements();
368 :
369 : inline NumberDictionary element_dictionary(); // Gets slow elements.
370 :
371 : // Requires: HasFastElements().
372 : static void EnsureWritableFastElements(Handle<JSObject> object);
373 :
374 : V8_WARN_UNUSED_RESULT static Maybe<bool> SetPropertyWithInterceptor(
375 : LookupIterator* it, Maybe<ShouldThrow> should_throw,
376 : Handle<Object> value);
377 :
378 : // The API currently still wants DefineOwnPropertyIgnoreAttributes to convert
379 : // AccessorInfo objects to data fields. We allow FORCE_FIELD as an exception
380 : // to the default behavior that calls the setter.
381 : enum AccessorInfoHandling { FORCE_FIELD, DONT_FORCE_FIELD };
382 :
383 : V8_WARN_UNUSED_RESULT static MaybeHandle<Object>
384 : DefineOwnPropertyIgnoreAttributes(
385 : LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
386 : AccessorInfoHandling handling = DONT_FORCE_FIELD);
387 :
388 : V8_WARN_UNUSED_RESULT static Maybe<bool> DefineOwnPropertyIgnoreAttributes(
389 : LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
390 : Maybe<ShouldThrow> should_throw,
391 : AccessorInfoHandling handling = DONT_FORCE_FIELD);
392 :
393 : V8_WARN_UNUSED_RESULT static MaybeHandle<Object>
394 : SetOwnPropertyIgnoreAttributes(Handle<JSObject> object, Handle<Name> name,
395 : Handle<Object> value,
396 : PropertyAttributes attributes);
397 :
398 : V8_WARN_UNUSED_RESULT static MaybeHandle<Object>
399 : SetOwnElementIgnoreAttributes(Handle<JSObject> object, uint32_t index,
400 : Handle<Object> value,
401 : PropertyAttributes attributes);
402 :
403 : // Equivalent to one of the above depending on whether |name| can be converted
404 : // to an array index.
405 : V8_WARN_UNUSED_RESULT static MaybeHandle<Object>
406 : DefinePropertyOrElementIgnoreAttributes(Handle<JSObject> object,
407 : Handle<Name> name,
408 : Handle<Object> value,
409 : PropertyAttributes attributes = NONE);
410 :
411 : // Adds or reconfigures a property to attributes NONE. It will fail when it
412 : // cannot.
413 : V8_WARN_UNUSED_RESULT static Maybe<bool> CreateDataProperty(
414 : LookupIterator* it, Handle<Object> value,
415 : Maybe<ShouldThrow> should_throw = Just(kDontThrow));
416 :
417 : static void AddProperty(Isolate* isolate, Handle<JSObject> object,
418 : Handle<Name> name, Handle<Object> value,
419 : PropertyAttributes attributes);
420 :
421 : // {name} must be a UTF-8 encoded, null-terminated string.
422 : static void AddProperty(Isolate* isolate, Handle<JSObject> object,
423 : const char* name, Handle<Object> value,
424 : PropertyAttributes attributes);
425 :
426 : static void AddDataElement(Handle<JSObject> receiver, uint32_t index,
427 : Handle<Object> value,
428 : PropertyAttributes attributes);
429 :
430 : // Extend the receiver with a single fast property appeared first in the
431 : // passed map. This also extends the property backing store if necessary.
432 : static void AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map);
433 :
434 : // Migrates the given object to a map whose field representations are the
435 : // lowest upper bound of all known representations for that field.
436 : static void MigrateInstance(Handle<JSObject> instance);
437 :
438 : // Migrates the given object only if the target map is already available,
439 : // or returns false if such a map is not yet available.
440 : static bool TryMigrateInstance(Handle<JSObject> instance);
441 :
442 : // Sets the property value in a normalized object given (key, value, details).
443 : // Handles the special representation of JS global objects.
444 : static void SetNormalizedProperty(Handle<JSObject> object, Handle<Name> name,
445 : Handle<Object> value,
446 : PropertyDetails details);
447 : static void SetDictionaryElement(Handle<JSObject> object, uint32_t index,
448 : Handle<Object> value,
449 : PropertyAttributes attributes);
450 : static void SetDictionaryArgumentsElement(Handle<JSObject> object,
451 : uint32_t index,
452 : Handle<Object> value,
453 : PropertyAttributes attributes);
454 :
455 : static void OptimizeAsPrototype(Handle<JSObject> object,
456 : bool enable_setup_mode = true);
457 : static void ReoptimizeIfPrototype(Handle<JSObject> object);
458 : static void MakePrototypesFast(Handle<Object> receiver,
459 : WhereToStart where_to_start, Isolate* isolate);
460 : static void LazyRegisterPrototypeUser(Handle<Map> user, Isolate* isolate);
461 : static void UpdatePrototypeUserRegistration(Handle<Map> old_map,
462 : Handle<Map> new_map,
463 : Isolate* isolate);
464 : static bool UnregisterPrototypeUser(Handle<Map> user, Isolate* isolate);
465 : static Map InvalidatePrototypeChains(Map map);
466 : static void InvalidatePrototypeValidityCell(JSGlobalObject global);
467 :
468 : // Updates prototype chain tracking information when an object changes its
469 : // map from |old_map| to |new_map|.
470 : static void NotifyMapChange(Handle<Map> old_map, Handle<Map> new_map,
471 : Isolate* isolate);
472 :
473 : // Utility used by many Array builtins and runtime functions
474 : static inline bool PrototypeHasNoElements(Isolate* isolate, JSObject object);
475 :
476 : // To be passed to PrototypeUsers::Compact.
477 : static void PrototypeRegistryCompactionCallback(HeapObject value,
478 : int old_index, int new_index);
479 :
480 : // Retrieve interceptors.
481 : inline InterceptorInfo GetNamedInterceptor();
482 : inline InterceptorInfo GetIndexedInterceptor();
483 :
484 : // Used from JSReceiver.
485 : V8_WARN_UNUSED_RESULT static Maybe<PropertyAttributes>
486 : GetPropertyAttributesWithInterceptor(LookupIterator* it);
487 : V8_WARN_UNUSED_RESULT static Maybe<PropertyAttributes>
488 : GetPropertyAttributesWithFailedAccessCheck(LookupIterator* it);
489 :
490 : // Defines an AccessorPair property on the given object.
491 : // TODO(mstarzinger): Rename to SetAccessor().
492 : static MaybeHandle<Object> DefineAccessor(Handle<JSObject> object,
493 : Handle<Name> name,
494 : Handle<Object> getter,
495 : Handle<Object> setter,
496 : PropertyAttributes attributes);
497 : static MaybeHandle<Object> DefineAccessor(LookupIterator* it,
498 : Handle<Object> getter,
499 : Handle<Object> setter,
500 : PropertyAttributes attributes);
501 :
502 : // Defines an AccessorInfo property on the given object.
503 : V8_WARN_UNUSED_RESULT static MaybeHandle<Object> SetAccessor(
504 : Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> info,
505 : PropertyAttributes attributes);
506 :
507 : // The result must be checked first for exceptions. If there's no exception,
508 : // the output parameter |done| indicates whether the interceptor has a result
509 : // or not.
510 : V8_WARN_UNUSED_RESULT static MaybeHandle<Object> GetPropertyWithInterceptor(
511 : LookupIterator* it, bool* done);
512 :
513 : static void ValidateElements(JSObject object);
514 :
515 : // Makes sure that this object can contain HeapObject as elements.
516 : static inline void EnsureCanContainHeapObjectElements(Handle<JSObject> obj);
517 :
518 : // Makes sure that this object can contain the specified elements.
519 : // TSlot here is either ObjectSlot or FullObjectSlot.
520 : template <typename TSlot>
521 : static inline void EnsureCanContainElements(Handle<JSObject> object,
522 : TSlot elements, uint32_t count,
523 : EnsureElementsMode mode);
524 : static inline void EnsureCanContainElements(Handle<JSObject> object,
525 : Handle<FixedArrayBase> elements,
526 : uint32_t length,
527 : EnsureElementsMode mode);
528 : static void EnsureCanContainElements(Handle<JSObject> object,
529 : Arguments* arguments, uint32_t first_arg,
530 : uint32_t arg_count,
531 : EnsureElementsMode mode);
532 :
533 : // Would we convert a fast elements array to dictionary mode given
534 : // an access at key?
535 : bool WouldConvertToSlowElements(uint32_t index);
536 :
537 : static const uint32_t kMinAddedElementsCapacity = 16;
538 :
539 : // Computes the new capacity when expanding the elements of a JSObject.
540 : static uint32_t NewElementsCapacity(uint32_t old_capacity) {
541 : // (old_capacity + 50%) + kMinAddedElementsCapacity
542 1291025 : return old_capacity + (old_capacity >> 1) + kMinAddedElementsCapacity;
543 : }
544 :
545 : // These methods do not perform access checks!
546 : template <AllocationSiteUpdateMode update_or_check =
547 : AllocationSiteUpdateMode::kUpdate>
548 : static bool UpdateAllocationSite(Handle<JSObject> object,
549 : ElementsKind to_kind);
550 :
551 : // Lookup interceptors are used for handling properties controlled by host
552 : // objects.
553 : inline bool HasNamedInterceptor();
554 : inline bool HasIndexedInterceptor();
555 :
556 : // Support functions for v8 api (needed for correct interceptor behavior).
557 : V8_WARN_UNUSED_RESULT static Maybe<bool> HasRealNamedProperty(
558 : Handle<JSObject> object, Handle<Name> name);
559 : V8_WARN_UNUSED_RESULT static Maybe<bool> HasRealElementProperty(
560 : Handle<JSObject> object, uint32_t index);
561 : V8_WARN_UNUSED_RESULT static Maybe<bool> HasRealNamedCallbackProperty(
562 : Handle<JSObject> object, Handle<Name> name);
563 :
564 : // Get the header size for a JSObject. Used to compute the index of
565 : // embedder fields as well as the number of embedder fields.
566 : // The |function_has_prototype_slot| parameter is needed only for
567 : // JSFunction objects.
568 : static int GetHeaderSize(InstanceType instance_type,
569 : bool function_has_prototype_slot = false);
570 : static inline int GetHeaderSize(const Map map);
571 : inline int GetHeaderSize() const;
572 :
573 : static inline int GetEmbedderFieldsStartOffset(const Map map);
574 : inline int GetEmbedderFieldsStartOffset();
575 :
576 : static inline int GetEmbedderFieldCount(const Map map);
577 : inline int GetEmbedderFieldCount() const;
578 : inline int GetEmbedderFieldOffset(int index);
579 : inline Object GetEmbedderField(int index);
580 : inline void SetEmbedderField(int index, Object value);
581 : inline void SetEmbedderField(int index, Smi value);
582 :
583 : // Returns true when the object is potentially a wrapper that gets special
584 : // garbage collection treatment.
585 : // TODO(mlippautz): Make check exact and replace the pattern match in
586 : // Heap::TracePossibleWrapper.
587 : bool IsApiWrapper();
588 :
589 : // Same as IsApiWrapper() but also allow dropping the wrapper on minor GCs.
590 : bool IsDroppableApiWrapper();
591 :
592 : // Returns a new map with all transitions dropped from the object's current
593 : // map and the ElementsKind set.
594 : static Handle<Map> GetElementsTransitionMap(Handle<JSObject> object,
595 : ElementsKind to_kind);
596 : static void TransitionElementsKind(Handle<JSObject> object,
597 : ElementsKind to_kind);
598 :
599 : // Always use this to migrate an object to a new map.
600 : // |expected_additional_properties| is only used for fast-to-slow transitions
601 : // and ignored otherwise.
602 : static void MigrateToMap(Handle<JSObject> object, Handle<Map> new_map,
603 : int expected_additional_properties = 0);
604 :
605 : // Forces a prototype without any of the checks that the regular SetPrototype
606 : // would do.
607 : static void ForceSetPrototype(Handle<JSObject> object, Handle<Object> proto);
608 :
609 : // Convert the object to use the canonical dictionary
610 : // representation. If the object is expected to have additional properties
611 : // added this number can be indicated to have the backing store allocated to
612 : // an initial capacity for holding these properties.
613 : static void NormalizeProperties(Handle<JSObject> object,
614 : PropertyNormalizationMode mode,
615 : int expected_additional_properties,
616 : const char* reason);
617 :
618 : // Convert and update the elements backing store to be a
619 : // NumberDictionary dictionary. Returns the backing after conversion.
620 : static Handle<NumberDictionary> NormalizeElements(Handle<JSObject> object);
621 :
622 : void RequireSlowElements(NumberDictionary dictionary);
623 :
624 : // Transform slow named properties to fast variants.
625 : static void MigrateSlowToFast(Handle<JSObject> object,
626 : int unused_property_fields, const char* reason);
627 :
628 : inline bool IsUnboxedDoubleField(FieldIndex index);
629 :
630 : // Access fast-case object properties at index.
631 : static Handle<Object> FastPropertyAt(Handle<JSObject> object,
632 : Representation representation,
633 : FieldIndex index);
634 : inline Object RawFastPropertyAt(FieldIndex index);
635 : inline double RawFastDoublePropertyAt(FieldIndex index);
636 : inline uint64_t RawFastDoublePropertyAsBitsAt(FieldIndex index);
637 :
638 : inline void FastPropertyAtPut(FieldIndex index, Object value);
639 : inline void RawFastPropertyAtPut(FieldIndex index, Object value);
640 : inline void RawFastDoublePropertyAsBitsAtPut(FieldIndex index, uint64_t bits);
641 : inline void WriteToField(int descriptor, PropertyDetails details,
642 : Object value);
643 :
644 : // Access to in object properties.
645 : inline int GetInObjectPropertyOffset(int index);
646 : inline Object InObjectPropertyAt(int index);
647 : inline Object InObjectPropertyAtPut(
648 : int index, Object value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
649 :
650 : // Set the object's prototype (only JSReceiver and null are allowed values).
651 : V8_WARN_UNUSED_RESULT static Maybe<bool> SetPrototype(
652 : Handle<JSObject> object, Handle<Object> value, bool from_javascript,
653 : ShouldThrow should_throw);
654 :
655 : // Makes the object prototype immutable
656 : // Never called from JavaScript
657 : static void SetImmutableProto(Handle<JSObject> object);
658 :
659 : // Initializes the body starting at |start_offset|. It is responsibility of
660 : // the caller to initialize object header. Fill the pre-allocated fields with
661 : // pre_allocated_value and the rest with filler_value.
662 : // Note: this call does not update write barrier, the caller is responsible
663 : // to ensure that |filler_value| can be collected without WB here.
664 : inline void InitializeBody(Map map, int start_offset,
665 : Object pre_allocated_value, Object filler_value);
666 :
667 : // Check whether this object references another object
668 : bool ReferencesObject(Object obj);
669 :
670 : V8_WARN_UNUSED_RESULT static Maybe<bool> TestIntegrityLevel(
671 : Handle<JSObject> object, IntegrityLevel lvl);
672 :
673 : V8_WARN_UNUSED_RESULT static Maybe<bool> PreventExtensions(
674 : Handle<JSObject> object, ShouldThrow should_throw);
675 :
676 : static bool IsExtensible(Handle<JSObject> object);
677 :
678 : DECL_CAST(JSObject)
679 :
680 : // Dispatched behavior.
681 : void JSObjectShortPrint(StringStream* accumulator);
682 : DECL_PRINTER(JSObject)
683 : DECL_VERIFIER(JSObject)
684 : #ifdef OBJECT_PRINT
685 : bool PrintProperties(std::ostream& os); // NOLINT
686 : void PrintElements(std::ostream& os); // NOLINT
687 : #endif
688 : #if defined(DEBUG) || defined(OBJECT_PRINT)
689 : void PrintTransitions(std::ostream& os); // NOLINT
690 : #endif
691 :
692 : static void PrintElementsTransition(FILE* file, Handle<JSObject> object,
693 : ElementsKind from_kind,
694 : Handle<FixedArrayBase> from_elements,
695 : ElementsKind to_kind,
696 : Handle<FixedArrayBase> to_elements);
697 :
698 : void PrintInstanceMigration(FILE* file, Map original_map, Map new_map);
699 :
700 : #ifdef DEBUG
701 : // Structure for collecting spill information about JSObjects.
702 : class SpillInformation {
703 : public:
704 : void Clear();
705 : void Print();
706 : int number_of_objects_;
707 : int number_of_objects_with_fast_properties_;
708 : int number_of_objects_with_fast_elements_;
709 : int number_of_fast_used_fields_;
710 : int number_of_fast_unused_fields_;
711 : int number_of_slow_used_properties_;
712 : int number_of_slow_unused_properties_;
713 : int number_of_fast_used_elements_;
714 : int number_of_fast_unused_elements_;
715 : int number_of_slow_used_elements_;
716 : int number_of_slow_unused_elements_;
717 : };
718 :
719 : void IncrementSpillStatistics(Isolate* isolate, SpillInformation* info);
720 : #endif
721 :
722 : #ifdef VERIFY_HEAP
723 : // If a GC was caused while constructing this object, the elements pointer
724 : // may point to a one pointer filler map. The object won't be rooted, but
725 : // our heap verification code could stumble across it.
726 : bool ElementsAreSafeToExamine() const;
727 : #endif
728 :
729 : Object SlowReverseLookup(Object value);
730 :
731 : // Maximal number of elements (numbered 0 .. kMaxElementCount - 1).
732 : // Also maximal value of JSArray's length property.
733 : static const uint32_t kMaxElementCount = 0xffffffffu;
734 :
735 : // Constants for heuristics controlling conversion of fast elements
736 : // to slow elements.
737 :
738 : // Maximal gap that can be introduced by adding an element beyond
739 : // the current elements length.
740 : static const uint32_t kMaxGap = 1024;
741 :
742 : // Maximal length of fast elements array that won't be checked for
743 : // being dense enough on expansion.
744 : static const int kMaxUncheckedFastElementsLength = 5000;
745 :
746 : // Same as above but for old arrays. This limit is more strict. We
747 : // don't want to be wasteful with long lived objects.
748 : static const int kMaxUncheckedOldFastElementsLength = 500;
749 :
750 : // This constant applies only to the initial map of "global.Object" and
751 : // not to arbitrary other JSObject maps.
752 : static const int kInitialGlobalObjectUnusedPropertiesCount = 4;
753 :
754 : static const int kMaxInstanceSize = 255 * kTaggedSize;
755 :
756 : // When extending the backing storage for property values, we increase
757 : // its size by more than the 1 entry necessary, so sequentially adding fields
758 : // to the same object requires fewer allocations and copies.
759 : static const int kFieldsAdded = 3;
760 : STATIC_ASSERT(kMaxNumberOfDescriptors + kFieldsAdded <=
761 : PropertyArray::kMaxLength);
762 :
763 : // Layout description.
764 : #define JS_OBJECT_FIELDS(V) \
765 : V(kElementsOffset, kTaggedSize) \
766 : /* Header size. */ \
767 : V(kHeaderSize, 0)
768 :
769 : DEFINE_FIELD_OFFSET_CONSTANTS(JSReceiver::kHeaderSize, JS_OBJECT_FIELDS)
770 : #undef JS_OBJECT_FIELDS
771 :
772 : STATIC_ASSERT(kHeaderSize == Internals::kJSObjectHeaderSize);
773 : static const int kMaxInObjectProperties =
774 : (kMaxInstanceSize - kHeaderSize) >> kTaggedSizeLog2;
775 : STATIC_ASSERT(kMaxInObjectProperties <= kMaxNumberOfDescriptors);
776 :
777 : static const int kMaxFirstInobjectPropertyOffset =
778 : (1 << kFirstInobjectPropertyOffsetBitCount) - 1;
779 : static const int kMaxEmbedderFields =
780 : (kMaxFirstInobjectPropertyOffset - kHeaderSize) / kEmbedderDataSlotSize;
781 : STATIC_ASSERT(kHeaderSize +
782 : kMaxEmbedderFields * kEmbedderDataSlotSizeInTaggedSlots <=
783 : kMaxInstanceSize);
784 :
785 : class BodyDescriptor;
786 :
787 : class FastBodyDescriptor;
788 :
789 : // Gets the number of currently used elements.
790 : int GetFastElementsUsage();
791 :
792 : static bool AllCanRead(LookupIterator* it);
793 : static bool AllCanWrite(LookupIterator* it);
794 :
795 : private:
796 : friend class JSReceiver;
797 : friend class Object;
798 :
799 : // Used from Object::GetProperty().
800 : V8_WARN_UNUSED_RESULT static MaybeHandle<Object>
801 : GetPropertyWithFailedAccessCheck(LookupIterator* it);
802 :
803 : V8_WARN_UNUSED_RESULT static Maybe<bool> SetPropertyWithFailedAccessCheck(
804 : LookupIterator* it, Handle<Object> value,
805 : Maybe<ShouldThrow> should_throw);
806 :
807 : V8_WARN_UNUSED_RESULT static Maybe<bool> DeletePropertyWithInterceptor(
808 : LookupIterator* it, ShouldThrow should_throw);
809 :
810 : bool ReferencesObjectFromElements(FixedArray elements, ElementsKind kind,
811 : Object object);
812 :
813 : // Helper for fast versions of preventExtensions, seal, and freeze.
814 : // attrs is one of NONE, SEALED, or FROZEN (depending on the operation).
815 : template <PropertyAttributes attrs>
816 : V8_WARN_UNUSED_RESULT static Maybe<bool> PreventExtensionsWithTransition(
817 : Handle<JSObject> object, ShouldThrow should_throw);
818 :
819 : OBJECT_CONSTRUCTORS(JSObject, JSReceiver);
820 : };
821 :
822 : // JSAccessorPropertyDescriptor is just a JSObject with a specific initial
823 : // map. This initial map adds in-object properties for "get", "set",
824 : // "enumerable" and "configurable" properties, as assigned by the
825 : // FromPropertyDescriptor function for regular accessor properties.
826 : class JSAccessorPropertyDescriptor : public JSObject {
827 : public:
828 : // Layout description.
829 : DEFINE_FIELD_OFFSET_CONSTANTS(
830 : JSObject::kHeaderSize,
831 : TORQUE_GENERATED_JSACCESSOR_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 : DEFINE_FIELD_OFFSET_CONSTANTS(
850 : JSObject::kHeaderSize, TORQUE_GENERATED_JSDATA_PROPERTY_DESCRIPTOR_FIELDS)
851 :
852 : // Indices of in-object properties.
853 : static const int kValueIndex = 0;
854 : static const int kWritableIndex = 1;
855 : static const int kEnumerableIndex = 2;
856 : static const int kConfigurableIndex = 3;
857 :
858 : private:
859 : DISALLOW_IMPLICIT_CONSTRUCTORS(JSDataPropertyDescriptor);
860 : };
861 :
862 : // JSIteratorResult is just a JSObject with a specific initial map.
863 : // This initial map adds in-object properties for "done" and "value",
864 : // as specified by ES6 section 25.1.1.3 The IteratorResult Interface
865 : class JSIteratorResult : public JSObject {
866 : public:
867 : DECL_ACCESSORS(value, Object)
868 :
869 : DECL_ACCESSORS(done, Object)
870 :
871 : // Layout description.
872 : #define JS_ITERATOR_RESULT_FIELDS(V) \
873 : V(kValueOffset, kTaggedSize) \
874 : V(kDoneOffset, kTaggedSize) \
875 : /* Total size. */ \
876 : V(kSize, 0)
877 :
878 : DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
879 : JS_ITERATOR_RESULT_FIELDS)
880 : #undef JS_ITERATOR_RESULT_FIELDS
881 :
882 : // Indices of in-object properties.
883 : static const int kValueIndex = 0;
884 : static const int kDoneIndex = 1;
885 :
886 : DECL_CAST(JSIteratorResult)
887 :
888 : OBJECT_CONSTRUCTORS(JSIteratorResult, JSObject);
889 : };
890 :
891 : // JSBoundFunction describes a bound function exotic object.
892 : class JSBoundFunction : public JSObject {
893 : public:
894 : // [bound_target_function]: The wrapped function object.
895 : inline Object raw_bound_target_function() const;
896 : DECL_ACCESSORS(bound_target_function, JSReceiver)
897 :
898 : // [bound_this]: The value that is always passed as the this value when
899 : // calling the wrapped function.
900 : DECL_ACCESSORS(bound_this, Object)
901 :
902 : // [bound_arguments]: A list of values whose elements are used as the first
903 : // arguments to any call to the wrapped function.
904 : DECL_ACCESSORS(bound_arguments, FixedArray)
905 :
906 : static MaybeHandle<String> GetName(Isolate* isolate,
907 : Handle<JSBoundFunction> function);
908 : static Maybe<int> GetLength(Isolate* isolate,
909 : Handle<JSBoundFunction> function);
910 : static MaybeHandle<NativeContext> GetFunctionRealm(
911 : Handle<JSBoundFunction> function);
912 :
913 : DECL_CAST(JSBoundFunction)
914 :
915 : // Dispatched behavior.
916 : DECL_PRINTER(JSBoundFunction)
917 : DECL_VERIFIER(JSBoundFunction)
918 :
919 : // The bound function's string representation implemented according
920 : // to ES6 section 19.2.3.5 Function.prototype.toString ( ).
921 : static Handle<String> ToString(Handle<JSBoundFunction> function);
922 :
923 : // Layout description.
924 : DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
925 : TORQUE_GENERATED_JSBOUND_FUNCTION_FIELDS)
926 :
927 : OBJECT_CONSTRUCTORS(JSBoundFunction, JSObject);
928 : };
929 :
930 : // JSFunction describes JavaScript functions.
931 : class JSFunction : public JSObject {
932 : public:
933 : // [prototype_or_initial_map]:
934 : DECL_ACCESSORS(prototype_or_initial_map, Object)
935 :
936 : // [shared]: The information about the function that
937 : // can be shared by instances.
938 : DECL_ACCESSORS(shared, SharedFunctionInfo)
939 :
940 : static const int kLengthDescriptorIndex = 0;
941 : static const int kNameDescriptorIndex = 1;
942 : // Home object descriptor index when function has a [[HomeObject]] slot.
943 : static const int kMaybeHomeObjectDescriptorIndex = 2;
944 :
945 : // [context]: The context for this function.
946 : inline Context context();
947 : inline bool has_context() const;
948 : inline void set_context(Object context);
949 : inline JSGlobalProxy global_proxy();
950 : inline NativeContext native_context();
951 :
952 : static Handle<Object> GetName(Isolate* isolate, Handle<JSFunction> function);
953 : static Maybe<int> GetLength(Isolate* isolate, Handle<JSFunction> function);
954 : static Handle<NativeContext> GetFunctionRealm(Handle<JSFunction> function);
955 :
956 : // [code]: The generated code object for this function. Executed
957 : // when the function is invoked, e.g. foo() or new foo(). See
958 : // [[Call]] and [[Construct]] description in ECMA-262, section
959 : // 8.6.2, page 27.
960 : inline Code code() const;
961 : inline void set_code(Code code);
962 : inline void set_code_no_write_barrier(Code code);
963 :
964 : // Get the abstract code associated with the function, which will either be
965 : // a Code object or a BytecodeArray.
966 : inline AbstractCode abstract_code();
967 :
968 : // Tells whether or not this function is interpreted.
969 : //
970 : // Note: function->IsInterpreted() does not necessarily return the same value
971 : // as function->shared()->IsInterpreted() because the closure might have been
972 : // optimized.
973 : inline bool IsInterpreted();
974 :
975 : // Tells whether or not this function checks its optimization marker in its
976 : // feedback vector.
977 : inline bool ChecksOptimizationMarker();
978 :
979 : // Tells whether or not this function holds optimized code.
980 : //
981 : // Note: Returning false does not necessarily mean that this function hasn't
982 : // been optimized, as it may have optimized code on its feedback vector.
983 : inline bool IsOptimized();
984 :
985 : // Tells whether or not this function has optimized code available to it,
986 : // either because it is optimized or because it has optimized code in its
987 : // feedback vector.
988 : inline bool HasOptimizedCode();
989 :
990 : // Tells whether or not this function has a (non-zero) optimization marker.
991 : inline bool HasOptimizationMarker();
992 :
993 : // Mark this function for lazy recompilation. The function will be recompiled
994 : // the next time it is executed.
995 : void MarkForOptimization(ConcurrencyMode mode);
996 :
997 : // Tells whether or not the function is already marked for lazy recompilation.
998 : inline bool IsMarkedForOptimization();
999 : inline bool IsMarkedForConcurrentOptimization();
1000 :
1001 : // Tells whether or not the function is on the concurrent recompilation queue.
1002 : inline bool IsInOptimizationQueue();
1003 :
1004 : // Clears the optimized code slot in the function's feedback vector.
1005 : inline void ClearOptimizedCodeSlot(const char* reason);
1006 :
1007 : // Sets the optimization marker in the function's feedback vector.
1008 : inline void SetOptimizationMarker(OptimizationMarker marker);
1009 :
1010 : // Clears the optimization marker in the function's feedback vector.
1011 : inline void ClearOptimizationMarker();
1012 :
1013 : // If slack tracking is active, it computes instance size of the initial map
1014 : // with minimum permissible object slack. If it is not active, it simply
1015 : // returns the initial map's instance size.
1016 : int ComputeInstanceSizeWithMinSlack(Isolate* isolate);
1017 :
1018 : // Completes inobject slack tracking on initial map if it is active.
1019 : inline void CompleteInobjectSlackTrackingIfActive();
1020 :
1021 : // [raw_feedback_cell]: Gives raw access to the FeedbackCell used to hold the
1022 : /// FeedbackVector eventually. Generally this shouldn't be used to get the
1023 : // feedback_vector, instead use feedback_vector() which correctly deals with
1024 : // the JSFunction's bytecode being flushed.
1025 : DECL_ACCESSORS(raw_feedback_cell, FeedbackCell)
1026 :
1027 : // Functions related to feedback vector. feedback_vector() can be used once
1028 : // the function has feedback vectors allocated. feedback vectors may not be
1029 : // available after compile when lazily allocating feedback vectors.
1030 : inline FeedbackVector feedback_vector() const;
1031 : inline bool has_feedback_vector() const;
1032 : static void EnsureFeedbackVector(Handle<JSFunction> function);
1033 :
1034 : // Functions related to clousre feedback cell array that holds feedback cells
1035 : // used to create closures from this function. We allocate closure feedback
1036 : // cell arrays after compile, when we want to allocate feedback vectors
1037 : // lazily.
1038 : inline bool has_closure_feedback_cell_array() const;
1039 : inline FixedArray closure_feedback_cell_array() const;
1040 : static void EnsureClosureFeedbackCellArray(Handle<JSFunction> function);
1041 :
1042 : // Initializes the feedback cell of |function|. In lite mode, this would be
1043 : // initialized to the closure feedback cell array that holds the feedback
1044 : // cells for create closure calls from this function. In the regular mode,
1045 : // this allocates feedback vector.
1046 : static void InitializeFeedbackCell(Handle<JSFunction> function);
1047 :
1048 : // Unconditionally clear the type feedback vector.
1049 : void ClearTypeFeedbackInfo();
1050 :
1051 : // Resets function to clear compiled data after bytecode has been flushed.
1052 : inline bool NeedsResetDueToFlushedBytecode();
1053 : inline void ResetIfBytecodeFlushed();
1054 :
1055 : inline bool has_prototype_slot() const;
1056 :
1057 : // The initial map for an object created by this constructor.
1058 : inline Map initial_map();
1059 : static void SetInitialMap(Handle<JSFunction> function, Handle<Map> map,
1060 : Handle<Object> prototype);
1061 : inline bool has_initial_map();
1062 : static void EnsureHasInitialMap(Handle<JSFunction> function);
1063 :
1064 : // Creates a map that matches the constructor's initial map, but with
1065 : // [[prototype]] being new.target.prototype. Because new.target can be a
1066 : // JSProxy, this can call back into JavaScript.
1067 : static V8_WARN_UNUSED_RESULT MaybeHandle<Map> GetDerivedMap(
1068 : Isolate* isolate, Handle<JSFunction> constructor,
1069 : Handle<JSReceiver> new_target);
1070 :
1071 : // Get and set the prototype property on a JSFunction. If the
1072 : // function has an initial map the prototype is set on the initial
1073 : // map. Otherwise, the prototype is put in the initial map field
1074 : // until an initial map is needed.
1075 : inline bool has_prototype();
1076 : inline bool has_instance_prototype();
1077 : inline Object prototype();
1078 : inline Object instance_prototype();
1079 : inline bool has_prototype_property();
1080 : inline bool PrototypeRequiresRuntimeLookup();
1081 : static void SetPrototype(Handle<JSFunction> function, Handle<Object> value);
1082 :
1083 : // Returns if this function has been compiled to native code yet.
1084 : inline bool is_compiled() const;
1085 :
1086 : static int GetHeaderSize(bool function_has_prototype_slot) {
1087 : return function_has_prototype_slot ? JSFunction::kSizeWithPrototype
1088 67952335 : : JSFunction::kSizeWithoutPrototype;
1089 : }
1090 :
1091 : // Prints the name of the function using PrintF.
1092 : void PrintName(FILE* out = stdout);
1093 :
1094 : DECL_CAST(JSFunction)
1095 :
1096 : // Calculate the instance size and in-object properties count.
1097 : static V8_WARN_UNUSED_RESULT int CalculateExpectedNofProperties(
1098 : Isolate* isolate, Handle<JSFunction> function);
1099 : static void CalculateInstanceSizeHelper(InstanceType instance_type,
1100 : bool has_prototype_slot,
1101 : int requested_embedder_fields,
1102 : int requested_in_object_properties,
1103 : int* instance_size,
1104 : int* in_object_properties);
1105 :
1106 : // Dispatched behavior.
1107 : DECL_PRINTER(JSFunction)
1108 : DECL_VERIFIER(JSFunction)
1109 :
1110 : // The function's name if it is configured, otherwise shared function info
1111 : // debug name.
1112 : static Handle<String> GetName(Handle<JSFunction> function);
1113 :
1114 : // ES6 section 9.2.11 SetFunctionName
1115 : // Because of the way this abstract operation is used in the spec,
1116 : // it should never fail, but in practice it will fail if the generated
1117 : // function name's length exceeds String::kMaxLength.
1118 : static V8_WARN_UNUSED_RESULT bool SetName(Handle<JSFunction> function,
1119 : Handle<Name> name,
1120 : Handle<String> prefix);
1121 :
1122 : // The function's displayName if it is set, otherwise name if it is
1123 : // configured, otherwise shared function info
1124 : // debug name.
1125 : static Handle<String> GetDebugName(Handle<JSFunction> function);
1126 :
1127 : // The function's string representation implemented according to
1128 : // ES6 section 19.2.3.5 Function.prototype.toString ( ).
1129 : static Handle<String> ToString(Handle<JSFunction> function);
1130 :
1131 : DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
1132 : TORQUE_GENERATED_JSFUNCTION_FIELDS)
1133 :
1134 : static constexpr int kSizeWithoutPrototype = kPrototypeOrInitialMapOffset;
1135 : static constexpr int kSizeWithPrototype = kSize;
1136 :
1137 : OBJECT_CONSTRUCTORS(JSFunction, JSObject);
1138 : };
1139 :
1140 : // JSGlobalProxy's prototype must be a JSGlobalObject or null,
1141 : // and the prototype is hidden. JSGlobalProxy always delegates
1142 : // property accesses to its prototype if the prototype is not null.
1143 : //
1144 : // A JSGlobalProxy can be reinitialized which will preserve its identity.
1145 : //
1146 : // Accessing a JSGlobalProxy requires security check.
1147 :
1148 : class JSGlobalProxy : public JSObject {
1149 : public:
1150 : // [native_context]: the owner native context of this global proxy object.
1151 : // It is null value if this object is not used by any context.
1152 : DECL_ACCESSORS(native_context, Object)
1153 :
1154 : DECL_CAST(JSGlobalProxy)
1155 :
1156 : inline bool IsDetachedFrom(JSGlobalObject global) const;
1157 :
1158 : static int SizeWithEmbedderFields(int embedder_field_count);
1159 :
1160 : // Dispatched behavior.
1161 : DECL_PRINTER(JSGlobalProxy)
1162 : DECL_VERIFIER(JSGlobalProxy)
1163 :
1164 : // Layout description.
1165 : DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
1166 : TORQUE_GENERATED_JSGLOBAL_PROXY_FIELDS)
1167 :
1168 : 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, NativeContext)
1176 :
1177 : // [global proxy]: the global proxy object of the context
1178 : DECL_ACCESSORS(global_proxy, JSGlobalProxy)
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 : 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_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
1227 : TORQUE_GENERATED_JSVALUE_FIELDS)
1228 :
1229 : OBJECT_CONSTRUCTORS(JSValue, JSObject);
1230 : };
1231 :
1232 : class DateCache;
1233 :
1234 : // Representation for JS date objects.
1235 : class JSDate : public JSObject {
1236 : public:
1237 : static V8_WARN_UNUSED_RESULT MaybeHandle<JSDate> New(
1238 : Handle<JSFunction> constructor, Handle<JSReceiver> new_target, double tv);
1239 :
1240 : // If one component is NaN, all of them are, indicating a NaN time value.
1241 : // [value]: the time value.
1242 : DECL_ACCESSORS(value, Object)
1243 : // [year]: caches year. Either undefined, smi, or NaN.
1244 : DECL_ACCESSORS(year, Object)
1245 : // [month]: caches month. Either undefined, smi, or NaN.
1246 : DECL_ACCESSORS(month, Object)
1247 : // [day]: caches day. Either undefined, smi, or NaN.
1248 : DECL_ACCESSORS(day, Object)
1249 : // [weekday]: caches day of week. Either undefined, smi, or NaN.
1250 : DECL_ACCESSORS(weekday, Object)
1251 : // [hour]: caches hours. Either undefined, smi, or NaN.
1252 : DECL_ACCESSORS(hour, Object)
1253 : // [min]: caches minutes. Either undefined, smi, or NaN.
1254 : DECL_ACCESSORS(min, Object)
1255 : // [sec]: caches seconds. Either undefined, smi, or NaN.
1256 : DECL_ACCESSORS(sec, Object)
1257 : // [cache stamp]: sample of the date cache stamp at the
1258 : // moment when chached fields were cached.
1259 : DECL_ACCESSORS(cache_stamp, Object)
1260 :
1261 : DECL_CAST(JSDate)
1262 :
1263 : // Returns the time value (UTC) identifying the current time.
1264 : static double CurrentTimeValue(Isolate* isolate);
1265 :
1266 : // Returns the date field with the specified index.
1267 : // See FieldIndex for the list of date fields.
1268 : // Arguments and result are raw Address values because this is called
1269 : // via ExternalReference.
1270 : // {raw_date} is a tagged Object pointer.
1271 : // {smi_index} is a tagged Smi.
1272 : // The return value is a tagged Object pointer.
1273 : static Address GetField(Address raw_date, Address smi_index);
1274 :
1275 : static Handle<Object> SetValue(Handle<JSDate> date, double v);
1276 :
1277 : void SetValue(Object value, bool is_value_nan);
1278 :
1279 : // Dispatched behavior.
1280 : DECL_PRINTER(JSDate)
1281 : DECL_VERIFIER(JSDate)
1282 :
1283 : // The order is important. It must be kept in sync with date macros
1284 : // in macros.py.
1285 : enum FieldIndex {
1286 : kDateValue,
1287 : kYear,
1288 : kMonth,
1289 : kDay,
1290 : kWeekday,
1291 : kHour,
1292 : kMinute,
1293 : kSecond,
1294 : kFirstUncachedField,
1295 : kMillisecond = kFirstUncachedField,
1296 : kDays,
1297 : kTimeInDay,
1298 : kFirstUTCField,
1299 : kYearUTC = kFirstUTCField,
1300 : kMonthUTC,
1301 : kDayUTC,
1302 : kWeekdayUTC,
1303 : kHourUTC,
1304 : kMinuteUTC,
1305 : kSecondUTC,
1306 : kMillisecondUTC,
1307 : kDaysUTC,
1308 : kTimeInDayUTC,
1309 : kTimezoneOffset
1310 : };
1311 :
1312 : DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
1313 : TORQUE_GENERATED_JSDATE_FIELDS)
1314 :
1315 : private:
1316 : inline Object DoGetField(FieldIndex index);
1317 :
1318 : Object GetUTCField(FieldIndex index, double value, DateCache* date_cache);
1319 :
1320 : // Computes and caches the cacheable fields of the date.
1321 : inline void SetCachedFields(int64_t local_time_ms, DateCache* date_cache);
1322 :
1323 : OBJECT_CONSTRUCTORS(JSDate, JSObject);
1324 : };
1325 :
1326 : // Representation of message objects used for error reporting through
1327 : // the API. The messages are formatted in JavaScript so this object is
1328 : // a real JavaScript object. The information used for formatting the
1329 : // error messages are not directly accessible from JavaScript to
1330 : // prevent leaking information to user code called during error
1331 : // formatting.
1332 : class JSMessageObject : public JSObject {
1333 : public:
1334 : // [type]: the type of error message.
1335 : inline MessageTemplate type() const;
1336 : inline void set_type(MessageTemplate value);
1337 :
1338 : // [arguments]: the arguments for formatting the error message.
1339 : DECL_ACCESSORS(argument, Object)
1340 :
1341 : // [script]: the script from which the error message originated.
1342 : DECL_ACCESSORS(script, Script)
1343 :
1344 : // [stack_frames]: an array of stack frames for this error object.
1345 : DECL_ACCESSORS(stack_frames, Object)
1346 :
1347 : // [start_position]: the start position in the script for the error message.
1348 : inline int start_position() const;
1349 : inline void set_start_position(int value);
1350 :
1351 : // [end_position]: the end position in the script for the error message.
1352 : inline int end_position() const;
1353 : inline void set_end_position(int value);
1354 :
1355 : // Returns the line number for the error message (1-based), or
1356 : // Message::kNoLineNumberInfo if the line cannot be determined.
1357 : int GetLineNumber() const;
1358 :
1359 : // Returns the offset of the given position within the containing line.
1360 : int GetColumnNumber() const;
1361 :
1362 : // Returns the source code line containing the given source
1363 : // position, or the empty string if the position is invalid.
1364 : Handle<String> GetSourceLine() const;
1365 :
1366 : inline int error_level() const;
1367 : inline void set_error_level(int level);
1368 :
1369 : DECL_CAST(JSMessageObject)
1370 :
1371 : // Dispatched behavior.
1372 : DECL_PRINTER(JSMessageObject)
1373 : DECL_VERIFIER(JSMessageObject)
1374 :
1375 : // Layout description.
1376 : #define JS_MESSAGE_FIELDS(V) \
1377 : /* Tagged fields. */ \
1378 : V(kTypeOffset, kTaggedSize) \
1379 : V(kArgumentsOffset, kTaggedSize) \
1380 : V(kScriptOffset, kTaggedSize) \
1381 : V(kStackFramesOffset, kTaggedSize) \
1382 : V(kPointerFieldsEndOffset, 0) \
1383 : /* Raw data fields. */ \
1384 : /* TODO(ishell): store as int32 instead of Smi. */ \
1385 : V(kStartPositionOffset, kTaggedSize) \
1386 : V(kEndPositionOffset, kTaggedSize) \
1387 : V(kErrorLevelOffset, kTaggedSize) \
1388 : /* Total size. */ \
1389 : V(kSize, 0)
1390 :
1391 : DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, JS_MESSAGE_FIELDS)
1392 : #undef JS_MESSAGE_FIELDS
1393 :
1394 : typedef FixedBodyDescriptor<HeapObject::kMapOffset, kPointerFieldsEndOffset,
1395 : kSize>
1396 : BodyDescriptor;
1397 :
1398 : OBJECT_CONSTRUCTORS(JSMessageObject, JSObject);
1399 : };
1400 :
1401 : // The [Async-from-Sync Iterator] object
1402 : // (proposal-async-iteration/#sec-async-from-sync-iterator-objects)
1403 : // An object which wraps an ordinary Iterator and converts it to behave
1404 : // according to the Async Iterator protocol.
1405 : // (See https://tc39.github.io/proposal-async-iteration/#sec-iteration)
1406 : class JSAsyncFromSyncIterator : public JSObject {
1407 : public:
1408 : DECL_CAST(JSAsyncFromSyncIterator)
1409 : DECL_PRINTER(JSAsyncFromSyncIterator)
1410 : DECL_VERIFIER(JSAsyncFromSyncIterator)
1411 :
1412 : // Async-from-Sync Iterator instances are ordinary objects that inherit
1413 : // properties from the %AsyncFromSyncIteratorPrototype% intrinsic object.
1414 : // Async-from-Sync Iterator instances are initially created with the internal
1415 : // slots listed in Table 4.
1416 : // (proposal-async-iteration/#table-async-from-sync-iterator-internal-slots)
1417 : DECL_ACCESSORS(sync_iterator, JSReceiver)
1418 :
1419 : // The "next" method is loaded during GetIterator, and is not reloaded for
1420 : // subsequent "next" invocations.
1421 : DECL_ACCESSORS(next, Object)
1422 :
1423 : DEFINE_FIELD_OFFSET_CONSTANTS(
1424 : JSObject::kHeaderSize, TORQUE_GENERATED_JSASYNC_FROM_SYNC_ITERATOR_FIELDS)
1425 :
1426 : OBJECT_CONSTRUCTORS(JSAsyncFromSyncIterator, JSObject);
1427 : };
1428 :
1429 : class JSStringIterator : public JSObject {
1430 : public:
1431 : // Dispatched behavior.
1432 : DECL_PRINTER(JSStringIterator)
1433 : DECL_VERIFIER(JSStringIterator)
1434 :
1435 : DECL_CAST(JSStringIterator)
1436 :
1437 : // [string]: the [[IteratedString]] inobject property.
1438 : DECL_ACCESSORS(string, String)
1439 :
1440 : // [index]: The [[StringIteratorNextIndex]] inobject property.
1441 : inline int index() const;
1442 : inline void set_index(int value);
1443 :
1444 : DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
1445 : TORQUE_GENERATED_JSSTRING_ITERATOR_FIELDS)
1446 :
1447 : OBJECT_CONSTRUCTORS(JSStringIterator, JSObject);
1448 : };
1449 :
1450 : } // namespace internal
1451 : } // namespace v8
1452 :
1453 : #include "src/objects/object-macros-undef.h"
1454 :
1455 : #endif // V8_OBJECTS_JS_OBJECTS_H_
|