this repo has no description
at trunk 89 lines 2.7 kB view raw
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 2#include "capi-typeslots.h" 3 4#include "cpython-data.h" 5 6#include "capi.h" 7#include "handles.h" 8#include "runtime.h" 9#include "thread.h" 10 11namespace py { 12 13const int kFirstSlot = Py_bf_getbuffer; 14const int kLastSlot = Py_tp_finalize; 15static_assert(kSlotFlags < kFirstSlot && kSlotBasicSize < kFirstSlot && 16 kSlotItemSize < kFirstSlot, 17 "slot indexes must not overlap with internal slots"); 18 19bool isValidSlotId(int slot_id) { 20 return kFirstSlot <= slot_id && slot_id <= kLastSlot; 21} 22 23bool isObjectSlotId(int slot_id) { 24 switch (slot_id) { 25 case Py_tp_base: 26 case Py_tp_bases: 27 return true; 28 } 29 return false; 30} 31 32static bool isInternalSlotId(int slot_id) { 33 switch (slot_id) { 34 case kSlotFlags: 35 case kSlotBasicSize: 36 case kSlotItemSize: 37 return true; 38 } 39 return false; 40} 41 42void typeSlotsAllocate(Thread* thread, const Type& type) { 43 DCHECK(!typeHasSlots(type), "type must not have slots yet"); 44 HandleScope scope(thread); 45 word length = kNumInternalSlots + kLastSlot + 1; 46 MutableTuple slots(&scope, thread->runtime()->newMutableTuple(length)); 47 type.setSlots(*slots); 48} 49 50bool typeHasSlots(const Type& type) { return !type.slots().isNoneType(); } 51 52void* typeSlotAt(const Type& type, int slot_id) { 53 DCHECK(isValidSlotId(slot_id) && !isObjectSlotId(slot_id), "invalid slot id"); 54 return Int::cast(MutableTuple::cast(type.slots()).at(kSlotOffset + slot_id)) 55 .asCPtr(); 56} 57 58void typeSlotAtPut(Thread* thread, const Type& type, int slot_id, void* value) { 59 DCHECK(isValidSlotId(slot_id) && !isObjectSlotId(slot_id), "invalid slot id"); 60 MutableTuple::cast(type.slots()) 61 .atPut(kSlotOffset + slot_id, thread->runtime()->newIntFromCPtr(value)); 62} 63 64RawObject typeSlotObjectAt(const Type& type, int slot_id) { 65 DCHECK(isObjectSlotId(slot_id), "invalid slot id"); 66 return MutableTuple::cast(type.slots()).at(kSlotOffset + slot_id); 67} 68 69void typeSlotObjectAtPut(const Type& type, int slot_id, RawObject value) { 70 DCHECK(isObjectSlotId(slot_id), "invalid slot id"); 71 MutableTuple::cast(type.slots()).atPut(kSlotOffset + slot_id, value); 72} 73 74uword typeSlotUWordAt(const Type& type, int slot_id) { 75 DCHECK(isInternalSlotId(slot_id), "expected internal slot"); 76 return Int::cast(MutableTuple::cast(type.slots()).at(kSlotOffset + slot_id)) 77 .asInt<uword>() 78 .value; 79} 80 81void typeSlotUWordAtPut(Thread* thread, const Type& type, int slot_id, 82 uword value) { 83 DCHECK(isInternalSlotId(slot_id), "expected internal slot"); 84 MutableTuple::cast(type.slots()) 85 .atPut(kSlotOffset + slot_id, 86 thread->runtime()->newIntFromUnsigned(value)); 87} 88 89} // namespace py