this repo has no description
at trunk 8360 lines 260 kB view raw
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