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