this repo has no description
1/* Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) */
2// Object structures
3// -----------------
4//
5// This file describes the layout of built-in types on the managed heap. There
6// is one class for each type providing an abstraction over a simple pointer.
7// Each class provides constants for field offsets and a getter and setter
8// function for each field.
9//
10// There should be a public getter and setter for every field using RawObject
11// or word types. The code is meant to abstract over the layout, not to provide
12// abstract data types: Do not add further type or consistency checks and leave
13// that to higher levels.
14#pragma once
15
16#include <cstdio>
17#include <limits>
18
19#include "globals.h"
20#include "utils.h"
21#include "view.h"
22
23namespace py {
24
25class Byteslike;
26class Frame;
27template <typename T>
28class Handle;
29class Thread;
30
31// Python types that store their value directly in a RawObject.
32#define IMMEDIATE_CLASS_NAMES(V) \
33 V(SmallInt) \
34 V(SmallBytes) \
35 V(SmallStr) \
36 V(Bool) \
37 V(NotImplementedType) \
38 V(Unbound) \
39 V(NoneType)
40
41// Python types that hold a pointer to heap-allocated data in a RawObject.
42// Subclasses of `RawInstance` are listed separately in `INSTANCE_CLASS_NAMES`.
43#define HEAP_CLASS_NAMES(V) \
44 V(Bytes) \
45 V(Complex) \
46 V(Ellipsis) \
47 V(Float) \
48 V(Int) \
49 V(LargeBytes) \
50 V(LargeInt) \
51 V(LargeStr) \
52 V(MutableBytes) \
53 V(MutableTuple) \
54 V(Str) \
55 V(Tuple)
56
57#define INSTANCE_CLASS_NAMES(V) \
58 V(Array) \
59 V(AsyncGenerator) \
60 V(AsyncGeneratorAclose) \
61 V(AsyncGeneratorAsend) \
62 V(AsyncGeneratorAthrow) \
63 V(AsyncGeneratorOpIterBase) \
64 V(AsyncGeneratorWrappedValue) \
65 V(BoundMethod) \
66 V(BufferedRandom) \
67 V(BufferedReader) \
68 V(BufferedWriter) \
69 V(Bytearray) \
70 V(BytearrayIterator) \
71 V(BytesIO) \
72 V(BytesIterator) \
73 V(Cell) \
74 V(ClassMethod) \
75 V(Code) \
76 V(Context) \
77 V(ContextVar) \
78 V(Coroutine) \
79 V(CoroutineWrapper) \
80 V(Deque) \
81 V(DequeIterator) \
82 V(DequeReverseIterator) \
83 V(Dict) \
84 V(DictItemIterator) \
85 V(DictItems) \
86 V(DictKeyIterator) \
87 V(DictKeys) \
88 V(DictValueIterator) \
89 V(DictValues) \
90 V(Enumerate) \
91 V(ExceptionState) \
92 V(FileIO) \
93 V(FrameProxy) \
94 V(FrozenSet) \
95 V(Function) \
96 V(Generator) \
97 V(GeneratorFrame) \
98 V(IncrementalNewlineDecoder) \
99 V(InstanceMethod) \
100 V(InstanceProxy) \
101 V(Layout) \
102 V(List) \
103 V(ListIterator) \
104 V(LongRangeIterator) \
105 V(MappingProxy) \
106 V(MemoryView) \
107 V(Mmap) \
108 V(Module) \
109 V(ModuleProxy) \
110 V(Object) \
111 V(Pointer) \
112 V(Property) \
113 V(Range) \
114 V(RangeIterator) \
115 V(SeqIterator) \
116 V(Set) \
117 V(SetIterator) \
118 V(Slice) \
119 V(SlotDescriptor) \
120 V(StaticMethod) \
121 V(StrArray) \
122 V(StrIterator) \
123 V(StringIO) \
124 V(Super) \
125 V(TextIOWrapper) \
126 V(Token) \
127 V(Traceback) \
128 V(TupleIterator) \
129 V(Type) \
130 V(TypeProxy) \
131 V(UnderBufferedIOBase) \
132 V(UnderBufferedIOMixin) \
133 V(UnderIOBase) \
134 V(UnderRawIOBase) \
135 V(UnderTextIOBase) \
136 V(ValueCell) \
137 V(WeakCallableProxy) \
138 V(WeakProxy) \
139 V(WeakLink) \
140 V(WeakRef)
141
142// Heap-allocated Python types in the BaseException hierarchy.
143#define EXCEPTION_CLASS_NAMES(V) \
144 V(ArithmeticError) \
145 V(AssertionError) \
146 V(AttributeError) \
147 V(BaseException) \
148 V(BlockingIOError) \
149 V(BrokenPipeError) \
150 V(BufferError) \
151 V(BytesWarning) \
152 V(ChildProcessError) \
153 V(ConnectionAbortedError) \
154 V(ConnectionError) \
155 V(ConnectionRefusedError) \
156 V(ConnectionResetError) \
157 V(DeprecationWarning) \
158 V(EOFError) \
159 V(Exception) \
160 V(FileExistsError) \
161 V(FileNotFoundError) \
162 V(FloatingPointError) \
163 V(FutureWarning) \
164 V(GeneratorExit) \
165 V(ImportError) \
166 V(ImportWarning) \
167 V(IndentationError) \
168 V(IndexError) \
169 V(InterruptedError) \
170 V(IsADirectoryError) \
171 V(KeyboardInterrupt) \
172 V(KeyError) \
173 V(LookupError) \
174 V(MemoryError) \
175 V(ModuleNotFoundError) \
176 V(NameError) \
177 V(NotADirectoryError) \
178 V(NotImplementedError) \
179 V(OSError) \
180 V(OverflowError) \
181 V(PendingDeprecationWarning) \
182 V(PermissionError) \
183 V(ProcessLookupError) \
184 V(RecursionError) \
185 V(ReferenceError) \
186 V(ResourceWarning) \
187 V(RuntimeError) \
188 V(RuntimeWarning) \
189 V(StopAsyncIteration) \
190 V(StopIteration) \
191 V(SyntaxError) \
192 V(SyntaxWarning) \
193 V(SystemError) \
194 V(SystemExit) \
195 V(TabError) \
196 V(TimeoutError) \
197 V(TypeError) \
198 V(UnboundLocalError) \
199 V(UnicodeDecodeError) \
200 V(UnicodeEncodeError) \
201 V(UnicodeError) \
202 V(UnicodeTranslateError) \
203 V(UnicodeWarning) \
204 V(UserWarning) \
205 V(ValueError) \
206 V(Warning) \
207 V(ZeroDivisionError)
208
209#define CLASS_NAMES(V) \
210 IMMEDIATE_CLASS_NAMES(V) \
211 HEAP_CLASS_NAMES(V) \
212 INSTANCE_CLASS_NAMES(V) \
213 EXCEPTION_CLASS_NAMES(V)
214
215// This enumerates layout ids of intrinsic classes. Notably, the layout of an
216// instance of an intrinsic class does not change.
217//
218// An instance of an intrinsic class that has an immediate representation
219// cannot have attributes added. An instance of an intrinsic class that is heap
220// allocated has a predefined number in-object attributes in the base
221// instance. For some of those types, the language forbids adding new
222// attributes. For the types which are permitted to have attributes added,
223// these types must include a hidden attribute that indirects to attribute
224// storage.
225//
226// NB: If you add something here make sure you add it to the appropriate macro
227// above
228enum class LayoutId : word {
229 // Immediate objects - note that the SmallInt class is also aliased to all
230 // even integers less than 32, so that classes of immediate objects can be
231 // looked up simply by using the low 5 bits of the immediate value. This
232 // implies that all other immediate class ids must be odd.
233 kSmallInt = 0,
234 kSmallBytes = 5,
235 kBool = 7,
236 kSmallStr = 13,
237 kNotImplementedType = 15,
238 // There is no RawType associated with the RawError object type, this is here
239 // as a placeholder.
240 kError = 21,
241 kUnbound = 23,
242 // We have room for one more immediate object with LayoutId = 29
243 kNoneType = 31,
244
245// clang-format off
246 // Heap objects
247#define LAYOUT_ID(name) k##name,
248#define GET_FIRST(name) k##name + 0 *
249#define GET_LAST(name) 0 + k##name *
250 HEAP_CLASS_NAMES(LAYOUT_ID)
251 kLastNonInstance = HEAP_CLASS_NAMES(GET_LAST) 1,
252
253 INSTANCE_CLASS_NAMES(LAYOUT_ID)
254 EXCEPTION_CLASS_NAMES(LAYOUT_ID)
255
256 // Mark the first and last Exception LayoutIds, to allow range comparisons.
257 kFirstException = EXCEPTION_CLASS_NAMES(GET_FIRST) 0,
258 kLastException = EXCEPTION_CLASS_NAMES(GET_LAST) 1,
259#undef GET_FIRST
260#undef GET_LAST
261#undef LAYOUT_ID
262 // clang-format on
263
264 kLastBuiltinId = kLastException,
265 kSentinelId = kLastBuiltinId + 1,
266};
267
268// Add functionality common to all RawObject subclasses, split into two parts
269// since some types manually define cast() but want everything else.
270#define RAW_OBJECT_COMMON_NO_CAST(ty) \
271 /* TODO(T34683229): Once Handle<T> doesn't inherit from T, delete this. \
272 * Right now it exists to prevent implicit conversion of Handle<T> to T. */ \
273 template <typename T> \
274 Raw##ty(const Handle<T>&) = delete; \
275 DISALLOW_HEAP_ALLOCATION()
276
277#define RAW_OBJECT_COMMON(ty) \
278 static Raw##ty cast(RawObject object) { \
279 DCHECK(object.is##ty(), "invalid cast, expected " #ty); \
280 return object.rawCast<Raw##ty>(); \
281 } \
282 RAW_OBJECT_COMMON_NO_CAST(ty)
283
284const int kObjectAlignmentLog2 = 4; // bits
285const int kObjectAlignment = word{1} << kObjectAlignmentLog2;
286
287bool isInstanceLayout(LayoutId id);
288
289word roundAllocationSize(word size);
290
291class RawObject {
292 public:
293 explicit RawObject(uword raw);
294
295 // Getters and setters.
296 uword raw() const;
297 bool isObject() const;
298 bool isInternal() const;
299 LayoutId layoutId() const;
300
301 // Immediate objects
302 bool isBool() const;
303 bool isError() const;
304 bool isErrorError() const;
305 bool isErrorException() const;
306 bool isErrorNoMoreItems() const;
307 bool isErrorNotFound() const;
308 bool isErrorOutOfBounds() const;
309 bool isErrorOutOfMemory() const;
310 bool isHeader() const;
311 bool isImmediateObjectNotSmallInt() const;
312 bool isNoneType() const;
313 bool isNotImplementedType() const;
314 bool isSmallBytes() const;
315 bool isSmallInt() const;
316 bool isSmallStr() const;
317 bool isUnbound() const;
318
319 // Heap objects
320 bool isArray() const;
321 bool isAsyncGenerator() const;
322 bool isAsyncGeneratorAclose() const;
323 bool isAsyncGeneratorAsend() const;
324 bool isAsyncGeneratorAthrow() const;
325 bool isAsyncGeneratorOpIterBase() const;
326 bool isAsyncGeneratorWrappedValue() const;
327 bool isAttributeDict() const;
328 bool isBaseException() const;
329 bool isBoundMethod() const;
330 bool isBufferedRandom() const;
331 bool isBufferedReader() const;
332 bool isBufferedWriter() const;
333 bool isBytearray() const;
334 bool isBytearrayIterator() const;
335 bool isBytesIO() const;
336 bool isBytesIterator() const;
337 bool isCell() const;
338 bool isClassMethod() const;
339 bool isCode() const;
340 bool isComplex() const;
341 bool isContext() const;
342 bool isContextVar() const;
343 bool isCoroutine() const;
344 bool isCoroutineWrapper() const;
345 bool isDataArray() const;
346 bool isDeque() const;
347 bool isDequeIterator() const;
348 bool isDequeReverseIterator() const;
349 bool isDict() const;
350 bool isDictItemIterator() const;
351 bool isDictItems() const;
352 bool isDictKeyIterator() const;
353 bool isDictKeys() const;
354 bool isDictValueIterator() const;
355 bool isDictValues() const;
356 bool isEllipsis() const;
357 bool isEnumerate() const;
358 bool isException() const;
359 bool isExceptionState() const;
360 bool isFileIO() const;
361 bool isFloat() const;
362 bool isFrameProxy() const;
363 bool isFrozenSet() const;
364 bool isFunction() const;
365 bool isGenerator() const;
366 bool isGeneratorFrame() const;
367 bool isHeapObject() const;
368 bool isHeapObjectWithLayout(LayoutId layout_id) const;
369 bool isImportError() const;
370 bool isIncrementalNewlineDecoder() const;
371 bool isIndexError() const;
372 bool isInstance() const;
373 bool isInstanceMethod() const;
374 bool isInstanceProxy() const;
375 bool isKeyError() const;
376 bool isLargeBytes() const;
377 bool isLargeInt() const;
378 bool isLargeStr() const;
379 bool isLayout() const;
380 bool isList() const;
381 bool isListIterator() const;
382 bool isLongRangeIterator() const;
383 bool isLookupError() const;
384 bool isMappingProxy() const;
385 bool isMemoryView() const;
386 bool isMmap() const;
387 bool isModule() const;
388 bool isModuleNotFoundError() const;
389 bool isModuleProxy() const;
390 bool isMutableBytes() const;
391 bool isMutableTuple() const;
392 bool isNotImplementedError() const;
393 bool isPointer() const;
394 bool isProperty() const;
395 bool isRange() const;
396 bool isRangeIterator() const;
397 bool isRuntimeError() const;
398 bool isSeqIterator() const;
399 bool isSet() const;
400 bool isSetIterator() const;
401 bool isSlice() const;
402 bool isSlotDescriptor() const;
403 bool isStaticMethod() const;
404 bool isStopIteration() const;
405 bool isStrArray() const;
406 bool isStrIterator() const;
407 bool isStringIO() const;
408 bool isSuper() const;
409 bool isSyntaxError() const;
410 bool isSystemExit() const;
411 bool isTextIOWrapper() const;
412 bool isToken() const;
413 bool isTraceback() const;
414 bool isTuple() const;
415 bool isTupleIterator() const;
416 bool isType() const;
417 bool isTypeProxy() const;
418 bool isUnderBufferedIOBase() const;
419 bool isUnderBufferedIOMixin() const;
420 bool isUnderIOBase() const;
421 bool isUnderRawIOBase() const;
422 bool isUnicodeDecodeError() const;
423 bool isUnicodeEncodeError() const;
424 bool isUnicodeError() const;
425 bool isUnicodeErrorBase() const;
426 bool isUnicodeTranslateError() const;
427 bool isValueCell() const;
428 bool isWeakCallableProxy() const;
429 bool isWeakProxy() const;
430 bool isWeakLink() const;
431 bool isWeakRef() const;
432
433 // superclass objects
434 bool isBytes() const;
435 bool isGeneratorBase() const;
436 bool isInt() const;
437 bool isSetBase() const;
438 bool isStr() const;
439
440 bool operator==(const RawObject& other) const;
441 bool operator!=(const RawObject& other) const;
442
443 // Constants
444
445 // Tags.
446 static const uword kSmallIntTag = 0; // 0b****0
447 static const uword kHeapObjectTag = 1; // 0b**001
448 static const uword kHeaderTag = 3; // 0b**011
449 static const uword kSmallBytesTag = 5; // 0b00101
450 static const uword kSmallStrTag = 13; // 0b01101
451 static const uword kErrorTag = 21; // 0b10101
452 // 0b11101 is unused
453 static const uword kBoolTag = 7; // 0b00111
454 static const uword kNotImplementedTag = 15; // 0b01111
455 static const uword kUnboundTag = 23; // 0b10111
456 static const uword kNoneTag = 31; // 0b11111
457
458 // Up to the five least significant bits are used to tag the object's layout.
459 // The three low bits make up a primary tag, used to differentiate Header and
460 // HeapObject from immediate objects. All even tags map to SmallInt, which is
461 // optimized by checking only the lowest bit for parity.
462 static const uword kSmallIntTagBits = 1;
463 static const uword kPrimaryTagBits = 3;
464 static const uword kImmediateTagBits = 5;
465 static const uword kSmallIntTagMask = (1 << kSmallIntTagBits) - 1;
466 static const uword kPrimaryTagMask = (1 << kPrimaryTagBits) - 1;
467 static const uword kImmediateTagMask = (1 << kImmediateTagBits) - 1;
468
469 // Cast this RawObject to another Raw* type with no runtime checks. Only used
470 // in a few limited situations; most code should use Raw*::cast() instead.
471 template <typename T>
472 T rawCast() const;
473
474 RAW_OBJECT_COMMON(Object);
475
476 private:
477 // Zero-initializing raw_ gives RawSmallInt::fromWord(0).
478 uword raw_{};
479};
480
481// CastError and OptInt<T> represent the result of a call to RawInt::asInt<T>():
482// If error == CastError::None, value contains the result. Otherwise, error
483// indicates why the value didn't fit in T.
484enum class CastError {
485 None,
486 Underflow,
487 Overflow,
488};
489
490template <typename T>
491class OptInt {
492 public:
493 static OptInt valid(T i) { return {i, CastError::None}; }
494 static OptInt underflow() { return {0, CastError::Underflow}; }
495 static OptInt overflow() { return {0, CastError::Overflow}; }
496
497 T value;
498 CastError error;
499};
500
501// Generic superclasses for Python types with multiple native types
502
503// Common `bytes` wrapper around RawSmallBytes/RawLargeBytes
504class RawBytes : public RawObject {
505 public:
506 // Singleton.
507 static RawBytes empty();
508
509 // Getters and setters.
510 word length() const;
511 byte byteAt(word index) const;
512 void copyTo(byte* dst, word length) const;
513 // Copy length bytes from this to dst, starting at the given index
514 void copyToStartAt(byte* dst, word length, word index) const;
515 bool isASCII() const;
516 // Read adjacent bytes as `uint16_t` integer.
517 uint16_t uint16At(word index) const;
518 // Read adjacent bytes as `uint32_t` integer.
519 uint32_t uint32At(word index) const;
520 // Read adjacent bytes as `uint64_t` integer.
521 uint64_t uint64At(word index) const;
522
523 // Rewrite the header to make UTF-8 conformant bytes look like a Str
524 RawObject becomeStr() const;
525
526 // Returns a positive value if 'this' is greater than 'that', a negative value
527 // if 'this' is less than 'that', and zero if they are the same.
528 // Does not guarantee to return -1, 0, or 1.
529 word compare(RawBytes that) const;
530
531 // Returns the index at which value is found in this[start:start+length] (not
532 // including end), or -1 if not found.
533 word findByte(byte value, word start, word length) const;
534
535 // Check for the presence of a non-zero byte.
536 bool includesByte(byte b) const;
537
538 // Conversion to an unescaped C string. The underlying memory is allocated
539 // with malloc and must be freed by the caller.
540 char* toCStr() const;
541
542 RAW_OBJECT_COMMON(Bytes);
543};
544
545// Common `int` wrapper around RawSmallInt/RawLargeInt/RawBool
546class RawInt : public RawObject {
547 public:
548 // Getters and setters.
549 word asWord() const;
550 // Returns the value as a word if it fits into a word.
551 // Otherwise, returns kMinWord for negative values or kMaxWord for positive
552 // values.
553 word asWordSaturated() const;
554 void* asCPtr() const;
555
556 // If this fits in T, get its value as a T. If not, indicate what went wrong.
557 template <typename T>
558 OptInt<T> asInt() const;
559
560 // Returns a positive value if 'this' is greater than 'other', zero if it
561 // is the same, a negavite value if smaller. The value does not have to be
562 // -1, 0, or 1.
563 word compare(RawInt that) const;
564
565 word bitLength() const;
566
567 bool isEven() const;
568 bool isNegative() const;
569 bool isOdd() const;
570 bool isPositive() const;
571 bool isZero() const;
572
573 // Indexing into digits
574 uword digitAt(word index) const;
575
576 // Number of digits
577 word numDigits() const;
578
579 // Copies digits bytewise to `dst`. Returns number of bytes copied.
580 word copyTo(byte* dst, word max_length) const;
581
582 RAW_OBJECT_COMMON(Int);
583};
584
585// Common `str` wrapper around RawSmallStr/RawLargeStr
586class RawStr : public RawObject {
587 public:
588 // Singletons.
589 static RawStr empty();
590
591 // Getters and setters.
592 byte byteAt(word index) const;
593 word length() const;
594 void copyTo(byte* dst, word char_length) const;
595 void copyToStartAt(byte* dst, word char_length, word char_start) const;
596
597 // Equality checks.
598 word compare(RawStr that) const;
599 word compareCStr(const char* c_str) const;
600 bool equals(RawStr that) const;
601 bool equalsCStr(const char* c_str) const;
602
603 bool includes(RawObject that) const;
604
605 // Check for the presence of a non-zero byte.
606 bool includesByte(byte b) const;
607
608 // Codepoints
609 int32_t codePointAt(word char_index, word* char_length) const;
610 word codePointLength() const;
611 bool isASCII() const;
612
613 // Find the number of occurences of substring `needle`.
614 word occurrencesOf(RawObject that) const;
615
616 // Returns an index into a string offset by either a positive or negative
617 // number of code points. Otherwise, if the new index would be negative, -1
618 // is returned or if the new index would be greater than the length of the
619 // string, the length is returned.
620 word offsetByCodePoints(word char_index, word count) const;
621
622 // Conversion to an unescaped C string. The underlying memory is allocated
623 // with malloc and must be freed by the caller.
624 char* toCStr() const;
625
626 RAW_OBJECT_COMMON(Str);
627};
628
629// Immediate objects
630
631class RawSmallInt : public RawObject {
632 public:
633 // Getters and setters.
634 word value() const;
635 void* asCPtr() const;
636 // Converts a `SmallInt` created by `fromAlignedCPtr()` back to a pointer.
637 void* asAlignedCPtr() const;
638 word asReinterpretedWord() const;
639
640 // If this fits in T, get its value as a T. If not, indicate what went wrong.
641 template <typename T>
642 if_signed_t<T, OptInt<T>> asInt() const;
643 template <typename T>
644 if_unsigned_t<T, OptInt<T>> asInt() const;
645
646 word hash() const;
647
648 // Construction.
649 static RawSmallInt fromWord(word value);
650 static RawSmallInt fromWordTruncated(word value);
651
652 // Reinterpret a word value with the lowest `kSmallIntTagBits` cleared
653 // directly as a `RawSmallInt` value, without performing the usual shift.
654 static RawSmallInt fromReinterpretedWord(word value);
655
656 // Create a `SmallInt` from an aligned C pointer.
657 // This is slightly faster than `Runtime::newIntFromCPtr()` but only works for
658 // pointers with an alignment of at least `2**kSmallIntTagBits`.
659 // Use `toAlignedCPtr()` to reverse this operation; `toCPtr()` will not work
660 // correctly.
661 static RawSmallInt fromAlignedCPtr(void* ptr);
662 static constexpr bool isValid(word value) {
663 return (value >= kMinValue) && (value <= kMaxValue);
664 }
665 static word truncate(word value);
666
667 // Constants.
668 static const word kBits = kBitsPerPointer - kSmallIntTagBits;
669 static const word kMinValue = -(word{1} << (kBits - 1));
670 static const word kMaxValue = (word{1} << (kBits - 1)) - 1;
671
672 static const word kMaxDigits10 = 18;
673 static const word kMaxDigits10Pow = 1000000000000000000;
674 static_assert((kMaxDigits10Pow <= kMaxValue) &&
675 (kMaxDigits10Pow > kMaxValue / 10),
676 "invalid max");
677
678 RAW_OBJECT_COMMON(SmallInt);
679};
680
681enum class ObjectFormat {
682 // Instances that do not contain objects
683 kData = 0,
684 // Instances that contain objects
685 kObjects = 1,
686};
687
688// RawHeader objects
689//
690// Headers are located in first logical word of a heap allocated object and
691// contain metadata related to the object its part of. A header is not
692// really object that the user will interact with directly. Nevertheless, we
693// tag them as immediate object. This allows the runtime to identify the start
694// of an object when scanning the heap.
695//
696// Headers encode the following information
697//
698// Name Size Description
699// ----------------------------------------------------------------------------
700// Tag 3 tag for a header object
701// Format 1 enumeration describing the object encoding
702// LayoutId 20 identifier for the layout, allowing 2^20 unique layouts
703// Count 8 number of array elements or instance variables
704// Hash 32 bits to use for an identity hash code
705class RawHeader : public RawObject {
706 public:
707 word hashCode() const;
708 RawHeader withHashCode(word value) const;
709
710 ObjectFormat format() const;
711
712 LayoutId layoutId() const;
713 RawHeader withLayoutId(LayoutId layout_id) const;
714
715 word count() const;
716
717 bool hasOverflow() const;
718
719 static RawHeader from(word count, word hash, LayoutId id,
720 ObjectFormat format);
721
722 // Layout.
723 static const int kFormatBits = 1;
724 static const int kFormatOffset = kPrimaryTagBits;
725 static const uword kFormatMask = (1 << kFormatBits) - 1;
726
727 static const int kLayoutIdBits = 20;
728 static const int kLayoutIdOffset = kFormatOffset + kFormatBits;
729 static const uword kLayoutIdMask = (1 << kLayoutIdBits) - 1;
730
731 static const int kCountBits = 8;
732 static const int kCountOffset = kLayoutIdOffset + kLayoutIdBits;
733 static const uword kCountMask = (1 << kCountBits) - 1;
734
735 static const int kHashCodeBits = 32;
736 static const int kHashCodeOffset = kCountOffset + kCountBits;
737 static const uword kHashCodeMask = (1UL << kHashCodeBits) - 1;
738
739 static const int kTotalBits = kHashCodeOffset + kHashCodeBits;
740 static_assert(kTotalBits == 64, "Header should be exactly 64 bits");
741
742 static const int kCountOverflowFlag = (1 << kCountBits) - 1;
743 static const int kCountMax = kCountOverflowFlag - 1;
744
745 static const int kSize = kPointerSize;
746
747 // Constants
748 static const word kMaxLayoutId = (1L << (kLayoutIdBits + 1)) - 1;
749 static const word kUninitializedHash = 0;
750
751 RAW_OBJECT_COMMON(Header);
752};
753
754class RawSmallData : public RawObject {
755 public:
756 // Getters and setters.
757 word length() const;
758 byte byteAt(word index) const;
759 void copyTo(byte* dst, word length) const;
760 // Copy length bytes from this to dst, starting at the given index
761 void copyToStartAt(byte* dst, word length, word index) const;
762 bool isASCII() const;
763 // Read adjacent bytes as `uint16_t` integer.
764 uint16_t uint16At(word index) const;
765 // Read adjacent bytes as `uint32_t` integer.
766 uint32_t uint32At(word index) const;
767
768 // Returns the index at which value is found in this[start:start+length] (not
769 // including end), or -1 if not found.
770 word findByte(byte value, word start, word length) const;
771
772 // Check for the presence of a non-zero byte.
773 bool includesByte(byte b) const;
774
775 // Codepoints
776 int32_t codePointAt(word char_index, word* char_length) const;
777 word codePointLength() const;
778 word offsetByCodePoints(word index, word count) const;
779
780 // Conversion to an unescaped C string. The underlying memory is allocated
781 // with malloc and must be freed by the caller.
782 char* toCStr() const;
783
784 word hash() const;
785
786 // Constants.
787 static const word kMaxLength = kWordSize - 1;
788
789 static const word kDataOffset = 1;
790
791 protected:
792 explicit RawSmallData(uword raw);
793};
794
795class RawSmallBytes : public RawSmallData {
796 public:
797 // Construction.
798 static RawSmallBytes fromBytes(View<byte> data);
799 static RawSmallBytes empty();
800
801 // Rewrite the tag byte to make UTF-8 conformant bytes look like a Str
802 RawObject becomeStr() const;
803
804 RAW_OBJECT_COMMON(SmallBytes);
805
806 private:
807 explicit RawSmallBytes(uword raw);
808};
809
810class RawSmallStr : public RawSmallData {
811 public:
812 // Construction.
813 static RawSmallStr fromCodePoint(int32_t code_point);
814 static RawSmallStr fromCStr(const char* value);
815 static RawSmallStr fromBytes(View<byte> data);
816 static RawSmallStr empty();
817
818 // Comparison
819 word compare(RawObject that) const;
820 word equalsCStr(const char* c_str) const;
821
822 bool includes(RawObject that) const;
823
824 // Check for the presence of a non-zero byte.
825 bool includesByte(byte b) const;
826
827 word occurrencesOf(RawObject that) const;
828
829 RawObject becomeBytes() const;
830
831 // Constants.
832 static const word kMaxLength = kWordSize - 1;
833
834 RAW_OBJECT_COMMON(SmallStr);
835
836 private:
837 explicit RawSmallStr(uword raw);
838};
839
840// An ErrorKind is in every RawError to give some high-level detail about what
841// went wrong.
842//
843// Note that the only ErrorKind that implies a raised exception is Exception.
844// All others are used either in situations where an exception wouldn't be
845// appropriate, or where the error could be intercepted by runtime code before
846// it has to be materialized into an actual exception, to avoid memory traffic
847// on the Thread.
848enum class ErrorKind : byte {
849 // Generic RawError: when none of the other kinds fit. Should be avoided if
850 // possible.
851 kNone,
852
853 // An exception was raised, and Thread::current()->hasPendingException() is
854 // true.
855 kException,
856
857 // The attribute/function/dict entry/other named entity requested by the
858 // caller was not found.
859 kNotFound,
860
861 // The given index was out of bounds for the container being searched.
862 kOutOfBounds,
863
864 // An allocation failed due to insufficient memory.
865 kOutOfMemory,
866
867 // An iterator hit the end of its container.
868 kNoMoreItems,
869
870 // If the largest ErrorKind is ever > 7, the immediate objects won't fit in
871 // one byte, which may have performance implications.
872};
873
874// RawError is a special object type, internal to the runtime. It is used to
875// signal that an error has occurred inside the runtime or native code, e.g. an
876// exception has been raised or a value wasn't found during a lookup.
877class RawError : public RawObject {
878 public:
879 // Singletons. See the documentation for ErrorKind for what each one means.
880 static RawError error();
881 static RawError exception();
882 static RawError noMoreItems();
883 static RawError notFound();
884 static RawError outOfBounds();
885 static RawError outOfMemory();
886
887 // Kind.
888 ErrorKind kind() const;
889
890 // Bit Layout.
891 static const int kTagMask = (1 << kBitsPerByte) - 1;
892 static const int kKindOffset = kBitsPerByte;
893 static const int kKindBits = 3;
894
895 RAW_OBJECT_COMMON(Error);
896
897 private:
898 RawError(ErrorKind kind);
899};
900
901// Force users to call RawObject::isError*() rather than
902// obj == Error::error(), since there isn't one unique RawError.
903bool operator==(const RawError&, const RawObject&) = delete;
904bool operator==(const RawObject&, const RawError&) = delete;
905bool operator!=(const RawError&, const RawObject&) = delete;
906bool operator!=(const RawObject&, const RawError&) = delete;
907
908class RawBool : public RawObject {
909 public:
910 // Getters and setters.
911 bool value() const;
912
913 word hash() const;
914
915 // Singletons
916 static RawBool trueObj();
917 static RawBool falseObj();
918
919 // Construction.
920 static RawBool fromBool(bool value);
921
922 static RawBool negate(RawObject value);
923
924 // Bit Layout.
925 static const int kTagMask = (1 << kBitsPerByte) - 1;
926 static const int kValueOffset = kBitsPerByte;
927
928 RAW_OBJECT_COMMON(Bool);
929};
930
931class RawNotImplementedType : public RawObject {
932 public:
933 // Singletons.
934 static RawNotImplementedType object();
935
936 RAW_OBJECT_COMMON(NotImplementedType);
937};
938
939class RawUnbound : public RawObject {
940 public:
941 // Singletons.
942 static RawUnbound object();
943
944 RAW_OBJECT_COMMON(Unbound);
945};
946
947class RawNoneType : public RawObject {
948 public:
949 // Singletons.
950 static RawNoneType object();
951
952 RAW_OBJECT_COMMON(NoneType);
953};
954
955// Heap objects
956
957class RawHeapObject : public RawObject {
958 public:
959 // Getters and setters.
960 uword address() const;
961 uword baseAddress() const;
962 RawHeader header() const;
963 void setHeader(RawHeader header) const;
964 word headerOverflow() const;
965 word headerCountOrOverflow() const;
966 word size() const;
967
968 // Construction.
969 static RawHeapObject fromAddress(uword address);
970
971 static RawHeapObject initializeHeader(uword address, word count, word hash,
972 LayoutId id, ObjectFormat format);
973
974 // Sizing
975 static word headerSize(word count);
976
977 // Garbage collection.
978 bool isRoot() const;
979 bool isForwarding() const;
980 RawObject forward() const;
981 void forwardTo(RawObject object) const;
982
983 // Layout.
984 static const int kHeaderOffset = -kPointerSize;
985 static const int kHeaderOverflowOffset = kHeaderOffset - kPointerSize;
986 static const int kSize = kHeaderOffset + kPointerSize;
987
988 RAW_OBJECT_COMMON(HeapObject);
989};
990
991// Instances are objects with attributes described via the layout system.
992class RawInstance : public RawHeapObject {
993 public:
994 // Sizing.
995 static word allocationSize(word num_attr);
996
997 // This is only public for the inline-cache to use. All other cases should
998 // use more specific getter methods in the subclasses.
999 RawObject instanceVariableAt(word offset) const;
1000 void instanceVariableAtPut(word offset, RawObject value) const;
1001
1002 void setLayoutId(LayoutId layout_id) const;
1003
1004 RAW_OBJECT_COMMON(Instance);
1005
1006 // Instance initialization should only done by the Runtime.
1007 static RawObject initializeWithNone(uword address, word num_attributes,
1008 LayoutId layout_id);
1009 static RawObject initializeWithZero(uword address, word num_attributes,
1010 LayoutId layout_id);
1011};
1012
1013class RawBaseException : public RawInstance {
1014 public:
1015 // Getters and setters.
1016 RawObject args() const;
1017 void setArgs(RawObject args) const;
1018
1019 // The traceback, cause, and context can all be Unbound to indicate that they
1020 // are "NULL" rather than the normal unset value of None. The only code that
1021 // cares about the distinction is a handful of C-API functions, so the
1022 // standard getters transparently replace Unbound with None. The *OrUnbound
1023 // getters return the value as it's stored in memory, and are used
1024 // in the few C-API functions that care about the distinction.
1025 RawObject traceback() const;
1026 RawObject tracebackOrUnbound() const;
1027 void setTraceback(RawObject traceback) const;
1028
1029 RawObject cause() const;
1030 RawObject causeOrUnbound() const;
1031 void setCause(RawObject cause) const;
1032
1033 RawObject context() const;
1034 RawObject contextOrUnbound() const;
1035 void setContext(RawObject context) const;
1036
1037 RawObject suppressContext() const;
1038 void setSuppressContext(RawObject suppress) const;
1039
1040 static const int kArgsOffset = RawHeapObject::kSize;
1041 static const int kTracebackOffset = kArgsOffset + kPointerSize;
1042 static const int kCauseOffset = kTracebackOffset + kPointerSize;
1043 static const int kContextOffset = kCauseOffset + kPointerSize;
1044 static const int kSuppressContextOffset = kContextOffset + kPointerSize;
1045 static const int kSize = kSuppressContextOffset + kPointerSize;
1046
1047 RAW_OBJECT_COMMON(BaseException);
1048};
1049
1050class RawException : public RawBaseException {
1051 public:
1052 RAW_OBJECT_COMMON(Exception);
1053};
1054
1055class RawSyntaxError : public RawException {
1056 public:
1057 static const int kFilenameOffset = RawException::kSize;
1058 static const int kLinenoOffset = kFilenameOffset + kPointerSize;
1059 static const int kMsgOffset = kLinenoOffset + kPointerSize;
1060 static const int kOffsetOffset = kMsgOffset + kPointerSize;
1061 static const int kPrintFileAndLineOffset = kOffsetOffset + kPointerSize;
1062 static const int kTextOffset = kPrintFileAndLineOffset + kPointerSize;
1063 static const int kSize = kTextOffset + kPointerSize;
1064
1065 RAW_OBJECT_COMMON(SyntaxError);
1066};
1067
1068class RawStopIteration : public RawBaseException {
1069 public:
1070 // Getters and setters.
1071 RawObject value() const;
1072 void setValue(RawObject value) const;
1073
1074 static const int kValueOffset = RawBaseException::kSize;
1075 static const int kSize = kValueOffset + kPointerSize;
1076
1077 RAW_OBJECT_COMMON(StopIteration);
1078};
1079
1080class RawSystemExit : public RawBaseException {
1081 public:
1082 RawObject code() const;
1083 void setCode(RawObject code) const;
1084
1085 static const int kCodeOffset = RawBaseException::kSize;
1086 static const int kSize = kCodeOffset + kPointerSize;
1087
1088 RAW_OBJECT_COMMON(SystemExit);
1089};
1090
1091class RawRuntimeError : public RawException {
1092 public:
1093 RAW_OBJECT_COMMON(RuntimeError);
1094};
1095
1096class RawNotImplementedError : public RawRuntimeError {
1097 public:
1098 RAW_OBJECT_COMMON(NotImplementedError);
1099};
1100
1101class RawImportError : public RawException {
1102 public:
1103 // Getters and setters
1104 RawObject msg() const;
1105 void setMsg(RawObject msg) const;
1106
1107 RawObject name() const;
1108 void setName(RawObject name) const;
1109
1110 RawObject path() const;
1111 void setPath(RawObject path) const;
1112
1113 static const int kMsgOffset = RawBaseException::kSize;
1114 static const int kNameOffset = kMsgOffset + kPointerSize;
1115 static const int kPathOffset = kNameOffset + kPointerSize;
1116 static const int kSize = kPathOffset + kPointerSize;
1117
1118 RAW_OBJECT_COMMON(ImportError);
1119};
1120
1121class RawModuleNotFoundError : public RawImportError {
1122 public:
1123 RAW_OBJECT_COMMON(ModuleNotFoundError);
1124};
1125
1126class RawLookupError : public RawException {
1127 public:
1128 RAW_OBJECT_COMMON(LookupError);
1129};
1130
1131class RawIndexError : public RawLookupError {
1132 public:
1133 RAW_OBJECT_COMMON(IndexError);
1134};
1135
1136class RawKeyError : public RawLookupError {
1137 public:
1138 RAW_OBJECT_COMMON(KeyError);
1139};
1140
1141class RawUnicodeError : public RawException {
1142 public:
1143 RAW_OBJECT_COMMON(UnicodeError);
1144};
1145
1146// This is a base class to allow for code reuse in the C++ implementations of
1147// the UnicodeError subclasses. According to the Python type system, each
1148// subclass of this Base class actually subclasses UnicodeError.
1149class RawUnicodeErrorBase : public RawException {
1150 public:
1151 RawObject encoding() const;
1152 void setEncoding(RawObject encoding_name) const;
1153
1154 RawObject object() const;
1155 void setObject(RawObject value) const;
1156
1157 RawObject start() const;
1158 void setStart(RawObject index) const;
1159
1160 RawObject end() const;
1161 void setEnd(RawObject index) const;
1162
1163 RawObject reason() const;
1164 void setReason(RawObject error_description) const;
1165
1166 static const int kEncodingOffset = RawBaseException::kSize;
1167 static const int kObjectOffset = kEncodingOffset + kPointerSize;
1168 static const int kStartOffset = kObjectOffset + kPointerSize;
1169 static const int kEndOffset = kStartOffset + kPointerSize;
1170 static const int kReasonOffset = kEndOffset + kPointerSize;
1171 static const int kSize = kReasonOffset + kPointerSize;
1172
1173 RAW_OBJECT_COMMON(UnicodeErrorBase);
1174};
1175
1176class RawUnicodeDecodeError : public RawUnicodeErrorBase {
1177 public:
1178 RAW_OBJECT_COMMON(UnicodeDecodeError);
1179};
1180
1181class RawUnicodeEncodeError : public RawUnicodeErrorBase {
1182 public:
1183 RAW_OBJECT_COMMON(UnicodeEncodeError);
1184};
1185
1186class RawUnicodeTranslateError : public RawUnicodeErrorBase {
1187 public:
1188 RAW_OBJECT_COMMON(UnicodeTranslateError);
1189};
1190
1191class RawAttributeDict : public RawInstance {
1192 public:
1193 RawObject attributes() const;
1194 void setAttributes(RawObject mutable_tuple) const;
1195
1196 word attributesRemaining() const;
1197 void setAttributesRemaining(word free) const;
1198
1199 static const int kAttributesOffset = RawInstance::kSize;
1200 static const int kAttributesRemainingOffset =
1201 kAttributesOffset + kPointerSize;
1202 static const int kSize = kAttributesRemainingOffset + kPointerSize;
1203
1204 RAW_OBJECT_COMMON(AttributeDict);
1205};
1206
1207class RawType : public RawAttributeDict {
1208 public:
1209 enum Flag : word {
1210 kNone = 0,
1211
1212 // Bits 0-7 are reserved to hold a LayoutId.
1213
1214 // Has non-empty __abstractmethods__
1215 kIsAbstract = 1 << 8,
1216
1217 // The type has an attribute dictionary in cpython but is not using the
1218 // usual tuple-overflow or dict-overflow modes in the layout to provide it.
1219 kHasCustomDict = 1 << 9,
1220
1221 // Instances have a block of of memory in the unmanaged C heap attached to
1222 // them. Instances are `RawNativeProxy`s.
1223 kHasNativeData = 1 << 10,
1224
1225 // Has the extension flag Py_TPFLAGS_HAVE_GC
1226 kHasCycleGC = 1 << 11,
1227
1228 // Has a default extension dealloc slot
1229 kHasDefaultDealloc = 1 << 12,
1230
1231 // Has __slots__ in itself or its base
1232 kHasSlots = 1 << 13,
1233
1234 // Runtime expects some attributes of this type to be at a fixed address.
1235 kIsFixedAttributeBase = 1 << 14,
1236
1237 // Whether the type should behave like a CPython heap-type. Heap-types are
1238 // the default for user defined types. Non-heap types are used for most
1239 // built-in types. They have immutable type dictionaries and deal with
1240 // `__module__`, `__name__` and `__qualname__` in a different way.
1241 kIsCPythonHeaptype = 1 << 15,
1242
1243 // Type may be used as a base class to create subclasses. A cleared basetype
1244 // is sometimes called "final class" in other languages.
1245 kIsBasetype = 1 << 16,
1246
1247 // This type is an instance of a metaclass that defined an `mro` method and
1248 // potentially installed an irregular MRO.
1249 kHasCustomMro = 1 << 17,
1250
1251 // this_type.__getattribute__ is object.__getattribute__.
1252 kHasObjectDunderGetattribute = 1 << 18,
1253
1254 // this_type.__getattribute__ is type.__getattribute__.
1255 kHasTypeDunderGetattribute = 1 << 19,
1256
1257 // this_type.__getattribute__ is module.__getattribute__.
1258 kHasModuleDunderGetattribute = 1 << 20,
1259
1260 // this_type.__new__ is object.__new__.
1261 kHasObjectDunderNew = 1 << 21,
1262
1263 // this_type.__hash__ is object.__hash__.
1264 kHasObjectDunderHash = 1 << 22,
1265
1266 // this_type.__hash__ is str.__hash__.
1267 kHasStrDunderHash = 1 << 23,
1268
1269 // this_type.__bool__ exists.
1270 kHasDunderBool = 1 << 24,
1271
1272 // this_type.__len__ exists.
1273 kHasDunderLen = 1 << 25,
1274
1275 // this_type.__class__ is object.__class__.
1276 kHasObjectDunderClass = 1 << 26,
1277
1278 // this_type.__get__ exists.
1279 kHasDunderGet = 1 << 27,
1280
1281 // this_type.__set__ exists.
1282 kHasDunderSet = 1 << 28,
1283
1284 // this_type.__delete__ exists.
1285 kHasDunderDelete = 1 << 29,
1286
1287 // this_type.__eq__ is object.__eq__.
1288 kHasObjectDunderEq = 1 << 30,
1289
1290 // this_type is a structseq (and not a subclass thereof)
1291 kIsStructseq = 1 << 31,
1292 };
1293
1294 static const word kAttributeFlags =
1295 Flag::kHasObjectDunderGetattribute | Flag::kHasTypeDunderGetattribute |
1296 Flag::kHasModuleDunderGetattribute | Flag::kHasObjectDunderNew |
1297 Flag::kHasObjectDunderHash | Flag::kHasStrDunderHash |
1298 Flag::kHasDunderBool | Flag::kHasDunderLen | Flag::kHasObjectDunderClass |
1299 Flag::kHasDunderGet | Flag::kHasDunderSet | Flag::kHasDunderDelete |
1300 Flag::kHasObjectDunderEq;
1301
1302 static const word kUninheritableFlags =
1303 Flag::kIsAbstract | Flag::kIsFixedAttributeBase | Flag::kIsBasetype |
1304 kAttributeFlags | kIsStructseq;
1305
1306 static const word kInheritableFlags = ~kUninheritableFlags;
1307
1308 // Getters and setters.
1309 RawObject instanceLayout() const;
1310 void setInstanceLayout(RawObject layout) const;
1311
1312 LayoutId instanceLayoutId() const;
1313 void setInstanceLayoutId(LayoutId id) const;
1314
1315 RawObject bases() const;
1316 void setBases(RawObject bases_tuple) const;
1317
1318 RawObject doc() const;
1319 void setDoc(RawObject doc) const;
1320
1321 RawObject mro() const;
1322 void setMro(RawObject object_array) const;
1323
1324 RawObject name() const;
1325 void setName(RawObject name) const;
1326
1327 // Flags.
1328 //
1329 // Bits 0-7 contain the LayoutId of the builtin base type. For builtin types,
1330 // this is the type itself, except for subtypes of int and str, which have
1331 // kInt and kStr, respectively. For user-defined types, it is the LayoutId of
1332 // the first builtin base class (kObject for most types).
1333 //
1334 // Bits 8+ are a bitmask of flags describing certain properties of the type.
1335 Flag flags() const;
1336 bool hasFlag(Flag bit) const;
1337 LayoutId builtinBase() const;
1338 void setFlags(Flag value) const;
1339 void setFlagsAndBuiltinBase(Flag value, LayoutId base) const;
1340 void setBuiltinBase(LayoutId base) const;
1341
1342 bool isBuiltin() const;
1343
1344 bool hasCustomDict() const;
1345 bool hasNativeData() const;
1346 bool isCPythonHeaptype() const;
1347 bool isBasetype() const;
1348
1349 RawObject slots() const;
1350 void setSlots(RawObject slots) const;
1351
1352 RawObject abstractMethods() const;
1353 void setAbstractMethods(RawObject methods) const;
1354
1355 RawObject subclasses() const;
1356 void setSubclasses(RawObject subclasses) const;
1357
1358 // Lazily allocated read-only proxy to the type dict.
1359 RawObject proxy() const;
1360 void setProxy(RawObject proxy) const;
1361
1362 // Constructor function for this class. Either type.__call__ or
1363 // a function that has the same effect as type.__call__.
1364 RawObject ctor() const;
1365 void setCtor(RawObject function) const;
1366
1367 RawObject qualname() const;
1368 void setQualname(RawObject qualname) const;
1369
1370 bool isBaseExceptionSubclass() const;
1371
1372 // Check if the type dictionary is mutable. If the current type's dict is
1373 // immutable, its parents' dicts are immutable too.
1374 bool hasMutableDict() const;
1375
1376 // Layout.
1377 static const int kMroOffset = RawAttributeDict::kSize;
1378 static const int kBasesOffset = kMroOffset + kPointerSize;
1379 static const int kInstanceLayoutOffset = kBasesOffset + kPointerSize;
1380 static const int kInstanceLayoutIdOffset =
1381 kInstanceLayoutOffset + kPointerSize;
1382 static const int kNameOffset = kInstanceLayoutIdOffset + kPointerSize;
1383 static const int kDocOffset = kNameOffset + kPointerSize;
1384 static const int kFlagsOffset = kDocOffset + kPointerSize;
1385 static const int kSlotsOffset = kFlagsOffset + kPointerSize;
1386 static const int kAbstractMethodsOffset = kSlotsOffset + kPointerSize;
1387 static const int kSubclassesOffset = kAbstractMethodsOffset + kPointerSize;
1388 static const int kProxyOffset = kSubclassesOffset + kPointerSize;
1389 static const int kCtorOffset = kProxyOffset + kPointerSize;
1390 static const int kQualnameOffset = kCtorOffset + kPointerSize;
1391 static const int kSize = kQualnameOffset + kPointerSize;
1392
1393 static const int kBuiltinBaseMask = 0xff;
1394
1395 RAW_OBJECT_COMMON(Type);
1396};
1397
1398class RawContext : public RawInstance {
1399 public:
1400 // Getters and setters
1401 RawObject data() const;
1402 void setData(RawObject data) const;
1403
1404 RawObject prevContext() const;
1405 void setPrevContext(RawObject prev_context) const;
1406
1407 // Layout
1408 static const int kDataOffset = RawHeapObject::kSize;
1409 static const int kPrevContextOffset = kDataOffset + kPointerSize;
1410 static const int kSize = kPrevContextOffset + kPointerSize;
1411
1412 RAW_OBJECT_COMMON(Context);
1413};
1414
1415class RawContextVar : public RawInstance {
1416 public:
1417 // Getters and setters
1418 RawObject defaultValue() const;
1419 void setDefaultValue(RawObject default_value) const;
1420
1421 RawObject name() const;
1422 void setName(RawObject name) const;
1423
1424 // Layout
1425 static const int kDefaultValueOffset = RawHeapObject::kSize;
1426 static const int kNameOffset = kDefaultValueOffset + kPointerSize;
1427 static const int kSize = kNameOffset + kPointerSize;
1428
1429 RAW_OBJECT_COMMON(ContextVar);
1430};
1431
1432class RawTypeProxy : public RawInstance {
1433 public:
1434 // The type is instance is a proxy to.
1435 RawObject type() const;
1436 void setType(RawObject type) const;
1437
1438 // Layout.
1439 static const int kTypeOffset = RawHeapObject::kSize;
1440 static const int kSize = kTypeOffset + kPointerSize;
1441
1442 RAW_OBJECT_COMMON(TypeProxy);
1443};
1444
1445class RawDataArray : public RawHeapObject {
1446 public:
1447 byte byteAt(word index) const;
1448
1449 int32_t codePointAt(word char_index, word* char_length) const;
1450 word codePointLength() const;
1451 word offsetByCodePoints(word index, word count) const;
1452
1453 void copyTo(byte* dst, word length) const;
1454 // Copy length bytes from this to dst, starting at the given index
1455 void copyToStartAt(byte* dst, word length, word index) const;
1456
1457 word compare(RawDataArray that) const;
1458 bool equals(RawDataArray that) const;
1459 bool equalsBytes(View<byte> bytes) const;
1460 bool equalsCStr(const char* c_str) const;
1461
1462 // Returns the index at which value is found in this[start:start+length] (not
1463 // including end), or -1 if not found.
1464 word findByte(byte value, word start, word length) const;
1465
1466 // Check for the presence of a non-zero byte.
1467 bool includesByte(byte b) const;
1468
1469 bool isASCII() const;
1470
1471 word length() const;
1472
1473 // Conversion to an unescaped C string. The underlying memory is allocated
1474 // with malloc and must be freed by the caller.
1475 char* toCStr() const;
1476
1477 // Read adjacent bytes as `uint16_t` integer.
1478 uint16_t uint16At(word index) const;
1479 // Read adjacent bytes as `uint32_t` integer.
1480 uint32_t uint32At(word index) const;
1481 // Read adjacent bytes as `uint64_t` integer.
1482 uint64_t uint64At(word index) const;
1483
1484 // Sizing. Sizing and initialization should only be done by the Runtime.
1485 static word allocationSize(word length);
1486 static RawObject initialize(uword address, word length, LayoutId layout_id);
1487
1488 RAW_OBJECT_COMMON(DataArray);
1489};
1490
1491class RawLargeBytes : public RawDataArray {
1492 public:
1493 // Rewrite the header to make UTF-8 conformant bytes look like a Str
1494 RawObject becomeStr() const;
1495
1496 RAW_OBJECT_COMMON(LargeBytes);
1497
1498 // Sizing. Sizing should only be done by the Runtime.
1499 static word allocationSize(word length);
1500};
1501
1502class RawLargeStr : public RawDataArray {
1503 public:
1504 bool includes(RawObject that) const;
1505
1506 word occurrencesOf(RawObject that) const;
1507
1508 // Sizing. Sizing should only be done by the Runtime.
1509 static word allocationSize(word length);
1510
1511 RAW_OBJECT_COMMON(LargeStr);
1512};
1513
1514class RawMutableBytes : public RawLargeBytes {
1515 public:
1516 void byteAtPut(word index, byte value) const;
1517
1518 void uint16AtPut(word index, uint16_t value) const;
1519
1520 void uint32AtPut(word index, uint32_t value) const;
1521
1522 // Find the first occurrence from a specified start of any byte in the given
1523 // byte sequence, return the number of bytes read before the occurrence
1524 word indexOfAny(View<byte> needle, word start) const;
1525
1526 // Replace the bytes from dst_start with count bytes from src
1527 void replaceFromWith(word dst_start, RawDataArray src, word count) const;
1528
1529 // Replace the bytes from dst_start with count bytes from src, starting at
1530 // src_start in src
1531 void replaceFromWithStartAt(word dst_start, RawDataArray src, word count,
1532 word src_start) const;
1533
1534 // Replace the bytes from dst_start with count bytes from src
1535 void replaceFromWithBytes(word dst_start, RawBytes src, word count) const;
1536
1537 void replaceFromWithByteslike(word dst_start, const Byteslike& byteslike,
1538 word count) const;
1539 void replaceFromWithByteslikeStartAt(word dst_start,
1540 const Byteslike& byteslike, word count,
1541 word src_start) const;
1542
1543 // Replace the bytes from dst_start with count bytes of value
1544 void replaceFromWithByte(word dst_start, byte value, word count) const;
1545
1546 // Replace the bytes from dst_start with count bytes from src, starting at
1547 // src_start in src
1548 void replaceFromWithBytesStartAt(word dst_start, RawBytes src, word count,
1549 word src_start) const;
1550
1551 // Replace the bytes from dst_start with count bytes from src.
1552 void replaceFromWithAll(word dst_start, View<byte> src) const;
1553
1554 // Replace the bytes from index with len bytes from string src
1555 void replaceFromWithStr(word index, RawStr src, word char_length) const;
1556
1557 void replaceFromWithStrStartAt(word dst_start, RawStr src, word char_length,
1558 word src_start_char) const;
1559
1560 RawObject becomeImmutable() const;
1561 RawObject becomeStr() const;
1562
1563 // Sizing. Sizing should only be done by the Runtime.
1564 static word allocationSize(word length);
1565
1566 RAW_OBJECT_COMMON(MutableBytes);
1567};
1568
1569// A mutable array, for the array module
1570//
1571// RawLayout:
1572// [Header ]
1573// [Buffer ] - Pointer to a RawMutableBytes with the underlying data.
1574// [Length ] - Number of bytes currently in the array.
1575// [Typecode] - Typecode of the array
1576class RawArray : public RawInstance {
1577 public:
1578 // Getters and setters
1579 RawObject buffer() const;
1580 void setBuffer(RawObject new_buffer) const;
1581
1582 word length() const;
1583 void setLength(word new_length) const;
1584
1585 RawObject typecode() const;
1586 void setTypecode(RawObject new_typecode) const;
1587
1588 // Layout
1589 static const int kBufferOffset = RawHeapObject::kSize;
1590 static const int kLengthOffset = kBufferOffset + kPointerSize;
1591 static const int kTypecodeOffset = kLengthOffset + kPointerSize;
1592 static const int kSize = kTypecodeOffset + kPointerSize;
1593
1594 RAW_OBJECT_COMMON(Array);
1595};
1596
1597// A container for an mmap'd pointer
1598//
1599// RawLayout:
1600// [Header ]
1601// [Access ] - A bitmask word storing the access permissions for the file
1602// [Data ] - A RawPointer holding the address + length of the memory
1603// [Fd ] - The file descriptor opened
1604class RawMmap : public RawInstance {
1605 public:
1606 enum Property {
1607 kReadable = 0x01,
1608 kWritable = 0x02,
1609 kCopyOnWrite = 0x04,
1610 };
1611 // Getters and setters
1612 word access() const;
1613 void setAccess(word new_access) const;
1614
1615 RawObject data() const;
1616 void setData(RawObject new_data) const;
1617
1618 RawObject fd() const;
1619 void setFd(RawObject new_fd) const;
1620
1621 // Getters and setters for the kAccessOffset bitmask word
1622 bool isReadable() const;
1623 void setReadable() const;
1624
1625 bool isWritable() const;
1626 void setWritable() const;
1627
1628 bool isCopyOnWrite() const;
1629 void setCopyOnWrite() const;
1630
1631 // Layout
1632 static const int kAccessOffset = RawHeapObject::kSize;
1633 static const int kDataOffset = kAccessOffset + kPointerSize;
1634 static const int kFdOffset = kDataOffset + kPointerSize;
1635 static const int kSize = kFdOffset + kPointerSize;
1636
1637 RAW_OBJECT_COMMON(Mmap);
1638};
1639
1640class RawTuple : public RawHeapObject {
1641 public:
1642 word length() const;
1643
1644 // Getters and setters.
1645 RawObject at(word index) const;
1646 void atPut(word index, RawObject value) const;
1647
1648 bool contains(RawObject object) const;
1649
1650 RAW_OBJECT_COMMON(Tuple);
1651};
1652
1653class RawMutableTuple : public RawTuple {
1654 public:
1655 // Sizing. Sizing should only be done by the Runtime.
1656 static word allocationSize(word length);
1657
1658 // Finalizes this object and turns it into an immutable Tuple.
1659 RawObject becomeImmutable() const;
1660
1661 void fill(RawObject value) const;
1662
1663 // Copy count elements from src to this tuple, starting at index dst_start
1664 void replaceFromWith(word dst_start, RawTuple src, word count) const;
1665
1666 // Copy count elements from src to this tuple, starting at index dst_start in
1667 // this and src_start in src
1668 void replaceFromWithStartAt(word dst_start, RawTuple src, word count,
1669 word src_start) const;
1670
1671 // Swap elements at indices i, j
1672 void swap(word i, word j) const;
1673
1674 // Initialization should only be done by the Runtime.
1675 static RawObject initialize(uword address, word length);
1676
1677 RAW_OBJECT_COMMON(MutableTuple);
1678};
1679
1680class RawUserTupleBase : public RawInstance {
1681 public:
1682 // Getters and setters.
1683 RawObject value() const;
1684 void setValue(RawObject value) const;
1685
1686 // RawLayout.
1687 static const int kValueOffset = RawHeapObject::kSize;
1688 static const int kSize = kValueOffset + kPointerSize;
1689
1690 RAW_OBJECT_COMMON_NO_CAST(UserTupleBase);
1691};
1692
1693RawTuple tupleUnderlying(RawObject object);
1694
1695// Arbitrary precision signed integer, with 64 bit digits in two's complement
1696// representation
1697class RawLargeInt : public RawHeapObject {
1698 public:
1699 // Getters and setters.
1700 word asWord() const;
1701
1702 // Return whether or not this RawLargeInt obeys the following invariants:
1703 // - numDigits() >= 1
1704 // - The value does not fit in a RawSmallInt
1705 // - Negative numbers do not have redundant sign-extended digits
1706 // - Positive numbers do not have redundant zero-extended digits
1707 bool isValid() const;
1708
1709 // RawLargeInt is also used for storing native pointers.
1710 void* asCPtr() const;
1711
1712 // If this fits in T, get its value as a T. If not, indicate what went wrong.
1713 template <typename T>
1714 if_signed_t<T, OptInt<T>> asInt() const;
1715 template <typename T>
1716 if_unsigned_t<T, OptInt<T>> asInt() const;
1717
1718 // Indexing into digits
1719 uword digitAt(word index) const;
1720 void digitAtPut(word index, uword digit) const;
1721
1722 bool isEven() const;
1723 bool isNegative() const;
1724 bool isPositive() const;
1725
1726 word bitLength() const;
1727
1728 // Number of digits
1729 word numDigits() const;
1730
1731 // Copies digits bytewise to `dst`. Returns number of bytes copied.
1732 word copyTo(byte* dst, word copy_length) const;
1733
1734 // Copy 'bytes' array into digits; if the array is too small set remaining
1735 // data to 'sign_extension' byte.
1736 void copyFrom(RawBytes bytes, byte sign_extension) const;
1737
1738 // Layout.
1739 static const int kValueOffset = RawHeapObject::kSize;
1740 static const int kSize = kValueOffset + kPointerSize;
1741
1742 // Sizing. Sizing and initialization should only be done by the Runtime.
1743 static word allocationSize(word num_digits);
1744 static RawObject initialize(uword address, word num_digits);
1745
1746 RAW_OBJECT_COMMON(LargeInt);
1747};
1748
1749class RawFloat : public RawHeapObject {
1750 public:
1751 // Getters and setters.
1752 double value() const;
1753
1754 // Layout.
1755 static const int kValueOffset = RawHeapObject::kSize;
1756 static const int kSize = kValueOffset + kDoubleSize;
1757
1758 // Instance initialization should only done by the Runtime.
1759 static RawObject initialize(uword address, double value);
1760 static word allocationSize();
1761
1762 RAW_OBJECT_COMMON(Float);
1763};
1764
1765class RawFrameProxy : public RawInstance {
1766 public:
1767 // The previous frame on the stack, or None if the current frame object
1768 // represents the bottom-most frame.
1769 RawObject back() const;
1770 void setBack(RawObject back) const;
1771
1772 // The function executed on the frame.
1773 RawObject function() const;
1774 void setFunction(RawObject function) const;
1775
1776 // The last instruction if called.
1777 RawObject lasti() const;
1778 void setLasti(RawObject lasti) const;
1779
1780 // The local symbol table, a dictionary.
1781 RawObject locals() const;
1782 void setLocals(RawObject locals) const;
1783
1784 // Layout.
1785 static const int kBackOffset = RawHeapObject::kSize;
1786 static const int kFunctionOffset = kBackOffset + kPointerSize;
1787 static const int kLastiOffset = kFunctionOffset + kPointerSize;
1788 static const int kLocalsOffset = kLastiOffset + kPointerSize;
1789 static const int kSize = kLocalsOffset + kPointerSize;
1790
1791 RAW_OBJECT_COMMON(FrameProxy);
1792};
1793
1794class RawUserBytesBase : public RawInstance {
1795 public:
1796 // Getters and setters.
1797 RawObject value() const;
1798 void setValue(RawObject value) const;
1799
1800 // RawLayout
1801 static const int kValueOffset = RawHeapObject::kSize;
1802 static const int kSize = kValueOffset + kPointerSize;
1803
1804 RAW_OBJECT_COMMON_NO_CAST(UserBytesBase);
1805};
1806
1807RawBytes bytesUnderlying(RawObject object);
1808
1809class RawUserFloatBase : public RawInstance {
1810 public:
1811 // Getters and setters.
1812 RawObject value() const;
1813 void setValue(RawObject value) const;
1814
1815 // RawLayout.
1816 static const int kValueOffset = RawHeapObject::kSize;
1817 static const int kSize = kValueOffset + kPointerSize;
1818
1819 RAW_OBJECT_COMMON_NO_CAST(UserFloatBase);
1820};
1821
1822RawFloat floatUnderlying(RawObject object);
1823
1824class RawUserIntBase : public RawInstance {
1825 public:
1826 // Getters and setters.
1827 RawObject value() const;
1828 void setValue(RawObject value) const;
1829
1830 // RawLayout.
1831 static const int kValueOffset = RawHeapObject::kSize;
1832 static const int kSize = kValueOffset + kPointerSize;
1833
1834 RAW_OBJECT_COMMON_NO_CAST(UserIntBase);
1835};
1836
1837RawInt intUnderlying(RawObject object);
1838
1839class RawUserStrBase : public RawInstance {
1840 public:
1841 // Getters and setters.
1842 RawObject value() const;
1843 void setValue(RawObject value) const;
1844
1845 // RawLayout.
1846 static const int kValueOffset = RawHeapObject::kSize;
1847 static const int kSize = kValueOffset + kPointerSize;
1848
1849 RAW_OBJECT_COMMON_NO_CAST(UserStrBase);
1850};
1851
1852RawStr strUnderlying(RawObject object);
1853
1854class RawComplex : public RawHeapObject {
1855 public:
1856 // Getters
1857 double real() const;
1858 double imag() const;
1859
1860 // Layout.
1861 static const int kRealOffset = RawHeapObject::kSize;
1862 static const int kImagOffset = kRealOffset + kDoubleSize;
1863 static const int kSize = kImagOffset + kDoubleSize;
1864
1865 // Instance initialization should only done by the Runtime.
1866 static RawObject initialize(uword address, double real, double imag);
1867 static word allocationSize();
1868
1869 RAW_OBJECT_COMMON(Complex);
1870};
1871
1872class RawUserComplexBase : public RawInstance {
1873 public:
1874 // Getters and setters.
1875 RawObject value() const;
1876 void setValue(RawObject value) const;
1877
1878 // RawLayout
1879 static const int kValueOffset = RawHeapObject::kSize;
1880 static const int kSize = kValueOffset + kPointerSize;
1881
1882 RAW_OBJECT_COMMON_NO_CAST(UserComplexBase);
1883};
1884
1885RawComplex complexUnderlying(RawObject object);
1886
1887class RawNativeProxy : public RawInstance {
1888 public:
1889 RawObject native() const;
1890 void setNative(RawObject native_ptr) const;
1891
1892 RawObject dict() const;
1893 void setDict(RawObject dict) const;
1894
1895 // A link to another object used by the garbage collector to create sets of
1896 // weak references for delayed processing.
1897 RawObject link() const;
1898 void setLink(RawObject reference) const;
1899
1900 // TODO(eelizondo): Other finalizers will require the same logic. This should
1901 // be moved to a more generic location
1902 static void enqueue(RawObject reference, RawObject* tail);
1903 static RawObject dequeue(RawObject* tail);
1904
1905 // Layout.NativeProxy appends its in-object attributes at the end of the given
1906 // base object.
1907 static const int kNativeOffsetFromEnd = -kPointerSize;
1908 static const int kDictOffsetFromEnd = kNativeOffsetFromEnd - kPointerSize;
1909 static const int kLinkOffsetFromEnd = kDictOffsetFromEnd - kPointerSize;
1910 static const int kSizeFromEnd = -kLinkOffsetFromEnd;
1911
1912 RAW_OBJECT_COMMON_NO_CAST(NativeProxy);
1913
1914 private:
1915 // Added here to prevent this field to be inherited from RawInstance.
1916 static const int kSize = -1;
1917};
1918
1919class RawPointer : public RawHeapObject {
1920 public:
1921 // Getters and setters
1922 void* cptr() const;
1923 void setCPtr(void* new_cptr) const;
1924
1925 word length() const;
1926 void setLength(word new_length) const;
1927
1928 // Layout.
1929 static const int kCPtrOffset = RawHeapObject::kSize;
1930 static const int kLengthOffset = kCPtrOffset + kPointerSize;
1931 static const int kSize = kLengthOffset + kPointerSize;
1932
1933 // Instance initialization should only done by the Runtime.
1934 static RawObject initialize(uword address, void* cptr, word length);
1935 static word allocationSize();
1936
1937 RAW_OBJECT_COMMON(Pointer);
1938};
1939
1940class RawProperty : public RawInstance {
1941 public:
1942 // Getters and setters
1943 RawObject getter() const;
1944 void setGetter(RawObject function) const;
1945
1946 RawObject setter() const;
1947 void setSetter(RawObject function) const;
1948
1949 RawObject deleter() const;
1950 void setDeleter(RawObject function) const;
1951
1952 // Layout.
1953 static const int kGetterOffset = RawHeapObject::kSize;
1954 static const int kSetterOffset = kGetterOffset + kPointerSize;
1955 static const int kDeleterOffset = kSetterOffset + kPointerSize;
1956 static const int kDocOffset = kDeleterOffset + kPointerSize;
1957 static const int kSize = kDocOffset + kPointerSize;
1958
1959 RAW_OBJECT_COMMON(Property);
1960};
1961
1962class RawRange : public RawInstance {
1963 public:
1964 // Getters and setters.
1965 RawObject start() const;
1966 void setStart(RawObject value) const;
1967
1968 RawObject stop() const;
1969 void setStop(RawObject value) const;
1970
1971 RawObject step() const;
1972 void setStep(RawObject value) const;
1973
1974 // Layout.
1975 static const int kStartOffset = RawHeapObject::kSize;
1976 static const int kStopOffset = kStartOffset + kPointerSize;
1977 static const int kStepOffset = kStopOffset + kPointerSize;
1978 static const int kSize = kStepOffset + kPointerSize;
1979
1980 RAW_OBJECT_COMMON(Range);
1981};
1982
1983class RawSlice : public RawInstance {
1984 public:
1985 // Getters.
1986 RawObject start() const;
1987 RawObject stop() const;
1988 RawObject step() const;
1989
1990 // Calculate the number of items that a slice addresses
1991 static word length(word start, word stop, word step);
1992
1993 // Adjusts the slice indices to fit a collection with the given length.
1994 // Returns the length of the slice, and modifies start and stop to fit within
1995 // the bounds of the collection.
1996 //
1997 // If start or stop is negative, adjust them relative to length. If they are
1998 // still negative, sets them to zero. Limits start and stop to the length of
1999 // the collection if they are greater than the length.
2000 static word adjustIndices(word length, word* start, word* stop, word step);
2001
2002 // Adjusts the bounds for searching a collection of the given length.
2003 //
2004 // NOTE: While this function is mostly the same as adjustIndices(), it does
2005 // not modify the start index when it is greater than the length.
2006 static void adjustSearchIndices(word* start, word* end, word length);
2007
2008 // Layout.
2009 static const int kStartOffset = RawHeapObject::kSize;
2010 static const int kStopOffset = kStartOffset + kPointerSize;
2011 static const int kStepOffset = kStopOffset + kPointerSize;
2012 static const int kSize = kStepOffset + kPointerSize;
2013
2014 RAW_OBJECT_COMMON(Slice);
2015
2016 private:
2017 // Setters.
2018 void setStart(RawObject value) const;
2019 void setStep(RawObject value) const;
2020 void setStop(RawObject value) const;
2021
2022 friend class Runtime;
2023};
2024
2025class RawSlotDescriptor : public RawInstance {
2026 public:
2027 // Setters and getters.
2028 // Type that this descriptor is created for.
2029 RawObject type() const;
2030 void setType(RawObject type) const;
2031
2032 // Name of attribute that this descriptor wraps.
2033 RawObject name() const;
2034 void setName(RawObject name) const;
2035
2036 // Offset of the attribute this descriptor is for.
2037 word offset() const;
2038 void setOffset(word offset) const;
2039
2040 // Layout.
2041 static const int kTypeOffset = RawHeapObject::kSize;
2042 static const int kNameOffset = kTypeOffset + kPointerSize;
2043 static const int kOffsetOffset = kNameOffset + kPointerSize;
2044 static const int kSize = kOffsetOffset + kPointerSize;
2045
2046 RAW_OBJECT_COMMON(SlotDescriptor);
2047};
2048
2049class RawStaticMethod : public RawInstance {
2050 public:
2051 // Getters and setters
2052 RawObject function() const;
2053 void setFunction(RawObject function) const;
2054
2055 // Layout.
2056 static const int kFunctionOffset = RawHeapObject::kSize;
2057 static const int kSize = kFunctionOffset + kPointerSize;
2058
2059 RAW_OBJECT_COMMON(StaticMethod);
2060};
2061
2062class RawIteratorBase : public RawInstance {
2063 public:
2064 // Getters and setters.
2065 word index() const;
2066 void setIndex(word index) const;
2067
2068 RawObject iterable() const;
2069 void setIterable(RawObject iterable) const;
2070
2071 // Layout.
2072 static const int kIterableOffset = RawHeapObject::kSize;
2073 static const int kIndexOffset = kIterableOffset + kPointerSize;
2074 static const int kSize = kIndexOffset + kPointerSize;
2075};
2076
2077class RawEnumerate : public RawInstance {
2078 public:
2079 RAW_OBJECT_COMMON(Enumerate);
2080 static const int kIteratorOffset = RawHeapObject::kSize;
2081 static const int kIndexOffset = kIteratorOffset + kPointerSize;
2082 static const int kSize = kIndexOffset + kPointerSize;
2083};
2084
2085class RawBytearrayIterator : public RawIteratorBase {
2086 public:
2087 RAW_OBJECT_COMMON(BytearrayIterator);
2088};
2089
2090class RawBytesIterator : public RawIteratorBase {
2091 public:
2092 RAW_OBJECT_COMMON(BytesIterator);
2093};
2094
2095class RawDequeIterator : public RawIteratorBase {
2096 public:
2097 // Getters and setters.
2098 word state() const;
2099 void setState(word state) const;
2100
2101 // Layout.
2102 static const int kStateOffset = RawIteratorBase::kSize;
2103 static const int kSize = kStateOffset + kPointerSize;
2104
2105 RAW_OBJECT_COMMON(DequeIterator);
2106};
2107
2108class RawDequeReverseIterator : public RawIteratorBase {
2109 public:
2110 // Getters and setters.
2111 word state() const;
2112 void setState(word state) const;
2113
2114 // Layout.
2115 static const int kStateOffset = RawIteratorBase::kSize;
2116 static const int kSize = kStateOffset + kPointerSize;
2117
2118 RAW_OBJECT_COMMON(DequeReverseIterator);
2119};
2120
2121class RawDictIteratorBase : public RawIteratorBase {
2122 public:
2123 // Getters and setters.
2124
2125 // This looks similar to index but is different and required in order to
2126 // implement interators properly. We cannot use index in __length_hint__
2127 // because index describes the position inside the internal buckets list of
2128 // our implementation of dict -- not the logical number of iterms. Therefore
2129 // we need an additional piece of state that refers to the logical number of
2130 // items seen so far.
2131 word numFound() const;
2132 void setNumFound(word num_found) const;
2133
2134 // Layout
2135 static const int kNumFoundOffset = RawIteratorBase::kSize;
2136 static const int kSize = kNumFoundOffset + kPointerSize;
2137};
2138
2139class RawDictItemIterator : public RawDictIteratorBase {
2140 public:
2141 RAW_OBJECT_COMMON(DictItemIterator);
2142};
2143
2144class RawDictKeyIterator : public RawDictIteratorBase {
2145 public:
2146 RAW_OBJECT_COMMON(DictKeyIterator);
2147};
2148
2149class RawDictValueIterator : public RawDictIteratorBase {
2150 public:
2151 RAW_OBJECT_COMMON(DictValueIterator);
2152};
2153
2154class RawListIterator : public RawIteratorBase {
2155 public:
2156 RAW_OBJECT_COMMON(ListIterator);
2157};
2158
2159class RawLongRangeIterator : public RawInstance {
2160 public:
2161 // Getters and setters.
2162 RawObject next() const;
2163 void setNext(RawObject next) const;
2164
2165 RawObject stop() const;
2166 void setStop(RawObject stop) const;
2167
2168 RawObject step() const;
2169 void setStep(RawObject step) const;
2170
2171 // Layout.
2172 static const int kNextOffset = RawHeapObject::kSize;
2173 static const int kStopOffset = kNextOffset + kPointerSize;
2174 static const int kStepOffset = kStopOffset + kPointerSize;
2175 static const int kSize = kStepOffset + kPointerSize;
2176
2177 RAW_OBJECT_COMMON(LongRangeIterator);
2178};
2179
2180// RangeIterator guarantees that start, stop, step, and length are all SmallInt.
2181class RawRangeIterator : public RawInstance {
2182 public:
2183 // Getters and setters.
2184 word next() const;
2185 void setNext(word next) const;
2186
2187 word step() const;
2188 void setStep(word step) const;
2189
2190 word length() const;
2191 void setLength(word length) const;
2192
2193 // Layout.
2194 static const int kNextOffset = RawHeapObject::kSize;
2195 static const int kStepOffset = kNextOffset + kPointerSize;
2196 static const int kLengthOffset = kStepOffset + kPointerSize;
2197 static const int kSize = kLengthOffset + kPointerSize;
2198
2199 RAW_OBJECT_COMMON(RangeIterator);
2200};
2201
2202class RawSeqIterator : public RawIteratorBase {
2203 public:
2204 RAW_OBJECT_COMMON(SeqIterator);
2205};
2206
2207class RawSetIterator : public RawIteratorBase {
2208 public:
2209 // Getters and setters
2210 word consumedCount() const;
2211 void setConsumedCount(word consumed) const;
2212
2213 // Layout.
2214 static const int kConsumedCountOffset = RawIteratorBase::kSize;
2215 static const int kSize = kConsumedCountOffset + kPointerSize;
2216
2217 RAW_OBJECT_COMMON(SetIterator);
2218};
2219
2220class RawStrIterator : public RawIteratorBase {
2221 public:
2222 RAW_OBJECT_COMMON(StrIterator);
2223};
2224
2225class RawTupleIterator : public RawIteratorBase {
2226 public:
2227 // Getters and setters.
2228 word length() const;
2229 void setLength(word length) const;
2230
2231 // Layout.
2232 static const int kLengthOffset = RawIteratorBase::kSize;
2233 static const int kSize = kLengthOffset + kPointerSize;
2234
2235 RAW_OBJECT_COMMON(TupleIterator);
2236};
2237
2238class RawCode : public RawInstance {
2239 public:
2240 // Matching CPython
2241 enum Flags {
2242 // Local variables are organized in an array and LOAD_FAST/STORE_FAST are
2243 // used when this flag is set. Otherwise local variable accesses use
2244 // LOAD_NAME/STORE_NAME to modify a dictionary ("implicit globals").
2245 kOptimized = 0x0001,
2246 // Local variables start in an uninitialized state. If this is not set then
2247 // the variables are initialized with the values in the implicit globals.
2248 kNewlocals = 0x0002,
2249 kVarargs = 0x0004,
2250 kVarkeyargs = 0x0008,
2251 kNested = 0x0010,
2252 kGenerator = 0x0020,
2253 kNofree = 0x0040, // Shortcut for no free or cell vars
2254 kCoroutine = 0x0080,
2255 kIterableCoroutine = 0x0100,
2256 kAsyncGenerator = 0x0200,
2257 kFutureDivision = 0x20000,
2258 kFutureAbsoluteImport = 0x40000,
2259 kFutureWithStatement = 0x80000,
2260 kFuturePrintFunction = 0x100000,
2261 kFutureUnicodeLiterals = 0x200000,
2262 kFutureBarryAsBdfl = 0x400000,
2263 kFutureGeneratorStop = 0x800000,
2264 kFutureAnnotations = 0x1000000,
2265 kBuiltin = 0x2000000,
2266 kMetadata = 0x4000000,
2267 kLast = kMetadata,
2268 };
2269
2270 // Getters and setters.
2271 word argcount() const;
2272 void setArgcount(word value) const;
2273 word totalArgs() const;
2274
2275 // The number of positional only arguments.
2276 word posonlyargcount() const;
2277 void setPosonlyargcount(word value) const;
2278
2279 RawObject cell2arg() const;
2280 void setCell2arg(RawObject value) const;
2281
2282 RawObject cellvars() const;
2283 void setCellvars(RawObject value) const;
2284 word numCellvars() const;
2285
2286 RawObject code() const;
2287 void setCode(RawObject value) const;
2288
2289 RawObject consts() const;
2290 void setConsts(RawObject value) const;
2291
2292 RawObject filename() const;
2293 void setFilename(RawObject value) const;
2294
2295 word firstlineno() const;
2296 void setFirstlineno(word value) const;
2297
2298 word flags() const;
2299 void setFlags(word value) const;
2300
2301 RawObject freevars() const;
2302 void setFreevars(RawObject value) const;
2303 word numFreevars() const;
2304
2305 bool isAsyncGenerator() const;
2306 bool isGeneratorLike() const;
2307 bool hasFreevarsOrCellvars() const;
2308 bool hasOptimizedAndNewlocals() const;
2309 bool hasOptimizedOrNewlocals() const;
2310
2311 bool isNative() const;
2312
2313 word kwonlyargcount() const;
2314 void setKwonlyargcount(word value) const;
2315
2316 RawObject lnotab() const;
2317 void setLnotab(RawObject value) const;
2318
2319 RawObject name() const;
2320 void setName(RawObject value) const;
2321
2322 RawObject names() const;
2323 void setNames(RawObject value) const;
2324
2325 word nlocals() const;
2326 void setNlocals(word value) const;
2327
2328 // Converts the offset in this code's bytecode into the corresponding line
2329 // number in the backing source file.
2330 word offsetToLineNum(word offset) const;
2331
2332 word stacksize() const;
2333 void setStacksize(word value) const;
2334
2335 RawObject varnames() const;
2336 void setVarnames(RawObject value) const;
2337
2338 // Returns nullptr if the function cannot be executed without a frame.
2339 void* intrinsic() const;
2340 void setIntrinsic(void* fp) const;
2341
2342 // Layout.
2343 static const int kArgcountOffset = RawHeapObject::kSize;
2344 static const int kPosonlyargcountOffset = kArgcountOffset + kPointerSize;
2345 static const int kKwonlyargcountOffset =
2346 kPosonlyargcountOffset + kPointerSize;
2347 static const int kNlocalsOffset = kKwonlyargcountOffset + kPointerSize;
2348 static const int kStacksizeOffset = kNlocalsOffset + kPointerSize;
2349 static const int kFlagsOffset = kStacksizeOffset + kPointerSize;
2350 static const int kFirstlinenoOffset = kFlagsOffset + kPointerSize;
2351 static const int kCodeOffset = kFirstlinenoOffset + kPointerSize;
2352 static const int kConstsOffset = kCodeOffset + kPointerSize;
2353 static const int kNamesOffset = kConstsOffset + kPointerSize;
2354 static const int kVarnamesOffset = kNamesOffset + kPointerSize;
2355 static const int kFreevarsOffset = kVarnamesOffset + kPointerSize;
2356 static const int kCellvarsOffset = kFreevarsOffset + kPointerSize;
2357 static const int kCell2argOffset = kCellvarsOffset + kPointerSize;
2358 static const int kFilenameOffset = kCell2argOffset + kPointerSize;
2359 static const int kNameOffset = kFilenameOffset + kPointerSize;
2360 static const int kLnotabOffset = kNameOffset + kPointerSize;
2361 static const int kIntrinsicOffset = kLnotabOffset + kPointerSize;
2362 static const int kSize = kIntrinsicOffset + kPointerSize;
2363
2364 static const word kCompileFlagsMask =
2365 Flags::kFutureDivision | Flags::kFutureAbsoluteImport |
2366 Flags::kFutureWithStatement | Flags::kFuturePrintFunction |
2367 Flags::kFutureUnicodeLiterals | Flags::kFutureBarryAsBdfl |
2368 Flags::kFutureGeneratorStop | Flags::kFutureAnnotations;
2369
2370 RAW_OBJECT_COMMON(Code);
2371};
2372
2373// A function object.
2374//
2375// This may contain a user-defined function or a built-in function.
2376//
2377// RawFunction objects have a set of pre-defined attributes, only some of which
2378// are writable outside of the runtime. The full set is defined at
2379//
2380// https://docs.python.org/3/reference/datamodel.html
2381class RawFunction : public RawInstance {
2382 public:
2383 // An entry point into a function.
2384 //
2385 // The entry point is called with the current thread, the caller's stack
2386 // frame, and the number of arguments that have been pushed onto the stack.
2387 using Entry = RawObject (*)(Thread*, word);
2388
2389 enum Flags {
2390 kNone = 0,
2391 // Matching Code::Flags (and CPython)
2392 kOptimized = RawCode::Flags::kOptimized,
2393 kNewlocals = RawCode::Flags::kNewlocals,
2394 kVarargs = RawCode::Flags::kVarargs,
2395 kVarkeyargs = RawCode::Flags::kVarkeyargs,
2396 kNested = RawCode::Flags::kNested,
2397 kGenerator = RawCode::Flags::kGenerator,
2398 kNofree = RawCode::Flags::kNofree,
2399 kCoroutine = RawCode::Flags::kCoroutine,
2400 kIterableCoroutine = RawCode::Flags::kIterableCoroutine,
2401 kAsyncGenerator = RawCode::Flags::kAsyncGenerator,
2402 kSimpleCall = RawCode::Flags::kLast << 1, // Speeds detection of fast call
2403 kInterpreted = RawCode::Flags::kLast << 2, // Executable by the interpreter
2404 kExtension = RawCode::Flags::kLast << 3, // C-API extension function
2405 kCompiled = RawCode::Flags::kLast << 4, // JIT-compiled
2406 kLast = kCompiled,
2407 };
2408
2409 // Getters and setters.
2410
2411 // A dict containing parameter annotations
2412 RawObject annotations() const;
2413 void setAnnotations(RawObject annotations) const;
2414
2415 // The number of positional arguments.
2416 word argcount() const;
2417 void setArgcount(word value) const;
2418
2419 // The code object backing this function or None
2420 RawObject code() const;
2421 void setCode(RawObject code) const;
2422
2423 // A tuple of cell objects that contain bindings for the function's free
2424 // variables. Read-only to user code.
2425 RawObject closure() const;
2426 void setClosure(RawObject closure) const;
2427
2428 // A tuple containing default values for arguments with defaults. Read-only
2429 // to user code.
2430 RawObject defaults() const;
2431 void setDefaults(RawObject defaults) const;
2432 bool hasDefaults() const;
2433
2434 // The function's docstring
2435 RawObject doc() const;
2436 void setDoc(RawObject doc) const;
2437
2438 // Returns the entry to be used when the function is invoked via
2439 // CALL_FUNCTION
2440 Entry entry() const;
2441 void setEntry(Entry thunk) const;
2442
2443 // Returns the entry to be used when the function is invoked via
2444 // CALL_FUNCTION_KW
2445 Entry entryKw() const;
2446 void setEntryKw(Entry thunk) const;
2447
2448 // Returns the entry to be used when the function is invoked via
2449 // CALL_FUNCTION_EX
2450 Entry entryEx() const;
2451 void setEntryEx(Entry thunk) const;
2452
2453 // Returns the entry to be used when the function is invoked in assembly.
2454 void* entryAsm() const;
2455 void setEntryAsm(void* thunk) const;
2456
2457 // Returns the function flags.
2458 word flags() const;
2459 void setFlags(word flags) const;
2460
2461 // Returns true if the function is an async generator.
2462 bool isAsyncGenerator() const;
2463
2464 // Returns true if the function is a coroutine.
2465 bool isCoroutine() const;
2466
2467 // Returns true if function has `kExtension` flag set.
2468 bool isExtension() const;
2469
2470 // Returns true if function has `kCompiled` flag set.
2471 bool isCompiled() const;
2472
2473 // Returns true if the function is a coroutine, a generator, or an async
2474 // generator.
2475 bool isGeneratorLike() const;
2476
2477 // Returns true if the function has free variables or cell variables.
2478 bool hasFreevarsOrCellvars() const;
2479
2480 // Returns true if the function is a generator.
2481 bool isGenerator() const;
2482
2483 // Returns true if the function is an iterable coroutine.
2484 bool isIterableCoroutine() const;
2485
2486 // Returns true if the function has the optimized or newlocals flag.
2487 bool hasOptimizedOrNewlocals() const;
2488
2489 // Returns true if the function has a simple calling convention.
2490 bool hasSimpleCall() const;
2491
2492 // Returns true if the function has varargs.
2493 bool hasVarargs() const;
2494
2495 // Returns true if the function has varargs or varkeyword arguments.
2496 bool hasVarargsOrVarkeyargs() const;
2497
2498 // Returns true if the function has varkeyword arguments.
2499 bool hasVarkeyargs() const;
2500
2501 // Returns true if the function consists of bytecode that can be executed
2502 // normally by the interpreter.
2503 bool isInterpreted() const;
2504 void setIsInterpreted(bool interpreted) const;
2505
2506 // Returns nullptr if the function cannot be executed without a frame.
2507 void* intrinsic() const;
2508 void setIntrinsic(void* fp) const;
2509
2510 // A dict containing defaults for keyword-only parameters
2511 RawObject kwDefaults() const;
2512 void setKwDefaults(RawObject kw_defaults) const;
2513
2514 // The name of the module the function was defined in
2515 RawObject moduleName() const;
2516 void setModuleName(RawObject module_name) const;
2517
2518 // The module where this function was defined
2519 RawObject moduleObject() const;
2520 void setModuleObject(RawObject module) const;
2521
2522 // The function's name
2523 RawObject name() const;
2524 void setName(RawObject name) const;
2525
2526 // The function's qualname
2527 RawObject qualname() const;
2528 void setQualname(RawObject qualname) const;
2529
2530 // Maximum stack size used by the bytecode.
2531 RawObject stacksizeOrBuiltin() const;
2532 void setStacksizeOrBuiltin(RawObject stacksize_or_builtin) const;
2533
2534 // Returns the number of parameters. This includes `code.argcount()`,
2535 // `code.kwonlyargcount()`, and an extra parameter for varargs and for
2536 // varkeyargs argument when necessary.
2537 word totalArgs() const;
2538 void setTotalArgs(word value) const;
2539
2540 // Returns number of variables. This is the number of locals that are not
2541 // parameters plus the number of cell variables and free variables.
2542 word totalVars() const;
2543 void setTotalVars(word value) const;
2544
2545 // Returns the number of locals. This is equivalent to
2546 // `code().nlocals() + code().numFreevars() + code().numCellvars()`.
2547 word totalLocals() const;
2548
2549 // Bytecode rewritten to a variant that uses inline caching.
2550 RawObject rewrittenBytecode() const;
2551 void setRewrittenBytecode(RawObject rewritten_bytecode) const;
2552
2553 // Tuple with values of the inline caches. See `ic.h`.
2554 RawObject caches() const;
2555 void setCaches(RawObject cache) const;
2556
2557 // The function's dictionary
2558 RawObject dict() const;
2559 void setDict(RawObject dict) const;
2560
2561 // Layout.
2562 static const int kCodeOffset = RawHeapObject::kSize;
2563 static const int kFlagsOffset = kCodeOffset + kPointerSize;
2564 static const int kArgcountOffset = kFlagsOffset + kPointerSize;
2565 static const int kTotalArgsOffset = kArgcountOffset + kPointerSize;
2566 static const int kTotalVarsOffset = kTotalArgsOffset + kPointerSize;
2567 static const int kStacksizeOrBuiltinOffset = kTotalVarsOffset + kPointerSize;
2568 static const int kDocOffset = kStacksizeOrBuiltinOffset + kPointerSize;
2569 static const int kNameOffset = kDocOffset + kPointerSize;
2570 static const int kQualnameOffset = kNameOffset + kPointerSize;
2571 static const int kModuleNameOffset = kQualnameOffset + kPointerSize;
2572 static const int kModuleObjectOffset = kModuleNameOffset + kPointerSize;
2573 static const int kDefaultsOffset = kModuleObjectOffset + kPointerSize;
2574 static const int kAnnotationsOffset = kDefaultsOffset + kPointerSize;
2575 static const int kKwDefaultsOffset = kAnnotationsOffset + kPointerSize;
2576 static const int kClosureOffset = kKwDefaultsOffset + kPointerSize;
2577 static const int kEntryOffset = kClosureOffset + kPointerSize;
2578 static const int kEntryKwOffset = kEntryOffset + kPointerSize;
2579 static const int kEntryExOffset = kEntryKwOffset + kPointerSize;
2580 static const int kEntryAsmOffset = kEntryExOffset + kPointerSize;
2581 static const int kRewrittenBytecodeOffset = kEntryAsmOffset + kPointerSize;
2582 static const int kCachesOffset = kRewrittenBytecodeOffset + kPointerSize;
2583 static const int kDictOffset = kCachesOffset + kPointerSize;
2584 static const int kIntrinsicOffset = kDictOffset + kPointerSize;
2585 static const int kSize = kIntrinsicOffset + kPointerSize;
2586
2587 RAW_OBJECT_COMMON(Function);
2588};
2589
2590class RawMappingProxy : public RawInstance {
2591 public:
2592 // Setters and getters.
2593 RawObject mapping() const;
2594 void setMapping(RawObject mapping) const;
2595
2596 // Layout.
2597 static const int kMappingOffset = RawHeapObject::kSize;
2598 static const int kSize = kMappingOffset + kPointerSize;
2599
2600 RAW_OBJECT_COMMON(MappingProxy);
2601};
2602
2603// Descriptor for a block of memory.
2604// Contrary to cpython, this is a reference to a `bytes` object which may be
2605// moved around by the garbage collector.
2606class RawMemoryView : public RawInstance {
2607 public:
2608 // Setters and getters.
2609 RawObject buffer() const;
2610 void setBuffer(RawObject buffer) const;
2611
2612 RawObject format() const;
2613 void setFormat(RawObject format) const;
2614
2615 // Length in bytes.
2616 word length() const;
2617 void setLength(word length) const;
2618
2619 // Original object that memoryview was created with
2620 RawObject object() const;
2621 void setObject(RawObject object) const;
2622
2623 // An integer indicating how many dimensions of a multi-dimensional array the
2624 // memory represents.
2625 RawObject ndim() const;
2626 void setNdim(RawObject ndim) const;
2627
2628 // Tuple of integers giving the shape of the memory as an N-dimensional array
2629 // In the 1-D case, shape will have one value which is equal to the length
2630 RawObject shape() const;
2631 void setShape(RawObject shape) const;
2632
2633 // Private variable used to store the starting index of a memoryview.
2634 // Default value is 0
2635 word start() const;
2636 void setStart(word start) const;
2637
2638 // Tuple of integers used to keep track of the number of bytes to step in each
2639 // dimension when traversing a memoryview buffer. In the 1-D case, strides
2640 // will will have one value which is equal to the step
2641 // Default value is (1,)
2642 RawObject strides() const;
2643 void setStrides(RawObject strides) const;
2644
2645 bool readOnly() const;
2646 void setReadOnly(bool read_only) const;
2647
2648 // Layout.
2649 static const int kBufferOffset = RawHeapObject::kSize;
2650 static const int kFormatOffset = kBufferOffset + kPointerSize;
2651 static const int kLengthOffset = kFormatOffset + kPointerSize;
2652 static const int kReadOnlyOffset = kLengthOffset + kPointerSize;
2653 static const int kObjectOffset = kReadOnlyOffset + kPointerSize;
2654 static const int kShapeOffset = kObjectOffset + kPointerSize;
2655 static const int kStartOffset = kShapeOffset + kPointerSize;
2656 static const int kStridesOffset = kStartOffset + kPointerSize;
2657 static const int kNdimOffset = kStridesOffset + kPointerSize;
2658 static const int kSize = kNdimOffset + kPointerSize;
2659
2660 RAW_OBJECT_COMMON(MemoryView);
2661};
2662
2663class RawModule : public RawAttributeDict {
2664 public:
2665 // Setters and getters.
2666 RawObject name() const;
2667 void setName(RawObject name) const;
2668
2669 // Contains the numeric address of mode definition object for C-API modules or
2670 // zero if the module was not defined through the C-API.
2671 RawObject def() const;
2672 bool hasDef() const;
2673 void setDef(RawObject def) const;
2674
2675 // Contains the numeric address of module state object for C-API modules or
2676 // zero if the module was not defined through the C-API.
2677 RawObject state() const;
2678 bool hasState() const;
2679 void setState(RawObject state) const;
2680
2681 // Lazily allocated ModuleProxy instance that behaves like dict.
2682 RawObject moduleProxy() const;
2683 void setModuleProxy(RawObject module_proxy) const;
2684
2685 // Unique ID allocated at module creation time.
2686 word id() const;
2687 void setId(word id) const;
2688
2689 // Layout.
2690 static const int kNameOffset = RawAttributeDict::kSize;
2691 static const int kDefOffset = kNameOffset + kPointerSize;
2692 static const int kStateOffset = kDefOffset + kPointerSize;
2693 static const int kModuleProxyOffset = kStateOffset + kPointerSize;
2694 static const int kSize = kModuleProxyOffset + kPointerSize;
2695
2696 // Constants.
2697 static const word kMaxModuleId = RawHeader::kHashCodeMask;
2698
2699 RAW_OBJECT_COMMON(Module);
2700};
2701
2702class RawModuleProxy : public RawInstance {
2703 public:
2704 // Module that this ModuleProxy is created for.
2705 // moduleproxy.module().moduleproxy() == moduleproxy holds.
2706 RawObject module() const;
2707 void setModule(RawObject module) const;
2708
2709 // Layout.
2710 static const int kModuleOffset = RawHeapObject::kSize;
2711 static const int kSize = kModuleOffset + kPointerSize;
2712
2713 RAW_OBJECT_COMMON(ModuleProxy);
2714};
2715
2716// A mutable array of bytes.
2717//
2718// Invariant: All allocated bytes past the end of the array are 0.
2719// Invariant: items() is a MutableBytes.
2720//
2721// RawLayout:
2722// [Header ]
2723// [Items ] - Pointer to a RawMutableBytes with the underlying data.
2724// [NumItems] - Number of bytes currently in the array.
2725class RawBytearray : public RawInstance {
2726 public:
2727 // Getters and setters
2728 byte byteAt(word index) const;
2729 void byteAtPut(word index, byte value) const;
2730 void copyTo(byte* dst, word length) const;
2731 RawObject items() const;
2732 void setItems(RawObject new_items) const;
2733 word numItems() const;
2734 void setNumItems(word num_bytes) const;
2735 void downsize(word new_length) const;
2736
2737 // The size of the underlying bytes
2738 word capacity() const;
2739
2740 // Compares the bytes in this to the bytes in that. Returns a negative value
2741 // if this is less than that, positive if this is greater than that, and zero
2742 // if they have the same bytes. Does not guarantee to return -1, 0, or 1.
2743 word compare(RawBytes that, word that_len);
2744
2745 // Replace the bytes from dst_start with count bytes from src
2746 void replaceFromWith(word dst_start, RawBytearray src, word count) const;
2747
2748 // Replace the bytes from dst_start with count bytes from src, starting at
2749 // src_start in src
2750 void replaceFromWithStartAt(word dst_start, RawBytearray src, word count,
2751 word src_start) const;
2752
2753 // Layout
2754 static const int kItemsOffset = RawHeapObject::kSize;
2755 static const int kNumItemsOffset = kItemsOffset + kPointerSize;
2756 static const int kSize = kNumItemsOffset + kPointerSize;
2757
2758 RAW_OBJECT_COMMON(Bytearray);
2759};
2760
2761// A mutable Unicode array, for internal string building.
2762//
2763// Invariant: The allocated code units form valid UTF-8.
2764//
2765// RawLayout:
2766// [Header ]
2767// [Items ] - Pointer to a RawMutableBytes with the underlying data.
2768// [NumItems] - Number of bytes currently in the array.
2769class RawStrArray : public RawInstance {
2770 public:
2771 // Getters and setters
2772 RawObject items() const;
2773 void setItems(RawObject new_items) const;
2774 word numItems() const;
2775 void setNumItems(word num_items) const;
2776
2777 void copyTo(byte* dst, word length) const;
2778 int32_t codePointAt(word index, word* length) const;
2779
2780 // Returns an index into a string offset by either a positive or negative
2781 // number of code points. Otherwise, if the new index would be negative, -1
2782 // is returned or if the new index would be greater than the length of the
2783 // string, the length is returned.
2784 word offsetByCodePoints(word char_index, word count) const;
2785
2786 // Rotate the code point from `last` to `first`.
2787 void rotateCodePoint(word first, word last) const;
2788
2789 // The size of the underlying string in bytes.
2790 word capacity() const;
2791
2792 // Layout
2793 static const int kItemsOffset = RawHeapObject::kSize;
2794 static const int kNumItemsOffset = kItemsOffset + kPointerSize;
2795 static const int kSize = kNumItemsOffset + kPointerSize;
2796
2797 RAW_OBJECT_COMMON(StrArray);
2798};
2799
2800// A double-ended queue
2801//
2802// RawLayout:
2803// [Header ]
2804// [Items ] - data
2805// [Left ] - head element
2806// [NumItems] - number of elements
2807// [Maxlen ] - maximum capacity
2808class RawDeque : public RawInstance {
2809 public:
2810 RawObject at(word index) const;
2811 void atPut(word index, RawObject value) const;
2812
2813 // Returns the total number of elements that may be held without growing
2814 // the underlying MutableTuple
2815 word capacity() const;
2816
2817 void clear() const;
2818
2819 // Getters and Setters
2820 RawObject items() const;
2821 void setItems(RawObject new_items) const;
2822
2823 word left() const;
2824 void setLeft(word left) const;
2825
2826 word numItems() const;
2827 void setNumItems(word num_items) const;
2828
2829 RawObject maxlen() const;
2830 void setMaxlen(RawObject maxlen) const;
2831
2832 word state() const;
2833 void setState(word state) const;
2834
2835 // Layout.
2836 static const int kItemsOffset = RawHeapObject::kSize;
2837 static const int kLeftOffset = kItemsOffset + kPointerSize;
2838 static const int kNumItemsOffset = kLeftOffset + kPointerSize;
2839 static const int kMaxlenOffset = kNumItemsOffset + kPointerSize;
2840 static const int kStateOffset = kMaxlenOffset + kPointerSize;
2841 static const int kSize = kStateOffset + kPointerSize;
2842
2843 RAW_OBJECT_COMMON(Deque);
2844};
2845
2846// A simple dict that uses open addressing and linear probing.
2847//
2848// RawLayout:
2849//
2850// [Header ]
2851// [NumItems] - Number of items currently in the dict
2852// [Data ] - RawTuple that stores the underlying data.
2853// [Indices ] - RawTuple storing indices into the data tuple.
2854// [FirstEmptyItemIndex] - Index pointing to the first empty item in data.
2855//
2856class RawDict : public RawInstance {
2857 public:
2858 // Number of items currently in the dict
2859 word numItems() const;
2860 void setNumItems(word num_items) const;
2861
2862 // Getters and setters.
2863 // RawTuple that stores the underlying data.
2864 RawObject data() const;
2865 void setData(RawObject data) const;
2866
2867 // RawTuple storing indices into the data tuple.
2868 RawObject indices() const;
2869 void setIndices(RawObject index_data) const;
2870
2871 // Index pointing to the first empty item in data.
2872 word firstEmptyItemIndex() const;
2873 void setFirstEmptyItemIndex(word first_empty_item_index) const;
2874
2875 // Number of indices.
2876 word numIndices() const;
2877
2878 // Layout.
2879 static const int kNumItemsOffset = RawHeapObject::kSize;
2880 static const int kDataOffset = kNumItemsOffset + kPointerSize;
2881 static const int kIndicesOffset = kDataOffset + kPointerSize;
2882 static const int kFirstEmptyItemIndexOffset = kIndicesOffset + kPointerSize;
2883 static const int kSize = kFirstEmptyItemIndexOffset + kPointerSize;
2884
2885 RAW_OBJECT_COMMON(Dict);
2886};
2887
2888class RawDictViewBase : public RawInstance {
2889 public:
2890 // Getters and setters
2891 RawObject dict() const;
2892 void setDict(RawObject dict) const;
2893
2894 // Layout
2895 static const int kDictOffset = RawHeapObject::kSize;
2896 static const int kSize = kDictOffset + kPointerSize;
2897};
2898
2899class RawDictItems : public RawDictViewBase {
2900 public:
2901 RAW_OBJECT_COMMON(DictItems);
2902};
2903
2904class RawDictKeys : public RawDictViewBase {
2905 public:
2906 RAW_OBJECT_COMMON(DictKeys);
2907};
2908
2909class RawDictValues : public RawDictViewBase {
2910 public:
2911 RAW_OBJECT_COMMON(DictValues);
2912};
2913
2914// A simple set implementation. Used by set and frozenset.
2915class RawSetBase : public RawInstance {
2916 public:
2917 // Getters and setters.
2918 // The RawTuple backing the set
2919 RawObject data() const;
2920 void setData(RawObject data) const;
2921
2922 // Number of items currently in the set
2923 word numItems() const;
2924 void setNumItems(word num_items) const;
2925
2926 // Number of active and tombstone items in the set
2927 word numFilled() const;
2928 void setNumFilled(word num_filled) const;
2929
2930 // Layout.
2931 static const int kDataOffset = RawHeapObject::kSize;
2932 static const int kNumItemsOffset = kDataOffset + kPointerSize;
2933 static const int kNumFilledOffset = kNumItemsOffset + kPointerSize;
2934 static const int kSize = kNumFilledOffset + kPointerSize;
2935
2936 RAW_OBJECT_COMMON(SetBase);
2937};
2938
2939class RawSet : public RawSetBase {
2940 public:
2941 RAW_OBJECT_COMMON(Set);
2942};
2943
2944class RawFrozenSet : public RawSetBase {
2945 public:
2946 RAW_OBJECT_COMMON(FrozenSet);
2947};
2948
2949// A growable array
2950//
2951// RawLayout:
2952//
2953// [Header ]
2954// [Items ] - Pointer to an RawTuple that contains list elements
2955// [NumItems] - Number of elements currently in the list
2956class RawList : public RawInstance {
2957 public:
2958 // Getters and setters.
2959 RawObject at(word index) const;
2960 void atPut(word index, RawObject value) const;
2961 RawObject items() const;
2962 void setItems(RawObject new_items) const;
2963 word numItems() const;
2964 void setNumItems(word num_items) const;
2965 void clearFrom(word idx) const;
2966
2967 // Return the total number of elements that may be held without growing the
2968 // list
2969 word capacity() const;
2970
2971 // Copy count elements from src to this list, starting at index start
2972 void replaceFromWith(word start, RawList src, word count) const;
2973
2974 // Copy count elements from src to this list, starting at index start in the
2975 // destination and index src_start in the source
2976 void replaceFromWithStartAt(word start, RawList src, word count,
2977 word src_start) const;
2978
2979 // Swap elements at indices i, j
2980 void swap(word i, word j) const;
2981
2982 // Layout.
2983 static const int kItemsOffset = RawHeapObject::kSize;
2984 static const int kNumItemsOffset = kItemsOffset + kPointerSize;
2985 static const int kSize = kNumItemsOffset + kPointerSize;
2986
2987 RAW_OBJECT_COMMON(List);
2988};
2989
2990class RawValueCell : public RawInstance {
2991 public:
2992 // Getters and setters
2993 RawObject value() const;
2994 void setValue(RawObject object) const;
2995 RawObject dependencyLink() const;
2996 void setDependencyLink(RawObject object) const;
2997 bool isPlaceholder() const;
2998 void makePlaceholder() const;
2999
3000 // Layout.
3001 static const int kValueOffset = RawHeapObject::kSize;
3002 static const int kDependencyLinkOffset = kValueOffset + kPointerSize;
3003 static const int kSize = kDependencyLinkOffset + kPointerSize;
3004
3005 RAW_OBJECT_COMMON(ValueCell);
3006};
3007
3008class RawEllipsis : public RawHeapObject {
3009 public:
3010 static word allocationSize();
3011
3012 // Initialization should only be done by the Runtime.
3013 static RawObject initialize(uword address);
3014
3015 RAW_OBJECT_COMMON(Ellipsis);
3016};
3017
3018class RawToken : public RawInstance {
3019 public:
3020 // Getters and setters
3021 RawObject context() const;
3022 void setContext(RawObject context) const;
3023
3024 RawObject oldValue() const;
3025 void setOldValue(RawObject old_value) const;
3026
3027 bool used() const;
3028 void setUsed(bool used) const;
3029
3030 RawObject var() const;
3031 void setVar(RawObject var) const;
3032
3033 // Layout
3034 static const int kContextOffset = RawHeapObject::kSize;
3035 static const int kOldValueOffset = kContextOffset + kPointerSize;
3036 static const int kUsedOffset = kOldValueOffset + kPointerSize;
3037 static const int kVarOffset = kUsedOffset + kPointerSize;
3038 static const int kSize = kVarOffset + kPointerSize;
3039
3040 RAW_OBJECT_COMMON(Token);
3041};
3042
3043class RawWeakRef : public RawInstance {
3044 public:
3045 // Getters and setters
3046
3047 // The object weakly-referenced by this instance. Set to None by the garbage
3048 // collector when the referent is being collected.
3049 RawObject referent() const;
3050 void setReferent(RawObject referent) const;
3051
3052 // A callable object invoked with the weakref object as an argument when the
3053 // referent is deemed to be "near death" and only reachable through a weak
3054 // reference.
3055 RawObject callback() const;
3056 void setCallback(RawObject callable) const;
3057
3058 // A link to another object used by the garbage collector to create sets of
3059 // weak references for delayed processing.
3060 RawObject link() const;
3061 void setLink(RawObject reference) const;
3062
3063 // The referent's hash
3064 RawObject hash() const;
3065 void setHash(RawObject hash) const;
3066
3067 static void enqueue(RawObject reference, RawObject* tail);
3068 static RawObject dequeue(RawObject* tail);
3069 static RawObject spliceQueue(RawObject tail1, RawObject tail2);
3070
3071 // Layout.
3072 static const int kReferentOffset = RawHeapObject::kSize;
3073 static const int kCallbackOffset = kReferentOffset + kPointerSize;
3074 static const int kLinkOffset = kCallbackOffset + kPointerSize;
3075 static const int kHashOffset = kLinkOffset + kPointerSize;
3076 static const int kSize = kHashOffset + kPointerSize;
3077
3078 RAW_OBJECT_COMMON(WeakRef);
3079};
3080
3081class RawUserWeakRefBase : public RawInstance {
3082 public:
3083 // Getters and setters.
3084 RawObject value() const;
3085 void setValue(RawObject value) const;
3086
3087 // RawLayout.
3088 static const int kValueOffset = RawHeapObject::kSize;
3089 static const int kSize = kValueOffset + kPointerSize;
3090
3091 RAW_OBJECT_COMMON_NO_CAST(UserWeakRefBase);
3092};
3093
3094RawWeakRef weakRefUnderlying(RawObject object);
3095
3096class RawWeakProxy : public RawInstance {
3097 public:
3098 // Getters and setters
3099
3100 // The object weakly-referenced by this instance. Set to None by the garbage
3101 // collector when the referent is being collected.
3102 RawObject referent() const;
3103 void setReferent(RawObject referent) const;
3104
3105 // Layout.
3106 static const int kReferentOffset = RawHeapObject::kSize;
3107 static const int kSize = kReferentOffset + kPointerSize;
3108
3109 RAW_OBJECT_COMMON(WeakProxy);
3110};
3111
3112class RawWeakCallableProxy : public RawInstance {
3113 public:
3114 // Getters and setters
3115
3116 // The object weakly-referenced by this instance. Set to None by the garbage
3117 // collector when the referent is being collected.
3118 RawObject referent() const;
3119 void setReferent(RawObject referent) const;
3120
3121 // Layout.
3122 static const int kReferentOffset = RawHeapObject::kSize;
3123 static const int kSize = kReferentOffset + kPointerSize;
3124
3125 RAW_OBJECT_COMMON(WeakCallableProxy);
3126};
3127
3128// RawWeakLink objects are used to form double linked lists where the elements
3129// can still be garbage collected.
3130//
3131// A main usage of this is to maintain a list of function objects
3132// to be notified of global variable cache invalidation.
3133class RawWeakLink : public RawWeakRef {
3134 public:
3135 // Getters and setters.
3136 RawObject next() const;
3137 void setNext(RawObject object) const;
3138 RawObject prev() const;
3139 void setPrev(RawObject object) const;
3140
3141 // Layout.
3142 static const int kNextOffset = RawWeakRef::kSize;
3143 static const int kPrevOffset = kNextOffset + kPointerSize;
3144 static const int kSize = kPrevOffset + kPointerSize;
3145
3146 RAW_OBJECT_COMMON(WeakLink);
3147};
3148
3149// A RawBoundMethod binds a RawFunction and its first argument (called `self`).
3150//
3151// These are typically created as a temporary object during a method call,
3152// though they may be created and passed around freely.
3153//
3154// Consider the following snippet of python code:
3155//
3156// class Foo:
3157// def bar(self):
3158// return self
3159// f = Foo()
3160// f.bar()
3161//
3162// The Python 3.6 bytecode produced for the line `f.bar()` is:
3163//
3164// LOAD_FAST 0 (f)
3165// LOAD_ATTR 1 (bar)
3166// CALL_FUNCTION 0
3167//
3168// The LOAD_ATTR for `f.bar` creates a `RawBoundMethod`, which is then called
3169// directly by the subsequent CALL_FUNCTION opcode.
3170class RawBoundMethod : public RawInstance {
3171 public:
3172 // Getters and setters
3173
3174 // The function to which "self" is bound
3175 RawObject function() const;
3176 void setFunction(RawObject function) const;
3177
3178 // The instance of "self" being bound
3179 RawObject self() const;
3180 void setSelf(RawObject self) const;
3181
3182 // Layout.
3183 static const int kFunctionOffset = RawHeapObject::kSize;
3184 static const int kSelfOffset = kFunctionOffset + kPointerSize;
3185 static const int kSize = kSelfOffset + kPointerSize;
3186
3187 RAW_OBJECT_COMMON(BoundMethod);
3188};
3189
3190class RawCell : public RawInstance {
3191 public:
3192 // Getters and setters
3193 RawObject value() const;
3194 void setValue(RawObject value) const;
3195
3196 // Layout.
3197 static const int kValueOffset = RawHeapObject::kSize;
3198 static const int kSize = kValueOffset + kPointerSize;
3199
3200 RAW_OBJECT_COMMON(Cell);
3201};
3202
3203class RawClassMethod : public RawInstance {
3204 public:
3205 // Getters and setters
3206 RawObject function() const;
3207 void setFunction(RawObject function) const;
3208
3209 // Layout.
3210 static const int kFunctionOffset = RawHeapObject::kSize;
3211 static const int kSize = kFunctionOffset + kPointerSize;
3212
3213 RAW_OBJECT_COMMON(ClassMethod);
3214};
3215
3216// A RawLayout describes the in-memory shape of an instance.
3217//
3218// RawInstance attributes are split into two classes: in-object attributes,
3219// which exist directly in the instance, and overflow attributes, which are
3220// stored in an object array pointed to by the last word of the instance.
3221// Graphically, this looks like:
3222//
3223// RawInstance RawTuple
3224// +---------------------------+ +------->+--------------------------+
3225// | First in-object attribute | | | First overflow attribute |
3226// +---------------------------+ | +--------------------------+
3227// | ... | | | ... |
3228// +---------------------------+ | +--------------------------+
3229// | Last in-object attribute | | | Last overflow attribute |
3230// +---------------------------+ | +--------------------------+
3231// | Overflow Attributes +-----+
3232// +---------------------------+
3233//
3234// Each instance is associated with a layout (whose id is stored in the header
3235// word). The layout acts as a roadmap for the instance; it describes where to
3236// find each attribute.
3237//
3238// In general, instances of the same class will have the same shape. Idiomatic
3239// Python typically initializes attributes in the same order for instances of
3240// the same class. Ideally, we would be able to share the same concrete
3241// RawLayout between two instances of the same shape. This both reduces memory
3242// overhead and enables effective caching of attribute location.
3243//
3244// To achieve structural sharing, layouts form an immutable DAG. Every class
3245// has a root layout that contains only in-object attributes. When an instance
3246// is created, it is assigned the root layout of its class. When a shape
3247// altering mutation to the instance occurs (e.g. adding an attribute), the
3248// current layout is searched for a corresponding edge. If such an edge exists,
3249// it is followed and the instance is assigned the resulting layout. If there
3250// is no such edge, a new layout is created, an edge is inserted between
3251// the two layouts, and the instance is assigned the new layout.
3252class RawLayout : public RawInstance {
3253 public:
3254 // Getters and setters.
3255 LayoutId id() const;
3256 void setId(LayoutId id) const;
3257
3258 // Returns the class whose instances are described by this layout
3259 RawObject describedType() const;
3260 void setDescribedType(RawObject type) const;
3261
3262 // Set the number of in-object attributes that may be stored on an instance
3263 // described by this layout.
3264 //
3265 // N.B. - This will always be larger than or equal to the length of the
3266 // RawTuple returned by inObjectAttributes().
3267 void setNumInObjectAttributes(word count) const;
3268 word numInObjectAttributes() const;
3269
3270 // Returns an RawTuple describing the attributes stored directly in
3271 // in the instance.
3272 //
3273 // Each item in the object array is a two element tuple. Each tuple is
3274 // composed of the following elements, in order:
3275 //
3276 // 1. The attribute name (RawStr, or NoneType if unnamed (name is kInvalid))
3277 // 2. The attribute info (AttributeInfo)
3278 RawObject inObjectAttributes() const;
3279 void setInObjectAttributes(RawObject attributes) const;
3280
3281 // Returns an RawTuple describing the attributes stored in the overflow
3282 // array of the instance.
3283 //
3284 // Each item in the object array is a two element tuple. Each tuple is
3285 // composed of the following elements, in order:
3286 //
3287 // 1. The attribute name (RawStr)
3288 // 2. The attribute info (AttributeInfo)
3289 RawObject overflowAttributes() const;
3290 void setOverflowAttributes(RawObject attributes) const;
3291
3292 void setDictOverflowOffset(word offset) const;
3293 word dictOverflowOffset() const;
3294
3295 // Returns a flattened list of tuples. Each tuple is composed of the
3296 // following elements, in order:
3297 //
3298 // 1. The attribute name (RawStr)
3299 // 2. The layout that would result if an attribute with that name
3300 // was added.
3301 RawObject additions() const;
3302 void setAdditions(RawObject additions) const;
3303
3304 // Returns a flattened list of tuples. Each tuple is composed of the
3305 // following elements, in order:
3306 //
3307 // 1. The attribute name (RawStr)
3308 // 2. The layout that would result if an attribute with that name
3309 // was deleted.
3310 RawObject deletions() const;
3311 void setDeletions(RawObject deletions) const;
3312
3313 // Returns the number of bytes in an instance described by this layout,
3314 // including the overflow array. Computed from the number of in-object
3315 // attributes and possible overflow slot.
3316 word instanceSize() const;
3317
3318 // Return the offset, in bytes, of the overflow slot
3319 word overflowOffset() const;
3320
3321 // Seal the attributes of the layout.
3322 void seal() const;
3323
3324 // Returns true if the layout has sealed attributes.
3325 bool isSealed() const;
3326
3327 // Returns true if the layout is for a NativeProxy type.
3328 bool isNativeProxyLayout() const;
3329
3330 // Returns true if the layout stores its overflow attributes in a dictionary.
3331 bool hasDictOverflow() const;
3332
3333 // Returns true if the layout stores its overflow attributes in a tuple.
3334 bool hasTupleOverflow() const;
3335
3336 // Layout.
3337 static const int kDescribedTypeOffset = RawHeapObject::kSize;
3338 static const int kInObjectAttributesOffset =
3339 kDescribedTypeOffset + kPointerSize;
3340 static const int kOverflowAttributesOffset =
3341 kInObjectAttributesOffset + kPointerSize;
3342 static const int kAdditionsOffset = kOverflowAttributesOffset + kPointerSize;
3343 static const int kDeletionsOffset = kAdditionsOffset + kPointerSize;
3344 static const int kNumInObjectAttributesOffset =
3345 kDeletionsOffset + kPointerSize;
3346 static const int kSize = kNumInObjectAttributesOffset + kPointerSize;
3347
3348 RAW_OBJECT_COMMON(Layout);
3349};
3350
3351class RawSuper : public RawInstance {
3352 public:
3353 // getters and setters
3354 RawObject type() const;
3355 void setType(RawObject type) const;
3356 RawObject object() const;
3357 void setObject(RawObject obj) const;
3358 RawObject objectType() const;
3359 void setObjectType(RawObject type) const;
3360
3361 // Layout.
3362 static const int kTypeOffset = RawHeapObject::kSize;
3363 static const int kObjectOffset = kTypeOffset + kPointerSize;
3364 static const int kObjectTypeOffset = kObjectOffset + kPointerSize;
3365 static const int kSize = kObjectTypeOffset + kPointerSize;
3366
3367 RAW_OBJECT_COMMON(Super);
3368};
3369
3370// TODO(T63568836): Replace GeneratorFrame by moving it variable
3371// length data into a MutableTuple and moving any other attributes
3372// into Generator.
3373// A Frame in a HeapObject, with space allocated before and after for stack and
3374// locals, respectively. It looks almost exactly like the ascii art diagram for
3375// Frame (from frame.h), except that there is a fixed amount of space allocated
3376// for the value stack, which comes from stacksize() on the Code object this is
3377// created from:
3378//
3379// +----------------------+ <--+
3380// | Arg 0 | |
3381// | ... | |
3382// | Arg N | |
3383// | Local 0 | | (totalArgs() + totalVars()) * kPointerSize
3384// | ... | |
3385// | Local N | |
3386// +----------------------+ <--+
3387// | | |
3388// | Frame | | Frame::kSize
3389// | | |
3390// +----------------------+ <--+ <-- frame()
3391// | | |
3392// | Value stack | | maxStackSize() * kPointerSize
3393// | | |
3394// +----------------------+ <--+
3395// | maxStackSize |
3396// +----------------------+
3397class RawGeneratorFrame : public RawInstance {
3398 public:
3399 // The size of the embedded frame + stack and locals, in words.
3400 word numFrameWords() const;
3401
3402 // Get or set the number of words allocated for the value stack. Used to
3403 // derive a pointer to the Frame inside this GeneratorFrame.
3404 word maxStackSize() const;
3405 void setMaxStackSize(word offset) const;
3406
3407 // Returns the function of a heap frame.
3408 // Note that using `frame()->function()` does not work for this!
3409 RawObject function() const;
3410
3411 // Accessors to the contained frame.
3412 RawObject popValue() const;
3413 void setVirtualPC(word value) const;
3414 RawObject* valueStackTop() const;
3415 word virtualPC() const;
3416
3417 word stackSize() const;
3418 void setStackSize(word size) const;
3419
3420 // Sizing.
3421 static word numAttributes(word extra_words);
3422
3423 // Layout.
3424 static const int kMaxStackSizeOffset = RawHeapObject::kSize;
3425 static const int kFrameOffset = kMaxStackSizeOffset + kPointerSize;
3426
3427 // Size and offsets within frame. Keep in sync with `Frame` class!
3428 static const int kFrameSize = 26 * kPointerSize;
3429 static const int kStackSizeFrameOffset = 2 * kPointerSize;
3430
3431 // Number of words that aren't the Frame.
3432 static const int kNumOverheadWords = kFrameOffset / kPointerSize;
3433
3434 RAW_OBJECT_COMMON(GeneratorFrame);
3435
3436 private:
3437 // The Frame contained in this GeneratorFrame.
3438 Frame* frame() const;
3439};
3440
3441// The exception currently being handled. Every Generator and Coroutine has its
3442// own exception state that is installed while it's running, to allow yielding
3443// from an except block without losing track of the caught exception.
3444//
3445// TODO(T38009294): This class won't exist forever. Think very hard about
3446// adding any more bits of state to it.
3447class RawExceptionState : public RawInstance {
3448 public:
3449 // Getters and setters.
3450 RawObject type() const;
3451 RawObject value() const;
3452 RawObject traceback() const;
3453
3454 void setType(RawObject type) const;
3455 void setValue(RawObject value) const;
3456 void setTraceback(RawObject tb) const;
3457
3458 RawObject previous() const;
3459 void setPrevious(RawObject prev) const;
3460
3461 // Layout.
3462 static const int kTypeOffset = RawHeapObject::kSize;
3463 static const int kValueOffset = kTypeOffset + kPointerSize;
3464 static const int kTracebackOffset = kValueOffset + kPointerSize;
3465 static const int kPreviousOffset = kTracebackOffset + kPointerSize;
3466 static const int kSize = kPreviousOffset + kPointerSize;
3467
3468 RAW_OBJECT_COMMON(ExceptionState);
3469};
3470
3471// Base class containing functionality needed by all objects representing a
3472// suspended execution frame: RawGenerator, RawCoroutine, and AsyncGenerator.
3473class RawGeneratorBase : public RawInstance {
3474 public:
3475 // Get or set the RawGeneratorFrame embedded in this RawGeneratorBase.
3476 RawObject generatorFrame() const;
3477 void setGeneratorFrame(RawObject obj) const;
3478
3479 RawObject exceptionState() const;
3480 void setExceptionState(RawObject obj) const;
3481
3482 RawObject name() const;
3483 void setName(RawObject obj) const;
3484
3485 RawObject running() const;
3486 void setRunning(RawObject obj) const;
3487
3488 RawObject qualname() const;
3489 void setQualname(RawObject obj) const;
3490
3491 // Layout.
3492 static const int kFrameOffset = RawHeapObject::kSize;
3493 static const int kExceptionStateOffset = kFrameOffset + kPointerSize;
3494 static const int kNameOffset = kExceptionStateOffset + kPointerSize;
3495 static const int kQualnameOffset = kNameOffset + kPointerSize;
3496 static const int kRunningOffset = kQualnameOffset + kPointerSize;
3497 static const int kSize = kRunningOffset + kPointerSize;
3498
3499 RAW_OBJECT_COMMON(GeneratorBase);
3500};
3501
3502class RawGenerator : public RawGeneratorBase {
3503 public:
3504 static const int kYieldFromOffset = RawGeneratorBase::kSize;
3505 static const int kSize = kYieldFromOffset + kPointerSize;
3506
3507 RAW_OBJECT_COMMON(Generator);
3508};
3509
3510class RawCoroutine : public RawGeneratorBase {
3511 public:
3512 // Layout.
3513 static const int kAwaitOffset = RawGeneratorBase::kSize;
3514 static const int kOriginOffset = kAwaitOffset + kPointerSize;
3515 static const int kSize = kOriginOffset + kPointerSize;
3516
3517 RAW_OBJECT_COMMON(Coroutine);
3518};
3519
3520class RawCoroutineWrapper : public RawInstance {
3521 public:
3522 RawObject coroutine() const;
3523 void setCoroutine(RawObject coroutine) const;
3524
3525 // Layout.
3526 static const int kCoroutineOffset = RawHeapObject::kSize;
3527 static const int kSize = kCoroutineOffset + kPointerSize;
3528
3529 RAW_OBJECT_COMMON(CoroutineWrapper);
3530};
3531
3532class RawAsyncGenerator : public RawGeneratorBase {
3533 public:
3534 RawObject finalizer() const;
3535 void setFinalizer(RawObject finalizer) const;
3536
3537 bool hooksInited() const;
3538 void setHooksInited(bool hooks_inited) const;
3539
3540 // Layout.
3541 static const int kFinalizerOffset = RawGeneratorBase::kSize;
3542 static const int kHooksInitedOffset = kFinalizerOffset + kPointerSize;
3543 static const int kSize = kHooksInitedOffset + kPointerSize;
3544
3545 RAW_OBJECT_COMMON(AsyncGenerator);
3546};
3547
3548class RawAsyncGeneratorOpIterBase : public RawInstance {
3549 public:
3550 enum class State : word { Init = 0, Iter = 1, Closed = 2 };
3551
3552 RawObject generator() const;
3553 void setGenerator(RawObject generator) const;
3554
3555 State state() const;
3556 void setState(State state) const;
3557
3558 // Layout.
3559 static const int kGeneratorOffset = RawHeapObject::kSize;
3560 static const int kStateOffset = kGeneratorOffset + kPointerSize;
3561 static const int kSize = kStateOffset + kPointerSize;
3562
3563 RAW_OBJECT_COMMON(AsyncGeneratorOpIterBase);
3564};
3565
3566class RawAsyncGeneratorAclose : public RawAsyncGeneratorOpIterBase {
3567 public:
3568 // Layout.
3569 static const int kSize = RawAsyncGeneratorOpIterBase::kSize;
3570
3571 RAW_OBJECT_COMMON(AsyncGeneratorAclose);
3572};
3573
3574class RawAsyncGeneratorAsend : public RawAsyncGeneratorOpIterBase {
3575 public:
3576 RawObject value() const;
3577 void setValue(RawObject value) const;
3578
3579 // Layout.
3580 static const int kValueOffset = RawAsyncGeneratorOpIterBase::kSize;
3581 static const int kSize = kValueOffset + kPointerSize;
3582
3583 RAW_OBJECT_COMMON(AsyncGeneratorAsend);
3584};
3585
3586class RawAsyncGeneratorAthrow : public RawAsyncGeneratorOpIterBase {
3587 public:
3588 RawObject exceptionTraceback() const;
3589 void setExceptionTraceback(RawObject traceback) const;
3590
3591 RawObject exceptionType() const;
3592 void setExceptionType(RawObject exception_type) const;
3593
3594 RawObject exceptionValue() const;
3595 void setExceptionValue(RawObject exception_value) const;
3596
3597 // Layout.
3598 static const int kExceptionTracebackOffset =
3599 RawAsyncGeneratorOpIterBase::kSize;
3600 static const int kExceptionTypeOffset =
3601 kExceptionTracebackOffset + kPointerSize;
3602 static const int kExceptionValueOffset = kExceptionTypeOffset + kPointerSize;
3603 static const int kSize = kExceptionValueOffset + kPointerSize;
3604
3605 RAW_OBJECT_COMMON(AsyncGeneratorAthrow);
3606};
3607
3608class RawAsyncGeneratorWrappedValue : public RawInstance {
3609 public:
3610 RawObject value() const;
3611 void setValue(RawObject value) const;
3612
3613 // Layout.
3614 static const int kValueOffset = RawHeapObject::kSize;
3615 static const int kSize = kValueOffset + kPointerSize;
3616
3617 RAW_OBJECT_COMMON(AsyncGeneratorWrappedValue);
3618};
3619
3620class RawTraceback : public RawInstance {
3621 public:
3622 RawObject function() const;
3623 void setFunction(RawObject function) const;
3624
3625 RawObject lasti() const;
3626 void setLasti(RawObject lasti) const;
3627
3628 RawObject lineno() const;
3629 void setLineno(RawObject lineno) const;
3630
3631 RawObject next() const;
3632 void setNext(RawObject next) const;
3633
3634 // Layout.
3635 static const int kNextOffset = RawHeapObject::kSize;
3636 static const int kFunctionOffset = kNextOffset + kPointerSize;
3637 static const int kLastiOffset = kFunctionOffset + kPointerSize;
3638 static const int kLinenoOffset = kLastiOffset + kPointerSize;
3639 static const int kSize = kLinenoOffset + kPointerSize;
3640
3641 RAW_OBJECT_COMMON(Traceback);
3642};
3643
3644// The primitive IO types
3645
3646class RawUnderIOBase : public RawInstance {
3647 public:
3648 // Getters and setters
3649 bool closed() const;
3650 void setClosed(bool closed) const;
3651
3652 // Layout
3653 static const int kClosedOffset = RawHeapObject::kSize;
3654 static const int kSize = kClosedOffset + kPointerSize;
3655
3656 RAW_OBJECT_COMMON_NO_CAST(UnderIOBase);
3657};
3658
3659class RawUnderRawIOBase : public RawUnderIOBase {
3660 public:
3661 RAW_OBJECT_COMMON_NO_CAST(UnderRawIOBase);
3662};
3663
3664class RawUnderBufferedIOBase : public RawUnderRawIOBase {
3665 public:
3666 RAW_OBJECT_COMMON_NO_CAST(UnderBufferedIOBase);
3667};
3668
3669class RawUnderBufferedIOMixin : public RawUnderBufferedIOBase {
3670 public:
3671 // Getters and setters
3672 RawObject underlying() const;
3673 void setUnderlying(RawObject value) const;
3674
3675 // Layout
3676 static const int kUnderlyingOffset = RawUnderBufferedIOBase::kSize;
3677 static const int kSize = kUnderlyingOffset + kPointerSize;
3678
3679 RAW_OBJECT_COMMON_NO_CAST(UnderBufferedIOMixin);
3680};
3681
3682class RawBufferedRandom : public RawUnderBufferedIOMixin {
3683 public:
3684 // Getters and setters
3685 word bufferSize() const;
3686 void setBufferSize(word buffer_size) const;
3687 RawObject reader() const;
3688 void setReader(RawObject reader) const;
3689 RawObject writeBuf() const;
3690 void setWriteBuf(RawObject under_write_buf) const;
3691 RawObject writeLock() const;
3692 void setWriteLock(RawObject under_write_lock) const;
3693
3694 // Layout
3695 static const int kBufferSizeOffset = RawUnderBufferedIOMixin::kSize;
3696 static const int kReaderOffset = kBufferSizeOffset + kPointerSize;
3697 static const int kWriteBufOffset = kReaderOffset + kPointerSize;
3698 static const int kWriteLockOffset = kWriteBufOffset + kPointerSize;
3699 static const int kSize = kWriteLockOffset + kPointerSize;
3700
3701 RAW_OBJECT_COMMON_NO_CAST(BufferedRandom);
3702};
3703
3704class RawBufferedReader : public RawUnderBufferedIOMixin {
3705 public:
3706 // Getters and setters
3707 word bufferSize() const;
3708 void setBufferSize(word buffer_size) const;
3709 RawObject readBuf() const;
3710 void setReadBuf(RawObject read_buf) const;
3711 word readPos() const;
3712 void setReadPos(word read_pos) const;
3713 word bufferNumBytes() const;
3714 void setBufferNumBytes(word buffer_num_bytes) const;
3715
3716 // Layout
3717 static const int kBufferSizeOffset = RawUnderBufferedIOMixin::kSize;
3718 static const int kReadBufOffset = kBufferSizeOffset + kPointerSize;
3719 static const int kReadPosOffset = kReadBufOffset + kPointerSize;
3720 static const int kBufferNumBytesOffset = kReadPosOffset + kPointerSize;
3721 static const int kSize = kBufferNumBytesOffset + kPointerSize;
3722
3723 RAW_OBJECT_COMMON_NO_CAST(BufferedReader);
3724};
3725
3726class RawBufferedWriter : public RawUnderBufferedIOMixin {
3727 public:
3728 // Getters and setters
3729 word bufferSize() const;
3730 void setBufferSize(RawObject buffer_size) const;
3731 RawObject writeBuf() const;
3732 void setWriteBuf(RawObject under_write_buf) const;
3733 RawObject writeLock() const;
3734 void setWriteLock(RawObject under_write_lock) const;
3735
3736 // Layout
3737 static const int kBufferSizeOffset = RawUnderBufferedIOMixin::kSize;
3738 static const int kWriteBufOffset = kBufferSizeOffset + kPointerSize;
3739 static const int kWriteLockOffset = kWriteBufOffset + kPointerSize;
3740 static const int kSize = kWriteLockOffset + kPointerSize;
3741
3742 RAW_OBJECT_COMMON_NO_CAST(BufferedWriter);
3743};
3744
3745class RawBytesIO : public RawUnderBufferedIOBase {
3746 public:
3747 // Getters and setters
3748 RawObject buffer() const;
3749 void setBuffer(RawObject buffer) const;
3750 word numItems() const;
3751 void setNumItems(word num_items) const;
3752 word pos() const;
3753 void setPos(word pos) const;
3754
3755 // Layout
3756 static const int kBufferOffset = RawUnderBufferedIOBase::kSize;
3757 static const int kNumItemsOffset = kBufferOffset + kPointerSize;
3758 static const int kPosOffset = kNumItemsOffset + kPointerSize;
3759 static const int kSize = kPosOffset + kPointerSize;
3760
3761 RAW_OBJECT_COMMON_NO_CAST(BytesIO);
3762};
3763
3764class RawFileIO : public RawUnderRawIOBase {
3765 public:
3766 // Getters and setters
3767 RawObject fd() const;
3768 void setFd(RawObject fd) const;
3769
3770 RawObject name() const;
3771 void setName(RawObject value) const;
3772
3773 RawObject isCreated() const;
3774 void setCreated(RawObject value) const;
3775
3776 RawObject isReadable() const;
3777 void setReadable(RawObject value) const;
3778
3779 RawObject isWritable() const;
3780 void setWritable(RawObject value) const;
3781
3782 RawObject isAppending() const;
3783 void setAppending(RawObject value) const;
3784
3785 RawObject seekable() const;
3786 void setSeekable(RawObject value) const;
3787
3788 RawObject shouldCloseFd() const;
3789 void setShouldCloseFd(RawObject value) const;
3790
3791 // Layout
3792 static const int kFdOffset = RawUnderRawIOBase::kSize;
3793 static const int kNameOffset = kFdOffset + kPointerSize;
3794 static const int kCreatedOffset = kNameOffset + kPointerSize;
3795 static const int kReadableOffset = kCreatedOffset + kPointerSize;
3796 static const int kWritableOffset = kReadableOffset + kPointerSize;
3797 static const int kAppendingOffset = kWritableOffset + kPointerSize;
3798 static const int kSeekableOffset = kAppendingOffset + kPointerSize;
3799 static const int kCloseFdOffset = kSeekableOffset + kPointerSize;
3800 static const int kSize = kCloseFdOffset + kPointerSize;
3801
3802 RAW_OBJECT_COMMON_NO_CAST(FileIO);
3803};
3804
3805class RawInstanceMethod : public RawInstance {
3806 public:
3807 // Getters and setters
3808
3809 RawObject function() const;
3810 void setFunction(RawObject function) const;
3811
3812 // Layout.
3813 static const int kFunctionOffset = RawHeapObject::kSize;
3814 static const int kSize = kFunctionOffset + kPointerSize;
3815
3816 RAW_OBJECT_COMMON(InstanceMethod);
3817};
3818
3819class RawInstanceProxy : public RawInstance {
3820 public:
3821 // Getters and setters
3822 RawObject instance() const;
3823 void setInstance(RawObject instance) const;
3824
3825 // Layout
3826 static const int kInstanceOffset = RawHeapObject::kSize;
3827 static const int kSize = kInstanceOffset + kPointerSize;
3828
3829 RAW_OBJECT_COMMON_NO_CAST(InstanceProxy);
3830};
3831
3832class RawIncrementalNewlineDecoder : public RawInstance {
3833 public:
3834 // Getters and setters
3835 RawObject errors() const;
3836 void setErrors(RawObject errors) const;
3837 RawObject translate() const;
3838 void setTranslate(RawObject translate) const;
3839 RawObject decoder() const;
3840 void setDecoder(RawObject decoder) const;
3841 RawObject seennl() const;
3842 void setSeennl(RawObject seennl) const;
3843 RawObject pendingcr() const;
3844 void setPendingcr(RawObject pendingcr) const;
3845
3846 // Layout
3847 static const int kErrorsOffset = RawHeapObject::kSize;
3848 static const int kTranslateOffset = kErrorsOffset + kPointerSize;
3849 static const int kDecoderOffset = kTranslateOffset + kPointerSize;
3850 static const int kSeennlOffset = kDecoderOffset + kPointerSize;
3851 static const int kPendingcrOffset = kSeennlOffset + kPointerSize;
3852 static const int kSize = kPendingcrOffset + kPointerSize;
3853
3854 RAW_OBJECT_COMMON_NO_CAST(IncrementalNewlineDecoder);
3855};
3856
3857// RawUnderTextIOBase
3858
3859class RawUnderTextIOBase : public RawUnderIOBase {
3860 public:
3861 RAW_OBJECT_COMMON_NO_CAST(UnderTextIOBase);
3862};
3863
3864// RawTextIOWrapper
3865
3866class RawTextIOWrapper : public RawUnderTextIOBase {
3867 public:
3868 // Getters and setters
3869 RawObject buffer() const;
3870 void setBuffer(RawObject buffer) const;
3871 bool detached() const;
3872 bool lineBuffering() const;
3873 void setLineBuffering(RawObject line_buffering) const;
3874 RawObject encoding() const;
3875 void setEncoding(RawObject encoding) const;
3876 RawObject errors() const;
3877 void setErrors(RawObject errors) const;
3878 bool readuniversal() const;
3879 void setReaduniversal(RawObject readuniversal) const;
3880 bool readtranslate() const;
3881 void setReadtranslate(RawObject readtranslate) const;
3882 RawObject readnl() const;
3883 void setReadnl(RawObject readnl) const;
3884 bool writetranslate() const;
3885 void setWritetranslate(RawObject writetranslate) const;
3886 RawObject writenl() const;
3887 void setWritenl(RawObject writenl) const;
3888 RawObject encoder() const;
3889 void setEncoder(RawObject encoder) const;
3890 RawObject decoder() const;
3891 void setDecoder(RawObject decoder) const;
3892 RawObject decodedChars() const;
3893 void setDecodedChars(RawObject decoded_chars) const;
3894 RawObject decodedCharsUsed() const;
3895 void setDecodedCharsUsed(RawObject decoded_chars_used) const;
3896 RawObject snapshot() const;
3897 void setSnapshot(RawObject snapshot) const;
3898 RawObject seekable() const;
3899 void setSeekable(RawObject seekable) const;
3900 RawObject hasRead1() const;
3901 void setHasRead1(RawObject has_read1) const;
3902 RawObject b2cratio() const;
3903 void setB2cratio(RawObject b2cratio) const;
3904 RawObject telling() const;
3905 void setTelling(RawObject telling) const;
3906
3907 // Layout
3908 static const int kBufferOffset = RawUnderTextIOBase::kSize;
3909 static const int kLineBufferingOffset = kBufferOffset + kPointerSize;
3910 static const int kEncodingOffset = kLineBufferingOffset + kPointerSize;
3911 static const int kErrorsOffset = kEncodingOffset + kPointerSize;
3912 static const int kReaduniversalOffset = kErrorsOffset + kPointerSize;
3913 static const int kReadtranslateOffset = kReaduniversalOffset + kPointerSize;
3914 static const int kReadnlOffset = kReadtranslateOffset + kPointerSize;
3915 static const int kWritetranslateOffset = kReadnlOffset + kPointerSize;
3916 static const int kWritenlOffset = kWritetranslateOffset + kPointerSize;
3917 static const int kEncoderOffset = kWritenlOffset + kPointerSize;
3918 static const int kDecoderOffset = kEncoderOffset + kPointerSize;
3919 static const int kDecodedCharsOffset = kDecoderOffset + kPointerSize;
3920 static const int kDecodedCharsUsedOffset = kDecodedCharsOffset + kPointerSize;
3921 static const int kSnapshotOffset = kDecodedCharsUsedOffset + kPointerSize;
3922 static const int kSeekableOffset = kSnapshotOffset + kPointerSize;
3923 static const int kHasRead1Offset = kSeekableOffset + kPointerSize;
3924 static const int kB2cratioOffset = kHasRead1Offset + kPointerSize;
3925 static const int kTellingOffset = kB2cratioOffset + kPointerSize;
3926 // TODO(T54575279): make mode an overflow attribute
3927 static const int kModeOffset = kTellingOffset + kPointerSize;
3928 static const int kSize = kModeOffset + kPointerSize;
3929
3930 RAW_OBJECT_COMMON_NO_CAST(TextIOWrapper);
3931};
3932
3933// RawStringIO
3934
3935class RawStringIO : public RawUnderTextIOBase {
3936 public:
3937 RawObject buffer() const;
3938 void setBuffer(RawObject buffer) const;
3939
3940 word pos() const;
3941 void setPos(word new_pos) const;
3942
3943 // TODO(T59697642): don't use a whole attribute, just read and write a bit in
3944 // a bitfield.
3945 RawObject readnl() const;
3946 void setReadnl(RawObject readnl) const;
3947
3948 // TODO(T59697642): don't use a whole attribute, just read and write a bit in
3949 // a bitfield.
3950 bool hasReadtranslate() const;
3951 void setReadtranslate(bool readtranslate) const;
3952
3953 // TODO(T59697642): don't use a whole attribute, just read and write a bit in
3954 // a bitfield.
3955 bool hasReaduniversal() const;
3956 void setReaduniversal(bool readuniversal) const;
3957
3958 // TODO(T59697642): don't use a whole attribute, just read and write bits in a
3959 // bitfield.
3960 RawObject seennl() const;
3961 void setSeennl(RawObject seennl) const;
3962
3963 // TODO(T59697642): don't use a whole attribute, just read and write a bit in
3964 // a bitfield.
3965 RawObject writenl() const;
3966 void setWritenl(RawObject writenl) const;
3967
3968 // TODO(T59697642): don't use a whole attribute, just read and write a bit in
3969 // a bitfield.
3970 bool hasWritetranslate() const;
3971 void setWritetranslate(bool writetranslate) const;
3972
3973 // Layout
3974 static const int kBufferOffset = RawUnderTextIOBase::kSize;
3975 static const int kPosOffset = kBufferOffset + kPointerSize;
3976 static const int kReadnlOffset = kPosOffset + kPointerSize;
3977 static const int kReadtranslateOffset = kReadnlOffset + kPointerSize;
3978 static const int kReaduniversalOffset = kReadtranslateOffset + kPointerSize;
3979 static const int kSeennlOffset = kReaduniversalOffset + kPointerSize;
3980 static const int kWritenlOffset = kSeennlOffset + kPointerSize;
3981 static const int kWritetranslateOffset = kWritenlOffset + kPointerSize;
3982 static const int kSize = kWritetranslateOffset + kPointerSize;
3983
3984 RAW_OBJECT_COMMON(StringIO);
3985};
3986
3987// RawObject
3988
3989inline word roundAllocationSize(word size) {
3990 return Utils::roundUp(size, kObjectAlignment);
3991}
3992
3993inline bool isInstanceLayout(LayoutId id) {
3994 return id > LayoutId::kLastNonInstance;
3995}
3996
3997inline RawObject::RawObject(uword raw) : raw_{raw} {}
3998
3999inline uword RawObject::raw() const { return raw_; }
4000
4001inline bool RawObject::isObject() const { return true; }
4002
4003inline LayoutId RawObject::layoutId() const {
4004 if (isHeapObject()) {
4005 return RawHeapObject::cast(*this).header().layoutId();
4006 }
4007 if (isSmallInt()) {
4008 return LayoutId::kSmallInt;
4009 }
4010 return static_cast<LayoutId>(raw() & kImmediateTagMask);
4011}
4012
4013inline bool RawObject::isBool() const {
4014 return (raw() & RawBool::kTagMask) == kBoolTag;
4015}
4016
4017inline bool RawObject::isError() const {
4018 return (raw() & RawError::kTagMask) == kErrorTag;
4019}
4020
4021inline bool RawObject::isErrorError() const {
4022 return raw() == RawError::error().raw();
4023}
4024
4025inline bool RawObject::isErrorException() const {
4026 return raw() == RawError::exception().raw();
4027}
4028
4029inline bool RawObject::isErrorNotFound() const {
4030 return raw() == RawError::notFound().raw();
4031}
4032
4033inline bool RawObject::isErrorOutOfBounds() const {
4034 return raw() == RawError::outOfBounds().raw();
4035}
4036
4037inline bool RawObject::isErrorOutOfMemory() const {
4038 return raw() == RawError::outOfMemory().raw();
4039}
4040
4041inline bool RawObject::isErrorNoMoreItems() const {
4042 return raw() == RawError::noMoreItems().raw();
4043}
4044
4045inline bool RawObject::isHeader() const {
4046 return (raw() & kPrimaryTagMask) == kHeaderTag;
4047}
4048
4049inline bool RawObject::isNoneType() const {
4050 return *this == RawNoneType::object();
4051}
4052
4053inline bool RawObject::isNotImplementedType() const {
4054 return *this == RawNotImplementedType::object();
4055}
4056
4057inline bool RawObject::isSmallBytes() const {
4058 return (raw() & kImmediateTagMask) == kSmallBytesTag;
4059}
4060
4061inline bool RawObject::isSmallInt() const {
4062 return (raw() & kSmallIntTagMask) == kSmallIntTag;
4063}
4064
4065inline bool RawObject::isSmallStr() const {
4066 return (raw() & kImmediateTagMask) == kSmallStrTag;
4067}
4068
4069inline bool RawObject::isUnbound() const {
4070 return *this == RawUnbound::object();
4071}
4072
4073inline bool RawObject::isHeapObject() const {
4074 return (raw() & kPrimaryTagMask) == kHeapObjectTag;
4075}
4076
4077inline bool RawObject::isHeapObjectWithLayout(LayoutId layout_id) const {
4078 return isHeapObject() &&
4079 RawHeapObject::cast(*this).header().layoutId() == layout_id;
4080}
4081
4082inline bool RawObject::isInternal() const {
4083 // Test whether an object is unsafe to expose to managed code
4084 return isError() || isMutableBytes() || isMutableTuple() || isLayout() ||
4085 isUnbound();
4086}
4087
4088inline bool RawObject::isImmediateObjectNotSmallInt() const {
4089 // Test whether object is not a heap object when it is known that it is not a
4090 // SmallInt (the lowest bit is guaranteed to be one so we don't need to
4091 // re-test that).
4092 static_assert((kHeapObjectTag & ~kSmallIntTagMask) == 0,
4093 "assumed heapobject tag bits outside smallint bit are 0");
4094 return (raw() & (kPrimaryTagMask & ~kSmallIntTagMask)) != 0;
4095}
4096
4097inline bool RawObject::isInstance() const {
4098 return isHeapObject() && (RawHeapObject::cast(*this).header().layoutId() >
4099 LayoutId::kLastNonInstance);
4100}
4101
4102inline bool RawObject::isArray() const {
4103 return isHeapObjectWithLayout(LayoutId::kArray);
4104}
4105
4106inline bool RawObject::isAsyncGenerator() const {
4107 return isHeapObjectWithLayout(LayoutId::kAsyncGenerator);
4108}
4109
4110inline bool RawObject::isAsyncGeneratorOpIterBase() const {
4111 return isAsyncGeneratorAclose() || isAsyncGeneratorAsend() ||
4112 isAsyncGeneratorAthrow();
4113}
4114
4115inline bool RawObject::isAsyncGeneratorAclose() const {
4116 return isHeapObjectWithLayout(LayoutId::kAsyncGeneratorAclose);
4117}
4118
4119inline bool RawObject::isAsyncGeneratorAsend() const {
4120 return isHeapObjectWithLayout(LayoutId::kAsyncGeneratorAsend);
4121}
4122
4123inline bool RawObject::isAsyncGeneratorAthrow() const {
4124 return isHeapObjectWithLayout(LayoutId::kAsyncGeneratorAthrow);
4125}
4126
4127inline bool RawObject::isAsyncGeneratorWrappedValue() const {
4128 return isHeapObjectWithLayout(LayoutId::kAsyncGeneratorWrappedValue);
4129}
4130
4131inline bool RawObject::isAttributeDict() const {
4132 return isType() || isModule();
4133}
4134
4135inline bool RawObject::isBaseException() const {
4136 return isHeapObjectWithLayout(LayoutId::kBaseException);
4137}
4138
4139inline bool RawObject::isBoundMethod() const {
4140 return isHeapObjectWithLayout(LayoutId::kBoundMethod);
4141}
4142
4143inline bool RawObject::isBufferedRandom() const {
4144 return isHeapObjectWithLayout(LayoutId::kBufferedRandom);
4145}
4146
4147inline bool RawObject::isBufferedReader() const {
4148 return isHeapObjectWithLayout(LayoutId::kBufferedReader);
4149}
4150
4151inline bool RawObject::isBufferedWriter() const {
4152 return isHeapObjectWithLayout(LayoutId::kBufferedWriter);
4153}
4154
4155inline bool RawObject::isUnderBufferedIOBase() const {
4156 return isHeapObjectWithLayout(LayoutId::kUnderBufferedIOBase);
4157}
4158
4159inline bool RawObject::isUnderBufferedIOMixin() const {
4160 return isHeapObjectWithLayout(LayoutId::kUnderBufferedIOMixin);
4161}
4162
4163inline bool RawObject::isBytearray() const {
4164 return isHeapObjectWithLayout(LayoutId::kBytearray);
4165}
4166
4167inline bool RawObject::isBytearrayIterator() const {
4168 return isHeapObjectWithLayout(LayoutId::kBytearrayIterator);
4169}
4170
4171inline bool RawObject::isBytesIO() const {
4172 return isHeapObjectWithLayout(LayoutId::kBytesIO);
4173}
4174
4175inline bool RawObject::isBytesIterator() const {
4176 return isHeapObjectWithLayout(LayoutId::kBytesIterator);
4177}
4178
4179inline bool RawObject::isCell() const {
4180 return isHeapObjectWithLayout(LayoutId::kCell);
4181}
4182
4183inline bool RawObject::isClassMethod() const {
4184 return isHeapObjectWithLayout(LayoutId::kClassMethod);
4185}
4186
4187inline bool RawObject::isCode() const {
4188 return isHeapObjectWithLayout(LayoutId::kCode);
4189}
4190
4191inline bool RawObject::isComplex() const {
4192 return isHeapObjectWithLayout(LayoutId::kComplex);
4193}
4194
4195inline bool RawObject::isContext() const {
4196 return isHeapObjectWithLayout(LayoutId::kContext);
4197}
4198
4199inline bool RawObject::isContextVar() const {
4200 return isHeapObjectWithLayout(LayoutId::kContextVar);
4201}
4202
4203inline bool RawObject::isCoroutine() const {
4204 return isHeapObjectWithLayout(LayoutId::kCoroutine);
4205}
4206
4207inline bool RawObject::isCoroutineWrapper() const {
4208 return isHeapObjectWithLayout(LayoutId::kCoroutineWrapper);
4209}
4210
4211inline bool RawObject::isDataArray() const {
4212 return isLargeBytes() || isLargeStr() || isMutableBytes();
4213}
4214
4215inline bool RawObject::isDeque() const {
4216 return isHeapObjectWithLayout(LayoutId::kDeque);
4217}
4218
4219inline bool RawObject::isDequeIterator() const {
4220 return isHeapObjectWithLayout(LayoutId::kDequeIterator);
4221}
4222
4223inline bool RawObject::isDequeReverseIterator() const {
4224 return isHeapObjectWithLayout(LayoutId::kDequeReverseIterator);
4225}
4226
4227inline bool RawObject::isDict() const {
4228 return isHeapObjectWithLayout(LayoutId::kDict);
4229}
4230
4231inline bool RawObject::isDictItemIterator() const {
4232 return isHeapObjectWithLayout(LayoutId::kDictItemIterator);
4233}
4234
4235inline bool RawObject::isDictItems() const {
4236 return isHeapObjectWithLayout(LayoutId::kDictItems);
4237}
4238
4239inline bool RawObject::isDictKeyIterator() const {
4240 return isHeapObjectWithLayout(LayoutId::kDictKeyIterator);
4241}
4242
4243inline bool RawObject::isDictKeys() const {
4244 return isHeapObjectWithLayout(LayoutId::kDictKeys);
4245}
4246
4247inline bool RawObject::isDictValueIterator() const {
4248 return isHeapObjectWithLayout(LayoutId::kDictValueIterator);
4249}
4250
4251inline bool RawObject::isDictValues() const {
4252 return isHeapObjectWithLayout(LayoutId::kDictValues);
4253}
4254
4255inline bool RawObject::isEllipsis() const {
4256 return isHeapObjectWithLayout(LayoutId::kEllipsis);
4257}
4258
4259inline bool RawObject::isEnumerate() const {
4260 return isHeapObjectWithLayout(LayoutId::kEnumerate);
4261}
4262
4263inline bool RawObject::isException() const {
4264 return isHeapObjectWithLayout(LayoutId::kException);
4265}
4266
4267inline bool RawObject::isExceptionState() const {
4268 return isHeapObjectWithLayout(LayoutId::kExceptionState);
4269}
4270
4271inline bool RawObject::isFileIO() const {
4272 return isHeapObjectWithLayout(LayoutId::kFileIO);
4273}
4274
4275inline bool RawObject::isFloat() const {
4276 return isHeapObjectWithLayout(LayoutId::kFloat);
4277}
4278
4279inline bool RawObject::isFrameProxy() const {
4280 return isHeapObjectWithLayout(LayoutId::kFrameProxy);
4281}
4282
4283inline bool RawObject::isFrozenSet() const {
4284 return isHeapObjectWithLayout(LayoutId::kFrozenSet);
4285}
4286
4287inline bool RawObject::isFunction() const {
4288 return isHeapObjectWithLayout(LayoutId::kFunction);
4289}
4290
4291inline bool RawObject::isGenerator() const {
4292 return isHeapObjectWithLayout(LayoutId::kGenerator);
4293}
4294
4295inline bool RawObject::isGeneratorFrame() const {
4296 return isHeapObjectWithLayout(LayoutId::kGeneratorFrame);
4297}
4298
4299inline bool RawObject::isIncrementalNewlineDecoder() const {
4300 return isHeapObjectWithLayout(LayoutId::kIncrementalNewlineDecoder);
4301}
4302
4303inline bool RawObject::isInstanceMethod() const {
4304 return isHeapObjectWithLayout(LayoutId::kInstanceMethod);
4305}
4306
4307inline bool RawObject::isInstanceProxy() const {
4308 return isHeapObjectWithLayout(LayoutId::kInstanceProxy);
4309}
4310
4311inline bool RawObject::isImportError() const {
4312 return isHeapObjectWithLayout(LayoutId::kImportError);
4313}
4314
4315inline bool RawObject::isIndexError() const {
4316 return isHeapObjectWithLayout(LayoutId::kIndexError);
4317}
4318
4319inline bool RawObject::isUnderIOBase() const {
4320 return isHeapObjectWithLayout(LayoutId::kUnderIOBase);
4321}
4322
4323inline bool RawObject::isKeyError() const {
4324 return isHeapObjectWithLayout(LayoutId::kKeyError);
4325}
4326
4327inline bool RawObject::isLargeBytes() const {
4328 return isHeapObjectWithLayout(LayoutId::kLargeBytes) || isMutableBytes();
4329}
4330
4331inline bool RawObject::isLargeInt() const {
4332 return isHeapObjectWithLayout(LayoutId::kLargeInt);
4333}
4334
4335inline bool RawObject::isLargeStr() const {
4336 return isHeapObjectWithLayout(LayoutId::kLargeStr);
4337}
4338
4339inline bool RawObject::isLayout() const {
4340 return isHeapObjectWithLayout(LayoutId::kLayout);
4341}
4342
4343inline bool RawObject::isList() const {
4344 return isHeapObjectWithLayout(LayoutId::kList);
4345}
4346
4347inline bool RawObject::isListIterator() const {
4348 return isHeapObjectWithLayout(LayoutId::kListIterator);
4349}
4350
4351inline bool RawObject::isLongRangeIterator() const {
4352 return isHeapObjectWithLayout(LayoutId::kLongRangeIterator);
4353}
4354
4355inline bool RawObject::isLookupError() const {
4356 return isHeapObjectWithLayout(LayoutId::kLookupError);
4357}
4358
4359inline bool RawObject::isMappingProxy() const {
4360 return isHeapObjectWithLayout(LayoutId::kMappingProxy);
4361}
4362
4363inline bool RawObject::isMemoryView() const {
4364 return isHeapObjectWithLayout(LayoutId::kMemoryView);
4365}
4366
4367inline bool RawObject::isMmap() const {
4368 return isHeapObjectWithLayout(LayoutId::kMmap);
4369}
4370
4371inline bool RawObject::isModule() const {
4372 return isHeapObjectWithLayout(LayoutId::kModule);
4373}
4374
4375inline bool RawObject::isModuleProxy() const {
4376 return isHeapObjectWithLayout(LayoutId::kModuleProxy);
4377}
4378
4379inline bool RawObject::isModuleNotFoundError() const {
4380 return isHeapObjectWithLayout(LayoutId::kModuleNotFoundError);
4381}
4382
4383inline bool RawObject::isMutableBytes() const {
4384 return isHeapObjectWithLayout(LayoutId::kMutableBytes);
4385}
4386
4387inline bool RawObject::isMutableTuple() const {
4388 return isHeapObjectWithLayout(LayoutId::kMutableTuple);
4389}
4390
4391inline bool RawObject::isNotImplementedError() const {
4392 return isHeapObjectWithLayout(LayoutId::kNotImplementedError);
4393}
4394
4395inline bool RawObject::isPointer() const {
4396 return isHeapObjectWithLayout(LayoutId::kPointer);
4397}
4398
4399inline bool RawObject::isProperty() const {
4400 return isHeapObjectWithLayout(LayoutId::kProperty);
4401}
4402
4403inline bool RawObject::isRange() const {
4404 return isHeapObjectWithLayout(LayoutId::kRange);
4405}
4406
4407inline bool RawObject::isRangeIterator() const {
4408 return isHeapObjectWithLayout(LayoutId::kRangeIterator);
4409}
4410
4411inline bool RawObject::isUnderRawIOBase() const {
4412 return isHeapObjectWithLayout(LayoutId::kUnderRawIOBase);
4413}
4414
4415inline bool RawObject::isRuntimeError() const {
4416 return isHeapObjectWithLayout(LayoutId::kRuntimeError);
4417}
4418
4419inline bool RawObject::isSeqIterator() const {
4420 return isHeapObjectWithLayout(LayoutId::kSeqIterator);
4421}
4422
4423inline bool RawObject::isSet() const {
4424 return isHeapObjectWithLayout(LayoutId::kSet);
4425}
4426
4427inline bool RawObject::isSetIterator() const {
4428 return isHeapObjectWithLayout(LayoutId::kSetIterator);
4429}
4430
4431inline bool RawObject::isSlice() const {
4432 return isHeapObjectWithLayout(LayoutId::kSlice);
4433}
4434
4435inline bool RawObject::isSlotDescriptor() const {
4436 return isHeapObjectWithLayout(LayoutId::kSlotDescriptor);
4437}
4438
4439inline bool RawObject::isStaticMethod() const {
4440 return isHeapObjectWithLayout(LayoutId::kStaticMethod);
4441}
4442
4443inline bool RawObject::isStopIteration() const {
4444 return isHeapObjectWithLayout(LayoutId::kStopIteration);
4445}
4446
4447inline bool RawObject::isStrArray() const {
4448 return isHeapObjectWithLayout(LayoutId::kStrArray);
4449}
4450
4451inline bool RawObject::isStringIO() const {
4452 return isHeapObjectWithLayout(LayoutId::kStringIO);
4453}
4454
4455inline bool RawObject::isStrIterator() const {
4456 return isHeapObjectWithLayout(LayoutId::kStrIterator);
4457}
4458
4459inline bool RawObject::isSuper() const {
4460 return isHeapObjectWithLayout(LayoutId::kSuper);
4461}
4462
4463inline bool RawObject::isSyntaxError() const {
4464 return isHeapObjectWithLayout(LayoutId::kSyntaxError);
4465}
4466
4467inline bool RawObject::isSystemExit() const {
4468 return isHeapObjectWithLayout(LayoutId::kSystemExit);
4469}
4470
4471inline bool RawObject::isTextIOWrapper() const {
4472 return isHeapObjectWithLayout(LayoutId::kTextIOWrapper);
4473}
4474
4475inline bool RawObject::isToken() const {
4476 return isHeapObjectWithLayout(LayoutId::kToken);
4477}
4478
4479inline bool RawObject::isTraceback() const {
4480 return isHeapObjectWithLayout(LayoutId::kTraceback);
4481}
4482
4483inline bool RawObject::isTuple() const {
4484 return isHeapObjectWithLayout(LayoutId::kTuple) || isMutableTuple();
4485}
4486
4487inline bool RawObject::isTupleIterator() const {
4488 return isHeapObjectWithLayout(LayoutId::kTupleIterator);
4489}
4490
4491inline bool RawObject::isType() const {
4492 return isHeapObjectWithLayout(LayoutId::kType);
4493}
4494
4495inline bool RawObject::isTypeProxy() const {
4496 return isHeapObjectWithLayout(LayoutId::kTypeProxy);
4497}
4498
4499inline bool RawObject::isUnicodeDecodeError() const {
4500 return isHeapObjectWithLayout(LayoutId::kUnicodeDecodeError);
4501}
4502
4503inline bool RawObject::isUnicodeEncodeError() const {
4504 return isHeapObjectWithLayout(LayoutId::kUnicodeEncodeError);
4505}
4506
4507inline bool RawObject::isUnicodeError() const {
4508 return isHeapObjectWithLayout(LayoutId::kUnicodeError);
4509}
4510
4511inline bool RawObject::isUnicodeErrorBase() const {
4512 return isUnicodeDecodeError() || isUnicodeEncodeError() ||
4513 isUnicodeTranslateError();
4514}
4515
4516inline bool RawObject::isUnicodeTranslateError() const {
4517 return isHeapObjectWithLayout(LayoutId::kUnicodeTranslateError);
4518}
4519
4520inline bool RawObject::isValueCell() const {
4521 return isHeapObjectWithLayout(LayoutId::kValueCell);
4522}
4523
4524inline bool RawObject::isWeakCallableProxy() const {
4525 return isHeapObjectWithLayout(LayoutId::kWeakCallableProxy);
4526}
4527
4528inline bool RawObject::isWeakProxy() const {
4529 return isHeapObjectWithLayout(LayoutId::kWeakProxy);
4530}
4531
4532inline bool RawObject::isWeakLink() const {
4533 return isHeapObjectWithLayout(LayoutId::kWeakLink);
4534}
4535
4536inline bool RawObject::isWeakRef() const {
4537 // WeakLink is a subclass of WeakLink sharing its layout, so this is safe.
4538 return isHeapObjectWithLayout(LayoutId::kWeakRef) ||
4539 isHeapObjectWithLayout(LayoutId::kWeakLink);
4540}
4541
4542inline bool RawObject::isBytes() const {
4543 return isSmallBytes() || isLargeBytes();
4544}
4545
4546inline bool RawObject::isGeneratorBase() const {
4547 return isGenerator() || isCoroutine() || isAsyncGenerator();
4548}
4549
4550inline bool RawObject::isInt() const {
4551 return isSmallInt() || isLargeInt() || isBool();
4552}
4553
4554inline bool RawObject::isSetBase() const { return isSet() || isFrozenSet(); }
4555
4556inline bool RawObject::isStr() const { return isSmallStr() || isLargeStr(); }
4557
4558inline bool RawObject::operator==(const RawObject& other) const {
4559 return raw() == other.raw();
4560}
4561
4562inline bool RawObject::operator!=(const RawObject& other) const {
4563 return !operator==(other);
4564}
4565
4566template <typename T>
4567T RawObject::rawCast() const {
4568 return *static_cast<const T*>(this);
4569}
4570
4571// RawBytes
4572
4573inline word RawBytes::findByte(byte value, word start, word length) const {
4574 if (isImmediateObjectNotSmallInt()) {
4575 return RawSmallBytes::cast(*this).findByte(value, start, length);
4576 }
4577 return RawLargeBytes::cast(*this).findByte(value, start, length);
4578}
4579
4580inline RawBytes RawBytes::empty() {
4581 return RawSmallBytes::empty().rawCast<RawBytes>();
4582}
4583
4584inline word RawBytes::length() const {
4585 if (isImmediateObjectNotSmallInt()) {
4586 return RawSmallBytes::cast(*this).length();
4587 }
4588 return RawLargeBytes::cast(*this).length();
4589}
4590
4591ALWAYS_INLINE byte RawBytes::byteAt(word index) const {
4592 if (isImmediateObjectNotSmallInt()) {
4593 return RawSmallBytes::cast(*this).byteAt(index);
4594 }
4595 return RawLargeBytes::cast(*this).byteAt(index);
4596}
4597
4598inline RawObject RawBytes::becomeStr() const {
4599 if (isImmediateObjectNotSmallInt()) {
4600 return RawSmallBytes::cast(*this).becomeStr();
4601 }
4602 return RawLargeBytes::cast(*this).becomeStr();
4603}
4604
4605inline void RawBytes::copyTo(byte* dst, word length) const {
4606 if (isImmediateObjectNotSmallInt()) {
4607 RawSmallBytes::cast(*this).copyTo(dst, length);
4608 return;
4609 }
4610 RawLargeBytes::cast(*this).copyTo(dst, length);
4611}
4612
4613inline void RawBytes::copyToStartAt(byte* dst, word length, word index) const {
4614 if (isImmediateObjectNotSmallInt()) {
4615 RawSmallBytes::cast(*this).copyToStartAt(dst, length, index);
4616 return;
4617 }
4618 RawLargeBytes::cast(*this).copyToStartAt(dst, length, index);
4619}
4620
4621inline bool RawBytes::includesByte(byte b) const {
4622 if (isImmediateObjectNotSmallInt()) {
4623 return RawSmallBytes::cast(*this).includesByte(b);
4624 }
4625 return RawLargeBytes::cast(*this).includesByte(b);
4626}
4627
4628inline bool RawBytes::isASCII() const {
4629 if (isImmediateObjectNotSmallInt()) {
4630 return RawSmallBytes::cast(*this).isASCII();
4631 }
4632 return RawLargeBytes::cast(*this).isASCII();
4633}
4634
4635inline char* RawBytes::toCStr() const {
4636 if (isImmediateObjectNotSmallInt()) {
4637 return RawSmallBytes::cast(*this).toCStr();
4638 }
4639 return RawLargeBytes::cast(*this).toCStr();
4640}
4641
4642inline uint16_t RawBytes::uint16At(word index) const {
4643 if (isImmediateObjectNotSmallInt()) {
4644 return RawSmallBytes::cast(*this).uint16At(index);
4645 }
4646 return RawLargeBytes::cast(*this).uint16At(index);
4647}
4648
4649inline uint32_t RawBytes::uint32At(word index) const {
4650 if (isImmediateObjectNotSmallInt()) {
4651 return RawSmallBytes::cast(*this).uint32At(index);
4652 }
4653 return RawLargeBytes::cast(*this).uint32At(index);
4654}
4655
4656inline uint64_t RawBytes::uint64At(word index) const {
4657 DCHECK(!isSmallBytes(), "uint64_t cannot fit into SmallBytes");
4658 return RawLargeBytes::cast(*this).uint64At(index);
4659}
4660
4661// RawInt
4662
4663inline word RawInt::asWord() const {
4664 if (isSmallInt()) {
4665 return RawSmallInt::cast(*this).value();
4666 }
4667 if (isBool()) {
4668 return RawBool::cast(*this).value();
4669 }
4670 return RawLargeInt::cast(*this).asWord();
4671}
4672
4673inline word RawInt::asWordSaturated() const {
4674 if (numDigits() == 1) return asWord();
4675 return isNegative() ? kMinWord : kMaxWord;
4676}
4677
4678inline void* RawInt::asCPtr() const {
4679 if (isSmallInt()) {
4680 return RawSmallInt::cast(*this).asCPtr();
4681 }
4682 return RawLargeInt::cast(*this).asCPtr();
4683}
4684
4685template <typename T>
4686OptInt<T> RawInt::asInt() const {
4687 if (isSmallInt()) {
4688 return RawSmallInt::cast(*this).asInt<T>();
4689 }
4690 if (isBool()) {
4691 return OptInt<T>::valid(RawBool::cast(*this).value() ? 1 : 0);
4692 }
4693 return RawLargeInt::cast(*this).asInt<T>();
4694}
4695
4696inline word RawInt::bitLength() const {
4697 if (isSmallInt()) {
4698 uword self = static_cast<uword>(std::abs(RawSmallInt::cast(*this).value()));
4699 return Utils::highestBit(self);
4700 }
4701 if (isBool()) {
4702 return RawBool::cast(*this) == RawBool::trueObj() ? 1 : 0;
4703 }
4704 return RawLargeInt::cast(*this).bitLength();
4705}
4706
4707inline bool RawInt::isEven() const {
4708 if (isSmallInt()) {
4709 return (RawSmallInt::cast(*this).value() & 1) == 0;
4710 }
4711 if (isBool()) {
4712 return *this == RawBool::falseObj();
4713 }
4714 return RawLargeInt::cast(*this).isEven();
4715}
4716
4717inline bool RawInt::isNegative() const {
4718 if (isSmallInt()) {
4719 return RawSmallInt::cast(*this).value() < 0;
4720 }
4721 if (isBool()) {
4722 return false;
4723 }
4724 return RawLargeInt::cast(*this).isNegative();
4725}
4726
4727inline bool RawInt::isOdd() const {
4728 if (isSmallInt()) {
4729 return (RawSmallInt::cast(*this).value() & 1) != 0;
4730 }
4731 if (isBool()) {
4732 return *this == RawBool::trueObj();
4733 }
4734 return !RawLargeInt::cast(*this).isEven();
4735}
4736
4737inline bool RawInt::isPositive() const {
4738 if (isSmallInt()) {
4739 return RawSmallInt::cast(*this).value() > 0;
4740 }
4741 if (isBool()) {
4742 return RawBool::cast(*this) == RawBool::trueObj();
4743 }
4744 return RawLargeInt::cast(*this).isPositive();
4745}
4746
4747inline bool RawInt::isZero() const {
4748 if (isSmallInt()) {
4749 return RawSmallInt::cast(*this).value() == 0;
4750 }
4751 if (isBool()) {
4752 return RawBool::cast(*this) == RawBool::falseObj();
4753 }
4754 // A RawLargeInt can never be zero
4755 DCHECK(isLargeInt(), "RawObject must be a RawLargeInt");
4756 return false;
4757}
4758
4759inline word RawInt::numDigits() const {
4760 if (isSmallInt() || isBool()) {
4761 return 1;
4762 }
4763 return RawLargeInt::cast(*this).numDigits();
4764}
4765
4766inline uword RawInt::digitAt(word index) const {
4767 if (isSmallInt()) {
4768 DCHECK(index == 0, "RawSmallInt digit index out of bounds");
4769 return RawSmallInt::cast(*this).value();
4770 }
4771 if (isBool()) {
4772 DCHECK(index == 0, "RawBool digit index out of bounds");
4773 return RawBool::cast(*this).value();
4774 }
4775 return RawLargeInt::cast(*this).digitAt(index);
4776}
4777
4778// RawSmallInt
4779
4780inline word RawSmallInt::value() const {
4781 return static_cast<word>(raw()) >> kSmallIntTagBits;
4782}
4783
4784inline void* RawSmallInt::asCPtr() const {
4785 return reinterpret_cast<void*>(value());
4786}
4787
4788inline void* RawSmallInt::asAlignedCPtr() const {
4789 return reinterpret_cast<void*>(asReinterpretedWord());
4790}
4791
4792inline word RawSmallInt::asReinterpretedWord() const {
4793 return static_cast<word>(raw());
4794}
4795
4796template <typename T>
4797if_signed_t<T, OptInt<T>> RawSmallInt::asInt() const {
4798 static_assert(sizeof(T) <= sizeof(word), "T must not be larger than word");
4799
4800 auto const value = this->value();
4801 if (value > std::numeric_limits<T>::max()) return OptInt<T>::overflow();
4802 if (value < std::numeric_limits<T>::min()) return OptInt<T>::underflow();
4803 return OptInt<T>::valid(value);
4804}
4805
4806template <typename T>
4807if_unsigned_t<T, OptInt<T>> RawSmallInt::asInt() const {
4808 static_assert(sizeof(T) <= sizeof(word), "T must not be larger than word");
4809 auto const max = std::numeric_limits<T>::max();
4810 auto const value = this->value();
4811
4812 if (value < 0) return OptInt<T>::underflow();
4813 if (max >= RawSmallInt::kMaxValue || static_cast<uword>(value) <= max) {
4814 return OptInt<T>::valid(value);
4815 }
4816 return OptInt<T>::overflow();
4817}
4818
4819inline RawSmallInt RawSmallInt::fromWord(word value) {
4820 DCHECK(RawSmallInt::isValid(value), "invalid cast");
4821 return cast(RawObject{static_cast<uword>(value) << kSmallIntTagBits});
4822}
4823
4824inline RawSmallInt RawSmallInt::fromWordTruncated(word value) {
4825 return cast(RawObject{static_cast<uword>(value) << kSmallIntTagBits});
4826}
4827
4828inline RawSmallInt RawSmallInt::fromReinterpretedWord(word value) {
4829 return cast(RawObject{static_cast<uword>(value)});
4830}
4831
4832inline RawSmallInt RawSmallInt::fromAlignedCPtr(void* ptr) {
4833 return fromReinterpretedWord(reinterpret_cast<word>(ptr));
4834}
4835
4836inline word RawSmallInt::truncate(word value) {
4837 return (value << kSmallIntTagBits) >> kSmallIntTagBits;
4838}
4839
4840inline word RawSmallInt::hash() const {
4841 word val = value();
4842 uword abs = static_cast<uword>(val);
4843 // Shortcut for positive values smaller than `kArithmeticHashModulus`.
4844 if (abs < kArithmeticHashModulus) {
4845 return value();
4846 }
4847 // Compute `value % kArithmeticHashModulus` (with C/C++ style modulo). This
4848 // uses the algorithm from `longIntHash()` simplified for a single word.
4849 const word bits_per_half = kBitsPerWord / 2;
4850 if (val < 0) {
4851 abs = -abs;
4852 }
4853 // The `longIntHash()` formula is simplified using the following equivalences:
4854 // (1) ((abs >> bits_per_half) & p) << bits_per_half
4855 // <=> abs & ((p >> bits_per_half) << bits_per_half)
4856 // (2) (abs >> bits_per_half) >> (kArithmeticHashBits - bits_per_half)
4857 // <=> abs >> kArithmeticHashBits
4858 uword result =
4859 (abs & ((kArithmeticHashModulus >> bits_per_half) << bits_per_half)) |
4860 abs >> kArithmeticHashBits;
4861 result += abs & ((uword{1} << bits_per_half) - 1);
4862 if (result >= kArithmeticHashModulus) {
4863 result -= kArithmeticHashModulus;
4864 }
4865 if (val < 0) {
4866 result = -result;
4867 // cpython replaces `-1` results with -2, because -1 is used as an
4868 // "uninitialized hash" marker in some situations. We do not use the same
4869 // marker, but do the same to match behavior.
4870 if (result == static_cast<uword>(word{-1})) {
4871 result -= 1;
4872 }
4873 }
4874 return result;
4875}
4876
4877// RawHeader
4878
4879inline word RawHeader::count() const {
4880 return static_cast<word>((raw() >> kCountOffset) & kCountMask);
4881}
4882
4883inline bool RawHeader::hasOverflow() const {
4884 return count() == kCountOverflowFlag;
4885}
4886
4887inline word RawHeader::hashCode() const {
4888 return static_cast<word>((raw() >> kHashCodeOffset) & kHashCodeMask);
4889}
4890
4891inline RawHeader RawHeader::withHashCode(word value) const {
4892 auto header = raw();
4893 header &= ~(kHashCodeMask << kHashCodeOffset);
4894 header |= (value & kHashCodeMask) << kHashCodeOffset;
4895 return cast(RawObject{header});
4896}
4897
4898inline LayoutId RawHeader::layoutId() const {
4899 return static_cast<LayoutId>((raw() >> kLayoutIdOffset) & kLayoutIdMask);
4900}
4901
4902inline RawHeader RawHeader::withLayoutId(LayoutId layout_id) const {
4903 DCHECK_BOUND(static_cast<word>(layout_id), kMaxLayoutId);
4904 auto header = raw();
4905 header &= ~(kLayoutIdMask << kLayoutIdOffset);
4906 header |= (static_cast<word>(layout_id) & kLayoutIdMask) << kLayoutIdOffset;
4907 return cast(RawObject{header});
4908}
4909
4910inline ObjectFormat RawHeader::format() const {
4911 return static_cast<ObjectFormat>((raw() >> kFormatOffset) & kFormatMask);
4912}
4913
4914inline RawHeader RawHeader::from(word count, word hash, LayoutId id,
4915 ObjectFormat format) {
4916 DCHECK(
4917 (count >= 0) && ((count <= kCountMax) || (count == kCountOverflowFlag)),
4918 "bounds violation, %ld not in 0..%d", count, kCountMax);
4919 uword result = kHeaderTag;
4920 result |= ((count > kCountMax) ? kCountOverflowFlag : count) << kCountOffset;
4921 result |= hash << kHashCodeOffset;
4922 result |= static_cast<uword>(id) << kLayoutIdOffset;
4923 result |= static_cast<uword>(format) << kFormatOffset;
4924 return cast(RawObject{result});
4925}
4926
4927// RawSmallData
4928
4929// Access data within a SmallData reference. This gives direct low-level
4930// access. It is only apropriate to use in code to build up higher abstractions.
4931inline const byte* smallDataData(const RawSmallData* obj) {
4932 static_assert(endian::native == endian::little, "big endian not implemented");
4933 return reinterpret_cast<const byte*>(obj) + RawSmallData::kDataOffset;
4934}
4935
4936inline RawSmallData::RawSmallData(uword raw) : RawObject(raw) {}
4937
4938inline word RawSmallData::length() const {
4939 return (raw() >> kImmediateTagBits) & kMaxLength;
4940}
4941
4942inline byte RawSmallData::byteAt(word index) const {
4943 DCHECK_INDEX(index, length());
4944 return smallDataData(this)[index];
4945}
4946
4947inline void RawSmallData::copyTo(byte* dst, word length) const {
4948 DCHECK_BOUND(length, this->length());
4949 std::memcpy(dst, smallDataData(this), length);
4950}
4951
4952inline void RawSmallData::copyToStartAt(byte* dst, word length,
4953 word index) const {
4954 DCHECK_BOUND(index, this->length());
4955 DCHECK_BOUND(length, this->length() - index);
4956 std::memcpy(dst, smallDataData(this) + index, length);
4957}
4958
4959inline uint16_t RawSmallData::uint16At(word index) const {
4960 uint16_t result;
4961 DCHECK_INDEX(index, length() - word{sizeof(result) - 1});
4962 std::memcpy(&result, smallDataData(this) + index, sizeof(result));
4963 return result;
4964}
4965
4966inline uint32_t RawSmallData::uint32At(word index) const {
4967 uint32_t result;
4968 DCHECK(kMaxLength >= sizeof(result), "SmallBytes cannot fit uint32_t");
4969 DCHECK_INDEX(index, length() - word{sizeof(result) - 1});
4970 std::memcpy(&result, smallDataData(this) + index, sizeof(result));
4971 return result;
4972}
4973
4974inline word RawSmallData::hash() const {
4975 return static_cast<word>(raw() >> RawObject::kImmediateTagBits);
4976}
4977
4978// RawSmallBytes
4979
4980inline RawSmallBytes::RawSmallBytes(uword raw) : RawSmallData(raw) {}
4981
4982inline RawSmallBytes RawSmallBytes::empty() {
4983 return RawSmallBytes(kSmallBytesTag);
4984}
4985
4986// RawSmallStr
4987
4988inline RawSmallStr::RawSmallStr(uword raw) : RawSmallData(raw) {}
4989
4990inline RawSmallStr RawSmallStr::empty() { return RawSmallStr(kSmallStrTag); }
4991
4992// RawError
4993
4994inline RawError::RawError(ErrorKind kind)
4995 : RawObject{(static_cast<uword>(kind) << kKindOffset) | kErrorTag} {}
4996
4997inline RawError RawError::error() { return RawError{ErrorKind::kNone}; }
4998
4999inline RawError RawError::exception() {
5000 return RawError{ErrorKind::kException};
5001}
5002
5003inline RawError RawError::notFound() { return RawError{ErrorKind::kNotFound}; }
5004
5005inline RawError RawError::noMoreItems() {
5006 return RawError{ErrorKind::kNoMoreItems};
5007}
5008
5009inline RawError RawError::outOfMemory() {
5010 return RawError{ErrorKind::kOutOfMemory};
5011}
5012
5013inline RawError RawError::outOfBounds() {
5014 return RawError{ErrorKind::kOutOfBounds};
5015}
5016
5017inline ErrorKind RawError::kind() const {
5018 return static_cast<ErrorKind>(raw() >> kKindOffset);
5019}
5020
5021// RawBool
5022
5023inline RawBool RawBool::trueObj() { return fromBool(true); }
5024
5025inline RawBool RawBool::falseObj() { return fromBool(false); }
5026
5027inline word RawBool::hash() const { return value(); }
5028
5029inline RawBool RawBool::negate(RawObject value) {
5030 DCHECK(value.isBool(), "not a boolean instance");
5031 return (value == trueObj()) ? falseObj() : trueObj();
5032}
5033
5034inline RawBool RawBool::fromBool(bool value) {
5035 return cast(
5036 RawObject{(static_cast<uword>(value) << kValueOffset) | kBoolTag});
5037}
5038
5039inline bool RawBool::value() const {
5040 return static_cast<byte>(raw() >> kValueOffset) ? true : false;
5041}
5042
5043// RawNotImplementedType
5044
5045inline RawNotImplementedType RawNotImplementedType::object() {
5046 return RawObject{kNotImplementedTag}.rawCast<RawNotImplementedType>();
5047}
5048
5049// RawUnbound
5050
5051inline RawUnbound RawUnbound::object() {
5052 return RawObject{kUnboundTag}.rawCast<RawUnbound>();
5053}
5054
5055// RawNoneType
5056
5057inline RawNoneType RawNoneType::object() {
5058 return RawObject{kMaxUword}.rawCast<RawNoneType>();
5059}
5060
5061// RawHeapObject
5062
5063inline uword RawHeapObject::address() const { return raw() - kHeapObjectTag; }
5064
5065inline uword RawHeapObject::baseAddress() const {
5066 uword result = address() - RawHeader::kSize;
5067 if (header().hasOverflow()) {
5068 result -= kPointerSize;
5069 }
5070 return result;
5071}
5072
5073inline RawHeader RawHeapObject::header() const {
5074 return *reinterpret_cast<RawHeader*>(address() + kHeaderOffset);
5075}
5076
5077inline void RawHeapObject::setHeader(RawHeader header) const {
5078 *reinterpret_cast<RawHeader*>(address() + kHeaderOffset) = header;
5079}
5080
5081inline word RawHeapObject::headerOverflow() const {
5082 DCHECK(header().hasOverflow(), "expected Overflow");
5083 return reinterpret_cast<RawSmallInt*>(address() + kHeaderOverflowOffset)
5084 ->value();
5085}
5086
5087inline RawHeapObject RawHeapObject::initializeHeader(uword address, word count,
5088 word hash, LayoutId id,
5089 ObjectFormat format) {
5090 if (count > RawHeader::kCountMax) {
5091 *reinterpret_cast<RawSmallInt*>(address) = RawSmallInt::fromWord(count);
5092 address += kPointerSize;
5093 count = RawHeader::kCountOverflowFlag;
5094 }
5095 *reinterpret_cast<RawHeader*>(address) =
5096 RawHeader::from(count, hash, id, format);
5097 address += kPointerSize;
5098 return fromAddress(address);
5099}
5100
5101inline RawHeapObject RawHeapObject::fromAddress(uword address) {
5102 DCHECK((address & kPrimaryTagMask) == 0,
5103 "invalid cast, expected heap address");
5104 return cast(RawObject{address + kHeapObjectTag});
5105}
5106
5107inline word RawHeapObject::headerCountOrOverflow() const {
5108 if (header().hasOverflow()) {
5109 return headerOverflow();
5110 }
5111 return header().count();
5112}
5113
5114inline word RawHeapObject::size() const {
5115 word count = headerCountOrOverflow();
5116 word result = headerSize(count);
5117 switch (header().format()) {
5118 case ObjectFormat::kData:
5119 result += count;
5120 break;
5121 case ObjectFormat::kObjects:
5122 result += count * kPointerSize;
5123 break;
5124 }
5125 return roundAllocationSize(result);
5126}
5127
5128inline word RawHeapObject::headerSize(word count) {
5129 word result = kPointerSize;
5130 if (count > RawHeader::kCountMax) {
5131 result += kPointerSize;
5132 }
5133 return result;
5134}
5135
5136inline RawObject RawInstance::initializeWithNone(uword address,
5137 word num_attributes,
5138 LayoutId layout_id) {
5139 RawHeapObject result = RawHeapObject::initializeHeader(
5140 address, /*count=*/num_attributes, /*hash=*/0, layout_id,
5141 ObjectFormat::kObjects);
5142 word start = RawHeapObject::kSize;
5143 word size = num_attributes * kPointerSize;
5144 std::memset(reinterpret_cast<byte*>(result.address() + start), -1,
5145 size - start);
5146 return result;
5147}
5148
5149inline RawObject RawInstance::initializeWithZero(uword address,
5150 word num_attributes,
5151 LayoutId layout_id) {
5152 // No memset necessary here, as the memory is guaranteed to be zero already.
5153 return RawHeapObject::initializeHeader(address, /*count=*/num_attributes,
5154 /*hash=*/0, layout_id,
5155 ObjectFormat::kObjects);
5156}
5157
5158inline bool RawHeapObject::isRoot() const {
5159 return header().format() == ObjectFormat::kObjects;
5160}
5161
5162inline bool RawHeapObject::isForwarding() const {
5163 // In case of forwarded objects the header was replaced with a reference
5164 // to the forwarded HeapObject.
5165 return !reinterpret_cast<RawObject*>(address() + kHeaderOffset)->isHeader();
5166}
5167
5168inline RawObject RawHeapObject::forward() const {
5169 return *reinterpret_cast<RawObject*>(address() + kHeaderOffset);
5170}
5171
5172inline void RawHeapObject::forwardTo(RawObject object) const {
5173 // Overwrite the header with the forwarding address.
5174 *reinterpret_cast<RawObject*>(address() + kHeaderOffset) = object;
5175}
5176
5177inline RawObject RawInstance::instanceVariableAt(word offset) const {
5178 DCHECK_INDEX(offset, headerCountOrOverflow() * kPointerSize);
5179 return *reinterpret_cast<RawObject*>(address() + offset);
5180}
5181
5182inline void RawInstance::instanceVariableAtPut(word offset,
5183 RawObject value) const {
5184 DCHECK_INDEX(offset, headerCountOrOverflow() * kPointerSize);
5185 *reinterpret_cast<RawObject*>(address() + offset) = value;
5186}
5187
5188inline void RawInstance::setLayoutId(LayoutId layout_id) const {
5189 setHeader(header().withLayoutId(layout_id));
5190}
5191
5192// RawBaseException
5193
5194inline RawObject RawBaseException::args() const {
5195 return instanceVariableAt(kArgsOffset);
5196}
5197
5198inline void RawBaseException::setArgs(RawObject args) const {
5199 instanceVariableAtPut(kArgsOffset, args);
5200}
5201
5202inline RawObject RawBaseException::traceback() const {
5203 RawObject o = tracebackOrUnbound();
5204 return o.isUnbound() ? RawNoneType::object() : o;
5205}
5206
5207inline RawObject RawBaseException::tracebackOrUnbound() const {
5208 return instanceVariableAt(kTracebackOffset);
5209}
5210
5211inline void RawBaseException::setTraceback(RawObject traceback) const {
5212 instanceVariableAtPut(kTracebackOffset, traceback);
5213}
5214
5215inline RawObject RawBaseException::cause() const {
5216 RawObject o = causeOrUnbound();
5217 return o.isUnbound() ? RawNoneType::object() : o;
5218}
5219
5220inline RawObject RawBaseException::causeOrUnbound() const {
5221 return instanceVariableAt(kCauseOffset);
5222}
5223
5224inline void RawBaseException::setCause(RawObject cause) const {
5225 instanceVariableAtPut(kCauseOffset, cause);
5226}
5227
5228inline RawObject RawBaseException::context() const {
5229 RawObject o = contextOrUnbound();
5230 return o.isUnbound() ? RawNoneType::object() : o;
5231}
5232
5233inline RawObject RawBaseException::contextOrUnbound() const {
5234 return instanceVariableAt(kContextOffset);
5235}
5236
5237inline void RawBaseException::setContext(RawObject context) const {
5238 instanceVariableAtPut(kContextOffset, context);
5239}
5240
5241inline RawObject RawBaseException::suppressContext() const {
5242 return instanceVariableAt(kSuppressContextOffset);
5243}
5244
5245inline void RawBaseException::setSuppressContext(RawObject suppress) const {
5246 instanceVariableAtPut(kSuppressContextOffset, suppress);
5247}
5248// RawStopIteration
5249
5250inline RawObject RawStopIteration::value() const {
5251 return instanceVariableAt(kValueOffset);
5252}
5253
5254inline void RawStopIteration::setValue(RawObject value) const {
5255 instanceVariableAtPut(kValueOffset, value);
5256}
5257
5258// RawSystemExit
5259
5260inline RawObject RawSystemExit::code() const {
5261 return instanceVariableAt(kCodeOffset);
5262}
5263
5264inline void RawSystemExit::setCode(RawObject code) const {
5265 instanceVariableAtPut(kCodeOffset, code);
5266}
5267
5268// RawImportError
5269
5270inline RawObject RawImportError::msg() const {
5271 return instanceVariableAt(kMsgOffset);
5272}
5273
5274inline void RawImportError::setMsg(RawObject msg) const {
5275 instanceVariableAtPut(kMsgOffset, msg);
5276}
5277
5278inline RawObject RawImportError::name() const {
5279 return instanceVariableAt(kNameOffset);
5280}
5281
5282inline void RawImportError::setName(RawObject name) const {
5283 instanceVariableAtPut(kNameOffset, name);
5284}
5285
5286inline RawObject RawImportError::path() const {
5287 return instanceVariableAt(kPathOffset);
5288}
5289
5290inline void RawImportError::setPath(RawObject path) const {
5291 instanceVariableAtPut(kPathOffset, path);
5292}
5293
5294// RawAttributeDict
5295
5296inline RawObject RawAttributeDict::attributes() const {
5297 return instanceVariableAt(kAttributesOffset);
5298}
5299
5300inline void RawAttributeDict::setAttributes(RawObject mutable_tuple) const {
5301 instanceVariableAtPut(kAttributesOffset, mutable_tuple);
5302}
5303
5304inline word RawAttributeDict::attributesRemaining() const {
5305 return RawSmallInt::cast(instanceVariableAt(kAttributesRemainingOffset))
5306 .value();
5307}
5308
5309inline void RawAttributeDict::setAttributesRemaining(word free) const {
5310 instanceVariableAtPut(kAttributesRemainingOffset,
5311 RawSmallInt::fromWord(free));
5312}
5313
5314// RawType
5315
5316inline RawObject RawType::bases() const {
5317 return instanceVariableAt(kBasesOffset);
5318}
5319
5320inline void RawType::setBases(RawObject bases_tuple) const {
5321 instanceVariableAtPut(kBasesOffset, bases_tuple);
5322}
5323
5324inline RawObject RawType::doc() const { return instanceVariableAt(kDocOffset); }
5325
5326inline void RawType::setDoc(RawObject doc) const {
5327 instanceVariableAtPut(kDocOffset, doc);
5328}
5329
5330inline RawObject RawType::mro() const { return instanceVariableAt(kMroOffset); }
5331
5332inline void RawType::setMro(RawObject object_array) const {
5333 instanceVariableAtPut(kMroOffset, object_array);
5334}
5335
5336inline RawObject RawType::instanceLayout() const {
5337 return instanceVariableAt(kInstanceLayoutOffset);
5338}
5339
5340inline void RawType::setInstanceLayout(RawObject layout) const {
5341 instanceVariableAtPut(kInstanceLayoutOffset, layout);
5342}
5343
5344inline LayoutId RawType::instanceLayoutId() const {
5345 return static_cast<LayoutId>(
5346 RawSmallInt::cast(instanceVariableAt(kInstanceLayoutIdOffset)).value());
5347}
5348
5349inline void RawType::setInstanceLayoutId(LayoutId id) const {
5350 instanceVariableAtPut(kInstanceLayoutIdOffset,
5351 RawSmallInt::fromWord(static_cast<word>(id)));
5352}
5353
5354inline RawObject RawType::name() const {
5355 return instanceVariableAt(kNameOffset);
5356}
5357
5358inline void RawType::setName(RawObject name) const {
5359 instanceVariableAtPut(kNameOffset, name);
5360}
5361
5362inline RawType::Flag RawType::flags() const {
5363 return static_cast<Flag>(
5364 RawSmallInt::cast(instanceVariableAt(kFlagsOffset)).value());
5365}
5366
5367inline void RawType::setFlagsAndBuiltinBase(Flag value, LayoutId base) const {
5368 auto raw_base = static_cast<int>(base);
5369 DCHECK((raw_base & kBuiltinBaseMask) == raw_base,
5370 "Builtin base LayoutId too high");
5371 setFlags(static_cast<Flag>((value & ~kBuiltinBaseMask) | raw_base));
5372}
5373
5374inline void RawType::setFlags(Flag value) const {
5375 instanceVariableAtPut(kFlagsOffset, RawSmallInt::fromWord(value));
5376}
5377
5378inline void RawType::setBuiltinBase(LayoutId base) const {
5379 auto raw = static_cast<int>(base);
5380 DCHECK((raw & kBuiltinBaseMask) == raw, "Builtin base LayoutId too high");
5381 setFlags(static_cast<Flag>((flags() & ~kBuiltinBaseMask) | raw));
5382}
5383
5384inline bool RawType::hasFlag(Flag bit) const { return (flags() & bit) != 0; }
5385
5386inline LayoutId RawType::builtinBase() const {
5387 return static_cast<LayoutId>(flags() & kBuiltinBaseMask);
5388}
5389
5390inline bool RawType::hasCustomDict() const {
5391 return hasFlag(RawType::Flag::kHasCustomDict);
5392}
5393
5394inline bool RawType::hasNativeData() const {
5395 return hasFlag(RawType::Flag::kHasNativeData);
5396}
5397
5398inline bool RawType::isCPythonHeaptype() const {
5399 return hasFlag(RawType::Flag::kIsCPythonHeaptype);
5400}
5401
5402inline bool RawType::isBasetype() const {
5403 return hasFlag(RawType::Flag::kIsBasetype);
5404}
5405
5406inline RawObject RawType::slots() const {
5407 return instanceVariableAt(kSlotsOffset);
5408}
5409
5410inline void RawType::setSlots(RawObject slots) const {
5411 instanceVariableAtPut(kSlotsOffset, slots);
5412}
5413
5414inline RawObject RawType::abstractMethods() const {
5415 return instanceVariableAt(kAbstractMethodsOffset);
5416}
5417
5418inline void RawType::setAbstractMethods(RawObject methods) const {
5419 instanceVariableAtPut(kAbstractMethodsOffset, methods);
5420}
5421
5422inline RawObject RawType::subclasses() const {
5423 return instanceVariableAt(kSubclassesOffset);
5424}
5425
5426inline void RawType::setSubclasses(RawObject subclasses) const {
5427 instanceVariableAtPut(kSubclassesOffset, subclasses);
5428}
5429
5430inline RawObject RawType::proxy() const {
5431 return instanceVariableAt(kProxyOffset);
5432}
5433
5434inline void RawType::setProxy(RawObject proxy) const {
5435 instanceVariableAtPut(kProxyOffset, proxy);
5436}
5437
5438inline RawObject RawType::ctor() const {
5439 return instanceVariableAt(kCtorOffset);
5440}
5441
5442inline void RawType::setCtor(RawObject function) const {
5443 instanceVariableAtPut(kCtorOffset, function);
5444}
5445
5446inline RawObject RawType::qualname() const {
5447 return instanceVariableAt(kQualnameOffset);
5448}
5449
5450inline void RawType::setQualname(RawObject qualname) const {
5451 instanceVariableAtPut(kQualnameOffset, qualname);
5452}
5453
5454inline bool RawType::isBuiltin() const {
5455 return instanceLayoutId() <= LayoutId::kLastBuiltinId;
5456}
5457
5458inline bool RawType::isBaseExceptionSubclass() const {
5459 LayoutId base = builtinBase();
5460 return base >= LayoutId::kFirstException && base <= LayoutId::kLastException;
5461}
5462
5463inline bool RawType::hasMutableDict() const { return isCPythonHeaptype(); }
5464
5465// RawContext
5466
5467inline RawObject RawContext::data() const {
5468 return instanceVariableAt(kDataOffset);
5469}
5470
5471inline void RawContext::setData(RawObject data) const {
5472 instanceVariableAtPut(kDataOffset, data);
5473}
5474
5475inline RawObject RawContext::prevContext() const {
5476 return instanceVariableAt(kPrevContextOffset);
5477}
5478
5479inline void RawContext::setPrevContext(RawObject prev_context) const {
5480 instanceVariableAtPut(kPrevContextOffset, prev_context);
5481}
5482
5483// RawContextVar
5484
5485inline RawObject RawContextVar::defaultValue() const {
5486 return instanceVariableAt(kDefaultValueOffset);
5487}
5488
5489inline void RawContextVar::setDefaultValue(RawObject default_value) const {
5490 instanceVariableAtPut(kDefaultValueOffset, default_value);
5491}
5492
5493inline RawObject RawContextVar::name() const {
5494 return instanceVariableAt(kNameOffset);
5495}
5496
5497inline void RawContextVar::setName(RawObject name) const {
5498 instanceVariableAtPut(kNameOffset, name);
5499}
5500
5501// RawTypeProxy
5502
5503inline RawObject RawTypeProxy::type() const {
5504 return instanceVariableAt(kTypeOffset);
5505}
5506
5507inline void RawTypeProxy::setType(RawObject type) const {
5508 instanceVariableAtPut(kTypeOffset, type);
5509}
5510
5511// RawDataArray
5512
5513inline word RawDataArray::allocationSize(word length) {
5514 DCHECK(length >= 0, "invalid length %ld", length);
5515 word size = headerSize(length) + length;
5516 return roundAllocationSize(size);
5517}
5518
5519inline byte RawDataArray::byteAt(word index) const {
5520 DCHECK_INDEX(index, length());
5521 return *reinterpret_cast<byte*>(address() + index);
5522}
5523
5524inline void RawDataArray::copyTo(byte* dst, word length) const {
5525 DCHECK_BOUND(length, this->length());
5526 copyToStartAt(dst, length, 0);
5527}
5528
5529inline void RawDataArray::copyToStartAt(byte* dst, word length,
5530 word index) const {
5531 DCHECK_BOUND(index + length, this->length());
5532 std::memmove(dst, reinterpret_cast<const byte*>(address() + index), length);
5533}
5534
5535inline word RawDataArray::length() const { return headerCountOrOverflow(); }
5536
5537inline uint16_t RawDataArray::uint16At(word index) const {
5538 uint16_t result;
5539 DCHECK_INDEX(index, length() - static_cast<word>(sizeof(result) - 1));
5540 std::memcpy(&result, reinterpret_cast<const char*>(address() + index),
5541 sizeof(result));
5542 return result;
5543}
5544
5545inline uint32_t RawDataArray::uint32At(word index) const {
5546 uint32_t result;
5547 DCHECK_INDEX(index, length() - static_cast<word>(sizeof(result) - 1));
5548 std::memcpy(&result, reinterpret_cast<const char*>(address() + index),
5549 sizeof(result));
5550 return result;
5551}
5552
5553inline uint64_t RawDataArray::uint64At(word index) const {
5554 uint64_t result;
5555 DCHECK_INDEX(index, length() - static_cast<word>(sizeof(result) - 1));
5556 std::memcpy(&result, reinterpret_cast<const char*>(address() + index),
5557 sizeof(result));
5558 return result;
5559}
5560
5561inline RawObject RawDataArray::initialize(uword address, word length,
5562 LayoutId layout_id) {
5563 return initializeHeader(address, /*count=*/length, /*hash=*/0, layout_id,
5564 ObjectFormat::kData);
5565}
5566
5567// RawLargeBytes
5568
5569inline word RawLargeBytes::allocationSize(word length) {
5570 DCHECK(length > RawSmallBytes::kMaxLength, "length %ld is too small",
5571 (long)length);
5572 return RawDataArray::allocationSize(length);
5573}
5574
5575// RawMutableBytes
5576
5577inline word RawMutableBytes::allocationSize(word length) {
5578 return RawDataArray::allocationSize(length);
5579}
5580
5581inline void RawMutableBytes::byteAtPut(word index, byte value) const {
5582 DCHECK_INDEX(index, length());
5583 *reinterpret_cast<byte*>(address() + index) = value;
5584}
5585
5586inline void RawMutableBytes::uint16AtPut(word index, uint16_t value) const {
5587 DCHECK_INDEX(index, length() - static_cast<word>(sizeof(value) - 1));
5588 std::memcpy(reinterpret_cast<char*>(address() + index), &value,
5589 sizeof(value));
5590}
5591
5592inline void RawMutableBytes::uint32AtPut(word index, uint32_t value) const {
5593 DCHECK_INDEX(index, length() - static_cast<word>(sizeof(value) - 1));
5594 std::memcpy(reinterpret_cast<char*>(address() + index), &value,
5595 sizeof(value));
5596}
5597
5598// RawArray
5599
5600inline RawObject RawArray::buffer() const {
5601 return instanceVariableAt(kBufferOffset);
5602}
5603
5604inline void RawArray::setBuffer(RawObject new_buffer) const {
5605 DCHECK(new_buffer.isMutableBytes(), "Array must be backed by MutableBytes");
5606 instanceVariableAtPut(kBufferOffset, new_buffer);
5607}
5608
5609inline word RawArray::length() const {
5610 return RawSmallInt::cast(instanceVariableAt(kLengthOffset)).value();
5611}
5612
5613inline void RawArray::setLength(word new_length) const {
5614 instanceVariableAtPut(kLengthOffset, RawSmallInt::fromWord(new_length));
5615}
5616
5617inline RawObject RawArray::typecode() const {
5618 return instanceVariableAt(kTypecodeOffset);
5619}
5620
5621inline void RawArray::setTypecode(RawObject new_typecode) const {
5622 instanceVariableAtPut(kTypecodeOffset, new_typecode);
5623}
5624
5625// RawMutableTuple
5626
5627inline word RawMutableTuple::allocationSize(word length) {
5628 DCHECK(length >= 0, "invalid length %ld", length);
5629 word size = headerSize(length) + length * kPointerSize;
5630 return roundAllocationSize(size);
5631}
5632
5633inline RawObject RawMutableTuple::becomeImmutable() const {
5634 setHeader(header().withLayoutId(LayoutId::kTuple));
5635 return *this;
5636}
5637
5638inline void RawMutableTuple::swap(word i, word j) const {
5639 RawObject tmp = at(i);
5640 atPut(i, at(j));
5641 atPut(j, tmp);
5642}
5643
5644inline RawObject RawMutableTuple::initialize(uword address, word length) {
5645 return initializeHeader(address, /*count=*/length, /*hash=*/0,
5646 LayoutId::kMutableTuple, ObjectFormat::kObjects);
5647}
5648
5649// RawTuple
5650
5651inline word RawTuple::length() const { return headerCountOrOverflow(); }
5652
5653inline RawObject RawTuple::at(word index) const {
5654 DCHECK_INDEX(index, length());
5655 return *reinterpret_cast<RawObject*>(address() + (index * kPointerSize));
5656}
5657
5658inline void RawTuple::atPut(word index, RawObject value) const {
5659 DCHECK_INDEX(index, length());
5660 *reinterpret_cast<RawObject*>(address() + (index * kPointerSize)) = value;
5661}
5662
5663// RawUserTupleBase
5664
5665inline RawObject RawUserTupleBase::value() const {
5666 return instanceVariableAt(kValueOffset);
5667}
5668
5669inline void RawUserTupleBase::setValue(RawObject value) const {
5670 DCHECK(value.isTuple(), "Only tuple type is permitted as a value");
5671 instanceVariableAtPut(kValueOffset, value);
5672}
5673
5674inline RawTuple tupleUnderlying(RawObject object) {
5675 if (object.isTuple()) {
5676 return RawTuple::cast(object);
5677 }
5678 return RawTuple::cast(object.rawCast<RawUserTupleBase>().value());
5679}
5680
5681// RawUnicodeError
5682
5683inline RawObject RawUnicodeErrorBase::encoding() const {
5684 return instanceVariableAt(kEncodingOffset);
5685}
5686
5687inline void RawUnicodeErrorBase::setEncoding(RawObject encoding_name) const {
5688 DCHECK(encoding_name.isStr(), "Only string type is permitted as a value");
5689 instanceVariableAtPut(kEncodingOffset, encoding_name);
5690}
5691
5692inline RawObject RawUnicodeErrorBase::object() const {
5693 return instanceVariableAt(kObjectOffset);
5694}
5695
5696inline void RawUnicodeErrorBase::setObject(RawObject value) const {
5697 DCHECK(value.isBytes() || value.isBytearray() || value.isStr(),
5698 "Only str or bytes-like types are permitted as values");
5699 instanceVariableAtPut(kObjectOffset, value);
5700}
5701
5702inline RawObject RawUnicodeErrorBase::start() const {
5703 return instanceVariableAt(kStartOffset);
5704}
5705
5706inline void RawUnicodeErrorBase::setStart(RawObject index) const {
5707 DCHECK(index.isInt(), "Only int type is permitted as a value");
5708 instanceVariableAtPut(kStartOffset, index);
5709}
5710
5711inline RawObject RawUnicodeErrorBase::end() const {
5712 return instanceVariableAt(kEndOffset);
5713}
5714
5715inline void RawUnicodeErrorBase::setEnd(RawObject index) const {
5716 DCHECK(index.isInt(), "Only int type is permitted as a value");
5717 instanceVariableAtPut(kEndOffset, index);
5718}
5719
5720inline RawObject RawUnicodeErrorBase::reason() const {
5721 return instanceVariableAt(kReasonOffset);
5722}
5723
5724inline void RawUnicodeErrorBase::setReason(RawObject error_description) const {
5725 DCHECK(error_description.isStr(), "Only string type is permitted as a value");
5726 instanceVariableAtPut(kReasonOffset, error_description);
5727}
5728
5729// RawCode
5730
5731inline word RawCode::argcount() const {
5732 return RawSmallInt::cast(instanceVariableAt(kArgcountOffset)).value();
5733}
5734
5735inline void RawCode::setArgcount(word value) const {
5736 instanceVariableAtPut(kArgcountOffset, RawSmallInt::fromWord(value));
5737}
5738
5739inline word RawCode::posonlyargcount() const {
5740 return RawSmallInt::cast(instanceVariableAt(kPosonlyargcountOffset)).value();
5741}
5742
5743inline void RawCode::setPosonlyargcount(word value) const {
5744 instanceVariableAtPut(kPosonlyargcountOffset, RawSmallInt::fromWord(value));
5745}
5746
5747inline RawObject RawCode::cell2arg() const {
5748 return instanceVariableAt(kCell2argOffset);
5749}
5750
5751inline word RawCode::totalArgs() const {
5752 uword f = flags();
5753 word res = argcount() + kwonlyargcount();
5754 if (f & kVarargs) {
5755 res++;
5756 }
5757 if (f & kVarkeyargs) {
5758 res++;
5759 }
5760 return res;
5761}
5762
5763inline void RawCode::setCell2arg(RawObject value) const {
5764 instanceVariableAtPut(kCell2argOffset, value);
5765}
5766
5767inline RawObject RawCode::cellvars() const {
5768 return instanceVariableAt(kCellvarsOffset);
5769}
5770
5771inline void RawCode::setCellvars(RawObject value) const {
5772 instanceVariableAtPut(kCellvarsOffset, value);
5773}
5774
5775inline word RawCode::numCellvars() const {
5776 RawObject object = cellvars();
5777 DCHECK(object.isNoneType() || object.isTuple(), "not an object array");
5778 if (object.isNoneType()) {
5779 return 0;
5780 }
5781 return RawTuple::cast(object).length();
5782}
5783
5784inline RawObject RawCode::code() const {
5785 return instanceVariableAt(kCodeOffset);
5786}
5787
5788inline void RawCode::setCode(RawObject value) const {
5789 instanceVariableAtPut(kCodeOffset, value);
5790}
5791
5792inline RawObject RawCode::consts() const {
5793 return instanceVariableAt(kConstsOffset);
5794}
5795
5796inline void RawCode::setConsts(RawObject value) const {
5797 instanceVariableAtPut(kConstsOffset, value);
5798}
5799
5800inline RawObject RawCode::filename() const {
5801 return instanceVariableAt(kFilenameOffset);
5802}
5803
5804inline void RawCode::setFilename(RawObject value) const {
5805 instanceVariableAtPut(kFilenameOffset, value);
5806}
5807
5808inline word RawCode::firstlineno() const {
5809 return RawSmallInt::cast(instanceVariableAt(kFirstlinenoOffset)).value();
5810}
5811
5812inline void RawCode::setFirstlineno(word value) const {
5813 instanceVariableAtPut(kFirstlinenoOffset, RawSmallInt::fromWord(value));
5814}
5815
5816inline word RawCode::flags() const {
5817 return RawSmallInt::cast(instanceVariableAt(kFlagsOffset)).value();
5818}
5819
5820inline void RawCode::setFlags(word value) const {
5821 instanceVariableAtPut(kFlagsOffset, RawSmallInt::fromWord(value));
5822}
5823
5824inline RawObject RawCode::freevars() const {
5825 return instanceVariableAt(kFreevarsOffset);
5826}
5827
5828inline void RawCode::setFreevars(RawObject value) const {
5829 instanceVariableAtPut(kFreevarsOffset, value);
5830}
5831
5832inline word RawCode::numFreevars() const {
5833 RawObject object = freevars();
5834 DCHECK(object.isNoneType() || object.isTuple(), "not an object array");
5835 if (object.isNoneType()) {
5836 return 0;
5837 }
5838 return RawTuple::cast(object).length();
5839}
5840
5841inline word RawCode::kwonlyargcount() const {
5842 return RawSmallInt::cast(instanceVariableAt(kKwonlyargcountOffset)).value();
5843}
5844
5845inline void RawCode::setKwonlyargcount(word value) const {
5846 instanceVariableAtPut(kKwonlyargcountOffset, RawSmallInt::fromWord(value));
5847}
5848
5849inline RawObject RawCode::lnotab() const {
5850 return instanceVariableAt(kLnotabOffset);
5851}
5852
5853inline void RawCode::setLnotab(RawObject value) const {
5854 instanceVariableAtPut(kLnotabOffset, value);
5855}
5856
5857inline RawObject RawCode::name() const {
5858 return instanceVariableAt(kNameOffset);
5859}
5860
5861inline void RawCode::setName(RawObject value) const {
5862 instanceVariableAtPut(kNameOffset, value);
5863}
5864
5865inline RawObject RawCode::names() const {
5866 return instanceVariableAt(kNamesOffset);
5867}
5868
5869inline void RawCode::setNames(RawObject value) const {
5870 instanceVariableAtPut(kNamesOffset, value);
5871}
5872
5873inline word RawCode::nlocals() const {
5874 return RawSmallInt::cast(instanceVariableAt(kNlocalsOffset)).value();
5875}
5876
5877inline void RawCode::setNlocals(word value) const {
5878 instanceVariableAtPut(kNlocalsOffset, RawSmallInt::fromWord(value));
5879}
5880
5881inline word RawCode::stacksize() const {
5882 return RawSmallInt::cast(instanceVariableAt(kStacksizeOffset)).value();
5883}
5884
5885inline void RawCode::setStacksize(word value) const {
5886 instanceVariableAtPut(kStacksizeOffset, RawSmallInt::fromWord(value));
5887}
5888
5889inline RawObject RawCode::varnames() const {
5890 return instanceVariableAt(kVarnamesOffset);
5891}
5892
5893inline void RawCode::setVarnames(RawObject value) const {
5894 instanceVariableAtPut(kVarnamesOffset, value);
5895}
5896
5897inline bool RawCode::isAsyncGenerator() const {
5898 return flags() & RawFunction::Flags::kAsyncGenerator;
5899}
5900
5901inline bool RawCode::isGeneratorLike() const {
5902 return flags() &
5903 (Flags::kCoroutine | Flags::kGenerator | Flags::kAsyncGenerator);
5904}
5905
5906inline bool RawCode::hasFreevarsOrCellvars() const {
5907 return !(flags() & Flags::kNofree);
5908}
5909
5910inline bool RawCode::hasOptimizedAndNewlocals() const {
5911 return (flags() & (Flags::kOptimized | Flags::kNewlocals)) ==
5912 (Flags::kOptimized | Flags::kNewlocals);
5913}
5914
5915inline bool RawCode::hasOptimizedOrNewlocals() const {
5916 return flags() & (Flags::kOptimized | Flags::kNewlocals);
5917}
5918
5919inline bool RawCode::isNative() const { return code().isInt(); }
5920
5921inline void* RawCode::intrinsic() const {
5922 return RawSmallInt::cast(instanceVariableAt(kIntrinsicOffset))
5923 .asAlignedCPtr();
5924}
5925
5926inline void RawCode::setIntrinsic(void* fp) const {
5927 instanceVariableAtPut(kIntrinsicOffset, RawSmallInt::fromAlignedCPtr(fp));
5928}
5929
5930// RawLargeInt
5931
5932inline word RawLargeInt::asWord() const {
5933 DCHECK(numDigits() == 1, "RawLargeInt cannot fit in a word");
5934 return static_cast<word>(digitAt(0));
5935}
5936
5937inline void* RawLargeInt::asCPtr() const {
5938 DCHECK(numDigits() == 1, "Large integer cannot fit in a pointer");
5939 DCHECK(isPositive(), "Cannot cast a negative value to a C pointer");
5940 return reinterpret_cast<void*>(asWord());
5941}
5942
5943template <typename T>
5944if_signed_t<T, OptInt<T>> RawLargeInt::asInt() const {
5945 static_assert(sizeof(T) <= sizeof(word), "T must not be larger than word");
5946
5947 if (numDigits() > 1) {
5948 auto const high_digit = static_cast<word>(digitAt(numDigits() - 1));
5949 return high_digit < 0 ? OptInt<T>::underflow() : OptInt<T>::overflow();
5950 }
5951 if (numDigits() == 1) {
5952 auto const value = asWord();
5953 if (value <= std::numeric_limits<T>::max() &&
5954 value >= std::numeric_limits<T>::min()) {
5955 return OptInt<T>::valid(value);
5956 }
5957 }
5958 return OptInt<T>::overflow();
5959}
5960
5961template <typename T>
5962if_unsigned_t<T, OptInt<T>> RawLargeInt::asInt() const {
5963 static_assert(sizeof(T) <= sizeof(word), "T must not be larger than word");
5964
5965 if (isNegative()) return OptInt<T>::underflow();
5966 if (static_cast<size_t>(bitLength()) > sizeof(T) * kBitsPerByte) {
5967 return OptInt<T>::overflow();
5968 }
5969 // No T accepted by this function needs more than one digit.
5970 return OptInt<T>::valid(digitAt(0));
5971}
5972
5973inline bool RawLargeInt::isEven() const {
5974 word lowest_digit = digitAt(0);
5975 return (lowest_digit & 1) == 0;
5976}
5977
5978inline bool RawLargeInt::isNegative() const {
5979 word highest_digit = digitAt(numDigits() - 1);
5980 return highest_digit < 0;
5981}
5982
5983inline bool RawLargeInt::isPositive() const {
5984 word highest_digit = digitAt(numDigits() - 1);
5985 return highest_digit >= 0;
5986}
5987
5988inline uword RawLargeInt::digitAt(word index) const {
5989 DCHECK_INDEX(index, numDigits());
5990 return reinterpret_cast<uword*>(address() + kValueOffset)[index];
5991}
5992
5993inline void RawLargeInt::digitAtPut(word index, uword digit) const {
5994 DCHECK_INDEX(index, numDigits());
5995 reinterpret_cast<uword*>(address() + kValueOffset)[index] = digit;
5996}
5997
5998inline word RawLargeInt::numDigits() const {
5999 return headerCountOrOverflow() / kWordSize;
6000}
6001
6002inline word RawLargeInt::allocationSize(word num_digits) {
6003 word size = headerSize(num_digits * kWordSize) + num_digits * kWordSize;
6004 return roundAllocationSize(size);
6005}
6006
6007inline RawObject RawLargeInt::initialize(uword address, word num_digits) {
6008 return initializeHeader(address, num_digits * kWordSize, 0,
6009 LayoutId::kLargeInt, ObjectFormat::kData);
6010}
6011
6012// RawFloat
6013
6014inline word RawFloat::allocationSize() {
6015 return roundAllocationSize(RawHeader::kSize + kSize);
6016}
6017
6018inline double RawFloat::value() const {
6019 return *reinterpret_cast<double*>(address() + kValueOffset);
6020}
6021
6022inline RawObject RawFloat::initialize(uword address, double value) {
6023 RawHeapObject raw =
6024 initializeHeader(address, /*count=*/RawFloat::kSize,
6025 /*hash=*/0, LayoutId::kFloat, ObjectFormat::kData);
6026 *reinterpret_cast<double*>(raw.address() + kValueOffset) = value;
6027 return raw;
6028}
6029
6030// RawComplex
6031
6032inline word RawComplex::allocationSize() {
6033 return roundAllocationSize(RawHeader::kSize + kSize);
6034}
6035
6036inline double RawComplex::real() const {
6037 return *reinterpret_cast<double*>(address() + kRealOffset);
6038}
6039
6040inline double RawComplex::imag() const {
6041 return *reinterpret_cast<double*>(address() + kImagOffset);
6042}
6043
6044inline RawObject RawComplex::initialize(uword address, double real,
6045 double imag) {
6046 RawHeapObject raw =
6047 initializeHeader(address, /*count=*/RawComplex::kSize,
6048 /*hash=*/0, LayoutId::kComplex, ObjectFormat::kData);
6049 *reinterpret_cast<double*>(raw.address() + kRealOffset) = real;
6050 *reinterpret_cast<double*>(raw.address() + kImagOffset) = imag;
6051 return raw;
6052}
6053
6054// RawFrameProxy
6055
6056inline RawObject RawFrameProxy::back() const {
6057 return instanceVariableAt(kBackOffset);
6058}
6059
6060inline void RawFrameProxy::setBack(RawObject back) const {
6061 instanceVariableAtPut(kBackOffset, back);
6062}
6063
6064inline RawObject RawFrameProxy::function() const {
6065 return instanceVariableAt(kFunctionOffset);
6066}
6067
6068inline void RawFrameProxy::setFunction(RawObject function) const {
6069 instanceVariableAtPut(kFunctionOffset, function);
6070}
6071
6072inline RawObject RawFrameProxy::lasti() const {
6073 return instanceVariableAt(kLastiOffset);
6074}
6075
6076inline void RawFrameProxy::setLasti(RawObject lasti) const {
6077 instanceVariableAtPut(kLastiOffset, lasti);
6078}
6079
6080inline RawObject RawFrameProxy::locals() const {
6081 return instanceVariableAt(kLocalsOffset);
6082}
6083
6084inline void RawFrameProxy::setLocals(RawObject locals) const {
6085 instanceVariableAtPut(kLocalsOffset, locals);
6086}
6087
6088// RawUserBytesBase
6089
6090inline RawObject RawUserBytesBase::value() const {
6091 return instanceVariableAt(kValueOffset);
6092}
6093
6094inline void RawUserBytesBase::setValue(RawObject value) const {
6095 DCHECK(value.isBytes(), "Only bytes type is permitted as a value.");
6096 instanceVariableAtPut(kValueOffset, value);
6097}
6098
6099inline RawBytes bytesUnderlying(RawObject object) {
6100 if (object.isBytes()) {
6101 return RawBytes::cast(object);
6102 }
6103 return RawBytes::cast(object.rawCast<RawUserBytesBase>().value());
6104}
6105
6106// RawUserComplexBase
6107
6108inline RawObject RawUserComplexBase::value() const {
6109 return instanceVariableAt(kValueOffset);
6110}
6111
6112inline void RawUserComplexBase::setValue(RawObject value) const {
6113 DCHECK(value.isComplex(), "Only complex type is permitted as a value.");
6114 instanceVariableAtPut(kValueOffset, value);
6115}
6116
6117inline RawComplex complexUnderlying(RawObject object) {
6118 if (object.isComplex()) {
6119 return RawComplex::cast(object);
6120 }
6121 return RawComplex::cast(object.rawCast<RawUserComplexBase>().value());
6122}
6123
6124// RawUserFloatBase
6125
6126inline RawObject RawUserFloatBase::value() const {
6127 return instanceVariableAt(kValueOffset);
6128}
6129
6130inline void RawUserFloatBase::setValue(RawObject value) const {
6131 DCHECK(value.isFloat(), "Only float type is permitted as a value");
6132 instanceVariableAtPut(kValueOffset, value);
6133}
6134
6135inline RawFloat floatUnderlying(RawObject object) {
6136 if (object.isFloat()) {
6137 return RawFloat::cast(object);
6138 }
6139 return RawFloat::cast(object.rawCast<RawUserFloatBase>().value());
6140}
6141
6142// RawUserIntBase
6143
6144inline RawObject RawUserIntBase::value() const {
6145 return instanceVariableAt(kValueOffset);
6146}
6147
6148inline void RawUserIntBase::setValue(RawObject value) const {
6149 DCHECK(value.isSmallInt() || value.isLargeInt(),
6150 "Only int types, not bool, are permitted as a value.");
6151 instanceVariableAtPut(kValueOffset, value);
6152}
6153
6154inline RawInt intUnderlying(RawObject object) {
6155 if (object.isInt()) {
6156 return RawInt::cast(object);
6157 }
6158 return RawInt::cast(object.rawCast<RawUserIntBase>().value());
6159}
6160
6161// RawUserStrBase
6162
6163inline RawObject RawUserStrBase::value() const {
6164 return instanceVariableAt(kValueOffset);
6165}
6166
6167inline void RawUserStrBase::setValue(RawObject value) const {
6168 DCHECK(value.isStr(), "Only str type is permitted as a value.");
6169 instanceVariableAtPut(kValueOffset, value);
6170}
6171
6172inline RawStr strUnderlying(RawObject object) {
6173 if (object.isStr()) {
6174 return RawStr::cast(object);
6175 }
6176 return RawStr::cast(object.rawCast<RawUserStrBase>().value());
6177}
6178
6179// RawRange
6180
6181inline RawObject RawRange::start() const {
6182 return instanceVariableAt(kStartOffset);
6183}
6184
6185inline void RawRange::setStart(RawObject value) const {
6186 instanceVariableAtPut(kStartOffset, value);
6187}
6188
6189inline RawObject RawRange::stop() const {
6190 return instanceVariableAt(kStopOffset);
6191}
6192
6193inline void RawRange::setStop(RawObject value) const {
6194 instanceVariableAtPut(kStopOffset, value);
6195}
6196
6197inline RawObject RawRange::step() const {
6198 return instanceVariableAt(kStepOffset);
6199}
6200
6201inline void RawRange::setStep(RawObject value) const {
6202 instanceVariableAtPut(kStepOffset, value);
6203}
6204
6205// RawPointer
6206
6207inline word RawPointer::allocationSize() {
6208 return roundAllocationSize(RawHeader::kSize + kSize);
6209}
6210
6211inline void* RawPointer::cptr() const {
6212 return *reinterpret_cast<void**>(address() + kCPtrOffset);
6213}
6214
6215inline void RawPointer::setCPtr(void* new_cptr) const {
6216 *reinterpret_cast<void**>(address() + kCPtrOffset) = new_cptr;
6217}
6218
6219inline word RawPointer::length() const {
6220 return *reinterpret_cast<word*>(address() + kLengthOffset);
6221}
6222
6223inline void RawPointer::setLength(word new_length) const {
6224 *reinterpret_cast<word*>(address() + kLengthOffset) = new_length;
6225}
6226
6227inline RawObject RawPointer::initialize(uword address, void* cptr,
6228 word length) {
6229 RawHeapObject raw =
6230 initializeHeader(address, /*count=*/RawPointer::kSize,
6231 /*hash=*/0, LayoutId::kPointer, ObjectFormat::kData);
6232 *reinterpret_cast<void**>(raw.address() + kCPtrOffset) = cptr;
6233 *reinterpret_cast<word*>(raw.address() + kLengthOffset) = length;
6234 return raw;
6235}
6236
6237// RawProperty
6238
6239inline RawObject RawProperty::getter() const {
6240 return instanceVariableAt(kGetterOffset);
6241}
6242
6243inline void RawProperty::setGetter(RawObject function) const {
6244 instanceVariableAtPut(kGetterOffset, function);
6245}
6246
6247inline RawObject RawProperty::setter() const {
6248 return instanceVariableAt(kSetterOffset);
6249}
6250
6251inline void RawProperty::setSetter(RawObject function) const {
6252 instanceVariableAtPut(kSetterOffset, function);
6253}
6254
6255inline RawObject RawProperty::deleter() const {
6256 return instanceVariableAt(kDeleterOffset);
6257}
6258
6259inline void RawProperty::setDeleter(RawObject function) const {
6260 instanceVariableAtPut(kDeleterOffset, function);
6261}
6262
6263// RawSlice
6264
6265inline RawObject RawSlice::start() const {
6266 return instanceVariableAt(kStartOffset);
6267}
6268
6269inline void RawSlice::setStart(RawObject value) const {
6270 instanceVariableAtPut(kStartOffset, value);
6271}
6272
6273inline RawObject RawSlice::stop() const {
6274 return instanceVariableAt(kStopOffset);
6275}
6276
6277inline void RawSlice::setStop(RawObject value) const {
6278 instanceVariableAtPut(kStopOffset, value);
6279}
6280
6281inline RawObject RawSlice::step() const {
6282 return instanceVariableAt(kStepOffset);
6283}
6284
6285inline void RawSlice::setStep(RawObject value) const {
6286 instanceVariableAtPut(kStepOffset, value);
6287}
6288
6289// RawSlotDescriptor
6290
6291inline RawObject RawSlotDescriptor::type() const {
6292 return RawSlotDescriptor::instanceVariableAt(kTypeOffset);
6293}
6294
6295inline void RawSlotDescriptor::setType(RawObject type) const {
6296 instanceVariableAtPut(kTypeOffset, type);
6297}
6298
6299inline RawObject RawSlotDescriptor::name() const {
6300 return RawSlotDescriptor::instanceVariableAt(kNameOffset);
6301}
6302
6303inline void RawSlotDescriptor::setName(RawObject name) const {
6304 instanceVariableAtPut(kNameOffset, name);
6305}
6306
6307inline word RawSlotDescriptor::offset() const {
6308 return RawSmallInt::cast(RawSlotDescriptor::instanceVariableAt(kOffsetOffset))
6309 .value();
6310}
6311
6312inline void RawSlotDescriptor::setOffset(word offset) const {
6313 instanceVariableAtPut(kOffsetOffset, RawSmallInt::fromWord(offset));
6314}
6315
6316// RawStaticMethod
6317
6318inline RawObject RawStaticMethod::function() const {
6319 return instanceVariableAt(kFunctionOffset);
6320}
6321
6322inline void RawStaticMethod::setFunction(RawObject function) const {
6323 instanceVariableAtPut(kFunctionOffset, function);
6324}
6325
6326// RawBytearray
6327
6328inline byte RawBytearray::byteAt(word index) const {
6329 DCHECK_INDEX(index, numItems());
6330 return RawMutableBytes::cast(items()).byteAt(index);
6331}
6332
6333inline void RawBytearray::byteAtPut(word index, byte value) const {
6334 DCHECK_INDEX(index, numItems());
6335 RawMutableBytes::cast(items()).byteAtPut(index, value);
6336}
6337
6338inline void RawBytearray::copyTo(byte* dst, word length) const {
6339 DCHECK_BOUND(length, numItems());
6340 RawMutableBytes::cast(items()).copyTo(dst, length);
6341}
6342
6343inline word RawBytearray::numItems() const {
6344 return RawSmallInt::cast(instanceVariableAt(kNumItemsOffset)).value();
6345}
6346
6347inline void RawBytearray::setNumItems(word num_bytes) const {
6348 DCHECK_BOUND(num_bytes, capacity());
6349 instanceVariableAtPut(kNumItemsOffset, RawSmallInt::fromWord(num_bytes));
6350}
6351
6352inline RawObject RawBytearray::items() const {
6353 return instanceVariableAt(kItemsOffset);
6354}
6355
6356inline void RawBytearray::setItems(RawObject new_items) const {
6357 DCHECK(new_items.isMutableBytes(), "backed by mutable bytes");
6358 instanceVariableAtPut(kItemsOffset, new_items);
6359}
6360
6361inline word RawBytearray::capacity() const {
6362 return RawMutableBytes::cast(items()).length();
6363}
6364
6365// RawStrArray
6366
6367inline RawObject RawStrArray::items() const {
6368 return instanceVariableAt(kItemsOffset);
6369}
6370
6371inline void RawStrArray::setItems(RawObject new_items) const {
6372 DCHECK(new_items.isMutableBytes(), "StrArray must be backed by MutableBytes");
6373 instanceVariableAtPut(kItemsOffset, new_items);
6374}
6375
6376inline word RawStrArray::numItems() const {
6377 return RawSmallInt::cast(instanceVariableAt(kNumItemsOffset)).value();
6378}
6379
6380inline void RawStrArray::setNumItems(word num_items) const {
6381 DCHECK_BOUND(num_items, capacity());
6382 instanceVariableAtPut(kNumItemsOffset, RawSmallInt::fromWord(num_items));
6383}
6384
6385inline void RawStrArray::copyTo(byte* dst, word length) const {
6386 DCHECK_BOUND(length, numItems());
6387 RawMutableBytes::cast(items()).copyTo(dst, length);
6388}
6389
6390inline word RawStrArray::capacity() const {
6391 return RawMutableBytes::cast(items()).length();
6392}
6393
6394// RawDeque
6395
6396inline RawObject RawDeque::at(word index) const {
6397 DCHECK_INDEX(index, capacity());
6398 return RawTuple::cast(items()).at(index);
6399}
6400
6401inline void RawDeque::atPut(word index, RawObject value) const {
6402 DCHECK_INDEX(index, capacity());
6403 RawTuple::cast(items()).atPut(index, value);
6404}
6405
6406inline word RawDeque::capacity() const {
6407 RawObject raw_items = items();
6408 if (raw_items == RawSmallInt::fromWord(0)) return 0;
6409 return RawTuple::cast(raw_items).length();
6410}
6411
6412inline void RawDeque::clear() const {
6413 if (numItems() == 0) return;
6414 RawMutableTuple::cast(items()).fill(RawNoneType::object());
6415 setLeft(0);
6416 setNumItems(0);
6417}
6418
6419inline RawObject RawDeque::items() const {
6420 return instanceVariableAt(kItemsOffset);
6421}
6422
6423inline void RawDeque::setItems(RawObject new_items) const {
6424 instanceVariableAtPut(kItemsOffset, new_items);
6425}
6426
6427inline word RawDeque::left() const {
6428 return RawSmallInt::cast(instanceVariableAt(kLeftOffset)).value();
6429}
6430
6431inline void RawDeque::setLeft(word left) const {
6432 instanceVariableAtPut(kLeftOffset, RawSmallInt::fromWord(left));
6433}
6434
6435inline word RawDeque::numItems() const {
6436 return RawSmallInt::cast(instanceVariableAt(kNumItemsOffset)).value();
6437}
6438
6439inline void RawDeque::setNumItems(word num_items) const {
6440 instanceVariableAtPut(kNumItemsOffset, RawSmallInt::fromWord(num_items));
6441}
6442
6443inline RawObject RawDeque::maxlen() const {
6444 return instanceVariableAt(kMaxlenOffset);
6445}
6446
6447inline void RawDeque::setMaxlen(RawObject maxlen) const {
6448 instanceVariableAtPut(kMaxlenOffset, maxlen);
6449}
6450
6451inline word RawDeque::state() const {
6452 return RawSmallInt::cast(instanceVariableAt(kStateOffset)).value();
6453}
6454
6455inline void RawDeque::setState(word state) const {
6456 instanceVariableAtPut(kStateOffset, RawSmallInt::fromWord(state));
6457}
6458
6459// RawDequeIterator
6460
6461inline word RawDequeIterator::state() const {
6462 return RawSmallInt::cast(instanceVariableAt(kStateOffset)).value();
6463}
6464
6465inline void RawDequeIterator::setState(word state) const {
6466 instanceVariableAtPut(kStateOffset, RawSmallInt::fromWord(state));
6467}
6468
6469// RawDequeReverseIterator
6470
6471inline word RawDequeReverseIterator::state() const {
6472 return RawSmallInt::cast(instanceVariableAt(kStateOffset)).value();
6473}
6474
6475inline void RawDequeReverseIterator::setState(word state) const {
6476 instanceVariableAtPut(kStateOffset, RawSmallInt::fromWord(state));
6477}
6478
6479// RawDict
6480
6481inline word RawDict::numItems() const {
6482 return RawSmallInt::cast(instanceVariableAt(kNumItemsOffset)).value();
6483}
6484
6485inline void RawDict::setNumItems(word num_items) const {
6486 instanceVariableAtPut(kNumItemsOffset, RawSmallInt::fromWord(num_items));
6487}
6488
6489inline RawObject RawDict::data() const {
6490 return instanceVariableAt(kDataOffset);
6491}
6492
6493inline void RawDict::setData(RawObject data) const {
6494 instanceVariableAtPut(kDataOffset, data);
6495}
6496
6497inline RawObject RawDict::indices() const {
6498 return instanceVariableAt(kIndicesOffset);
6499}
6500
6501inline void RawDict::setIndices(RawObject index_data) const {
6502 instanceVariableAtPut(kIndicesOffset, index_data);
6503}
6504
6505inline word RawDict::firstEmptyItemIndex() const {
6506 return RawSmallInt::cast(instanceVariableAt(kFirstEmptyItemIndexOffset))
6507 .value();
6508}
6509
6510inline void RawDict::setFirstEmptyItemIndex(word first_empty_item_index) const {
6511 instanceVariableAtPut(kFirstEmptyItemIndexOffset,
6512 RawSmallInt::fromWord(first_empty_item_index));
6513}
6514
6515inline word RawDict::numIndices() const {
6516 RawObject indices_obj = indices();
6517 if (indices_obj == RawSmallInt::fromWord(0)) return 0;
6518 return RawMutableBytes::cast(indices_obj).length() >> 2;
6519}
6520
6521// RawDictIteratorBase
6522
6523inline word RawDictIteratorBase::numFound() const {
6524 return RawSmallInt::cast(instanceVariableAt(kNumFoundOffset)).value();
6525}
6526
6527inline void RawDictIteratorBase::setNumFound(word num_found) const {
6528 instanceVariableAtPut(kNumFoundOffset, RawSmallInt::fromWord(num_found));
6529}
6530
6531// RawDictViewBase
6532
6533inline RawObject RawDictViewBase::dict() const {
6534 return instanceVariableAt(kDictOffset);
6535}
6536
6537inline void RawDictViewBase::setDict(RawObject dict) const {
6538 instanceVariableAtPut(kDictOffset, dict);
6539}
6540
6541// RawFunction
6542
6543inline RawObject RawFunction::annotations() const {
6544 return instanceVariableAt(kAnnotationsOffset);
6545}
6546
6547inline void RawFunction::setAnnotations(RawObject annotations) const {
6548 instanceVariableAtPut(kAnnotationsOffset, annotations);
6549}
6550
6551inline word RawFunction::argcount() const {
6552 return RawSmallInt::cast(instanceVariableAt(kArgcountOffset)).value();
6553}
6554
6555inline void RawFunction::setArgcount(word value) const {
6556 instanceVariableAtPut(kArgcountOffset, RawSmallInt::fromWord(value));
6557}
6558
6559inline RawObject RawFunction::closure() const {
6560 return instanceVariableAt(kClosureOffset);
6561}
6562
6563inline void RawFunction::setClosure(RawObject closure) const {
6564 instanceVariableAtPut(kClosureOffset, closure);
6565}
6566
6567inline RawObject RawFunction::code() const {
6568 return instanceVariableAt(kCodeOffset);
6569}
6570
6571inline void RawFunction::setCode(RawObject code) const {
6572 instanceVariableAtPut(kCodeOffset, code);
6573}
6574
6575inline RawObject RawFunction::defaults() const {
6576 return instanceVariableAt(kDefaultsOffset);
6577}
6578
6579inline void RawFunction::setDefaults(RawObject defaults) const {
6580 instanceVariableAtPut(kDefaultsOffset, defaults);
6581}
6582
6583inline bool RawFunction::hasDefaults() const {
6584 return !defaults().isNoneType();
6585}
6586
6587inline RawObject RawFunction::doc() const {
6588 return instanceVariableAt(kDocOffset);
6589}
6590
6591inline void RawFunction::setDoc(RawObject doc) const {
6592 instanceVariableAtPut(kDocOffset, doc);
6593}
6594
6595inline RawFunction::Entry RawFunction::entry() const {
6596 RawObject object = instanceVariableAt(kEntryOffset);
6597 return reinterpret_cast<Entry>(RawSmallInt::cast(object).asAlignedCPtr());
6598}
6599
6600inline void RawFunction::setEntry(RawFunction::Entry thunk) const {
6601 RawObject object =
6602 RawSmallInt::fromAlignedCPtr(reinterpret_cast<void*>(thunk));
6603 instanceVariableAtPut(kEntryOffset, object);
6604}
6605
6606inline RawFunction::Entry RawFunction::entryKw() const {
6607 RawObject object = instanceVariableAt(kEntryKwOffset);
6608 return reinterpret_cast<Entry>(RawSmallInt::cast(object).asAlignedCPtr());
6609}
6610
6611inline void RawFunction::setEntryKw(RawFunction::Entry thunk) const {
6612 RawObject object =
6613 RawSmallInt::fromAlignedCPtr(reinterpret_cast<void*>(thunk));
6614 instanceVariableAtPut(kEntryKwOffset, object);
6615}
6616
6617inline RawFunction::Entry RawFunction::entryEx() const {
6618 RawObject object = instanceVariableAt(kEntryExOffset);
6619 return reinterpret_cast<Entry>(RawSmallInt::cast(object).asAlignedCPtr());
6620}
6621
6622inline void RawFunction::setEntryEx(RawFunction::Entry thunk) const {
6623 RawObject object =
6624 RawSmallInt::fromAlignedCPtr(reinterpret_cast<void*>(thunk));
6625 instanceVariableAtPut(kEntryExOffset, object);
6626}
6627
6628inline void* RawFunction::entryAsm() const {
6629 RawObject object = instanceVariableAt(kEntryAsmOffset);
6630 return reinterpret_cast<void*>(RawSmallInt::cast(object).asAlignedCPtr());
6631}
6632
6633inline void RawFunction::setEntryAsm(void* thunk) const {
6634 RawObject object = RawSmallInt::fromAlignedCPtr(thunk);
6635 instanceVariableAtPut(kEntryAsmOffset, object);
6636}
6637
6638inline word RawFunction::flags() const {
6639 return RawSmallInt::cast(instanceVariableAt(kFlagsOffset)).value();
6640}
6641
6642inline void RawFunction::setFlags(word flags) const {
6643 instanceVariableAtPut(kFlagsOffset, RawSmallInt::fromWord(flags));
6644}
6645
6646inline bool RawFunction::isAsyncGenerator() const {
6647 return flags() & Flags::kAsyncGenerator;
6648}
6649
6650inline bool RawFunction::isCoroutine() const {
6651 return flags() & Flags::kCoroutine;
6652}
6653
6654inline bool RawFunction::isExtension() const {
6655 return flags() & Flags::kExtension;
6656}
6657
6658inline bool RawFunction::isCompiled() const {
6659 return flags() & Flags::kCompiled;
6660}
6661
6662inline bool RawFunction::isGeneratorLike() const {
6663 return flags() &
6664 (Flags::kCoroutine | Flags::kGenerator | Flags::kAsyncGenerator);
6665}
6666
6667inline bool RawFunction::hasFreevarsOrCellvars() const {
6668 return !(flags() & Flags::kNofree);
6669}
6670
6671inline bool RawFunction::isGenerator() const {
6672 return flags() & Flags::kGenerator;
6673}
6674
6675inline bool RawFunction::isIterableCoroutine() const {
6676 return flags() & Flags::kIterableCoroutine;
6677}
6678
6679inline bool RawFunction::hasOptimizedOrNewlocals() const {
6680 return flags() & (Flags::kOptimized | Flags::kNewlocals);
6681}
6682
6683inline bool RawFunction::hasSimpleCall() const {
6684 return flags() & Flags::kSimpleCall;
6685}
6686
6687inline bool RawFunction::hasVarargs() const {
6688 return flags() & Flags::kVarargs;
6689}
6690
6691inline bool RawFunction::hasVarkeyargs() const {
6692 return flags() & Flags::kVarkeyargs;
6693}
6694
6695inline bool RawFunction::hasVarargsOrVarkeyargs() const {
6696 return flags() & (Flags::kVarargs | Flags::kVarkeyargs);
6697}
6698
6699inline bool RawFunction::isInterpreted() const {
6700 return flags() & Flags::kInterpreted;
6701}
6702
6703inline void RawFunction::setIsInterpreted(bool interpreted) const {
6704 setFlags(interpreted ? flags() | Flags::kInterpreted
6705 : flags() & ~Flags::kInterpreted);
6706}
6707
6708inline void* RawFunction::intrinsic() const {
6709 return RawSmallInt::cast(instanceVariableAt(kIntrinsicOffset))
6710 .asAlignedCPtr();
6711}
6712
6713inline void RawFunction::setIntrinsic(void* fp) const {
6714 instanceVariableAtPut(kIntrinsicOffset, RawSmallInt::fromAlignedCPtr(fp));
6715}
6716
6717inline RawObject RawFunction::kwDefaults() const {
6718 return instanceVariableAt(kKwDefaultsOffset);
6719}
6720
6721inline void RawFunction::setKwDefaults(RawObject kw_defaults) const {
6722 instanceVariableAtPut(kKwDefaultsOffset, kw_defaults);
6723}
6724
6725inline RawObject RawFunction::moduleName() const {
6726 return instanceVariableAt(kModuleNameOffset);
6727}
6728
6729inline void RawFunction::setModuleName(RawObject module_name) const {
6730 DCHECK(module_name.isStr(), "module_name is expected to be a Str");
6731 instanceVariableAtPut(kModuleNameOffset, module_name);
6732}
6733
6734inline RawObject RawFunction::moduleObject() const {
6735 return instanceVariableAt(kModuleObjectOffset);
6736}
6737
6738inline void RawFunction::setModuleObject(RawObject module_object) const {
6739 instanceVariableAtPut(kModuleObjectOffset, module_object);
6740}
6741
6742inline RawObject RawFunction::name() const {
6743 return instanceVariableAt(kNameOffset);
6744}
6745
6746inline void RawFunction::setName(RawObject name) const {
6747 instanceVariableAtPut(kNameOffset, name);
6748}
6749
6750inline RawObject RawFunction::qualname() const {
6751 return instanceVariableAt(kQualnameOffset);
6752}
6753
6754inline void RawFunction::setQualname(RawObject qualname) const {
6755 instanceVariableAtPut(kQualnameOffset, qualname);
6756}
6757
6758inline word RawFunction::totalArgs() const {
6759 return RawSmallInt::cast(instanceVariableAt(kTotalArgsOffset)).value();
6760}
6761
6762inline void RawFunction::setTotalArgs(word value) const {
6763 instanceVariableAtPut(kTotalArgsOffset, RawSmallInt::fromWord(value));
6764}
6765
6766inline word RawFunction::totalVars() const {
6767 return RawSmallInt::cast(instanceVariableAt(kTotalVarsOffset)).value();
6768}
6769
6770inline void RawFunction::setTotalVars(word value) const {
6771 instanceVariableAtPut(kTotalVarsOffset, RawSmallInt::fromWord(value));
6772}
6773
6774inline word RawFunction::totalLocals() const {
6775 return totalArgs() + totalVars();
6776}
6777
6778inline RawObject RawFunction::stacksizeOrBuiltin() const {
6779 return instanceVariableAt(kStacksizeOrBuiltinOffset);
6780}
6781
6782inline void RawFunction::setStacksizeOrBuiltin(
6783 RawObject stacksize_or_builtin) const {
6784 instanceVariableAtPut(kStacksizeOrBuiltinOffset, stacksize_or_builtin);
6785}
6786
6787inline RawObject RawFunction::rewrittenBytecode() const {
6788 return instanceVariableAt(kRewrittenBytecodeOffset);
6789}
6790
6791inline void RawFunction::setRewrittenBytecode(
6792 RawObject rewritten_bytecode) const {
6793 instanceVariableAtPut(kRewrittenBytecodeOffset, rewritten_bytecode);
6794}
6795
6796inline RawObject RawFunction::caches() const {
6797 return instanceVariableAt(kCachesOffset);
6798}
6799
6800inline void RawFunction::setCaches(RawObject cache) const {
6801 instanceVariableAtPut(kCachesOffset, cache);
6802}
6803
6804inline RawObject RawFunction::dict() const {
6805 return instanceVariableAt(kDictOffset);
6806}
6807
6808inline void RawFunction::setDict(RawObject dict) const {
6809 instanceVariableAtPut(kDictOffset, dict);
6810}
6811
6812// RawInstance
6813
6814inline word RawInstance::allocationSize(word num_attr) {
6815 DCHECK(num_attr >= 0, "invalid number of attributes %ld", num_attr);
6816 word size = headerSize(num_attr) + num_attr * kPointerSize;
6817 return roundAllocationSize(size);
6818}
6819
6820// RawList
6821
6822inline RawObject RawList::items() const {
6823 return instanceVariableAt(kItemsOffset);
6824}
6825
6826inline void RawList::setItems(RawObject new_items) const {
6827 instanceVariableAtPut(kItemsOffset, new_items);
6828}
6829
6830inline word RawList::capacity() const {
6831 return RawTuple::cast(items()).length();
6832}
6833
6834inline word RawList::numItems() const {
6835 return RawSmallInt::cast(instanceVariableAt(kNumItemsOffset)).value();
6836}
6837
6838inline void RawList::setNumItems(word num_items) const {
6839 instanceVariableAtPut(kNumItemsOffset, RawSmallInt::fromWord(num_items));
6840}
6841
6842inline void RawList::clearFrom(word idx) const {
6843 if (numItems() == 0) return;
6844 DCHECK_INDEX(idx, numItems());
6845 std::memset(reinterpret_cast<byte*>(RawTuple::cast(items()).address()) +
6846 idx * kPointerSize,
6847 -1, (numItems() - idx) * kWordSize);
6848 setNumItems(idx);
6849}
6850
6851inline void RawList::atPut(word index, RawObject value) const {
6852 DCHECK_INDEX(index, numItems());
6853 RawObject items = instanceVariableAt(kItemsOffset);
6854 RawTuple::cast(items).atPut(index, value);
6855}
6856
6857inline RawObject RawList::at(word index) const {
6858 DCHECK_INDEX(index, numItems());
6859 return RawTuple::cast(items()).at(index);
6860}
6861
6862inline void RawList::swap(word i, word j) const {
6863 DCHECK_INDEX(i, numItems());
6864 DCHECK_INDEX(j, numItems());
6865 RawMutableTuple::cast(items()).swap(i, j);
6866}
6867
6868// RawMappingProxy
6869
6870inline RawObject RawMappingProxy::mapping() const {
6871 return RawMappingProxy::instanceVariableAt(kMappingOffset);
6872}
6873
6874inline void RawMappingProxy::setMapping(RawObject mapping) const {
6875 instanceVariableAtPut(kMappingOffset, mapping);
6876}
6877
6878// RawMemoryView
6879
6880inline RawObject RawMemoryView::buffer() const {
6881 return RawMemoryView::instanceVariableAt(kBufferOffset);
6882}
6883
6884inline void RawMemoryView::setBuffer(RawObject buffer) const {
6885 instanceVariableAtPut(kBufferOffset, buffer);
6886}
6887
6888inline RawObject RawMemoryView::format() const {
6889 return RawMemoryView::instanceVariableAt(kFormatOffset);
6890}
6891
6892inline void RawMemoryView::setFormat(RawObject format) const {
6893 instanceVariableAtPut(kFormatOffset, format);
6894}
6895
6896inline bool RawMemoryView::readOnly() const {
6897 return RawBool::cast(instanceVariableAt(kReadOnlyOffset)).value();
6898}
6899
6900inline void RawMemoryView::setReadOnly(bool read_only) const {
6901 instanceVariableAtPut(kReadOnlyOffset, RawBool::fromBool(read_only));
6902}
6903
6904inline word RawMemoryView::length() const {
6905 return RawSmallInt::cast(instanceVariableAt(kLengthOffset)).value();
6906}
6907
6908inline void RawMemoryView::setLength(word length) const {
6909 instanceVariableAtPut(kLengthOffset, RawSmallInt::fromWord(length));
6910}
6911
6912inline RawObject RawMemoryView::object() const {
6913 return RawMemoryView::instanceVariableAt(kObjectOffset);
6914}
6915
6916inline void RawMemoryView::setObject(RawObject object) const {
6917 instanceVariableAtPut(kObjectOffset, object);
6918}
6919
6920inline RawObject RawMemoryView::ndim() const {
6921 return RawMemoryView::instanceVariableAt(kNdimOffset);
6922}
6923
6924inline void RawMemoryView::setNdim(RawObject ndim) const {
6925 instanceVariableAtPut(kNdimOffset, ndim);
6926}
6927
6928inline RawObject RawMemoryView::shape() const {
6929 return RawMemoryView::instanceVariableAt(kShapeOffset);
6930}
6931
6932inline void RawMemoryView::setShape(RawObject shape) const {
6933 instanceVariableAtPut(kShapeOffset, shape);
6934}
6935
6936inline word RawMemoryView::start() const {
6937 return RawSmallInt::cast(instanceVariableAt(kStartOffset)).value();
6938}
6939
6940inline void RawMemoryView::setStart(word start) const {
6941 instanceVariableAtPut(kStartOffset, RawSmallInt::fromWord(start));
6942}
6943
6944inline RawObject RawMemoryView::strides() const {
6945 return RawMemoryView::instanceVariableAt(kStridesOffset);
6946}
6947
6948inline void RawMemoryView::setStrides(RawObject strides) const {
6949 instanceVariableAtPut(kStridesOffset, strides);
6950}
6951
6952// RawMmap
6953
6954inline word RawMmap::access() const {
6955 return RawSmallInt::cast(instanceVariableAt(kAccessOffset)).value();
6956}
6957
6958inline void RawMmap::setAccess(word new_access) const {
6959 instanceVariableAtPut(kAccessOffset, RawSmallInt::fromWord(new_access));
6960}
6961
6962inline RawObject RawMmap::data() const {
6963 return instanceVariableAt(kDataOffset);
6964}
6965
6966inline void RawMmap::setData(RawObject new_data) const {
6967 instanceVariableAtPut(kDataOffset, new_data);
6968}
6969
6970inline RawObject RawMmap::fd() const { return instanceVariableAt(kFdOffset); }
6971
6972inline void RawMmap::setFd(RawObject new_fd) const {
6973 instanceVariableAtPut(kFdOffset, new_fd);
6974}
6975
6976inline bool RawMmap::isReadable() const {
6977 return RawSmallInt::cast(instanceVariableAt(kAccessOffset)).value() &
6978 Property::kReadable;
6979}
6980
6981inline void RawMmap::setReadable() const {
6982 word mask = RawSmallInt::cast(instanceVariableAt(kAccessOffset)).value();
6983 instanceVariableAtPut(kAccessOffset,
6984 RawSmallInt::fromWord(mask | Property::kReadable));
6985}
6986
6987inline bool RawMmap::isWritable() const {
6988 return RawSmallInt::cast(instanceVariableAt(kAccessOffset)).value() &
6989 Property::kWritable;
6990}
6991
6992inline void RawMmap::setWritable() const {
6993 word mask = RawSmallInt::cast(instanceVariableAt(kAccessOffset)).value();
6994 instanceVariableAtPut(kAccessOffset,
6995 RawSmallInt::fromWord(mask | Property::kWritable));
6996}
6997
6998inline bool RawMmap::isCopyOnWrite() const {
6999 return RawSmallInt::cast(instanceVariableAt(kAccessOffset)).value() &
7000 Property::kCopyOnWrite;
7001}
7002
7003inline void RawMmap::setCopyOnWrite() const {
7004 word mask = RawSmallInt::cast(instanceVariableAt(kAccessOffset)).value();
7005 instanceVariableAtPut(kAccessOffset,
7006 RawSmallInt::fromWord(mask | Property::kCopyOnWrite));
7007}
7008
7009// RawModule
7010
7011inline RawObject RawModule::name() const {
7012 return instanceVariableAt(kNameOffset);
7013}
7014
7015inline void RawModule::setName(RawObject name) const {
7016 instanceVariableAtPut(kNameOffset, name);
7017}
7018
7019inline RawObject RawModule::def() const {
7020 return instanceVariableAt(kDefOffset);
7021}
7022
7023inline bool RawModule::hasDef() const {
7024 RawObject def_value = def();
7025 return def_value.isInt() && RawInt::cast(def_value).asCPtr() != nullptr;
7026}
7027
7028inline void RawModule::setDef(RawObject def) const {
7029 instanceVariableAtPut(kDefOffset, def);
7030}
7031
7032inline RawObject RawModule::state() const {
7033 return instanceVariableAt(kStateOffset);
7034}
7035
7036inline bool RawModule::hasState() const {
7037 RawObject state_value = state();
7038 return state_value.isInt() && RawInt::cast(state_value).asCPtr() != nullptr;
7039}
7040
7041inline void RawModule::setState(RawObject state) const {
7042 instanceVariableAtPut(kStateOffset, state);
7043}
7044
7045inline RawObject RawModule::moduleProxy() const {
7046 return instanceVariableAt(kModuleProxyOffset);
7047}
7048
7049inline void RawModule::setModuleProxy(RawObject module_proxy) const {
7050 instanceVariableAtPut(kModuleProxyOffset, module_proxy);
7051}
7052
7053inline word RawModule::id() const {
7054 word index = header().hashCode();
7055 DCHECK(index != RawHeader::kUninitializedHash,
7056 "Module header hash field should contain a valid ID");
7057 return index;
7058}
7059
7060inline void RawModule::setId(word id) const {
7061 DCHECK(static_cast<word>(id & RawHeader::kHashCodeMask) == id,
7062 "Module ID %ld doesn't fit in hash code", id);
7063 setHeader(header().withHashCode(id));
7064}
7065
7066// RawModuleProxy
7067
7068inline RawObject RawModuleProxy::module() const {
7069 return instanceVariableAt(kModuleOffset);
7070}
7071
7072inline void RawModuleProxy::setModule(RawObject module) const {
7073 instanceVariableAtPut(kModuleOffset, module);
7074}
7075
7076// RawStr
7077
7078inline byte RawStr::byteAt(word index) const {
7079 if (isImmediateObjectNotSmallInt()) {
7080 return RawSmallStr::cast(*this).byteAt(index);
7081 }
7082 return RawLargeStr::cast(*this).byteAt(index);
7083}
7084
7085inline int32_t RawStr::codePointAt(word index, word* char_length) const {
7086 if (isImmediateObjectNotSmallInt()) {
7087 return RawSmallStr::cast(*this).codePointAt(index, char_length);
7088 }
7089 return RawLargeStr::cast(*this).codePointAt(index, char_length);
7090}
7091
7092inline word RawStr::length() const {
7093 if (isImmediateObjectNotSmallInt()) {
7094 return RawSmallStr::cast(*this).length();
7095 }
7096 return RawLargeStr::cast(*this).length();
7097}
7098
7099inline word RawStr::compare(RawStr that) const {
7100 if (*this == that) {
7101 return 0;
7102 }
7103 if (isImmediateObjectNotSmallInt()) {
7104 if (that.isSmallStr()) {
7105 word result = __builtin_bswap64(this->raw() & ~uword{0xFF}) -
7106 __builtin_bswap64(that.raw() & ~uword{0xFF});
7107 return LIKELY(result != 0)
7108 ? result
7109 : this->length() - RawSmallStr::cast(that).length();
7110 }
7111 return RawSmallStr::cast(*this).compare(that);
7112 }
7113 if (that.isImmediateObjectNotSmallInt()) {
7114 return -RawSmallStr::cast(that).compare(*this);
7115 }
7116 return RawLargeStr::cast(*this).compare(RawLargeStr::cast(that));
7117}
7118
7119inline void RawStr::copyTo(byte* dst, word length) const {
7120 if (isImmediateObjectNotSmallInt()) {
7121 RawSmallStr::cast(*this).copyTo(dst, length);
7122 return;
7123 }
7124 return RawLargeStr::cast(*this).copyTo(dst, length);
7125}
7126
7127inline void RawStr::copyToStartAt(byte* dst, word char_length,
7128 word char_start) const {
7129 if (isImmediateObjectNotSmallInt()) {
7130 RawSmallStr::cast(*this).copyToStartAt(dst, char_length, char_start);
7131 return;
7132 }
7133 return RawLargeStr::cast(*this).copyToStartAt(dst, char_length, char_start);
7134}
7135
7136inline word RawStr::codePointLength() const {
7137 if (isImmediateObjectNotSmallInt()) {
7138 return RawSmallStr::cast(*this).codePointLength();
7139 }
7140 return RawLargeStr::cast(*this).codePointLength();
7141}
7142
7143inline RawStr RawStr::empty() { return RawSmallStr::empty().rawCast<RawStr>(); }
7144
7145inline bool RawStr::equals(RawStr that) const {
7146 if (*this == that) return true;
7147 if (isImmediateObjectNotSmallInt()) return false;
7148 if (that.isImmediateObjectNotSmallInt()) return false;
7149 return RawLargeStr::cast(*this).equals(RawLargeStr::cast(that));
7150}
7151
7152inline bool RawStr::equalsCStr(const char* c_str) const {
7153 if (isImmediateObjectNotSmallInt()) {
7154 return RawSmallStr::cast(*this).equalsCStr(c_str);
7155 }
7156 return RawLargeStr::cast(*this).equalsCStr(c_str);
7157}
7158
7159inline bool RawStr::includes(RawObject that) const {
7160 if (*this == that) return true;
7161 if (isSmallStr()) {
7162 return RawSmallStr::cast(*this).includes(that);
7163 }
7164 return RawLargeStr::cast(*this).includes(that);
7165}
7166
7167inline bool RawStr::includesByte(byte b) const {
7168 if (isImmediateObjectNotSmallInt()) {
7169 return RawSmallStr::cast(*this).includesByte(b);
7170 }
7171 return RawLargeStr::cast(*this).includesByte(b);
7172}
7173
7174inline bool RawStr::isASCII() const {
7175 if (isImmediateObjectNotSmallInt()) {
7176 return RawSmallStr::cast(*this).isASCII();
7177 }
7178 return RawLargeStr::cast(*this).isASCII();
7179}
7180
7181inline word RawStr::occurrencesOf(RawObject that) const {
7182 if (isImmediateObjectNotSmallInt()) {
7183 return RawSmallStr::cast(*this).occurrencesOf(that);
7184 }
7185 return RawLargeStr::cast(*this).occurrencesOf(that);
7186}
7187
7188inline word RawStr::offsetByCodePoints(word index, word count) const {
7189 if (isImmediateObjectNotSmallInt()) {
7190 return RawSmallStr::cast(*this).offsetByCodePoints(index, count);
7191 }
7192 return RawLargeStr::cast(*this).offsetByCodePoints(index, count);
7193}
7194
7195inline char* RawStr::toCStr() const {
7196 if (isImmediateObjectNotSmallInt()) {
7197 return RawSmallStr::cast(*this).toCStr();
7198 }
7199 return RawLargeStr::cast(*this).toCStr();
7200}
7201
7202// RawLargeStr
7203
7204inline word RawLargeStr::allocationSize(word length) {
7205 DCHECK(length > RawSmallStr::kMaxLength, "length %ld is too small",
7206 (long)length);
7207 return RawDataArray::allocationSize(length);
7208}
7209
7210// RawValueCell
7211
7212inline RawObject RawValueCell::value() const {
7213 return instanceVariableAt(kValueOffset);
7214}
7215
7216inline void RawValueCell::setValue(RawObject object) const {
7217 // TODO(T44801497): Disallow a ValueCell in another ValueCell.
7218 DCHECK(*this != object, "ValueCell can't self-reference itself");
7219 instanceVariableAtPut(kValueOffset, object);
7220}
7221
7222inline RawObject RawValueCell::dependencyLink() const {
7223 return instanceVariableAt(kDependencyLinkOffset);
7224}
7225
7226inline void RawValueCell::setDependencyLink(RawObject object) const {
7227 instanceVariableAtPut(kDependencyLinkOffset, object);
7228}
7229
7230inline void RawValueCell::makePlaceholder() const {
7231 instanceVariableAtPut(kValueOffset, *this);
7232}
7233
7234inline bool RawValueCell::isPlaceholder() const { return *this == value(); }
7235
7236// RawEllipsis
7237
7238inline word RawEllipsis::allocationSize() {
7239 return roundAllocationSize(RawHeader::kSize);
7240}
7241
7242inline RawObject RawEllipsis::initialize(uword address) {
7243 return initializeHeader(address, /*count=*/0,
7244 /*hash=*/0, LayoutId::kEllipsis, ObjectFormat::kData);
7245}
7246
7247// RawSetBase
7248
7249inline word RawSetBase::numItems() const {
7250 return RawSmallInt::cast(instanceVariableAt(kNumItemsOffset)).value();
7251}
7252
7253inline void RawSetBase::setNumItems(word num_items) const {
7254 instanceVariableAtPut(kNumItemsOffset, RawSmallInt::fromWord(num_items));
7255}
7256
7257inline word RawSetBase::numFilled() const {
7258 return RawSmallInt::cast(instanceVariableAt(kNumFilledOffset)).value();
7259}
7260
7261inline void RawSetBase::setNumFilled(word num_filled) const {
7262 instanceVariableAtPut(kNumFilledOffset, RawSmallInt::fromWord(num_filled));
7263}
7264
7265inline RawObject RawSetBase::data() const {
7266 return instanceVariableAt(kDataOffset);
7267}
7268
7269inline void RawSetBase::setData(RawObject data) const {
7270 instanceVariableAtPut(kDataOffset, data);
7271}
7272
7273// RawBoundMethod
7274
7275inline RawObject RawBoundMethod::function() const {
7276 return instanceVariableAt(kFunctionOffset);
7277}
7278
7279inline void RawBoundMethod::setFunction(RawObject function) const {
7280 instanceVariableAtPut(kFunctionOffset, function);
7281}
7282
7283inline RawObject RawBoundMethod::self() const {
7284 return instanceVariableAt(kSelfOffset);
7285}
7286
7287inline void RawBoundMethod::setSelf(RawObject self) const {
7288 instanceVariableAtPut(kSelfOffset, self);
7289}
7290
7291// RawCell
7292
7293inline RawObject RawCell::value() const {
7294 return instanceVariableAt(kValueOffset);
7295}
7296
7297inline void RawCell::setValue(RawObject value) const {
7298 instanceVariableAtPut(kValueOffset, value);
7299}
7300
7301// RawClassMethod
7302
7303inline RawObject RawClassMethod::function() const {
7304 return instanceVariableAt(kFunctionOffset);
7305}
7306
7307inline void RawClassMethod::setFunction(RawObject function) const {
7308 instanceVariableAtPut(kFunctionOffset, function);
7309}
7310
7311// RawToken
7312
7313inline RawObject RawToken::context() const {
7314 return instanceVariableAt(kContextOffset);
7315}
7316
7317inline void RawToken::setContext(RawObject context) const {
7318 instanceVariableAtPut(kContextOffset, context);
7319}
7320
7321inline RawObject RawToken::oldValue() const {
7322 return instanceVariableAt(kOldValueOffset);
7323}
7324
7325inline void RawToken::setOldValue(RawObject old_value) const {
7326 instanceVariableAtPut(kOldValueOffset, old_value);
7327}
7328
7329inline bool RawToken::used() const {
7330 return RawBool::cast(instanceVariableAt(kUsedOffset)).value();
7331}
7332
7333inline void RawToken::setUsed(bool used) const {
7334 instanceVariableAtPut(kUsedOffset, RawBool::fromBool(used));
7335}
7336
7337inline RawObject RawToken::var() const {
7338 return instanceVariableAt(kVarOffset);
7339}
7340
7341inline void RawToken::setVar(RawObject var) const {
7342 instanceVariableAtPut(kVarOffset, var);
7343}
7344
7345// RawWeakRef
7346
7347inline RawObject RawWeakRef::referent() const {
7348 return instanceVariableAt(kReferentOffset);
7349}
7350
7351inline void RawWeakRef::setReferent(RawObject referent) const {
7352 instanceVariableAtPut(kReferentOffset, referent);
7353}
7354
7355inline RawObject RawWeakRef::callback() const {
7356 return instanceVariableAt(kCallbackOffset);
7357}
7358
7359inline void RawWeakRef::setCallback(RawObject callable) const {
7360 instanceVariableAtPut(kCallbackOffset, callable);
7361}
7362
7363inline RawObject RawWeakRef::link() const {
7364 return instanceVariableAt(kLinkOffset);
7365}
7366
7367inline void RawWeakRef::setLink(RawObject reference) const {
7368 instanceVariableAtPut(kLinkOffset, reference);
7369}
7370
7371inline RawObject RawWeakRef::hash() const {
7372 return instanceVariableAt(kHashOffset);
7373}
7374
7375inline void RawWeakRef::setHash(RawObject hash) const {
7376 instanceVariableAtPut(kHashOffset, hash);
7377}
7378
7379// RawUserWeakRefBase
7380
7381inline RawObject RawUserWeakRefBase::value() const {
7382 return instanceVariableAt(kValueOffset);
7383}
7384
7385inline void RawUserWeakRefBase::setValue(RawObject value) const {
7386 DCHECK(value.isWeakRef(), "Only tuple type is permitted as a value");
7387 instanceVariableAtPut(kValueOffset, value);
7388}
7389
7390inline RawWeakRef weakRefUnderlying(RawObject object) {
7391 if (object.isWeakRef()) {
7392 return RawWeakRef::cast(object);
7393 }
7394 return RawWeakRef::cast(object.rawCast<RawUserWeakRefBase>().value());
7395}
7396
7397// RawWeakLink
7398
7399inline RawObject RawWeakLink::next() const {
7400 return instanceVariableAt(kNextOffset);
7401}
7402
7403inline void RawWeakLink::setNext(RawObject object) const {
7404 instanceVariableAtPut(kNextOffset, object);
7405}
7406
7407inline RawObject RawWeakLink::prev() const {
7408 return instanceVariableAt(kPrevOffset);
7409}
7410
7411inline void RawWeakLink::setPrev(RawObject object) const {
7412 instanceVariableAtPut(kPrevOffset, object);
7413}
7414
7415// RawLayout
7416
7417inline LayoutId RawLayout::id() const {
7418 return static_cast<LayoutId>(header().hashCode());
7419}
7420
7421inline void RawLayout::setId(LayoutId id) const {
7422 setHeader(header().withHashCode(static_cast<word>(id)));
7423}
7424
7425inline void RawLayout::setDescribedType(RawObject type) const {
7426 instanceVariableAtPut(kDescribedTypeOffset, type);
7427}
7428
7429inline RawObject RawLayout::describedType() const {
7430 return instanceVariableAt(kDescribedTypeOffset);
7431}
7432
7433inline void RawLayout::setInObjectAttributes(RawObject attributes) const {
7434 instanceVariableAtPut(kInObjectAttributesOffset, attributes);
7435}
7436
7437inline RawObject RawLayout::inObjectAttributes() const {
7438 return instanceVariableAt(kInObjectAttributesOffset);
7439}
7440
7441inline void RawLayout::setOverflowAttributes(RawObject attributes) const {
7442 instanceVariableAtPut(kOverflowAttributesOffset, attributes);
7443}
7444
7445inline void RawLayout::setDictOverflowOffset(word offset) const {
7446 instanceVariableAtPut(kOverflowAttributesOffset,
7447 RawSmallInt::fromWord(offset));
7448}
7449
7450inline word RawLayout::dictOverflowOffset() const {
7451 return RawSmallInt::cast(instanceVariableAt(kOverflowAttributesOffset))
7452 .value();
7453}
7454
7455inline word RawLayout::instanceSize() const {
7456 word instance_size_in_words = numInObjectAttributes();
7457 if (!isSealed()) {
7458 instance_size_in_words += 1;
7459 }
7460 if (isNativeProxyLayout()) {
7461 instance_size_in_words += RawNativeProxy::kSizeFromEnd / kPointerSize;
7462 }
7463 return instance_size_in_words * kPointerSize;
7464}
7465
7466inline bool RawLayout::hasDictOverflow() const {
7467 return overflowAttributes().isSmallInt();
7468}
7469
7470inline bool RawLayout::hasTupleOverflow() const {
7471 return overflowAttributes().isTuple();
7472}
7473
7474inline RawObject RawLayout::overflowAttributes() const {
7475 return instanceVariableAt(kOverflowAttributesOffset);
7476}
7477
7478inline void RawLayout::setAdditions(RawObject additions) const {
7479 instanceVariableAtPut(kAdditionsOffset, additions);
7480}
7481
7482inline RawObject RawLayout::additions() const {
7483 return instanceVariableAt(kAdditionsOffset);
7484}
7485
7486inline void RawLayout::setDeletions(RawObject deletions) const {
7487 instanceVariableAtPut(kDeletionsOffset, deletions);
7488}
7489
7490inline RawObject RawLayout::deletions() const {
7491 return instanceVariableAt(kDeletionsOffset);
7492}
7493
7494inline word RawLayout::overflowOffset() const {
7495 DCHECK(hasTupleOverflow() || hasDictOverflow(),
7496 "must have tuple or dict overflow");
7497 return numInObjectAttributes() * kPointerSize;
7498}
7499
7500inline word RawLayout::numInObjectAttributes() const {
7501 return RawSmallInt::cast(instanceVariableAt(kNumInObjectAttributesOffset))
7502 .value();
7503}
7504
7505inline void RawLayout::setNumInObjectAttributes(word count) const {
7506 instanceVariableAtPut(kNumInObjectAttributesOffset,
7507 RawSmallInt::fromWord(count));
7508}
7509
7510inline void RawLayout::seal() const {
7511 setOverflowAttributes(RawNoneType::object());
7512}
7513
7514inline bool RawLayout::isSealed() const {
7515 return overflowAttributes().isNoneType();
7516}
7517
7518inline bool RawLayout::isNativeProxyLayout() const {
7519 RawObject described_type = describedType();
7520 if (described_type.isNoneType()) {
7521 return false;
7522 }
7523 return described_type.rawCast<RawType>().hasNativeData();
7524}
7525
7526// RawSetIterator
7527
7528inline word RawSetIterator::consumedCount() const {
7529 return RawSmallInt::cast(instanceVariableAt(kConsumedCountOffset)).value();
7530}
7531
7532inline void RawSetIterator::setConsumedCount(word consumed) const {
7533 instanceVariableAtPut(kConsumedCountOffset, RawSmallInt::fromWord(consumed));
7534}
7535
7536// RawIteratorBase
7537
7538inline RawObject RawIteratorBase::iterable() const {
7539 return instanceVariableAt(kIterableOffset);
7540}
7541
7542inline void RawIteratorBase::setIterable(RawObject iterable) const {
7543 instanceVariableAtPut(kIterableOffset, iterable);
7544}
7545
7546inline word RawIteratorBase::index() const {
7547 return RawSmallInt::cast(instanceVariableAt(kIndexOffset)).value();
7548}
7549
7550inline void RawIteratorBase::setIndex(word index) const {
7551 instanceVariableAtPut(kIndexOffset, RawSmallInt::fromWord(index));
7552}
7553
7554// RawLongRangeIterator
7555
7556inline RawObject RawLongRangeIterator::next() const {
7557 return instanceVariableAt(kNextOffset);
7558}
7559
7560inline void RawLongRangeIterator::setNext(RawObject next) const {
7561 return instanceVariableAtPut(kNextOffset, next);
7562}
7563
7564inline RawObject RawLongRangeIterator::stop() const {
7565 return instanceVariableAt(kStopOffset);
7566}
7567
7568inline void RawLongRangeIterator::setStop(RawObject stop) const {
7569 return instanceVariableAtPut(kStopOffset, stop);
7570}
7571
7572inline RawObject RawLongRangeIterator::step() const {
7573 return instanceVariableAt(kStepOffset);
7574}
7575
7576inline void RawLongRangeIterator::setStep(RawObject step) const {
7577 return instanceVariableAtPut(kStepOffset, step);
7578}
7579
7580// RawRangeIterator
7581
7582inline word RawRangeIterator::next() const {
7583 return RawSmallInt::cast(instanceVariableAt(kNextOffset)).value();
7584}
7585
7586inline void RawRangeIterator::setNext(word next) const {
7587 return instanceVariableAtPut(kNextOffset, RawSmallInt::fromWord(next));
7588}
7589
7590inline word RawRangeIterator::step() const {
7591 return RawSmallInt::cast(instanceVariableAt(kStepOffset)).value();
7592}
7593
7594inline void RawRangeIterator::setStep(word step) const {
7595 return instanceVariableAtPut(kStepOffset, RawSmallInt::fromWord(step));
7596}
7597
7598inline word RawRangeIterator::length() const {
7599 return RawSmallInt::cast(instanceVariableAt(kLengthOffset)).value();
7600}
7601
7602inline void RawRangeIterator::setLength(word length) const {
7603 return instanceVariableAtPut(kLengthOffset, RawSmallInt::fromWord(length));
7604}
7605
7606// RawSuper
7607
7608inline RawObject RawSuper::type() const {
7609 return instanceVariableAt(kTypeOffset);
7610}
7611
7612inline void RawSuper::setType(RawObject type) const {
7613 instanceVariableAtPut(kTypeOffset, type);
7614}
7615
7616inline RawObject RawSuper::object() const {
7617 return instanceVariableAt(kObjectOffset);
7618}
7619
7620inline void RawSuper::setObject(RawObject obj) const {
7621 instanceVariableAtPut(kObjectOffset, obj);
7622}
7623
7624inline RawObject RawSuper::objectType() const {
7625 return instanceVariableAt(kObjectTypeOffset);
7626}
7627
7628inline void RawSuper::setObjectType(RawObject type) const {
7629 instanceVariableAtPut(kObjectTypeOffset, type);
7630}
7631
7632// RawTupleIterator
7633
7634inline word RawTupleIterator::length() const {
7635 return RawSmallInt::cast(instanceVariableAt(kLengthOffset)).value();
7636}
7637
7638inline void RawTupleIterator::setLength(word length) const {
7639 instanceVariableAtPut(kLengthOffset, RawSmallInt::fromWord(length));
7640}
7641
7642// RawExceptionState
7643
7644inline RawObject RawExceptionState::type() const {
7645 return instanceVariableAt(kTypeOffset);
7646}
7647
7648inline RawObject RawExceptionState::value() const {
7649 return instanceVariableAt(kValueOffset);
7650}
7651
7652inline RawObject RawExceptionState::traceback() const {
7653 return instanceVariableAt(kTracebackOffset);
7654}
7655
7656inline void RawExceptionState::setType(RawObject type) const {
7657 instanceVariableAtPut(kTypeOffset, type);
7658}
7659
7660inline void RawExceptionState::setValue(RawObject value) const {
7661 instanceVariableAtPut(kValueOffset, value);
7662}
7663
7664inline void RawExceptionState::setTraceback(RawObject tb) const {
7665 instanceVariableAtPut(kTracebackOffset, tb);
7666}
7667
7668inline RawObject RawExceptionState::previous() const {
7669 return instanceVariableAt(kPreviousOffset);
7670}
7671
7672inline void RawExceptionState::setPrevious(RawObject prev) const {
7673 instanceVariableAtPut(kPreviousOffset, prev);
7674}
7675
7676// RawGeneratorBase
7677
7678inline RawObject RawGeneratorBase::generatorFrame() const {
7679 return instanceVariableAt(kFrameOffset);
7680}
7681
7682inline void RawGeneratorBase::setGeneratorFrame(RawObject obj) const {
7683 instanceVariableAtPut(kFrameOffset, obj);
7684}
7685
7686inline RawObject RawGeneratorBase::exceptionState() const {
7687 return instanceVariableAt(kExceptionStateOffset);
7688}
7689
7690inline void RawGeneratorBase::setExceptionState(RawObject obj) const {
7691 instanceVariableAtPut(kExceptionStateOffset, obj);
7692}
7693
7694inline RawObject RawGeneratorBase::name() const {
7695 return instanceVariableAt(kNameOffset);
7696}
7697
7698inline void RawGeneratorBase::setName(RawObject obj) const {
7699 instanceVariableAtPut(kNameOffset, obj);
7700}
7701
7702inline RawObject RawGeneratorBase::running() const {
7703 return instanceVariableAt(kRunningOffset);
7704}
7705
7706inline void RawGeneratorBase::setRunning(RawObject obj) const {
7707 instanceVariableAtPut(kRunningOffset, obj);
7708}
7709
7710inline RawObject RawGeneratorBase::qualname() const {
7711 return instanceVariableAt(kQualnameOffset);
7712}
7713
7714inline void RawGeneratorBase::setQualname(RawObject obj) const {
7715 instanceVariableAtPut(kQualnameOffset, obj);
7716}
7717
7718// RawGeneratorFrame
7719
7720inline Frame* RawGeneratorFrame::frame() const {
7721 return reinterpret_cast<Frame*>(address() + kFrameOffset +
7722 maxStackSize() * kPointerSize);
7723}
7724
7725inline RawObject RawGeneratorFrame::function() const {
7726 return instanceVariableAt(kFrameOffset +
7727 (numFrameWords() - 1) * kPointerSize);
7728}
7729
7730inline word RawGeneratorFrame::numAttributes(word extra_words) {
7731 return kNumOverheadWords + kFrameSize / kPointerSize + extra_words;
7732}
7733
7734inline word RawGeneratorFrame::numFrameWords() const {
7735 return headerCountOrOverflow() - kNumOverheadWords;
7736}
7737
7738inline word RawGeneratorFrame::maxStackSize() const {
7739 return RawSmallInt::cast(instanceVariableAt(kMaxStackSizeOffset)).value();
7740}
7741
7742inline void RawGeneratorFrame::setMaxStackSize(word offset) const {
7743 instanceVariableAtPut(kMaxStackSizeOffset, RawSmallInt::fromWord(offset));
7744}
7745
7746inline void RawGeneratorFrame::setStackSize(word size) const {
7747 word offset =
7748 maxStackSize() * kPointerSize + kFrameOffset + kStackSizeFrameOffset;
7749 instanceVariableAtPut(offset, RawSmallInt::fromWord(size));
7750}
7751
7752inline word RawGeneratorFrame::stackSize() const {
7753 word offset =
7754 maxStackSize() * kPointerSize + kFrameOffset + kStackSizeFrameOffset;
7755 return RawSmallInt::cast(instanceVariableAt(offset)).value();
7756}
7757
7758// RawCoroutineWrapper
7759
7760inline RawObject RawCoroutineWrapper::coroutine() const {
7761 return instanceVariableAt(kCoroutineOffset);
7762}
7763
7764inline void RawCoroutineWrapper::setCoroutine(RawObject coroutine) const {
7765 instanceVariableAtPut(kCoroutineOffset, coroutine);
7766}
7767
7768// RawUnderIOBase
7769
7770inline bool RawUnderIOBase::closed() const {
7771 RawObject closed = instanceVariableAt(kClosedOffset);
7772 return closed.isBool() && RawBool::cast(closed).value();
7773}
7774
7775inline void RawUnderIOBase::setClosed(bool closed) const {
7776 instanceVariableAtPut(kClosedOffset, RawBool::fromBool(closed));
7777}
7778
7779// RawUnderBufferedIOMixin
7780
7781inline RawObject RawUnderBufferedIOMixin::underlying() const {
7782 return instanceVariableAt(kUnderlyingOffset);
7783}
7784
7785inline void RawUnderBufferedIOMixin::setUnderlying(RawObject value) const {
7786 instanceVariableAtPut(kUnderlyingOffset, value);
7787}
7788
7789// RawBufferedRandom
7790
7791inline word RawBufferedRandom::bufferSize() const {
7792 return RawSmallInt::cast(instanceVariableAt(kBufferSizeOffset)).value();
7793}
7794
7795inline void RawBufferedRandom::setBufferSize(word buffer_size) const {
7796 instanceVariableAtPut(kBufferSizeOffset, RawSmallInt::fromWord(buffer_size));
7797}
7798
7799inline RawObject RawBufferedRandom::reader() const {
7800 return instanceVariableAt(kReaderOffset);
7801}
7802
7803inline void RawBufferedRandom::setReader(RawObject reader) const {
7804 instanceVariableAtPut(kReaderOffset, reader);
7805}
7806
7807inline RawObject RawBufferedRandom::writeBuf() const {
7808 return instanceVariableAt(kWriteBufOffset);
7809}
7810
7811inline void RawBufferedRandom::setWriteBuf(RawObject write_buf) const {
7812 instanceVariableAtPut(kWriteBufOffset, write_buf);
7813}
7814
7815inline RawObject RawBufferedRandom::writeLock() const {
7816 return instanceVariableAt(kWriteLockOffset);
7817}
7818
7819inline void RawBufferedRandom::setWriteLock(RawObject write_lock) const {
7820 instanceVariableAtPut(kWriteLockOffset, write_lock);
7821}
7822
7823// RawBufferedReader
7824
7825inline word RawBufferedReader::bufferSize() const {
7826 return RawSmallInt::cast(instanceVariableAt(kBufferSizeOffset)).value();
7827}
7828
7829inline void RawBufferedReader::setBufferSize(word buffer_size) const {
7830 instanceVariableAtPut(kBufferSizeOffset, RawSmallInt::fromWord(buffer_size));
7831}
7832
7833inline RawObject RawBufferedReader::readBuf() const {
7834 return instanceVariableAt(kReadBufOffset);
7835}
7836
7837inline void RawBufferedReader::setReadBuf(RawObject read_buf) const {
7838 instanceVariableAtPut(kReadBufOffset, read_buf);
7839}
7840
7841inline word RawBufferedReader::readPos() const {
7842 return RawSmallInt::cast(instanceVariableAt(kReadPosOffset)).value();
7843}
7844
7845inline void RawBufferedReader::setReadPos(word read_pos) const {
7846 instanceVariableAtPut(kReadPosOffset, RawSmallInt::fromWord(read_pos));
7847}
7848
7849inline word RawBufferedReader::bufferNumBytes() const {
7850 return RawSmallInt::cast(instanceVariableAt(kBufferNumBytesOffset)).value();
7851}
7852
7853inline void RawBufferedReader::setBufferNumBytes(word buffer_num_bytes) const {
7854 instanceVariableAtPut(kBufferNumBytesOffset,
7855 RawSmallInt::fromWord(buffer_num_bytes));
7856}
7857
7858// RawBufferedWriter
7859
7860inline word RawBufferedWriter::bufferSize() const {
7861 return RawSmallInt::cast(instanceVariableAt(kBufferSizeOffset)).value();
7862}
7863
7864inline void RawBufferedWriter::setBufferSize(RawObject buffer_size) const {
7865 instanceVariableAtPut(kBufferSizeOffset, buffer_size);
7866}
7867
7868inline RawObject RawBufferedWriter::writeBuf() const {
7869 return instanceVariableAt(kWriteBufOffset);
7870}
7871
7872inline void RawBufferedWriter::setWriteBuf(RawObject write_buf) const {
7873 instanceVariableAtPut(kWriteBufOffset, write_buf);
7874}
7875
7876inline RawObject RawBufferedWriter::writeLock() const {
7877 return instanceVariableAt(kWriteLockOffset);
7878}
7879
7880inline void RawBufferedWriter::setWriteLock(RawObject write_lock) const {
7881 instanceVariableAtPut(kWriteLockOffset, write_lock);
7882}
7883
7884// RawBytesIO
7885
7886inline RawObject RawBytesIO::buffer() const {
7887 return instanceVariableAt(kBufferOffset);
7888}
7889
7890inline void RawBytesIO::setBuffer(RawObject buffer) const {
7891 instanceVariableAtPut(kBufferOffset, buffer);
7892}
7893
7894inline word RawBytesIO::numItems() const {
7895 return RawSmallInt::cast(instanceVariableAt(kNumItemsOffset)).value();
7896}
7897
7898inline void RawBytesIO::setNumItems(word num_items) const {
7899 instanceVariableAtPut(kNumItemsOffset, RawSmallInt::fromWord(num_items));
7900}
7901
7902inline word RawBytesIO::pos() const {
7903 return RawSmallInt::cast(instanceVariableAt(kPosOffset)).value();
7904}
7905
7906inline void RawBytesIO::setPos(word pos) const {
7907 instanceVariableAtPut(kPosOffset, RawSmallInt::fromWord(pos));
7908}
7909
7910// RawFileIO
7911
7912inline RawObject RawFileIO::fd() const { return instanceVariableAt(kFdOffset); }
7913
7914inline void RawFileIO::setFd(RawObject fd) const {
7915 instanceVariableAtPut(kFdOffset, fd);
7916}
7917
7918inline RawObject RawFileIO::isCreated() const {
7919 return instanceVariableAt(kCreatedOffset);
7920}
7921
7922inline void RawFileIO::setCreated(RawObject value) const {
7923 instanceVariableAtPut(kCreatedOffset, value);
7924}
7925
7926inline RawObject RawFileIO::isReadable() const {
7927 return instanceVariableAt(kReadableOffset);
7928}
7929
7930inline void RawFileIO::setReadable(RawObject value) const {
7931 instanceVariableAtPut(kReadableOffset, value);
7932}
7933
7934inline RawObject RawFileIO::isWritable() const {
7935 return instanceVariableAt(kWritableOffset);
7936}
7937
7938inline void RawFileIO::setWritable(RawObject value) const {
7939 instanceVariableAtPut(kWritableOffset, value);
7940}
7941
7942inline RawObject RawFileIO::isAppending() const {
7943 return instanceVariableAt(kAppendingOffset);
7944}
7945
7946inline void RawFileIO::setAppending(RawObject value) const {
7947 instanceVariableAtPut(kAppendingOffset, value);
7948}
7949
7950inline RawObject RawFileIO::seekable() const {
7951 return instanceVariableAt(kSeekableOffset);
7952}
7953
7954inline void RawFileIO::setSeekable(RawObject value) const {
7955 instanceVariableAtPut(kSeekableOffset, value);
7956}
7957
7958inline RawObject RawFileIO::shouldCloseFd() const {
7959 return instanceVariableAt(kCloseFdOffset);
7960}
7961
7962inline void RawFileIO::setShouldCloseFd(RawObject value) const {
7963 instanceVariableAtPut(kCloseFdOffset, value);
7964}
7965
7966// RawStringIO
7967
7968inline RawObject RawStringIO::buffer() const {
7969 return instanceVariableAt(kBufferOffset);
7970}
7971
7972inline void RawStringIO::setBuffer(RawObject buffer) const {
7973 instanceVariableAtPut(kBufferOffset, buffer);
7974}
7975
7976inline word RawStringIO::pos() const {
7977 return RawSmallInt::cast(instanceVariableAt(kPosOffset)).value();
7978}
7979
7980inline void RawStringIO::setPos(word new_pos) const {
7981 instanceVariableAtPut(kPosOffset, RawSmallInt::fromWord(new_pos));
7982}
7983
7984inline RawObject RawStringIO::readnl() const {
7985 return instanceVariableAt(kReadnlOffset);
7986}
7987
7988inline void RawStringIO::setReadnl(RawObject readnl) const {
7989 instanceVariableAtPut(kReadnlOffset, readnl);
7990}
7991
7992inline bool RawStringIO::hasReadtranslate() const {
7993 return RawBool::cast(instanceVariableAt(kReadtranslateOffset)).value();
7994}
7995
7996inline void RawStringIO::setReadtranslate(bool readtranslate) const {
7997 instanceVariableAtPut(kReadtranslateOffset, RawBool::fromBool(readtranslate));
7998}
7999
8000inline bool RawStringIO::hasReaduniversal() const {
8001 return RawBool::cast(instanceVariableAt(kReaduniversalOffset)).value();
8002}
8003
8004inline void RawStringIO::setReaduniversal(bool readuniversal) const {
8005 instanceVariableAtPut(kReaduniversalOffset, RawBool::fromBool(readuniversal));
8006}
8007
8008inline RawObject RawStringIO::seennl() const {
8009 return instanceVariableAt(kSeennlOffset);
8010}
8011
8012inline void RawStringIO::setSeennl(RawObject seennl) const {
8013 instanceVariableAtPut(kSeennlOffset, seennl);
8014}
8015
8016inline RawObject RawStringIO::writenl() const {
8017 return instanceVariableAt(kWritenlOffset);
8018}
8019
8020inline void RawStringIO::setWritenl(RawObject writenl) const {
8021 instanceVariableAtPut(kWritenlOffset, writenl);
8022}
8023
8024inline bool RawStringIO::hasWritetranslate() const {
8025 return RawBool::cast(instanceVariableAt(kWritetranslateOffset)).value();
8026}
8027
8028inline void RawStringIO::setWritetranslate(bool writetranslate) const {
8029 instanceVariableAtPut(kWritetranslateOffset,
8030 RawBool::fromBool(writetranslate));
8031}
8032
8033// RawInstanceMethod
8034
8035inline RawObject RawInstanceMethod::function() const {
8036 return instanceVariableAt(kFunctionOffset);
8037}
8038
8039inline void RawInstanceMethod::setFunction(RawObject function) const {
8040 return instanceVariableAtPut(kFunctionOffset, function);
8041}
8042
8043// RawIncrementalNewlineDecoder
8044
8045inline RawObject RawIncrementalNewlineDecoder::errors() const {
8046 return instanceVariableAt(kErrorsOffset);
8047}
8048
8049inline void RawIncrementalNewlineDecoder::setErrors(RawObject errors) const {
8050 instanceVariableAtPut(kErrorsOffset, errors);
8051}
8052
8053inline RawObject RawIncrementalNewlineDecoder::translate() const {
8054 return instanceVariableAt(kTranslateOffset);
8055}
8056
8057inline void RawIncrementalNewlineDecoder::setTranslate(
8058 RawObject translate) const {
8059 instanceVariableAtPut(kTranslateOffset, translate);
8060}
8061
8062inline RawObject RawIncrementalNewlineDecoder::decoder() const {
8063 return instanceVariableAt(kDecoderOffset);
8064}
8065
8066inline void RawIncrementalNewlineDecoder::setDecoder(RawObject decoder) const {
8067 instanceVariableAtPut(kDecoderOffset, decoder);
8068}
8069
8070inline RawObject RawIncrementalNewlineDecoder::seennl() const {
8071 return instanceVariableAt(kSeennlOffset);
8072}
8073
8074inline void RawIncrementalNewlineDecoder::setSeennl(RawObject seennl) const {
8075 instanceVariableAtPut(kSeennlOffset, seennl);
8076}
8077
8078inline RawObject RawIncrementalNewlineDecoder::pendingcr() const {
8079 return instanceVariableAt(kPendingcrOffset);
8080}
8081
8082inline void RawIncrementalNewlineDecoder::setPendingcr(
8083 RawObject pendingcr) const {
8084 instanceVariableAtPut(kPendingcrOffset, pendingcr);
8085}
8086
8087// RawTextIOWrapper
8088
8089inline RawObject RawTextIOWrapper::buffer() const {
8090 return instanceVariableAt(kBufferOffset);
8091}
8092
8093inline void RawTextIOWrapper::setBuffer(RawObject buffer) const {
8094 instanceVariableAtPut(kBufferOffset, buffer);
8095}
8096
8097inline bool RawTextIOWrapper::detached() const { return buffer().isNoneType(); }
8098
8099inline bool RawTextIOWrapper::lineBuffering() const {
8100 return RawBool::cast(instanceVariableAt(kLineBufferingOffset)).value();
8101}
8102
8103inline void RawTextIOWrapper::setLineBuffering(RawObject line_buffering) const {
8104 instanceVariableAtPut(kLineBufferingOffset, line_buffering);
8105}
8106
8107inline RawObject RawTextIOWrapper::encoding() const {
8108 return instanceVariableAt(kEncodingOffset);
8109}
8110
8111inline void RawTextIOWrapper::setEncoding(RawObject encoding) const {
8112 instanceVariableAtPut(kEncodingOffset, encoding);
8113}
8114
8115inline RawObject RawTextIOWrapper::errors() const {
8116 return instanceVariableAt(kErrorsOffset);
8117}
8118
8119inline void RawTextIOWrapper::setErrors(RawObject errors) const {
8120 instanceVariableAtPut(kErrorsOffset, errors);
8121}
8122
8123inline bool RawTextIOWrapper::readuniversal() const {
8124 return RawBool::cast(instanceVariableAt(kReaduniversalOffset)).value();
8125}
8126
8127inline void RawTextIOWrapper::setReaduniversal(RawObject readuniversal) const {
8128 instanceVariableAtPut(kReaduniversalOffset, readuniversal);
8129}
8130
8131inline bool RawTextIOWrapper::readtranslate() const {
8132 return RawBool::cast(instanceVariableAt(kReadtranslateOffset)).value();
8133}
8134
8135inline void RawTextIOWrapper::setReadtranslate(RawObject readtranslate) const {
8136 instanceVariableAtPut(kReadtranslateOffset, readtranslate);
8137}
8138
8139inline RawObject RawTextIOWrapper::readnl() const {
8140 return instanceVariableAt(kReadnlOffset);
8141}
8142
8143inline void RawTextIOWrapper::setReadnl(RawObject readnl) const {
8144 instanceVariableAtPut(kReadnlOffset, readnl);
8145}
8146
8147inline bool RawTextIOWrapper::writetranslate() const {
8148 return RawBool::cast(instanceVariableAt(kWritetranslateOffset)).value();
8149}
8150
8151inline void RawTextIOWrapper::setWritetranslate(
8152 RawObject writetranslate) const {
8153 instanceVariableAtPut(kWritetranslateOffset, writetranslate);
8154}
8155
8156inline RawObject RawTextIOWrapper::writenl() const {
8157 return instanceVariableAt(kWritenlOffset);
8158}
8159
8160inline void RawTextIOWrapper::setWritenl(RawObject writenl) const {
8161 instanceVariableAtPut(kWritenlOffset, writenl);
8162}
8163
8164inline RawObject RawTextIOWrapper::encoder() const {
8165 return instanceVariableAt(kEncoderOffset);
8166}
8167
8168inline void RawTextIOWrapper::setEncoder(RawObject encoder) const {
8169 instanceVariableAtPut(kEncoderOffset, encoder);
8170}
8171
8172inline RawObject RawTextIOWrapper::decoder() const {
8173 return instanceVariableAt(kDecoderOffset);
8174}
8175
8176inline void RawTextIOWrapper::setDecoder(RawObject decoder) const {
8177 instanceVariableAtPut(kDecoderOffset, decoder);
8178}
8179
8180inline RawObject RawTextIOWrapper::decodedChars() const {
8181 return instanceVariableAt(kDecodedCharsOffset);
8182}
8183
8184inline void RawTextIOWrapper::setDecodedChars(RawObject decoded_chars) const {
8185 instanceVariableAtPut(kDecodedCharsOffset, decoded_chars);
8186}
8187
8188inline RawObject RawTextIOWrapper::decodedCharsUsed() const {
8189 return instanceVariableAt(kDecodedCharsUsedOffset);
8190}
8191
8192inline void RawTextIOWrapper::setDecodedCharsUsed(
8193 RawObject decoded_chars_used) const {
8194 instanceVariableAtPut(kDecodedCharsUsedOffset, decoded_chars_used);
8195}
8196
8197inline RawObject RawTextIOWrapper::snapshot() const {
8198 return instanceVariableAt(kSnapshotOffset);
8199}
8200
8201inline void RawTextIOWrapper::setSnapshot(RawObject snapshot) const {
8202 instanceVariableAtPut(kSnapshotOffset, snapshot);
8203}
8204
8205inline RawObject RawTextIOWrapper::seekable() const {
8206 return instanceVariableAt(kSeekableOffset);
8207}
8208
8209inline void RawTextIOWrapper::setSeekable(RawObject seekable) const {
8210 instanceVariableAtPut(kSeekableOffset, seekable);
8211}
8212
8213inline RawObject RawTextIOWrapper::hasRead1() const {
8214 return instanceVariableAt(kHasRead1Offset);
8215}
8216
8217inline void RawTextIOWrapper::setHasRead1(RawObject has_read1) const {
8218 instanceVariableAtPut(kHasRead1Offset, has_read1);
8219}
8220
8221inline RawObject RawTextIOWrapper::b2cratio() const {
8222 return instanceVariableAt(kB2cratioOffset);
8223}
8224
8225inline void RawTextIOWrapper::setB2cratio(RawObject b2cratio) const {
8226 instanceVariableAtPut(kB2cratioOffset, b2cratio);
8227}
8228
8229inline RawObject RawTextIOWrapper::telling() const {
8230 return instanceVariableAt(kTellingOffset);
8231}
8232
8233inline void RawTextIOWrapper::setTelling(RawObject telling) const {
8234 instanceVariableAtPut(kTellingOffset, telling);
8235}
8236
8237// RawAsyncGenerator
8238
8239inline RawObject RawAsyncGenerator::finalizer() const {
8240 return instanceVariableAt(kFinalizerOffset);
8241}
8242
8243inline void RawAsyncGenerator::setFinalizer(RawObject finalizer) const {
8244 instanceVariableAtPut(kFinalizerOffset, finalizer);
8245}
8246
8247inline bool RawAsyncGenerator::hooksInited() const {
8248 return RawBool::cast(instanceVariableAt(kHooksInitedOffset)).value();
8249}
8250
8251inline void RawAsyncGenerator::setHooksInited(bool hooks_inited) const {
8252 instanceVariableAtPut(kHooksInitedOffset, RawBool::fromBool(hooks_inited));
8253}
8254
8255// RawAsyncGeneratorOpIterBase
8256
8257inline RawObject RawAsyncGeneratorOpIterBase::generator() const {
8258 return instanceVariableAt(kGeneratorOffset);
8259}
8260
8261inline void RawAsyncGeneratorOpIterBase::setGenerator(
8262 RawObject generator) const {
8263 instanceVariableAtPut(kGeneratorOffset, generator);
8264}
8265
8266inline RawAsyncGeneratorOpIterBase::State RawAsyncGeneratorOpIterBase::state()
8267 const {
8268 return static_cast<State>(
8269 RawSmallInt::cast(instanceVariableAt(kStateOffset)).value());
8270}
8271
8272inline void RawAsyncGeneratorOpIterBase::setState(State state) const {
8273 instanceVariableAtPut(kStateOffset,
8274 RawSmallInt::fromWord(static_cast<word>(state)));
8275}
8276
8277// RawAsyncGeneratorAsend
8278
8279inline RawObject RawAsyncGeneratorAsend::value() const {
8280 return instanceVariableAt(kValueOffset);
8281}
8282
8283inline void RawAsyncGeneratorAsend::setValue(RawObject value) const {
8284 instanceVariableAtPut(kValueOffset, value);
8285}
8286
8287// RawAsyncGeneratorAthrow
8288
8289inline RawObject RawAsyncGeneratorAthrow::exceptionTraceback() const {
8290 return instanceVariableAt(kExceptionTracebackOffset);
8291}
8292
8293inline void RawAsyncGeneratorAthrow::setExceptionTraceback(
8294 RawObject exception_traceback) const {
8295 instanceVariableAtPut(kExceptionTracebackOffset, exception_traceback);
8296}
8297
8298inline RawObject RawAsyncGeneratorAthrow::exceptionType() const {
8299 return instanceVariableAt(kExceptionTypeOffset);
8300}
8301
8302inline void RawAsyncGeneratorAthrow::setExceptionType(
8303 RawObject exception_type) const {
8304 instanceVariableAtPut(kExceptionTypeOffset, exception_type);
8305}
8306
8307inline RawObject RawAsyncGeneratorAthrow::exceptionValue() const {
8308 return instanceVariableAt(kExceptionValueOffset);
8309}
8310
8311inline void RawAsyncGeneratorAthrow::setExceptionValue(
8312 RawObject exception_value) const {
8313 instanceVariableAtPut(kExceptionValueOffset, exception_value);
8314}
8315
8316// RawAsyncGeneratorWrappedValue
8317
8318inline RawObject RawAsyncGeneratorWrappedValue::value() const {
8319 return instanceVariableAt(kValueOffset);
8320}
8321
8322inline void RawAsyncGeneratorWrappedValue::setValue(RawObject value) const {
8323 instanceVariableAtPut(kValueOffset, value);
8324}
8325
8326// RawTraceback
8327
8328inline RawObject RawTraceback::function() const {
8329 return instanceVariableAt(kFunctionOffset);
8330}
8331
8332inline void RawTraceback::setFunction(RawObject function) const {
8333 instanceVariableAtPut(kFunctionOffset, function);
8334}
8335
8336inline RawObject RawTraceback::lasti() const {
8337 return instanceVariableAt(kLastiOffset);
8338}
8339
8340inline void RawTraceback::setLasti(RawObject lasti) const {
8341 instanceVariableAtPut(kLastiOffset, lasti);
8342}
8343
8344inline RawObject RawTraceback::lineno() const {
8345 return instanceVariableAt(kLinenoOffset);
8346}
8347
8348inline void RawTraceback::setLineno(RawObject lineno) const {
8349 instanceVariableAtPut(kLinenoOffset, lineno);
8350}
8351
8352inline RawObject RawTraceback::next() const {
8353 return instanceVariableAt(kNextOffset);
8354}
8355
8356inline void RawTraceback::setNext(RawObject next) const {
8357 instanceVariableAtPut(kNextOffset, next);
8358}
8359
8360} // namespace py