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 | |
183 | namespace v8 { |
184 | namespace internal { |
185 | |
186 | struct InliningPosition; |
187 | class 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. |
193 | enum 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. |
202 | enum 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. |
209 | enum 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. |
218 | enum 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. |
226 | enum DescriptorFlag { |
227 | ALL_DESCRIPTORS, |
228 | OWN_DESCRIPTORS |
229 | }; |
230 | |
231 | // Instance size sentinel for objects of variable size. |
232 | const int kVariableSizeSentinel = 0; |
233 | |
234 | // We may store the unsigned bit field as signed Smi value and do not |
235 | // use the sign bit. |
236 | const int kStubMajorKeyBits = 8; |
237 | const 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. |
241 | enum 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.) |
249 | bool ComparisonResultToBool(Operation op, ComparisonResult result); |
250 | |
251 | enum class OnNonExistent { kThrowReferenceError, kReturnUndefined }; |
252 | |
253 | class AbstractCode; |
254 | class AccessorPair; |
255 | class AccessCheckInfo; |
256 | class AllocationSite; |
257 | class ByteArray; |
258 | class CachedTemplateObject; |
259 | class Cell; |
260 | class ClosureFeedbackCellArray; |
261 | class ConsString; |
262 | class DependentCode; |
263 | class ElementsAccessor; |
264 | class EnumCache; |
265 | class FixedArrayBase; |
266 | class FixedDoubleArray; |
267 | class FreeSpace; |
268 | class FunctionLiteral; |
269 | class FunctionTemplateInfo; |
270 | class JSAsyncGeneratorObject; |
271 | class JSGlobalProxy; |
272 | class JSPromise; |
273 | class JSProxy; |
274 | class JSProxyRevocableResult; |
275 | class KeyAccumulator; |
276 | class LayoutDescriptor; |
277 | class LookupIterator; |
278 | class FieldType; |
279 | class Module; |
280 | class ModuleInfoEntry; |
281 | class MutableHeapNumber; |
282 | class ObjectHashTable; |
283 | class ObjectTemplateInfo; |
284 | class ObjectVisitor; |
285 | class PreparseData; |
286 | class PropertyArray; |
287 | class PropertyCell; |
288 | class PropertyDescriptor; |
289 | class PrototypeInfo; |
290 | class ReadOnlyRoots; |
291 | class RegExpMatchInfo; |
292 | class RootVisitor; |
293 | class SafepointEntry; |
294 | class ScriptContextTable; |
295 | class SharedFunctionInfo; |
296 | class StringStream; |
297 | class Symbol; |
298 | class FeedbackCell; |
299 | class FeedbackMetadata; |
300 | class FeedbackVector; |
301 | class UncompiledData; |
302 | class TemplateInfo; |
303 | class TransitionArray; |
304 | class TemplateList; |
305 | class WasmInstanceObject; |
306 | class WasmMemoryObject; |
307 | template <typename T> |
308 | class 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. |
535 | enum class ElementTypes { kAll, kStringAndSymbol }; |
536 | |
537 | // TODO(mythria): Move this to a better place. |
538 | ShouldThrow 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. |
547 | class 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 (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 = 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 | |
1015 | V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, const Object& obj); |
1016 | |
1017 | // In objects.h to be usable without objects-inl.h inclusion. |
1018 | bool Object::IsSmi() const { return HAS_SMI_TAG(ptr()); } |
1019 | bool Object::IsHeapObject() const { |
1020 | DCHECK_EQ(!IsSmi(), Internals::HasHeapObjectTag(ptr())); |
1021 | return !IsSmi(); |
1022 | } |
1023 | |
1024 | struct 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 | |
1033 | V8_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. |
1037 | V8_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. |
1045 | class 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 | |
1086 | template <int start_offset, int end_offset, int size> |
1087 | class FixedBodyDescriptor; |
1088 | |
1089 | template <int start_offset> |
1090 | class FlexibleBodyDescriptor; |
1091 | |
1092 | template <int start_offset> |
1093 | class FlexibleWeakBodyDescriptor; |
1094 | |
1095 | template <class ParentBodyDescriptor, class ChildBodyDescriptor> |
1096 | class SubclassBodyDescriptor; |
1097 | |
1098 | enum 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. |
1106 | enum AccessorComponent { |
1107 | ACCESSOR_GETTER, |
1108 | ACCESSOR_SETTER |
1109 | }; |
1110 | |
1111 | enum class GetKeysConversion { |
1112 | kKeepNumbers = static_cast<int>(v8::KeyConversionMode::kKeepNumbers), |
1113 | kConvertToString = static_cast<int>(v8::KeyConversionMode::kConvertToString) |
1114 | }; |
1115 | |
1116 | enum 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. |
1125 | class 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. |
1146 | class 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 | |