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_H_
6#define V8_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/assert-scope.h"
15#include "src/base/bits.h"
16#include "src/base/build_config.h"
17#include "src/base/flags.h"
18#include "src/base/logging.h"
19#include "src/checks.h"
20#include "src/constants-arch.h"
21#include "src/elements-kind.h"
22#include "src/field-index.h"
23#include "src/flags.h"
24#include "src/message-template.h"
25#include "src/objects-definitions.h"
26#include "src/property-details.h"
27#include "src/utils.h"
28
29// Has to be the last include (doesn't have include guards):
30#include "src/objects/object-macros.h"
31
32//
33// Most object types in the V8 JavaScript are described in this file.
34//
35// Inheritance hierarchy:
36// - Object
37// - Smi (immediate small integer)
38// - HeapObject (superclass for everything allocated in the heap)
39// - JSReceiver (suitable for property access)
40// - JSObject
41// - JSArray
42// - JSArrayBuffer
43// - JSArrayBufferView
44// - JSTypedArray
45// - JSDataView
46// - JSBoundFunction
47// - JSCollection
48// - JSSet
49// - JSMap
50// - JSStringIterator
51// - JSSetIterator
52// - JSMapIterator
53// - JSWeakCollection
54// - JSWeakMap
55// - JSWeakSet
56// - JSRegExp
57// - JSFunction
58// - JSGeneratorObject
59// - JSGlobalObject
60// - JSGlobalProxy
61// - JSValue
62// - JSDate
63// - JSMessageObject
64// - JSModuleNamespace
65// - JSV8BreakIterator // If V8_INTL_SUPPORT enabled.
66// - JSCollator // If V8_INTL_SUPPORT enabled.
67// - JSDateTimeFormat // If V8_INTL_SUPPORT enabled.
68// - JSListFormat // If V8_INTL_SUPPORT enabled.
69// - JSLocale // If V8_INTL_SUPPORT enabled.
70// - JSNumberFormat // If V8_INTL_SUPPORT enabled.
71// - JSPluralRules // If V8_INTL_SUPPORT enabled.
72// - JSRelativeTimeFormat // If V8_INTL_SUPPORT enabled.
73// - JSSegmentIterator // If V8_INTL_SUPPORT enabled.
74// - JSSegmenter // If V8_INTL_SUPPORT enabled.
75// - WasmExceptionObject
76// - WasmGlobalObject
77// - WasmInstanceObject
78// - WasmMemoryObject
79// - WasmModuleObject
80// - WasmTableObject
81// - JSProxy
82// - FixedArrayBase
83// - ByteArray
84// - BytecodeArray
85// - FixedArray
86// - FrameArray
87// - HashTable
88// - Dictionary
89// - StringTable
90// - StringSet
91// - CompilationCacheTable
92// - MapCache
93// - OrderedHashTable
94// - OrderedHashSet
95// - OrderedHashMap
96// - FeedbackMetadata
97// - TemplateList
98// - TransitionArray
99// - ScopeInfo
100// - ModuleInfo
101// - ScriptContextTable
102// - ClosureFeedbackCellArray
103// - FixedDoubleArray
104// - Name
105// - String
106// - SeqString
107// - SeqOneByteString
108// - SeqTwoByteString
109// - SlicedString
110// - ConsString
111// - ThinString
112// - ExternalString
113// - ExternalOneByteString
114// - ExternalTwoByteString
115// - InternalizedString
116// - SeqInternalizedString
117// - SeqOneByteInternalizedString
118// - SeqTwoByteInternalizedString
119// - ConsInternalizedString
120// - ExternalInternalizedString
121// - ExternalOneByteInternalizedString
122// - ExternalTwoByteInternalizedString
123// - Symbol
124// - Context
125// - NativeContext
126// - HeapNumber
127// - BigInt
128// - Cell
129// - DescriptorArray
130// - PropertyCell
131// - PropertyArray
132// - Code
133// - AbstractCode, a wrapper around Code or BytecodeArray
134// - Map
135// - Oddball
136// - Foreign
137// - SmallOrderedHashTable
138// - SmallOrderedHashMap
139// - SmallOrderedHashSet
140// - SharedFunctionInfo
141// - Struct
142// - AccessorInfo
143// - AsmWasmData
144// - PromiseReaction
145// - PromiseCapability
146// - AccessorPair
147// - AccessCheckInfo
148// - InterceptorInfo
149// - CallHandlerInfo
150// - EnumCache
151// - TemplateInfo
152// - FunctionTemplateInfo
153// - ObjectTemplateInfo
154// - Script
155// - DebugInfo
156// - BreakPoint
157// - BreakPointInfo
158// - StackFrameInfo
159// - StackTraceFrame
160// - SourcePositionTableWithFrameCache
161// - CodeCache
162// - PrototypeInfo
163// - Microtask
164// - CallbackTask
165// - CallableTask
166// - PromiseReactionJobTask
167// - PromiseFulfillReactionJobTask
168// - PromiseRejectReactionJobTask
169// - PromiseResolveThenableJobTask
170// - Module
171// - ModuleInfoEntry
172// - FeedbackCell
173// - FeedbackVector
174// - PreparseData
175// - UncompiledData
176// - UncompiledDataWithoutPreparseData
177// - UncompiledDataWithPreparseData
178//
179// Formats of Object::ptr_:
180// Smi: [31 bit signed int] 0
181// HeapObject: [32 bit direct pointer] (4 byte aligned) | 01
182
183namespace v8 {
184namespace internal {
185
186struct InliningPosition;
187class PropertyDescriptorObject;
188
189// SKIP_WRITE_BARRIER skips the write barrier.
190// UPDATE_WEAK_WRITE_BARRIER skips the marking part of the write barrier and
191// only performs the generational part.
192// UPDATE_WRITE_BARRIER is doing the full barrier, marking and generational.
193enum WriteBarrierMode {
194 SKIP_WRITE_BARRIER,
195 UPDATE_WEAK_WRITE_BARRIER,
196 UPDATE_EPHEMERON_KEY_WRITE_BARRIER,
197 UPDATE_WRITE_BARRIER
198};
199
200// PropertyNormalizationMode is used to specify whether to keep
201// inobject properties when normalizing properties of a JSObject.
202enum PropertyNormalizationMode {
203 CLEAR_INOBJECT_PROPERTIES,
204 KEEP_INOBJECT_PROPERTIES
205};
206
207
208// Indicates whether transitions can be added to a source map or not.
209enum TransitionFlag {
210 INSERT_TRANSITION,
211 OMIT_TRANSITION
212};
213
214
215// Indicates whether the transition is simple: the target map of the transition
216// either extends the current map with a new property, or it modifies the
217// property that was added last to the current map.
218enum SimpleTransitionFlag {
219 SIMPLE_PROPERTY_TRANSITION,
220 PROPERTY_TRANSITION,
221 SPECIAL_TRANSITION
222};
223
224// Indicates whether we are only interested in the descriptors of a particular
225// map, or in all descriptors in the descriptor array.
226enum DescriptorFlag {
227 ALL_DESCRIPTORS,
228 OWN_DESCRIPTORS
229};
230
231// Instance size sentinel for objects of variable size.
232const int kVariableSizeSentinel = 0;
233
234// We may store the unsigned bit field as signed Smi value and do not
235// use the sign bit.
236const int kStubMajorKeyBits = 8;
237const int kStubMinorKeyBits = kSmiValueSize - kStubMajorKeyBits - 1;
238
239// Result of an abstract relational comparison of x and y, implemented according
240// to ES6 section 7.2.11 Abstract Relational Comparison.
241enum class ComparisonResult {
242 kLessThan, // x < y
243 kEqual, // x = y
244 kGreaterThan, // x > y
245 kUndefined // at least one of x or y was undefined or NaN
246};
247
248// (Returns false whenever {result} is kUndefined.)
249bool ComparisonResultToBool(Operation op, ComparisonResult result);
250
251enum class OnNonExistent { kThrowReferenceError, kReturnUndefined };
252
253class AbstractCode;
254class AccessorPair;
255class AccessCheckInfo;
256class AllocationSite;
257class ByteArray;
258class CachedTemplateObject;
259class Cell;
260class ClosureFeedbackCellArray;
261class ConsString;
262class DependentCode;
263class ElementsAccessor;
264class EnumCache;
265class FixedArrayBase;
266class FixedDoubleArray;
267class FreeSpace;
268class FunctionLiteral;
269class FunctionTemplateInfo;
270class JSAsyncGeneratorObject;
271class JSGlobalProxy;
272class JSPromise;
273class JSProxy;
274class JSProxyRevocableResult;
275class KeyAccumulator;
276class LayoutDescriptor;
277class LookupIterator;
278class FieldType;
279class Module;
280class ModuleInfoEntry;
281class MutableHeapNumber;
282class ObjectHashTable;
283class ObjectTemplateInfo;
284class ObjectVisitor;
285class PreparseData;
286class PropertyArray;
287class PropertyCell;
288class PropertyDescriptor;
289class PrototypeInfo;
290class ReadOnlyRoots;
291class RegExpMatchInfo;
292class RootVisitor;
293class SafepointEntry;
294class ScriptContextTable;
295class SharedFunctionInfo;
296class StringStream;
297class Symbol;
298class FeedbackCell;
299class FeedbackMetadata;
300class FeedbackVector;
301class UncompiledData;
302class TemplateInfo;
303class TransitionArray;
304class TemplateList;
305class WasmInstanceObject;
306class WasmMemoryObject;
307template <typename T>
308class ZoneForwardList;
309
310#ifdef OBJECT_PRINT
311#define DECL_PRINTER(Name) void Name##Print(std::ostream& os); // NOLINT
312#else
313#define DECL_PRINTER(Name)
314#endif
315
316#define OBJECT_TYPE_LIST(V) \
317 V(Smi) \
318 V(LayoutDescriptor) \
319 V(HeapObject) \
320 V(Primitive) \
321 V(Number) \
322 V(Numeric)
323
324#define HEAP_OBJECT_ORDINARY_TYPE_LIST_BASE(V) \
325 V(AbstractCode) \
326 V(AccessCheckNeeded) \
327 V(AllocationSite) \
328 V(ArrayList) \
329 V(BigInt) \
330 V(BigIntWrapper) \
331 V(ObjectBoilerplateDescription) \
332 V(Boolean) \
333 V(BooleanWrapper) \
334 V(BreakPoint) \
335 V(BreakPointInfo) \
336 V(ByteArray) \
337 V(BytecodeArray) \
338 V(CachedTemplateObject) \
339 V(CallHandlerInfo) \
340 V(Callable) \
341 V(Cell) \
342 V(ClassBoilerplate) \
343 V(Code) \
344 V(CodeDataContainer) \
345 V(CompilationCacheTable) \
346 V(ConsString) \
347 V(Constructor) \
348 V(Context) \
349 V(CoverageInfo) \
350 V(ClosureFeedbackCellArray) \
351 V(DataHandler) \
352 V(DeoptimizationData) \
353 V(DependentCode) \
354 V(DescriptorArray) \
355 V(EmbedderDataArray) \
356 V(EphemeronHashTable) \
357 V(EnumCache) \
358 V(ExternalOneByteString) \
359 V(ExternalString) \
360 V(ExternalTwoByteString) \
361 V(FeedbackCell) \
362 V(FeedbackMetadata) \
363 V(FeedbackVector) \
364 V(Filler) \
365 V(FixedArray) \
366 V(FixedArrayBase) \
367 V(FixedArrayExact) \
368 V(FixedBigInt64Array) \
369 V(FixedBigUint64Array) \
370 V(FixedDoubleArray) \
371 V(FixedFloat32Array) \
372 V(FixedFloat64Array) \
373 V(FixedInt16Array) \
374 V(FixedInt32Array) \
375 V(FixedInt8Array) \
376 V(FixedTypedArrayBase) \
377 V(FixedUint16Array) \
378 V(FixedUint32Array) \
379 V(FixedUint8Array) \
380 V(FixedUint8ClampedArray) \
381 V(Foreign) \
382 V(FrameArray) \
383 V(FreeSpace) \
384 V(Function) \
385 V(GlobalDictionary) \
386 V(HandlerTable) \
387 V(HeapNumber) \
388 V(InternalizedString) \
389 V(JSArgumentsObject) \
390 V(JSArgumentsObjectWithLength) \
391 V(JSArray) \
392 V(JSArrayBuffer) \
393 V(JSArrayBufferView) \
394 V(JSArrayIterator) \
395 V(JSAsyncFromSyncIterator) \
396 V(JSAsyncFunctionObject) \
397 V(JSAsyncGeneratorObject) \
398 V(JSBoundFunction) \
399 V(JSCollection) \
400 V(JSContextExtensionObject) \
401 V(JSDataView) \
402 V(JSDate) \
403 V(JSError) \
404 V(JSFunction) \
405 V(JSGeneratorObject) \
406 V(JSGlobalObject) \
407 V(JSGlobalProxy) \
408 V(JSMap) \
409 V(JSMapIterator) \
410 V(JSMessageObject) \
411 V(JSModuleNamespace) \
412 V(JSObject) \
413 V(JSPromise) \
414 V(JSProxy) \
415 V(JSReceiver) \
416 V(JSRegExp) \
417 V(JSRegExpResult) \
418 V(JSRegExpStringIterator) \
419 V(JSSet) \
420 V(JSSetIterator) \
421 V(JSSloppyArgumentsObject) \
422 V(JSStringIterator) \
423 V(JSTypedArray) \
424 V(JSValue) \
425 V(JSWeakRef) \
426 V(JSWeakCollection) \
427 V(JSFinalizationGroup) \
428 V(JSFinalizationGroupCleanupIterator) \
429 V(JSWeakMap) \
430 V(JSWeakSet) \
431 V(LoadHandler) \
432 V(Map) \
433 V(MapCache) \
434 V(Microtask) \
435 V(ModuleInfo) \
436 V(MutableHeapNumber) \
437 V(Name) \
438 V(NameDictionary) \
439 V(NativeContext) \
440 V(NormalizedMapCache) \
441 V(NumberDictionary) \
442 V(NumberWrapper) \
443 V(ObjectHashSet) \
444 V(ObjectHashTable) \
445 V(Oddball) \
446 V(OrderedHashMap) \
447 V(OrderedHashSet) \
448 V(OrderedNameDictionary) \
449 V(PreparseData) \
450 V(PromiseReactionJobTask) \
451 V(PropertyArray) \
452 V(PropertyCell) \
453 V(PropertyDescriptorObject) \
454 V(RegExpMatchInfo) \
455 V(ScopeInfo) \
456 V(ScriptContextTable) \
457 V(ScriptWrapper) \
458 V(SeqOneByteString) \
459 V(SeqString) \
460 V(SeqTwoByteString) \
461 V(SharedFunctionInfo) \
462 V(SimpleNumberDictionary) \
463 V(SlicedString) \
464 V(SloppyArgumentsElements) \
465 V(SmallOrderedHashMap) \
466 V(SmallOrderedHashSet) \
467 V(SmallOrderedNameDictionary) \
468 V(SourcePositionTableWithFrameCache) \
469 V(StoreHandler) \
470 V(String) \
471 V(StringSet) \
472 V(StringTable) \
473 V(StringWrapper) \
474 V(Struct) \
475 V(Symbol) \
476 V(SymbolWrapper) \
477 V(TemplateInfo) \
478 V(TemplateList) \
479 V(TemplateObjectDescription) \
480 V(ThinString) \
481 V(TransitionArray) \
482 V(UncompiledData) \
483 V(UncompiledDataWithPreparseData) \
484 V(UncompiledDataWithoutPreparseData) \
485 V(Undetectable) \
486 V(UniqueName) \
487 V(WasmExceptionObject) \
488 V(WasmGlobalObject) \
489 V(WasmInstanceObject) \
490 V(WasmMemoryObject) \
491 V(WasmModuleObject) \
492 V(WasmTableObject) \
493 V(WeakFixedArray) \
494 V(WeakArrayList) \
495 V(WeakCell)
496
497#ifdef V8_INTL_SUPPORT
498#define HEAP_OBJECT_ORDINARY_TYPE_LIST(V) \
499 HEAP_OBJECT_ORDINARY_TYPE_LIST_BASE(V) \
500 V(JSV8BreakIterator) \
501 V(JSCollator) \
502 V(JSDateTimeFormat) \
503 V(JSListFormat) \
504 V(JSLocale) \
505 V(JSNumberFormat) \
506 V(JSPluralRules) \
507 V(JSRelativeTimeFormat) \
508 V(JSSegmentIterator) \
509 V(JSSegmenter)
510#else
511#define HEAP_OBJECT_ORDINARY_TYPE_LIST(V) HEAP_OBJECT_ORDINARY_TYPE_LIST_BASE(V)
512#endif // V8_INTL_SUPPORT
513
514#define HEAP_OBJECT_TEMPLATE_TYPE_LIST(V) \
515 V(Dictionary) \
516 V(HashTable)
517
518#define HEAP_OBJECT_TYPE_LIST(V) \
519 HEAP_OBJECT_ORDINARY_TYPE_LIST(V) \
520 HEAP_OBJECT_TEMPLATE_TYPE_LIST(V)
521
522#define ODDBALL_LIST(V) \
523 V(Undefined, undefined_value) \
524 V(Null, null_value) \
525 V(TheHole, the_hole_value) \
526 V(Exception, exception) \
527 V(Uninitialized, uninitialized_value) \
528 V(True, true_value) \
529 V(False, false_value) \
530 V(ArgumentsMarker, arguments_marker) \
531 V(OptimizedOut, optimized_out) \
532 V(StaleRegister, stale_register)
533
534// The element types selection for CreateListFromArrayLike.
535enum class ElementTypes { kAll, kStringAndSymbol };
536
537// TODO(mythria): Move this to a better place.
538ShouldThrow GetShouldThrow(Isolate* isolate, Maybe<ShouldThrow> should_throw);
539
540// Object is the abstract superclass for all classes in the
541// object hierarchy.
542// Object does not use any virtual functions to avoid the
543// allocation of the C++ vtable.
544// There must only be a single data member in Object: the Address ptr,
545// containing the tagged heap pointer that this Object instance refers to.
546// For a design overview, see https://goo.gl/Ph4CGz.
547class Object {
548 public:
549 constexpr Object() : ptr_(kNullAddress) {}
550 explicit constexpr Object(Address ptr) : ptr_(ptr) {}
551
552 // Make clang on Linux catch what MSVC complains about on Windows:
553 operator bool() const = delete;
554
555 bool operator==(const Object that) const { return this->ptr() == that.ptr(); }
556 bool operator!=(const Object that) const { return this->ptr() != that.ptr(); }
557 // Usage in std::set requires operator<.
558 bool operator<(const Object that) const { return this->ptr() < that.ptr(); }
559
560 // Returns the tagged "(heap) object pointer" representation of this object.
561 constexpr Address ptr() const { return ptr_; }
562
563 // These operator->() overloads are required for handlified code.
564 Object* operator->() { return this; }
565 const Object* operator->() const { return this; }
566
567 // Type testing.
568 bool IsObject() const { return true; }
569
570#define IS_TYPE_FUNCTION_DECL(Type) V8_INLINE bool Is##Type() const;
571 OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
572 HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
573#undef IS_TYPE_FUNCTION_DECL
574
575// Oddball checks are faster when they are raw pointer comparisons, so the
576// isolate/read-only roots overloads should be preferred where possible.
577#define IS_TYPE_FUNCTION_DECL(Type, Value) \
578 V8_INLINE bool Is##Type(Isolate* isolate) const; \
579 V8_INLINE bool Is##Type(ReadOnlyRoots roots) const; \
580 V8_INLINE bool Is##Type() const;
581 ODDBALL_LIST(IS_TYPE_FUNCTION_DECL)
582#undef IS_TYPE_FUNCTION_DECL
583
584 V8_INLINE bool IsNullOrUndefined(Isolate* isolate) const;
585 V8_INLINE bool IsNullOrUndefined(ReadOnlyRoots roots) const;
586 V8_INLINE bool IsNullOrUndefined() const;
587
588 enum class Conversion { kToNumber, kToNumeric };
589
590#define RETURN_FAILURE(isolate, should_throw, call) \
591 do { \
592 if ((should_throw) == kDontThrow) { \
593 return Just(false); \
594 } else { \
595 isolate->Throw(*isolate->factory()->call); \
596 return Nothing<bool>(); \
597 } \
598 } while (false)
599
600#define MAYBE_RETURN(call, value) \
601 do { \
602 if ((call).IsNothing()) return value; \
603 } while (false)
604
605#define MAYBE_RETURN_NULL(call) MAYBE_RETURN(call, MaybeHandle<Object>())
606
607#define MAYBE_ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, dst, call) \
608 do { \
609 Isolate* __isolate__ = (isolate); \
610 if (!(call).To(&dst)) { \
611 DCHECK(__isolate__->has_pending_exception()); \
612 return ReadOnlyRoots(__isolate__).exception(); \
613 } \
614 } while (false)
615
616#define DECL_STRUCT_PREDICATE(NAME, Name, name) V8_INLINE bool Is##Name() const;
617 STRUCT_LIST(DECL_STRUCT_PREDICATE)
618#undef DECL_STRUCT_PREDICATE
619
620 // ES6, #sec-isarray. NOT to be confused with %_IsArray.
621 V8_INLINE
622 V8_WARN_UNUSED_RESULT static Maybe<bool> IsArray(Handle<Object> object);
623
624 V8_INLINE bool IsHashTableBase() const;
625 V8_INLINE bool IsSmallOrderedHashTable() const;
626
627 // Extract the number.
628 inline double Number() const;
629 V8_INLINE bool IsNaN() const;
630 V8_INLINE bool IsMinusZero() const;
631 V8_EXPORT_PRIVATE bool ToInt32(int32_t* value);
632 inline bool ToUint32(uint32_t* value) const;
633
634 inline Representation OptimalRepresentation();
635
636 inline ElementsKind OptimalElementsKind();
637
638 inline bool FitsRepresentation(Representation representation);
639
640 inline bool FilterKey(PropertyFilter filter);
641
642 Handle<FieldType> OptimalType(Isolate* isolate,
643 Representation representation);
644
645 V8_EXPORT_PRIVATE static Handle<Object> NewStorageFor(
646 Isolate* isolate, Handle<Object> object, Representation representation);
647
648 static Handle<Object> WrapForRead(Isolate* isolate, Handle<Object> object,
649 Representation representation);
650
651 // Returns true if the object is of the correct type to be used as a
652 // implementation of a JSObject's elements.
653 inline bool HasValidElements();
654
655 // ECMA-262 9.2.
656 V8_EXPORT_PRIVATE bool BooleanValue(Isolate* isolate);
657 Object ToBoolean(Isolate* isolate);
658
659 // ES6 section 7.2.11 Abstract Relational Comparison
660 V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<ComparisonResult>
661 Compare(Isolate* isolate, Handle<Object> x, Handle<Object> y);
662
663 // ES6 section 7.2.12 Abstract Equality Comparison
664 V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<bool> Equals(
665 Isolate* isolate, Handle<Object> x, Handle<Object> y);
666
667 // ES6 section 7.2.13 Strict Equality Comparison
668 V8_EXPORT_PRIVATE bool StrictEquals(Object that);
669
670 // ES6 section 7.1.13 ToObject
671 // Convert to a JSObject if needed.
672 // native_context is used when creating wrapper object.
673 //
674 // Passing a non-null method_name allows us to give a more informative
675 // error message for those cases where ToObject is being called on
676 // the receiver of a built-in method.
677 V8_WARN_UNUSED_RESULT static inline MaybeHandle<JSReceiver> ToObject(
678 Isolate* isolate, Handle<Object> object,
679 const char* method_name = nullptr);
680 V8_WARN_UNUSED_RESULT static MaybeHandle<JSReceiver> ToObjectImpl(
681 Isolate* isolate, Handle<Object> object,
682 const char* method_name = nullptr);
683
684 // ES6 section 9.2.1.2, OrdinaryCallBindThis for sloppy callee.
685 V8_WARN_UNUSED_RESULT static MaybeHandle<JSReceiver> ConvertReceiver(
686 Isolate* isolate, Handle<Object> object);
687
688 // ES6 section 7.1.14 ToPropertyKey
689 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Name> ToName(
690 Isolate* isolate, Handle<Object> input);
691
692 // ES6 section 7.1.1 ToPrimitive
693 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> ToPrimitive(
694 Handle<Object> input, ToPrimitiveHint hint = ToPrimitiveHint::kDefault);
695
696 // ES6 section 7.1.3 ToNumber
697 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> ToNumber(
698 Isolate* isolate, Handle<Object> input);
699
700 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> ToNumeric(
701 Isolate* isolate, Handle<Object> input);
702
703 // ES6 section 7.1.4 ToInteger
704 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> ToInteger(
705 Isolate* isolate, Handle<Object> input);
706
707 // ES6 section 7.1.5 ToInt32
708 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> ToInt32(
709 Isolate* isolate, Handle<Object> input);
710
711 // ES6 section 7.1.6 ToUint32
712 V8_WARN_UNUSED_RESULT inline static MaybeHandle<Object> ToUint32(
713 Isolate* isolate, Handle<Object> input);
714
715 // ES6 section 7.1.12 ToString
716 V8_WARN_UNUSED_RESULT static inline MaybeHandle<String> ToString(
717 Isolate* isolate, Handle<Object> input);
718
719 V8_EXPORT_PRIVATE static Handle<String> NoSideEffectsToString(
720 Isolate* isolate, Handle<Object> input);
721
722 // ES6 section 7.1.14 ToPropertyKey
723 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> ToPropertyKey(
724 Isolate* isolate, Handle<Object> value);
725
726 // ES6 section 7.1.15 ToLength
727 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> ToLength(
728 Isolate* isolate, Handle<Object> input);
729
730 // ES6 section 7.1.17 ToIndex
731 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> ToIndex(
732 Isolate* isolate, Handle<Object> input, MessageTemplate error_index);
733
734 // ES6 section 7.3.9 GetMethod
735 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> GetMethod(
736 Handle<JSReceiver> receiver, Handle<Name> name);
737
738 // ES6 section 7.3.17 CreateListFromArrayLike
739 V8_WARN_UNUSED_RESULT static MaybeHandle<FixedArray> CreateListFromArrayLike(
740 Isolate* isolate, Handle<Object> object, ElementTypes element_types);
741
742 // Get length property and apply ToLength.
743 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> GetLengthFromArrayLike(
744 Isolate* isolate, Handle<JSReceiver> object);
745
746 // ES6 section 12.5.6 The typeof Operator
747 static Handle<String> TypeOf(Isolate* isolate, Handle<Object> object);
748
749 // ES6 section 12.7 Additive Operators
750 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> Add(Isolate* isolate,
751 Handle<Object> lhs,
752 Handle<Object> rhs);
753
754 // ES6 section 12.9 Relational Operators
755 V8_WARN_UNUSED_RESULT static inline Maybe<bool> GreaterThan(Isolate* isolate,
756 Handle<Object> x,
757 Handle<Object> y);
758 V8_WARN_UNUSED_RESULT static inline Maybe<bool> GreaterThanOrEqual(
759 Isolate* isolate, Handle<Object> x, Handle<Object> y);
760 V8_WARN_UNUSED_RESULT static inline Maybe<bool> LessThan(Isolate* isolate,
761 Handle<Object> x,
762 Handle<Object> y);
763 V8_WARN_UNUSED_RESULT static inline Maybe<bool> LessThanOrEqual(
764 Isolate* isolate, Handle<Object> x, Handle<Object> y);
765
766 // ES6 section 7.3.19 OrdinaryHasInstance (C, O).
767 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> OrdinaryHasInstance(
768 Isolate* isolate, Handle<Object> callable, Handle<Object> object);
769
770 // ES6 section 12.10.4 Runtime Semantics: InstanceofOperator(O, C)
771 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> InstanceOf(
772 Isolate* isolate, Handle<Object> object, Handle<Object> callable);
773
774 V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static MaybeHandle<Object>
775 GetProperty(LookupIterator* it,
776 OnNonExistent on_non_existent = OnNonExistent::kReturnUndefined);
777
778 // ES6 [[Set]] (when passed kDontThrow)
779 // Invariants for this and related functions (unless stated otherwise):
780 // 1) When the result is Nothing, an exception is pending.
781 // 2) When passed kThrowOnError, the result is never Just(false).
782 // In some cases, an exception is thrown regardless of the ShouldThrow
783 // argument. These cases are either in accordance with the spec or not
784 // covered by it (eg., concerning API callbacks).
785 V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<bool> SetProperty(
786 LookupIterator* it, Handle<Object> value, StoreOrigin store_origin,
787 Maybe<ShouldThrow> should_throw = Nothing<ShouldThrow>());
788 V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static MaybeHandle<Object>
789 SetProperty(Isolate* isolate, Handle<Object> object, Handle<Name> name,
790 Handle<Object> value,
791 StoreOrigin store_origin = StoreOrigin::kMaybeKeyed,
792 Maybe<ShouldThrow> should_throw = Nothing<ShouldThrow>());
793 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> SetPropertyOrElement(
794 Isolate* isolate, Handle<Object> object, Handle<Name> name,
795 Handle<Object> value,
796 Maybe<ShouldThrow> should_throw = Nothing<ShouldThrow>(),
797 StoreOrigin store_origin = StoreOrigin::kMaybeKeyed);
798
799 V8_WARN_UNUSED_RESULT static Maybe<bool> SetSuperProperty(
800 LookupIterator* it, Handle<Object> value, StoreOrigin store_origin,
801 Maybe<ShouldThrow> should_throw = Nothing<ShouldThrow>());
802
803 V8_WARN_UNUSED_RESULT static Maybe<bool> CannotCreateProperty(
804 Isolate* isolate, Handle<Object> receiver, Handle<Object> name,
805 Handle<Object> value, Maybe<ShouldThrow> should_throw);
806 V8_WARN_UNUSED_RESULT static Maybe<bool> WriteToReadOnlyProperty(
807 LookupIterator* it, Handle<Object> value,
808 Maybe<ShouldThrow> should_throw);
809 V8_WARN_UNUSED_RESULT static Maybe<bool> WriteToReadOnlyProperty(
810 Isolate* isolate, Handle<Object> receiver, Handle<Object> name,
811 Handle<Object> value, ShouldThrow should_throw);
812 V8_WARN_UNUSED_RESULT static Maybe<bool> RedefineIncompatibleProperty(
813 Isolate* isolate, Handle<Object> name, Handle<Object> value,
814 Maybe<ShouldThrow> should_throw);
815 V8_WARN_UNUSED_RESULT static Maybe<bool> SetDataProperty(
816 LookupIterator* it, Handle<Object> value);
817 V8_WARN_UNUSED_RESULT static Maybe<bool> AddDataProperty(
818 LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
819 Maybe<ShouldThrow> should_throw, StoreOrigin store_origin);
820 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> GetPropertyOrElement(
821 Isolate* isolate, Handle<Object> object, Handle<Name> name);
822 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> GetPropertyOrElement(
823 Handle<Object> receiver, Handle<Name> name, Handle<JSReceiver> holder);
824 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> GetProperty(
825 Isolate* isolate, Handle<Object> object, Handle<Name> name);
826
827 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> GetPropertyWithAccessor(
828 LookupIterator* it);
829 V8_WARN_UNUSED_RESULT static Maybe<bool> SetPropertyWithAccessor(
830 LookupIterator* it, Handle<Object> value,
831 Maybe<ShouldThrow> should_throw);
832
833 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> GetPropertyWithDefinedGetter(
834 Handle<Object> receiver, Handle<JSReceiver> getter);
835 V8_WARN_UNUSED_RESULT static Maybe<bool> SetPropertyWithDefinedSetter(
836 Handle<Object> receiver, Handle<JSReceiver> setter, Handle<Object> value,
837 Maybe<ShouldThrow> should_throw);
838
839 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> GetElement(
840 Isolate* isolate, Handle<Object> object, uint32_t index);
841
842 V8_WARN_UNUSED_RESULT static inline MaybeHandle<Object> SetElement(
843 Isolate* isolate, Handle<Object> object, uint32_t index,
844 Handle<Object> value, ShouldThrow should_throw);
845
846 // Returns the permanent hash code associated with this object. May return
847 // undefined if not yet created.
848 inline Object GetHash();
849
850 // Returns the permanent hash code associated with this object depending on
851 // the actual object type. May create and store a hash code if needed and none
852 // exists.
853 V8_EXPORT_PRIVATE Smi GetOrCreateHash(Isolate* isolate);
854
855 // Checks whether this object has the same value as the given one. This
856 // function is implemented according to ES5, section 9.12 and can be used
857 // to implement the Object.is function.
858 V8_EXPORT_PRIVATE bool SameValue(Object other);
859
860 // A part of SameValue which handles Number vs. Number case.
861 // Treats NaN == NaN and +0 != -0.
862 inline static bool SameNumberValue(double number1, double number2);
863
864 // Checks whether this object has the same value as the given one.
865 // +0 and -0 are treated equal. Everything else is the same as SameValue.
866 // This function is implemented according to ES6, section 7.2.4 and is used
867 // by ES6 Map and Set.
868 bool SameValueZero(Object other);
869
870 // ES6 section 9.4.2.3 ArraySpeciesCreate (part of it)
871 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> ArraySpeciesConstructor(
872 Isolate* isolate, Handle<Object> original_array);
873
874 // ES6 section 7.3.20 SpeciesConstructor ( O, defaultConstructor )
875 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> SpeciesConstructor(
876 Isolate* isolate, Handle<JSReceiver> recv,
877 Handle<JSFunction> default_ctor);
878
879 // Tries to convert an object to an array length. Returns true and sets the
880 // output parameter if it succeeds.
881 inline bool ToArrayLength(uint32_t* index) const;
882
883 // Tries to convert an object to an array index. Returns true and sets the
884 // output parameter if it succeeds. Equivalent to ToArrayLength, but does not
885 // allow kMaxUInt32.
886 V8_WARN_UNUSED_RESULT inline bool ToArrayIndex(uint32_t* index) const;
887
888 // Returns true if the result of iterating over the object is the same
889 // (including observable effects) as simply accessing the properties between 0
890 // and length.
891 bool IterationHasObservableEffects();
892
893 //
894 // The following GetHeapObjectXX methods mimic corresponding functionality
895 // in MaybeObject. Having them here allows us to unify code that processes
896 // ObjectSlots and MaybeObjectSlots.
897 //
898
899 // If this Object is a strong pointer to a HeapObject, returns true and
900 // sets *result. Otherwise returns false.
901 inline bool GetHeapObjectIfStrong(HeapObject* result) const;
902
903 // If this Object is a strong pointer to a HeapObject (weak pointers are not
904 // expected), returns true and sets *result. Otherwise returns false.
905 inline bool GetHeapObject(HeapObject* result) const;
906
907 // DCHECKs that this Object is a strong pointer to a HeapObject and returns
908 // the HeapObject.
909 inline HeapObject GetHeapObject() const;
910
911 // Always returns false because Object is not expected to be a weak pointer
912 // to a HeapObject.
913 inline bool GetHeapObjectIfWeak(HeapObject* result) const {
914 DCHECK(!HasWeakHeapObjectTag(ptr()));
915 return false;
916 }
917 // Always returns false because Object is not expected to be a weak pointer
918 // to a HeapObject.
919 inline bool IsCleared() const { return false; }
920
921 EXPORT_DECL_VERIFIER(Object)
922
923#ifdef VERIFY_HEAP
924 // Verify a pointer is a valid object pointer.
925 static void VerifyPointer(Isolate* isolate, Object p);
926#endif
927
928 inline void VerifyApiCallResultType();
929
930 // Prints this object without details.
931 V8_EXPORT_PRIVATE void ShortPrint(FILE* out = stdout) const;
932
933 // Prints this object without details to a message accumulator.
934 V8_EXPORT_PRIVATE void ShortPrint(StringStream* accumulator) const;
935
936 V8_EXPORT_PRIVATE void ShortPrint(std::ostream& os) const; // NOLINT
937
938 inline static Object cast(Object object) { return object; }
939 inline static Object unchecked_cast(Object object) { return object; }
940
941 // Layout description.
942 static const int kHeaderSize = 0; // Object does not take up any space.
943
944#ifdef OBJECT_PRINT
945 // For our gdb macros, we should perhaps change these in the future.
946 V8_EXPORT_PRIVATE void Print() const;
947
948 // Prints this object with details.
949 V8_EXPORT_PRIVATE void Print(std::ostream& os) const; // NOLINT
950#else
951 void Print() const { ShortPrint(); }
952 void Print(std::ostream& os) const { ShortPrint(os); } // NOLINT
953#endif
954
955 // For use with std::unordered_set.
956 struct Hasher {
957 size_t operator()(const Object o) const {
958 return std::hash<v8::internal::Address>{}(o.ptr());
959 }
960 };
961
962 // For use with std::map.
963 struct Comparer {
964 bool operator()(const Object a, const Object b) const {
965 return a.ptr() < b.ptr();
966 }
967 };
968
969 private:
970 friend class CompressedObjectSlot;
971 friend class FullObjectSlot;
972 friend class LookupIterator;
973 friend class StringStream;
974
975 // Return the map of the root of object's prototype chain.
976 Map GetPrototypeChainRootMap(Isolate* isolate) const;
977
978 // Returns a non-SMI for JSReceivers, but returns the hash code for
979 // simple objects. This avoids a double lookup in the cases where
980 // we know we will add the hash to the JSReceiver if it does not
981 // already exist.
982 //
983 // Despite its size, this needs to be inlined for performance
984 // reasons.
985 static inline Object GetSimpleHash(Object object);
986
987 // Helper for SetProperty and SetSuperProperty.
988 // Return value is only meaningful if [found] is set to true on return.
989 V8_WARN_UNUSED_RESULT static Maybe<bool> SetPropertyInternal(
990 LookupIterator* it, Handle<Object> value, Maybe<ShouldThrow> should_throw,
991 StoreOrigin store_origin, bool* found);
992
993 V8_WARN_UNUSED_RESULT static MaybeHandle<Name> ConvertToName(
994 Isolate* isolate, Handle<Object> input);
995 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> ConvertToPropertyKey(
996 Isolate* isolate, Handle<Object> value);
997 V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static MaybeHandle<String>
998 ConvertToString(Isolate* isolate, Handle<Object> input);
999 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> ConvertToNumberOrNumeric(
1000 Isolate* isolate, Handle<Object> input, Conversion mode);
1001 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> ConvertToInteger(
1002 Isolate* isolate, Handle<Object> input);
1003 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> ConvertToInt32(
1004 Isolate* isolate, Handle<Object> input);
1005 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> ConvertToUint32(
1006 Isolate* isolate, Handle<Object> input);
1007 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> ConvertToLength(
1008 Isolate* isolate, Handle<Object> input);
1009 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> ConvertToIndex(
1010 Isolate* isolate, Handle<Object> input, MessageTemplate error_index);
1011
1012 Address ptr_;
1013};
1014
1015V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, const Object& obj);
1016
1017// In objects.h to be usable without objects-inl.h inclusion.
1018bool Object::IsSmi() const { return HAS_SMI_TAG(ptr()); }
1019bool Object::IsHeapObject() const {
1020 DCHECK_EQ(!IsSmi(), Internals::HasHeapObjectTag(ptr()));
1021 return !IsSmi();
1022}
1023
1024struct Brief {
1025 V8_EXPORT_PRIVATE explicit Brief(const Object v);
1026 explicit Brief(const MaybeObject v);
1027 // {value} is a tagged heap object reference (weak or strong), equivalent to
1028 // a MaybeObject's payload. It has a plain Address type to keep #includes
1029 // lightweight.
1030 const Address value;
1031};
1032
1033V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, const Brief& v);
1034
1035// Objects should never have the weak tag; this variant is for overzealous
1036// checking.
1037V8_INLINE static bool HasWeakHeapObjectTag(const Object value) {
1038 return ((value->ptr() & kHeapObjectTagMask) == kWeakHeapObjectTag);
1039}
1040
1041// Heap objects typically have a map pointer in their first word. However,
1042// during GC other data (e.g. mark bits, forwarding addresses) is sometimes
1043// encoded in the first word. The class MapWord is an abstraction of the
1044// value in a heap object's first word.
1045class MapWord {
1046 public:
1047 // Normal state: the map word contains a map pointer.
1048
1049 // Create a map word from a map pointer.
1050 static inline MapWord FromMap(const Map map);
1051
1052 // View this map word as a map pointer.
1053 inline Map ToMap() const;
1054
1055 // Scavenge collection: the map word of live objects in the from space
1056 // contains a forwarding address (a heap object pointer in the to space).
1057
1058 // True if this map word is a forwarding address for a scavenge
1059 // collection. Only valid during a scavenge collection (specifically,
1060 // when all map words are heap object pointers, i.e. not during a full GC).
1061 inline bool IsForwardingAddress() const;
1062
1063 // Create a map word from a forwarding address.
1064 static inline MapWord FromForwardingAddress(HeapObject object);
1065
1066 // View this map word as a forwarding address.
1067 inline HeapObject ToForwardingAddress();
1068
1069 static inline MapWord FromRawValue(uintptr_t value) {
1070 return MapWord(value);
1071 }
1072
1073 inline uintptr_t ToRawValue() {
1074 return value_;
1075 }
1076
1077 private:
1078 // HeapObject calls the private constructor and directly reads the value.
1079 friend class HeapObject;
1080
1081 explicit MapWord(Address value) : value_(value) {}
1082
1083 Address value_;
1084};
1085
1086template <int start_offset, int end_offset, int size>
1087class FixedBodyDescriptor;
1088
1089template <int start_offset>
1090class FlexibleBodyDescriptor;
1091
1092template <int start_offset>
1093class FlexibleWeakBodyDescriptor;
1094
1095template <class ParentBodyDescriptor, class ChildBodyDescriptor>
1096class SubclassBodyDescriptor;
1097
1098enum EnsureElementsMode {
1099 DONT_ALLOW_DOUBLE_ELEMENTS,
1100 ALLOW_COPIED_DOUBLE_ELEMENTS,
1101 ALLOW_CONVERTED_DOUBLE_ELEMENTS
1102};
1103
1104
1105// Indicator for one component of an AccessorPair.
1106enum AccessorComponent {
1107 ACCESSOR_GETTER,
1108 ACCESSOR_SETTER
1109};
1110
1111enum class GetKeysConversion {
1112 kKeepNumbers = static_cast<int>(v8::KeyConversionMode::kKeepNumbers),
1113 kConvertToString = static_cast<int>(v8::KeyConversionMode::kConvertToString)
1114};
1115
1116enum class KeyCollectionMode {
1117 kOwnOnly = static_cast<int>(v8::KeyCollectionMode::kOwnOnly),
1118 kIncludePrototypes =
1119 static_cast<int>(v8::KeyCollectionMode::kIncludePrototypes)
1120};
1121
1122// Utility superclass for stack-allocated objects that must be updated
1123// on gc. It provides two ways for the gc to update instances, either
1124// iterating or updating after gc.
1125class Relocatable {
1126 public:
1127 explicit inline Relocatable(Isolate* isolate);
1128 inline virtual ~Relocatable();
1129 virtual void IterateInstance(RootVisitor* v) {}
1130 virtual void PostGarbageCollection() { }
1131
1132 static void PostGarbageCollectionProcessing(Isolate* isolate);
1133 static int ArchiveSpacePerThread();
1134 static char* ArchiveState(Isolate* isolate, char* to);
1135 static char* RestoreState(Isolate* isolate, char* from);
1136 static void Iterate(Isolate* isolate, RootVisitor* v);
1137 static void Iterate(RootVisitor* v, Relocatable* top);
1138 static char* Iterate(RootVisitor* v, char* t);
1139
1140 private:
1141 Isolate* isolate_;
1142 Relocatable* prev_;
1143};
1144
1145// BooleanBit is a helper class for setting and getting a bit in an integer.
1146class BooleanBit : public AllStatic {
1147 public:
1148 static inline bool get(int value, int bit_position) {
1149 return (value & (1 << bit_position)) != 0;
1150 }
1151
1152 static inline int set(int value, int bit_position, bool v) {
1153 if (v) {
1154 value |= (1 << bit_position);
1155 } else {
1156 value &= ~(1 << bit_position);
1157 }
1158 return value;
1159 }
1160};
1161
1162
1163} // NOLINT, false-positive due to second-order macros.
1164} // NOLINT, false-positive due to second-order macros.
1165
1166#include "src/objects/object-macros-undef.h"
1167
1168#endif // V8_OBJECTS_H_
1169