this repo has no description
1/* Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) */
2#pragma once
3
4#include "handles-decl.h"
5#include "objects.h"
6
7// This file contains all of the functions and data needed from the runtime to
8// poke at C-extension internals. Ideally, the extension layer would sit on top
9// of the runtime and be neatly insulated from it, but at least right now this
10// is not possible. To avoid bringing extension types and internals directly
11// into the runtime, we provide a bridge in the form of a small set of APIs.
12//
13// Please keep this list as small as possible. Think if you can get away with
14// instead calling a Python-level function for your use-case, or if you really
15// need a C-API bridge.
16
17// from Include/longobject.h
18extern "C" const unsigned char _PyLong_DigitValue[]; // NOLINT
19
20struct PyModuleDef;
21
22// TODO(T67311848): Remove this. This is a temporary workaround until we fork
23// the readline module into the runtime.
24extern "C" char* PyOS_Readline(FILE*, FILE*, const char*);
25
26namespace py {
27
28class HandleVisitor;
29class PointerVisitor;
30class Runtime;
31class Scavenger;
32class Thread;
33
34static const word kCAPIStateSize = 256;
35
36extern struct _inittab* PyImport_Inittab;
37
38void disposeExtensionObjects(Runtime* runtime);
39
40void disposeApiHandles(Runtime* runtime);
41
42void finalizeCAPIModules();
43void finalizeCAPIState(Runtime* runtime);
44
45void finalizeExtensionObject(Thread* thread, RawObject object);
46
47void freeExtensionModules(Thread* thread);
48
49// Returns `true` if there is a built-in extension module with name `name`.
50bool isBuiltinExtensionModule(const Str& name);
51
52void initializeCAPIModules();
53void initializeCAPIState(Runtime* runtime);
54
55// Runs the executable functions found in the PyModuleDef
56word moduleExecDef(Thread* thread, const Module& module, PyModuleDef* def);
57
58// Initialize built-in extension module `name` if it exists, otherwise
59// return `nullptr`.
60RawObject moduleInitBuiltinExtension(Thread* thread, const Str& name);
61
62// Load extension module `name` from dynamic library in file `path`.
63RawObject moduleLoadDynamicExtension(Thread* thread, const Str& name,
64 const Str& path);
65
66word numApiHandles(Runtime* runtime);
67
68word numExtensionObjects(Runtime* runtime);
69
70RawObject objectGetMember(Thread* thread, RawObject ptr, RawObject name);
71
72// Check if a borrowed reference to the object has a non-null cache.
73// WARNING: This function should only be used in the GC.
74bool objectHasHandleCache(Runtime* runtime, RawObject obj);
75
76// Pin a handle for the object until the runtime exits.
77// WARNING: This function should only be used in builtins.id()
78void* objectNewReference(Runtime* runtime, RawObject obj);
79
80void objectSetMember(Runtime* runtime, RawObject old_ptr, RawObject new_val);
81
82// Return the type's tp_basicsize. Use only with extension types.
83uword typeGetBasicSize(const Type& type);
84
85// Return the either computed CPython flags based on Pyro type state or an
86// extension type's tp_flags. Use with either managed types or extension types.
87uword typeGetFlags(const Type& type);
88
89// Type has a list of type slots attached to it. The type slots are used by the
90// C-API emulation layer for C extension types.
91bool typeHasSlots(const Type& type);
92
93// Inherit slots defined by a C Extension
94RawObject typeInheritSlots(Thread* thread, const Type& type, const Type& base);
95
96// NOTE: THIS FUNCTION IS A HACK. It is slow. Do not use this function. It is
97// here to serve Cython modules that occasionally create Python memoryviews
98// from buffer protocol objects. It is much better practice to instead use
99// builtin types where possible.
100//
101// Call bf_getbuffer, copy data into a Bytes, and call bf_releasebuffer.
102// Assumes the object is not builtin.
103// Raises TypeError if slots are not defined.
104RawObject newBytesFromBuffer(Thread* thread, const Object& obj);
105
106void visitExtensionObjects(Runtime* runtime, Scavenger* scavenger,
107 PointerVisitor* visitor);
108
109// Calls `visitor->visitHandle` for all `ApiHandle`s.
110void visitApiHandles(Runtime* runtime, HandleVisitor* visitor);
111
112// Visits all `ApiHandle`s with `refcount > 1`. `ApiHandle`s with refcount zero
113// are ignored here and will be handled by
114// `visitNotIncrementedBorrowedApiHandles`.
115void visitIncrementedApiHandles(Runtime* runtime, PointerVisitor* visitor);
116
117// Should be called when all GC roots are processed and no gray objects remain.
118// This disposes `ApiHandle`s with reference count 0 that are not referenced
119// from live objects in the managed heap ("white" objects after GC tri-color
120// marking).
121void visitNotIncrementedBorrowedApiHandles(Runtime* runtime,
122 Scavenger* scavenger,
123 PointerVisitor* visitor);
124
125} // namespace py