this repo has no description
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