• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 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_OBJECTS_H_
6 #define V8_OBJECTS_OBJECTS_H_
7 
8 #include <iosfwd>
9 #include <memory>
10 
11 #include "include/v8-internal.h"
12 #include "include/v8.h"
13 #include "include/v8config.h"
14 #include "src/base/bits.h"
15 #include "src/base/build_config.h"
16 #include "src/base/flags.h"
17 #include "src/base/logging.h"
18 #include "src/base/memory.h"
19 #include "src/codegen/constants-arch.h"
20 #include "src/common/assert-scope.h"
21 #include "src/common/checks.h"
22 #include "src/common/message-template.h"
23 #include "src/flags/flags.h"
24 #include "src/objects/elements-kind.h"
25 #include "src/objects/field-index.h"
26 #include "src/objects/object-list-macros.h"
27 #include "src/objects/objects-definitions.h"
28 #include "src/objects/property-details.h"
29 #include "src/objects/tagged-impl.h"
30 #include "src/utils/utils.h"
31 
32 // Has to be the last include (doesn't have include guards):
33 #include "src/objects/object-macros.h"
34 
35 //
36 // Most object types in the V8 JavaScript are described in this file.
37 //
38 // Inheritance hierarchy:
39 // - Object
40 //   - Smi          (immediate small integer)
41 //   - TaggedIndex  (properly sign-extended immediate small integer)
42 //   - HeapObject   (superclass for everything allocated in the heap)
43 //     - JSReceiver  (suitable for property access)
44 //       - JSObject
45 //         - JSArray
46 //         - JSArrayBuffer
47 //         - JSArrayBufferView
48 //           - JSTypedArray
49 //           - JSDataView
50 //         - JSCollection
51 //           - JSSet
52 //           - JSMap
53 //         - JSCustomElementsObject (may have elements despite empty FixedArray)
54 //           - JSSpecialObject (requires custom property lookup handling)
55 //             - JSGlobalObject
56 //             - JSGlobalProxy
57 //             - JSModuleNamespace
58 //           - JSPrimitiveWrapper
59 //         - JSDate
60 //         - JSFunctionOrBoundFunction
61 //           - JSBoundFunction
62 //           - JSFunction
63 //         - JSGeneratorObject
64 //         - JSMapIterator
65 //         - JSMessageObject
66 //         - JSRegExp
67 //         - JSSetIterator
68 //         - JSStringIterator
69 //         - JSWeakCollection
70 //           - JSWeakMap
71 //           - JSWeakSet
72 //         - JSCollator            // If V8_INTL_SUPPORT enabled.
73 //         - JSDateTimeFormat      // If V8_INTL_SUPPORT enabled.
74 //         - JSDisplayNames        // If V8_INTL_SUPPORT enabled.
75 //         - JSListFormat          // If V8_INTL_SUPPORT enabled.
76 //         - JSLocale              // If V8_INTL_SUPPORT enabled.
77 //         - JSNumberFormat        // If V8_INTL_SUPPORT enabled.
78 //         - JSPluralRules         // If V8_INTL_SUPPORT enabled.
79 //         - JSRelativeTimeFormat  // If V8_INTL_SUPPORT enabled.
80 //         - JSSegmenter           // If V8_INTL_SUPPORT enabled.
81 //         - JSSegments            // If V8_INTL_SUPPORT enabled.
82 //         - JSSegmentIterator     // If V8_INTL_SUPPORT enabled.
83 //         - JSV8BreakIterator     // If V8_INTL_SUPPORT enabled.
84 //         - WasmExceptionObject
85 //         - WasmGlobalObject
86 //         - WasmInstanceObject
87 //         - WasmMemoryObject
88 //         - WasmModuleObject
89 //         - WasmTableObject
90 //       - JSProxy
91 //     - FixedArrayBase
92 //       - ByteArray
93 //       - BytecodeArray
94 //       - FixedArray
95 //         - FrameArray
96 //         - HashTable
97 //           - Dictionary
98 //           - StringTable
99 //           - StringSet
100 //           - CompilationCacheTable
101 //           - MapCache
102 //         - OrderedHashTable
103 //           - OrderedHashSet
104 //           - OrderedHashMap
105 //         - FeedbackMetadata
106 //         - TemplateList
107 //         - TransitionArray
108 //         - ScopeInfo
109 //         - SourceTextModuleInfo
110 //         - ScriptContextTable
111 //         - ClosureFeedbackCellArray
112 //       - FixedDoubleArray
113 //     - PrimitiveHeapObject
114 //       - BigInt
115 //       - HeapNumber
116 //       - Name
117 //         - String
118 //           - SeqString
119 //             - SeqOneByteString
120 //             - SeqTwoByteString
121 //           - SlicedString
122 //           - ConsString
123 //           - ThinString
124 //           - ExternalString
125 //             - ExternalOneByteString
126 //             - ExternalTwoByteString
127 //           - InternalizedString
128 //             - SeqInternalizedString
129 //               - SeqOneByteInternalizedString
130 //               - SeqTwoByteInternalizedString
131 //             - ConsInternalizedString
132 //             - ExternalInternalizedString
133 //               - ExternalOneByteInternalizedString
134 //               - ExternalTwoByteInternalizedString
135 //         - Symbol
136 //       - Oddball
137 //     - Context
138 //       - NativeContext
139 //     - Cell
140 //     - DescriptorArray
141 //     - PropertyCell
142 //     - PropertyArray
143 //     - Code
144 //     - AbstractCode, a wrapper around Code or BytecodeArray
145 //     - Map
146 //     - Foreign
147 //     - SmallOrderedHashTable
148 //       - SmallOrderedHashMap
149 //       - SmallOrderedHashSet
150 //     - SharedFunctionInfo
151 //     - Struct
152 //       - AccessorInfo
153 //       - AsmWasmData
154 //       - PromiseReaction
155 //       - PromiseCapability
156 //       - AccessorPair
157 //       - AccessCheckInfo
158 //       - InterceptorInfo
159 //       - CallHandlerInfo
160 //       - EnumCache
161 //       - TemplateInfo
162 //         - FunctionTemplateInfo
163 //         - ObjectTemplateInfo
164 //       - Script
165 //       - DebugInfo
166 //       - BreakPoint
167 //       - BreakPointInfo
168 //       - CachedTemplateObject
169 //       - StackFrameInfo
170 //       - StackTraceFrame
171 //       - CodeCache
172 //       - PropertyDescriptorObject
173 //       - PrototypeInfo
174 //       - Microtask
175 //         - CallbackTask
176 //         - CallableTask
177 //         - PromiseReactionJobTask
178 //           - PromiseFulfillReactionJobTask
179 //           - PromiseRejectReactionJobTask
180 //         - PromiseResolveThenableJobTask
181 //       - Module
182 //         - SourceTextModule
183 //         - SyntheticModule
184 //       - SourceTextModuleInfoEntry
185 //       - WasmValue
186 //     - FeedbackCell
187 //     - FeedbackVector
188 //     - PreparseData
189 //     - UncompiledData
190 //       - UncompiledDataWithoutPreparseData
191 //       - UncompiledDataWithPreparseData
192 //
193 // Formats of Object::ptr_:
194 //  Smi:        [31 bit signed int] 0
195 //  HeapObject: [32 bit direct pointer] (4 byte aligned) | 01
196 
197 namespace v8 {
198 namespace internal {
199 
200 struct InliningPosition;
201 class PropertyDescriptorObject;
202 
203 // UNSAFE_SKIP_WRITE_BARRIER skips the write barrier.
204 // SKIP_WRITE_BARRIER skips the write barrier and asserts that this is safe in
205 // the MemoryOptimizer
206 // UPDATE_WEAK_WRITE_BARRIER skips the marking part of the write barrier and
207 // only performs the generational part.
208 // UPDATE_WRITE_BARRIER is doing the full barrier, marking and generational.
209 enum WriteBarrierMode {
210   SKIP_WRITE_BARRIER,
211   UNSAFE_SKIP_WRITE_BARRIER,
212   UPDATE_WEAK_WRITE_BARRIER,
213   UPDATE_EPHEMERON_KEY_WRITE_BARRIER,
214   UPDATE_WRITE_BARRIER
215 };
216 
217 // PropertyNormalizationMode is used to specify whether to keep
218 // inobject properties when normalizing properties of a JSObject.
219 enum PropertyNormalizationMode {
220   CLEAR_INOBJECT_PROPERTIES,
221   KEEP_INOBJECT_PROPERTIES
222 };
223 
224 // Indicates whether transitions can be added to a source map or not.
225 enum TransitionFlag { INSERT_TRANSITION, OMIT_TRANSITION };
226 
227 // Indicates whether the transition is simple: the target map of the transition
228 // either extends the current map with a new property, or it modifies the
229 // property that was added last to the current map.
230 enum SimpleTransitionFlag {
231   SIMPLE_PROPERTY_TRANSITION,
232   PROPERTY_TRANSITION,
233   SPECIAL_TRANSITION
234 };
235 
236 // Indicates whether we are only interested in the descriptors of a particular
237 // map, or in all descriptors in the descriptor array.
238 enum DescriptorFlag { ALL_DESCRIPTORS, OWN_DESCRIPTORS };
239 
240 // Instance size sentinel for objects of variable size.
241 const int kVariableSizeSentinel = 0;
242 
243 // We may store the unsigned bit field as signed Smi value and do not
244 // use the sign bit.
245 const int kStubMajorKeyBits = 8;
246 const int kStubMinorKeyBits = kSmiValueSize - kStubMajorKeyBits - 1;
247 
248 // Result of an abstract relational comparison of x and y, implemented according
249 // to ES6 section 7.2.11 Abstract Relational Comparison.
250 enum class ComparisonResult {
251   kLessThan,     // x < y
252   kEqual,        // x = y
253   kGreaterThan,  // x > y
254   kUndefined     // at least one of x or y was undefined or NaN
255 };
256 
257 // (Returns false whenever {result} is kUndefined.)
258 bool ComparisonResultToBool(Operation op, ComparisonResult result);
259 
260 enum class OnNonExistent { kThrowReferenceError, kReturnUndefined };
261 
262 // The element types selection for CreateListFromArrayLike.
263 enum class ElementTypes { kAll, kStringAndSymbol };
264 
265 // TODO(mythria): Move this to a better place.
266 ShouldThrow GetShouldThrow(Isolate* isolate, Maybe<ShouldThrow> should_throw);
267 
268 // Object is the abstract superclass for all classes in the
269 // object hierarchy.
270 // Object does not use any virtual functions to avoid the
271 // allocation of the C++ vtable.
272 // There must only be a single data member in Object: the Address ptr,
273 // containing the tagged heap pointer that this Object instance refers to.
274 // For a design overview, see https://goo.gl/Ph4CGz.
275 class Object : public TaggedImpl<HeapObjectReferenceType::STRONG, Address> {
276  public:
Object()277   constexpr Object() : TaggedImpl(kNullAddress) {}
Object(Address ptr)278   explicit constexpr Object(Address ptr) : TaggedImpl(ptr) {}
279 
280   V8_INLINE bool IsTaggedIndex() const;
281 
282 #define IS_TYPE_FUNCTION_DECL(Type) \
283   V8_INLINE bool Is##Type() const;  \
284   V8_INLINE bool Is##Type(IsolateRoot isolate) const;
285   OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
286   HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
287   IS_TYPE_FUNCTION_DECL(HashTableBase)
288   IS_TYPE_FUNCTION_DECL(SmallOrderedHashTable)
289 #undef IS_TYPE_FUNCTION_DECL
290   V8_INLINE bool IsNumber(ReadOnlyRoots roots) const;
291 
292 // Oddball checks are faster when they are raw pointer comparisons, so the
293 // isolate/read-only roots overloads should be preferred where possible.
294 #define IS_TYPE_FUNCTION_DECL(Type, Value)              \
295   V8_INLINE bool Is##Type(Isolate* isolate) const;      \
296   V8_INLINE bool Is##Type(LocalIsolate* isolate) const; \
297   V8_INLINE bool Is##Type(ReadOnlyRoots roots) const;   \
298   V8_INLINE bool Is##Type() const;
299   ODDBALL_LIST(IS_TYPE_FUNCTION_DECL)
300   IS_TYPE_FUNCTION_DECL(NullOrUndefined, /* unused */)
301 #undef IS_TYPE_FUNCTION_DECL
302 
303   V8_INLINE bool IsZero() const;
304   V8_INLINE bool IsNoSharedNameSentinel() const;
305   V8_INLINE bool IsPrivateSymbol() const;
306   V8_INLINE bool IsPublicSymbol() const;
307 
308   enum class Conversion { kToNumber, kToNumeric };
309 
310 #define DECL_STRUCT_PREDICATE(NAME, Name, name) \
311   V8_INLINE bool Is##Name() const;              \
312   V8_INLINE bool Is##Name(IsolateRoot isolate) const;
313   STRUCT_LIST(DECL_STRUCT_PREDICATE)
314 #undef DECL_STRUCT_PREDICATE
315 
316   // ES6, #sec-isarray.  NOT to be confused with %_IsArray.
317   V8_INLINE
318   V8_WARN_UNUSED_RESULT static Maybe<bool> IsArray(Handle<Object> object);
319 
320   // Extract the number.
321   inline double Number() const;
322   V8_INLINE bool IsNaN() const;
323   V8_INLINE bool IsMinusZero() const;
324   V8_EXPORT_PRIVATE bool ToInt32(int32_t* value);
325   inline bool ToUint32(uint32_t* value) const;
326 
327   inline Representation OptimalRepresentation(IsolateRoot isolate) const;
328 
329   inline ElementsKind OptimalElementsKind(IsolateRoot isolate) const;
330 
331   inline bool FitsRepresentation(Representation representation);
332 
333   inline bool FilterKey(PropertyFilter filter);
334 
335   Handle<FieldType> OptimalType(Isolate* isolate,
336                                 Representation representation);
337 
338   V8_EXPORT_PRIVATE static Handle<Object> NewStorageFor(
339       Isolate* isolate, Handle<Object> object, Representation representation);
340 
341   static Handle<Object> WrapForRead(Isolate* isolate, Handle<Object> object,
342                                     Representation representation);
343 
344   // Returns true if the object is of the correct type to be used as a
345   // implementation of a JSObject's elements.
346   inline bool HasValidElements();
347 
348   // ECMA-262 9.2.
349   V8_EXPORT_PRIVATE bool BooleanValue(Isolate* isolate);
350   Object ToBoolean(Isolate* isolate);
351 
352   // ES6 section 7.2.11 Abstract Relational Comparison
353   V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<ComparisonResult>
354   Compare(Isolate* isolate, Handle<Object> x, Handle<Object> y);
355 
356   // ES6 section 7.2.12 Abstract Equality Comparison
357   V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<bool> Equals(
358       Isolate* isolate, Handle<Object> x, Handle<Object> y);
359 
360   // ES6 section 7.2.13 Strict Equality Comparison
361   V8_EXPORT_PRIVATE bool StrictEquals(Object that);
362 
363   // ES6 section 7.1.13 ToObject
364   // Convert to a JSObject if needed.
365   // native_context is used when creating wrapper object.
366   //
367   // Passing a non-null method_name allows us to give a more informative
368   // error message for those cases where ToObject is being called on
369   // the receiver of a built-in method.
370   V8_WARN_UNUSED_RESULT static inline MaybeHandle<JSReceiver> ToObject(
371       Isolate* isolate, Handle<Object> object,
372       const char* method_name = nullptr);
373   V8_WARN_UNUSED_RESULT static MaybeHandle<JSReceiver> ToObjectImpl(
374       Isolate* isolate, Handle<Object> object,
375       const char* method_name = nullptr);
376 
377   // ES6 section 9.2.1.2, OrdinaryCallBindThis for sloppy callee.
378   V8_WARN_UNUSED_RESULT static MaybeHandle<JSReceiver> ConvertReceiver(
379       Isolate* isolate, Handle<Object> object);
380 
381   // ES6 section 7.1.14 ToPropertyKey
382   V8_WARN_UNUSED_RESULT static inline MaybeHandle<Name> ToName(
383       Isolate* isolate, Handle<Object> input);
384 
385   // ES6 section 7.1.1 ToPrimitive
386   V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> ToPrimitive(
387       Handle<Object> input, ToPrimitiveHint hint = ToPrimitiveHint::kDefault);
388 
389   // ES6 section 7.1.3 ToNumber
390   V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> ToNumber(
391       Isolate* isolate, Handle<Object> input);
392 
393   V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> ToNumeric(
394       Isolate* isolate, Handle<Object> input);
395 
396   // ES6 section 7.1.4 ToInteger
397   V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> ToInteger(
398       Isolate* isolate, Handle<Object> input);
399 
400   // ES6 section 7.1.5 ToInt32
401   V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> ToInt32(
402       Isolate* isolate, Handle<Object> input);
403 
404   // ES6 section 7.1.6 ToUint32
405   V8_WARN_UNUSED_RESULT inline static MaybeHandle<Object> ToUint32(
406       Isolate* isolate, Handle<Object> input);
407 
408   // ES6 section 7.1.12 ToString
409   V8_WARN_UNUSED_RESULT static inline MaybeHandle<String> ToString(
410       Isolate* isolate, Handle<Object> input);
411 
412   V8_EXPORT_PRIVATE static Handle<String> NoSideEffectsToString(
413       Isolate* isolate, Handle<Object> input);
414 
415   // ES6 section 7.1.14 ToPropertyKey
416   V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> ToPropertyKey(
417       Isolate* isolate, Handle<Object> value);
418 
419   // ES6 section 7.1.15 ToLength
420   V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> ToLength(
421       Isolate* isolate, Handle<Object> input);
422 
423   // ES6 section 7.1.17 ToIndex
424   V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> ToIndex(
425       Isolate* isolate, Handle<Object> input, MessageTemplate error_index);
426 
427   // ES6 section 7.3.9 GetMethod
428   V8_WARN_UNUSED_RESULT static MaybeHandle<Object> GetMethod(
429       Handle<JSReceiver> receiver, Handle<Name> name);
430 
431   // ES6 section 7.3.17 CreateListFromArrayLike
432   V8_WARN_UNUSED_RESULT static MaybeHandle<FixedArray> CreateListFromArrayLike(
433       Isolate* isolate, Handle<Object> object, ElementTypes element_types);
434 
435   // Get length property and apply ToLength.
436   V8_WARN_UNUSED_RESULT static MaybeHandle<Object> GetLengthFromArrayLike(
437       Isolate* isolate, Handle<JSReceiver> object);
438 
439   // ES6 section 12.5.6 The typeof Operator
440   static Handle<String> TypeOf(Isolate* isolate, Handle<Object> object);
441 
442   // ES6 section 12.7 Additive Operators
443   V8_WARN_UNUSED_RESULT static MaybeHandle<Object> Add(Isolate* isolate,
444                                                        Handle<Object> lhs,
445                                                        Handle<Object> rhs);
446 
447   // ES6 section 12.9 Relational Operators
448   V8_WARN_UNUSED_RESULT static inline Maybe<bool> GreaterThan(Isolate* isolate,
449                                                               Handle<Object> x,
450                                                               Handle<Object> y);
451   V8_WARN_UNUSED_RESULT static inline Maybe<bool> GreaterThanOrEqual(
452       Isolate* isolate, Handle<Object> x, Handle<Object> y);
453   V8_WARN_UNUSED_RESULT static inline Maybe<bool> LessThan(Isolate* isolate,
454                                                            Handle<Object> x,
455                                                            Handle<Object> y);
456   V8_WARN_UNUSED_RESULT static inline Maybe<bool> LessThanOrEqual(
457       Isolate* isolate, Handle<Object> x, Handle<Object> y);
458 
459   // ES6 section 7.3.19 OrdinaryHasInstance (C, O).
460   V8_WARN_UNUSED_RESULT static MaybeHandle<Object> OrdinaryHasInstance(
461       Isolate* isolate, Handle<Object> callable, Handle<Object> object);
462 
463   // ES6 section 12.10.4 Runtime Semantics: InstanceofOperator(O, C)
464   V8_WARN_UNUSED_RESULT static MaybeHandle<Object> InstanceOf(
465       Isolate* isolate, Handle<Object> object, Handle<Object> callable);
466 
467   V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static MaybeHandle<Object>
468   GetProperty(LookupIterator* it, bool is_global_reference = false);
469 
470   // ES6 [[Set]] (when passed kDontThrow)
471   // Invariants for this and related functions (unless stated otherwise):
472   // 1) When the result is Nothing, an exception is pending.
473   // 2) When passed kThrowOnError, the result is never Just(false).
474   // In some cases, an exception is thrown regardless of the ShouldThrow
475   // argument.  These cases are either in accordance with the spec or not
476   // covered by it (eg., concerning API callbacks).
477   V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<bool> SetProperty(
478       LookupIterator* it, Handle<Object> value, StoreOrigin store_origin,
479       Maybe<ShouldThrow> should_throw = Nothing<ShouldThrow>());
480   V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static MaybeHandle<Object>
481   SetProperty(Isolate* isolate, Handle<Object> object, Handle<Name> name,
482               Handle<Object> value,
483               StoreOrigin store_origin = StoreOrigin::kMaybeKeyed,
484               Maybe<ShouldThrow> should_throw = Nothing<ShouldThrow>());
485   V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> SetPropertyOrElement(
486       Isolate* isolate, Handle<Object> object, Handle<Name> name,
487       Handle<Object> value,
488       Maybe<ShouldThrow> should_throw = Nothing<ShouldThrow>(),
489       StoreOrigin store_origin = StoreOrigin::kMaybeKeyed);
490 
491   V8_WARN_UNUSED_RESULT static Maybe<bool> SetSuperProperty(
492       LookupIterator* it, Handle<Object> value, StoreOrigin store_origin,
493       Maybe<ShouldThrow> should_throw = Nothing<ShouldThrow>());
494 
495   V8_WARN_UNUSED_RESULT static Maybe<bool> CannotCreateProperty(
496       Isolate* isolate, Handle<Object> receiver, Handle<Object> name,
497       Handle<Object> value, Maybe<ShouldThrow> should_throw);
498   V8_WARN_UNUSED_RESULT static Maybe<bool> WriteToReadOnlyProperty(
499       LookupIterator* it, Handle<Object> value,
500       Maybe<ShouldThrow> should_throw);
501   V8_WARN_UNUSED_RESULT static Maybe<bool> WriteToReadOnlyProperty(
502       Isolate* isolate, Handle<Object> receiver, Handle<Object> name,
503       Handle<Object> value, ShouldThrow should_throw);
504   V8_WARN_UNUSED_RESULT static Maybe<bool> RedefineIncompatibleProperty(
505       Isolate* isolate, Handle<Object> name, Handle<Object> value,
506       Maybe<ShouldThrow> should_throw);
507   V8_WARN_UNUSED_RESULT static Maybe<bool> SetDataProperty(
508       LookupIterator* it, Handle<Object> value);
509   V8_WARN_UNUSED_RESULT static Maybe<bool> AddDataProperty(
510       LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
511       Maybe<ShouldThrow> should_throw, StoreOrigin store_origin);
512   V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> GetPropertyOrElement(
513       Isolate* isolate, Handle<Object> object, Handle<Name> name);
514   V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> GetPropertyOrElement(
515       Handle<Object> receiver, Handle<Name> name, Handle<JSReceiver> holder);
516   V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> GetProperty(
517       Isolate* isolate, Handle<Object> object, Handle<Name> name);
518 
519   V8_WARN_UNUSED_RESULT static MaybeHandle<Object> GetPropertyWithAccessor(
520       LookupIterator* it);
521   V8_WARN_UNUSED_RESULT static Maybe<bool> SetPropertyWithAccessor(
522       LookupIterator* it, Handle<Object> value,
523       Maybe<ShouldThrow> should_throw);
524 
525   V8_WARN_UNUSED_RESULT static MaybeHandle<Object> GetPropertyWithDefinedGetter(
526       Handle<Object> receiver, Handle<JSReceiver> getter);
527   V8_WARN_UNUSED_RESULT static Maybe<bool> SetPropertyWithDefinedSetter(
528       Handle<Object> receiver, Handle<JSReceiver> setter, Handle<Object> value,
529       Maybe<ShouldThrow> should_throw);
530 
531   V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> GetElement(
532       Isolate* isolate, Handle<Object> object, uint32_t index);
533 
534   V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> SetElement(
535       Isolate* isolate, Handle<Object> object, uint32_t index,
536       Handle<Object> value, ShouldThrow should_throw);
537 
538   // Returns the permanent hash code associated with this object. May return
539   // undefined if not yet created.
540   inline Object GetHash();
541 
542   // Returns the permanent hash code associated with this object depending on
543   // the actual object type. May create and store a hash code if needed and none
544   // exists.
545   V8_EXPORT_PRIVATE Smi GetOrCreateHash(Isolate* isolate);
546 
547   // Checks whether this object has the same value as the given one.  This
548   // function is implemented according to ES5, section 9.12 and can be used
549   // to implement the Object.is function.
550   V8_EXPORT_PRIVATE bool SameValue(Object other);
551 
552   // A part of SameValue which handles Number vs. Number case.
553   // Treats NaN == NaN and +0 != -0.
554   inline static bool SameNumberValue(double number1, double number2);
555 
556   // Checks whether this object has the same value as the given one.
557   // +0 and -0 are treated equal. Everything else is the same as SameValue.
558   // This function is implemented according to ES6, section 7.2.4 and is used
559   // by ES6 Map and Set.
560   bool SameValueZero(Object other);
561 
562   // ES6 section 9.4.2.3 ArraySpeciesCreate (part of it)
563   V8_WARN_UNUSED_RESULT static MaybeHandle<Object> ArraySpeciesConstructor(
564       Isolate* isolate, Handle<Object> original_array);
565 
566   // ES6 section 7.3.20 SpeciesConstructor ( O, defaultConstructor )
567   V8_WARN_UNUSED_RESULT static MaybeHandle<Object> SpeciesConstructor(
568       Isolate* isolate, Handle<JSReceiver> recv,
569       Handle<JSFunction> default_ctor);
570 
571   // Tries to convert an object to an array length. Returns true and sets the
572   // output parameter if it succeeds.
573   inline bool ToArrayLength(uint32_t* index) const;
574 
575   // Tries to convert an object to an array index. Returns true and sets the
576   // output parameter if it succeeds. Equivalent to ToArrayLength, but does not
577   // allow kMaxUInt32.
578   V8_WARN_UNUSED_RESULT inline bool ToArrayIndex(uint32_t* index) const;
579 
580   // Tries to convert an object to an index (in the range 0..size_t::max).
581   // Returns true and sets the output parameter if it succeeds.
582   inline bool ToIntegerIndex(size_t* index) const;
583 
584   // Returns true if the result of iterating over the object is the same
585   // (including observable effects) as simply accessing the properties between 0
586   // and length.
587   bool IterationHasObservableEffects();
588 
589   // TC39 "Dynamic Code Brand Checks"
590   bool IsCodeLike(Isolate* isolate) const;
591 
592   EXPORT_DECL_VERIFIER(Object)
593 
594 #ifdef VERIFY_HEAP
595   // Verify a pointer is a valid object pointer.
596   static void VerifyPointer(Isolate* isolate, Object p);
597 #endif
598 
599   inline void VerifyApiCallResultType();
600 
601   // Prints this object without details.
602   V8_EXPORT_PRIVATE void ShortPrint(FILE* out = stdout) const;
603 
604   // Prints this object without details to a message accumulator.
605   V8_EXPORT_PRIVATE void ShortPrint(StringStream* accumulator) const;
606 
607   V8_EXPORT_PRIVATE void ShortPrint(std::ostream& os) const;  // NOLINT
608 
cast(Object object)609   inline static Object cast(Object object) { return object; }
unchecked_cast(Object object)610   inline static Object unchecked_cast(Object object) { return object; }
611 
612   // Layout description.
613   static const int kHeaderSize = 0;  // Object does not take up any space.
614 
615 #ifdef OBJECT_PRINT
616   // For our gdb macros, we should perhaps change these in the future.
617   V8_EXPORT_PRIVATE void Print() const;
618 
619   // Prints this object with details.
620   V8_EXPORT_PRIVATE void Print(std::ostream& os) const;  // NOLINT
621 #else
Print()622   void Print() const { ShortPrint(); }
Print(std::ostream & os)623   void Print(std::ostream& os) const { ShortPrint(os); }  // NOLINT
624 #endif
625 
626   // For use with std::unordered_set.
627   struct Hasher {
operatorHasher628     size_t operator()(const Object o) const {
629       return std::hash<v8::internal::Address>{}(static_cast<Tagged_t>(o.ptr()));
630     }
631   };
632 
633   // For use with std::map.
634   struct Comparer {
operatorComparer635     bool operator()(const Object a, const Object b) const { return a < b; }
636   };
637 
638   template <class T, typename std::enable_if<std::is_arithmetic<T>::value,
639                                              int>::type = 0>
ReadField(size_t offset)640   inline T ReadField(size_t offset) const {
641     // Pointer compression causes types larger than kTaggedSize to be unaligned.
642 #ifdef V8_COMPRESS_POINTERS
643     constexpr bool v8_pointer_compression_unaligned = sizeof(T) > kTaggedSize;
644 #else
645     constexpr bool v8_pointer_compression_unaligned = false;
646 #endif
647     if (std::is_same<T, double>::value || v8_pointer_compression_unaligned) {
648       // Bug(v8:8875) Double fields may be unaligned.
649       return base::ReadUnalignedValue<T>(field_address(offset));
650     } else {
651       return base::Memory<T>(field_address(offset));
652     }
653   }
654 
655   template <class T, typename std::enable_if<std::is_arithmetic<T>::value,
656                                              int>::type = 0>
WriteField(size_t offset,T value)657   inline void WriteField(size_t offset, T value) const {
658     // Pointer compression causes types larger than kTaggedSize to be unaligned.
659 #ifdef V8_COMPRESS_POINTERS
660     constexpr bool v8_pointer_compression_unaligned = sizeof(T) > kTaggedSize;
661 #else
662     constexpr bool v8_pointer_compression_unaligned = false;
663 #endif
664     if (std::is_same<T, double>::value || v8_pointer_compression_unaligned) {
665       // Bug(v8:8875) Double fields may be unaligned.
666       base::WriteUnalignedValue<T>(field_address(offset), value);
667     } else {
668       base::Memory<T>(field_address(offset)) = value;
669     }
670   }
671 
672   //
673   // ExternalPointer_t field accessors.
674   //
675   inline void InitExternalPointerField(size_t offset, Isolate* isolate);
676   inline void InitExternalPointerField(size_t offset, Isolate* isolate,
677                                        Address value, ExternalPointerTag tag);
678   inline Address ReadExternalPointerField(size_t offset, IsolateRoot isolate,
679                                           ExternalPointerTag tag) const;
680   inline void WriteExternalPointerField(size_t offset, Isolate* isolate,
681                                         Address value, ExternalPointerTag tag);
682 
683  protected:
field_address(size_t offset)684   inline Address field_address(size_t offset) const {
685     return ptr() + offset - kHeapObjectTag;
686   }
687 
688  private:
689   friend class CompressedObjectSlot;
690   friend class FullObjectSlot;
691   friend class LookupIterator;
692   friend class StringStream;
693 
694   // Return the map of the root of object's prototype chain.
695   Map GetPrototypeChainRootMap(Isolate* isolate) const;
696 
697   // Returns a non-SMI for JSReceivers, but returns the hash code for
698   // simple objects.  This avoids a double lookup in the cases where
699   // we know we will add the hash to the JSReceiver if it does not
700   // already exist.
701   //
702   // Despite its size, this needs to be inlined for performance
703   // reasons.
704   static inline Object GetSimpleHash(Object object);
705 
706   // Helper for SetProperty and SetSuperProperty.
707   // Return value is only meaningful if [found] is set to true on return.
708   V8_WARN_UNUSED_RESULT static Maybe<bool> SetPropertyInternal(
709       LookupIterator* it, Handle<Object> value, Maybe<ShouldThrow> should_throw,
710       StoreOrigin store_origin, bool* found);
711 
712   V8_WARN_UNUSED_RESULT static MaybeHandle<Name> ConvertToName(
713       Isolate* isolate, Handle<Object> input);
714   V8_WARN_UNUSED_RESULT static MaybeHandle<Object> ConvertToPropertyKey(
715       Isolate* isolate, Handle<Object> value);
716   V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static MaybeHandle<String>
717   ConvertToString(Isolate* isolate, Handle<Object> input);
718   V8_WARN_UNUSED_RESULT static MaybeHandle<Object> ConvertToNumberOrNumeric(
719       Isolate* isolate, Handle<Object> input, Conversion mode);
720   V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static MaybeHandle<Object>
721   ConvertToInteger(Isolate* isolate, Handle<Object> input);
722   V8_WARN_UNUSED_RESULT static MaybeHandle<Object> ConvertToInt32(
723       Isolate* isolate, Handle<Object> input);
724   V8_WARN_UNUSED_RESULT static MaybeHandle<Object> ConvertToUint32(
725       Isolate* isolate, Handle<Object> input);
726   V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static MaybeHandle<Object>
727   ConvertToLength(Isolate* isolate, Handle<Object> input);
728   V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static MaybeHandle<Object>
729   ConvertToIndex(Isolate* isolate, Handle<Object> input,
730                  MessageTemplate error_index);
731 };
732 
733 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, const Object& obj);
734 
735 struct Brief {
736   template <typename TObject>
BriefBrief737   explicit Brief(TObject v) : value{v.ptr()} {}
738   // {value} is a tagged heap object reference (weak or strong), equivalent to
739   // a MaybeObject's payload. It has a plain Address type to keep #includes
740   // lightweight.
741   const Address value;
742 };
743 
744 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, const Brief& v);
745 
746 // Objects should never have the weak tag; this variant is for overzealous
747 // checking.
HasWeakHeapObjectTag(const Object value)748 V8_INLINE static bool HasWeakHeapObjectTag(const Object value) {
749   return HAS_WEAK_HEAP_OBJECT_TAG(value.ptr());
750 }
751 
752 // Heap objects typically have a map pointer in their first word.  However,
753 // during GC other data (e.g. mark bits, forwarding addresses) is sometimes
754 // encoded in the first word.  The class MapWord is an abstraction of the
755 // value in a heap object's first word.
756 class MapWord {
757  public:
758   // Normal state: the map word contains a map pointer.
759 
760   // Create a map word from a map pointer.
761   static inline MapWord FromMap(const Map map);
762 
763   // View this map word as a map pointer.
764   inline Map ToMap() const;
765 
766   // Scavenge collection: the map word of live objects in the from space
767   // contains a forwarding address (a heap object pointer in the to space).
768 
769   // True if this map word is a forwarding address for a scavenge
770   // collection.  Only valid during a scavenge collection (specifically,
771   // when all map words are heap object pointers, i.e. not during a full GC).
772   inline bool IsForwardingAddress() const;
773 
774   // Create a map word from a forwarding address.
775   static inline MapWord FromForwardingAddress(HeapObject object);
776 
777   // View this map word as a forwarding address.
778   inline HeapObject ToForwardingAddress();
779 
ptr()780   inline Address ptr() { return value_; }
781 
782  private:
783   // HeapObject calls the private constructor and directly reads the value.
784   friend class HeapObject;
785   template <typename TFieldType, int kFieldOffset>
786   friend class TaggedField;
787 
MapWord(Address value)788   explicit MapWord(Address value) : value_(value) {}
789 
790   Address value_;
791 };
792 
793 template <int start_offset, int end_offset, int size>
794 class FixedBodyDescriptor;
795 
796 template <int start_offset>
797 class FlexibleBodyDescriptor;
798 
799 template <int start_offset>
800 class FlexibleWeakBodyDescriptor;
801 
802 template <class ParentBodyDescriptor, class ChildBodyDescriptor>
803 class SubclassBodyDescriptor;
804 
805 enum EnsureElementsMode {
806   DONT_ALLOW_DOUBLE_ELEMENTS,
807   ALLOW_COPIED_DOUBLE_ELEMENTS,
808   ALLOW_CONVERTED_DOUBLE_ELEMENTS
809 };
810 
811 // Indicator for one component of an AccessorPair.
812 enum AccessorComponent { ACCESSOR_GETTER, ACCESSOR_SETTER };
813 
814 enum class GetKeysConversion {
815   kKeepNumbers = static_cast<int>(v8::KeyConversionMode::kKeepNumbers),
816   kConvertToString = static_cast<int>(v8::KeyConversionMode::kConvertToString),
817   kNoNumbers = static_cast<int>(v8::KeyConversionMode::kNoNumbers)
818 };
819 
820 enum class KeyCollectionMode {
821   kOwnOnly = static_cast<int>(v8::KeyCollectionMode::kOwnOnly),
822   kIncludePrototypes =
823       static_cast<int>(v8::KeyCollectionMode::kIncludePrototypes)
824 };
825 
826 // Utility superclass for stack-allocated objects that must be updated
827 // on gc.  It provides two ways for the gc to update instances, either
828 // iterating or updating after gc.
829 class Relocatable {
830  public:
831   explicit inline Relocatable(Isolate* isolate);
832   inline virtual ~Relocatable();
IterateInstance(RootVisitor * v)833   virtual void IterateInstance(RootVisitor* v) {}
PostGarbageCollection()834   virtual void PostGarbageCollection() {}
835 
836   static void PostGarbageCollectionProcessing(Isolate* isolate);
837   static int ArchiveSpacePerThread();
838   static char* ArchiveState(Isolate* isolate, char* to);
839   static char* RestoreState(Isolate* isolate, char* from);
840   static void Iterate(Isolate* isolate, RootVisitor* v);
841   static void Iterate(RootVisitor* v, Relocatable* top);
842   static char* Iterate(RootVisitor* v, char* t);
843 
844  private:
845   Isolate* isolate_;
846   Relocatable* prev_;
847 };
848 
849 // BooleanBit is a helper class for setting and getting a bit in an integer.
850 class BooleanBit : public AllStatic {
851  public:
get(int value,int bit_position)852   static inline bool get(int value, int bit_position) {
853     return (value & (1 << bit_position)) != 0;
854   }
855 
set(int value,int bit_position,bool v)856   static inline int set(int value, int bit_position, bool v) {
857     if (v) {
858       value |= (1 << bit_position);
859     } else {
860       value &= ~(1 << bit_position);
861     }
862     return value;
863   }
864 };
865 
866 }  // namespace internal
867 }  // namespace v8
868 
869 #include "src/objects/object-macros-undef.h"
870 
871 #endif  // V8_OBJECTS_OBJECTS_H_
872