diff --git a/python3-sys/src/frameobject.rs b/python3-sys/src/frameobject.rs new file mode 100644 index 00000000..c30c80ee --- /dev/null +++ b/python3-sys/src/frameobject.rs @@ -0,0 +1,78 @@ +use libc::{c_char, c_int}; +use object::*; +use code::{PyCodeObject, CO_MAXBLOCKS}; +use pystate::PyThreadState; + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct PyTryBlock { + pub b_type : c_int, + pub b_handler : c_int, + pub b_level : c_int, +} + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct PyFrameObject { + pub ob_base: PyVarObject, + pub f_back: *mut PyFrameObject, /* previous frame, or NULL */ + pub f_code: *mut PyCodeObject, /* code segment */ + pub f_builtins: *mut PyObject, /* builtin symbol table (PyDictObject) */ + pub f_globals: *mut PyObject, /* global symbol table (PyDictObject) */ + pub f_locals: *mut PyObject, /* local symbol table (any mapping) */ + pub f_valuestack: *mut *mut PyObject, /* points after the last local */ + /* Next free slot in f_valuestack. Frame creation sets to f_valuestack. + Frame evaluation usually NULLs it, but a frame that yields sets it + to the current stack top. */ + pub f_stacktop: *mut *mut PyObject, + pub f_trace: *mut PyObject, /* Trace function */ + + pub f_exc_type: *mut PyObject, + pub f_exc_value: *mut PyObject, + pub f_exc_traceback: *mut PyObject, + + #[cfg(not(Py_3_4))] + pub f_tstate: *mut PyThreadState, + + #[cfg(Py_3_4)] + pub f_gen: *mut PyObject, + + pub f_lasti: c_int, /* Last instruction if called */ + /* Call PyFrame_GetLineNumber() instead of reading this field + directly. As of 2.3 f_lineno is only valid when tracing is + active (i.e. when f_trace is set). At other times we use + PyCode_Addr2Line to calculate the line from the current + bytecode index. */ + pub f_lineno: c_int, /* Current line number */ + pub f_iblock: c_int, /* index in f_blockstack */ + #[cfg(Py_3_4)] + pub f_executing: c_char, /* whether the frame is still executing */ + pub f_blockstack: [PyTryBlock; CO_MAXBLOCKS], /* for try and loop blocks */ + pub f_localsplus: [*mut PyObject; 1] /* locals+stack, dynamically sized */ +} + +extern "C" { + pub static mut PyFrame_Type: PyTypeObject; +} + +#[inline] +pub unsafe fn PyFrame_Check(op: *mut PyObject) -> c_int { + (Py_TYPE(op) == &mut PyFrame_Type) as c_int +} + +extern "C" { + pub fn PyFrame_New(tstate: *mut PyThreadState, code: *mut PyCodeObject, + globals: *mut PyObject, locals: *mut PyObject) -> *mut PyFrameObject; + + pub fn PyFrame_BlockSetup(f: *mut PyFrameObject, _type: c_int, handler: c_int, level: c_int) -> (); + pub fn PyFrame_BlockPop(f: *mut PyFrameObject) -> *mut PyTryBlock; + + pub fn PyFrame_LocalsToFast(f: *mut PyFrameObject, clear: c_int) -> (); + #[cfg(Py_3_4)] + pub fn PyFrame_FastToLocalsWithError(f: *mut PyFrameObject) -> c_int; + pub fn PyFrame_FastToLocals(f: *mut PyFrameObject) -> (); + + pub fn PyFrame_ClearFreeList() -> c_int; + pub fn PyFrame_GetLineNumber(f: *mut PyFrameObject) -> c_int; +} + diff --git a/python3-sys/src/lib.rs b/python3-sys/src/lib.rs index 9a8df999..5a7c8b8d 100644 --- a/python3-sys/src/lib.rs +++ b/python3-sys/src/lib.rs @@ -16,6 +16,9 @@ pub use pymem::*; pub use object::*; pub use objimpl::*; pub use typeslots::*; +#[cfg(Py_3_4)] pub use pyhash::*; + +pub use pydebug::*; pub use bytearrayobject::*; pub use bytesobject::*; @@ -64,6 +67,7 @@ pub use compile::*; pub use eval::*; pub use pystrtod::*; +pub use frameobject::PyFrameObject; mod pyport; // mod pymacro; contains nothing of interest for Rust @@ -78,11 +82,11 @@ mod pyport; mod pymem; mod object; -mod objimpl; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5 -mod typeslots; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5 -// mod pyhash; new in 3.4; contains nothing of interest +mod objimpl; +mod typeslots; +#[cfg(Py_3_4)] mod pyhash; -// mod pydebug; TODO excluded by PEP-384 +mod pydebug; mod bytearrayobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5 mod bytesobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5 @@ -151,5 +155,10 @@ mod pystrtod; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and // Additional headers that are not exported by Python.h pub mod structmember; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5 -pub enum PyFrameObject {} +#[cfg(not(Py_LIMITED_API))] +pub mod frameobject; +#[cfg(Py_LIMITED_API)] +pub mod frameobject { + pub enum PyFrameObject {} +} diff --git a/python3-sys/src/modsupport.rs b/python3-sys/src/modsupport.rs index 87f823c2..ad05f236 100644 --- a/python3-sys/src/modsupport.rs +++ b/python3-sys/src/modsupport.rs @@ -34,6 +34,16 @@ extern "C" { arg2: *const c_char, arg3: *const c_char) -> c_int; + #[cfg(Py_3_5)] + pub fn PyModule_SetDocString(arg1: *mut PyObject, + arg2: *const c_char) + -> c_int; + #[cfg(Py_3_5)] + pub fn PyModule_AddFunctions(arg1: *mut PyObject, arg2: *mut PyMethodDef) + -> c_int; + #[cfg(Py_3_5)] + pub fn PyModule_ExecDef(module: *mut PyObject, def: *mut PyModuleDef) + -> c_int; } pub const Py_CLEANUP_SUPPORTED: i32 = 0x20000; @@ -49,6 +59,20 @@ extern "C" { #[cfg(py_sys_config="Py_TRACE_REFS")] fn PyModule_Create2TraceRefs(module: *mut PyModuleDef, apiver: c_int) -> *mut PyObject; + + #[cfg(not(py_sys_config="Py_TRACE_REFS"))] + #[cfg(Py_3_5)] + pub fn PyModule_FromDefAndSpec2(def: *mut PyModuleDef, + spec: *mut PyObject, + module_api_version: c_int) + -> *mut PyObject; + + #[cfg(py_sys_config="Py_TRACE_REFS")] + #[cfg(Py_3_5)] + fn PyModule_FromDefAndSpec2TraceRefs(def: *mut PyModuleDef, + spec: *mut PyObject, + module_api_version: c_int) + -> *mut PyObject; } #[cfg(py_sys_config="Py_TRACE_REFS")] @@ -58,8 +82,24 @@ pub unsafe fn PyModule_Create2(module: *mut PyModuleDef, PyModule_Create2TraceRefs(arg1, apiver) } +#[cfg(py_sys_config="Py_TRACE_REFS")] +#[cfg(Py_3_5)] #[inline] -pub unsafe fn PyModule_Create(module: *mut PyModuleDef) -> *mut PyObject { - PyModule_Create2(module, PYTHON_ABI_VERSION) +pub unsafe fn PyModule_FromDefAndSpec2(def: *mut PyModuleDef, + spec: *mut PyObject, + module_api_version: c_int) + -> *mut PyObject { + PyModule_FromDefAndSpec2TraceRefs(def, spec, module_api_version) +} + +#[inline] +pub unsafe fn PyModule_Create(module: *mut PyModuleDef) -> *mut PyObject { + PyModule_Create2(module, if cfg!(Py_LIMITED_API) { PYTHON_ABI_VERSION } else { PYTHON_API_VERSION }) +} + +#[inline] +#[cfg(Py_3_5)] +pub unsafe fn PyModule_FromDefAndSpec(def: *mut PyModuleDef, spec: *mut PyObject) -> *mut PyObject { + PyModule_FromDefAndSpec2(def, spec, if cfg!(Py_LIMITED_API) { PYTHON_ABI_VERSION } else { PYTHON_API_VERSION }) } diff --git a/python3-sys/src/objimpl.rs b/python3-sys/src/objimpl.rs index 4b7f1535..3a3385e4 100644 --- a/python3-sys/src/objimpl.rs +++ b/python3-sys/src/objimpl.rs @@ -4,6 +4,8 @@ use object::*; extern "C" { pub fn PyObject_Malloc(size: size_t) -> *mut c_void; + #[cfg(Py_3_5)] + pub fn PyObject_Calloc(nelem: size_t, elsize: size_t) -> *mut c_void; pub fn PyObject_Realloc(ptr: *mut c_void, new_size: size_t) -> *mut c_void; pub fn PyObject_Free(ptr: *mut c_void) -> (); @@ -20,6 +22,33 @@ extern "C" { pub fn PyGC_Collect() -> Py_ssize_t; } +#[repr(C)] +#[derive(Copy)] +#[cfg(all(not(Py_LIMITED_API), Py_3_4))] +pub struct PyObjectArenaAllocator { + pub ctx: *mut c_void, + pub alloc: Option *mut c_void>, + pub free: Option ()>, +} +#[cfg(all(not(Py_LIMITED_API), Py_3_4))] +impl Clone for PyObjectArenaAllocator { + #[inline] fn clone(&self) -> Self { *self } +} +#[cfg(all(not(Py_LIMITED_API), Py_3_4))] +impl Default for PyObjectArenaAllocator { + #[inline] fn default() -> Self { unsafe { ::std::mem::zeroed() } } +} +#[cfg(all(not(Py_LIMITED_API), Py_3_4))] +extern "C" { + pub fn PyObject_GetArenaAllocator(allocator: *mut PyObjectArenaAllocator) + -> (); + pub fn PyObject_SetArenaAllocator(allocator: *mut PyObjectArenaAllocator) + -> (); +} /// Test if a type has a GC head #[inline(always)] @@ -27,9 +56,9 @@ pub unsafe fn PyType_IS_GC(t : *mut PyTypeObject) -> c_int { PyType_HasFeature((t), Py_TPFLAGS_HAVE_GC) } -/* /// Test if an object has a GC head #[inline(always)] +#[cfg(not(Py_LIMITED_API))] pub unsafe fn PyObject_IS_GC(o : *mut PyObject) -> c_int { (PyType_IS_GC(Py_TYPE(o)) != 0 && match (*Py_TYPE(o)).tp_is_gc { @@ -37,13 +66,14 @@ pub unsafe fn PyObject_IS_GC(o : *mut PyObject) -> c_int { None => true }) as c_int } -*/ extern "C" { pub fn _PyObject_GC_Resize(arg1: *mut PyVarObject, arg2: Py_ssize_t) -> *mut PyVarObject; - pub fn _PyObject_GC_Malloc(arg1: size_t) -> *mut PyObject; + pub fn _PyObject_GC_Malloc(size: size_t) -> *mut PyObject; + #[cfg(Py_3_5)] + pub fn _PyObject_GC_Calloc(size: size_t) -> *mut PyObject; pub fn _PyObject_GC_New(arg1: *mut PyTypeObject) -> *mut PyObject; pub fn _PyObject_GC_NewVar(arg1: *mut PyTypeObject, arg2: Py_ssize_t) -> *mut PyVarObject; @@ -52,17 +82,17 @@ extern "C" { pub fn PyObject_GC_Del(arg1: *mut c_void) -> (); } -/* /// Test if a type supports weak references #[inline(always)] +#[cfg(not(Py_LIMITED_API))] pub unsafe fn PyType_SUPPORTS_WEAKREFS(t : *mut PyTypeObject) -> c_int { ((*t).tp_weaklistoffset > 0) as c_int } #[inline(always)] +#[cfg(not(Py_LIMITED_API))] pub unsafe fn PyObject_GET_WEAKREFS_LISTPTR(o : *mut PyObject) -> *mut *mut PyObject { let weaklistoffset = (*Py_TYPE(o)).tp_weaklistoffset as isize; - (o as *mut c_char).offset(weaklistoffset) as *mut *mut PyObject + (o as *mut u8).offset(weaklistoffset) as *mut *mut PyObject } -*/ diff --git a/python3-sys/src/pydebug.rs b/python3-sys/src/pydebug.rs new file mode 100644 index 00000000..1986bc09 --- /dev/null +++ b/python3-sys/src/pydebug.rs @@ -0,0 +1,23 @@ +use libc::c_int; + +#[cfg(not(Py_LIMITED_API))] +extern "C" { + pub static mut Py_DebugFlag: c_int; + pub static mut Py_VerboseFlag: c_int; + pub static mut Py_QuietFlag: c_int; + pub static mut Py_InteractiveFlag: c_int; + pub static mut Py_InspectFlag: c_int; + pub static mut Py_OptimizeFlag: c_int; + pub static mut Py_NoSiteFlag: c_int; + pub static mut Py_BytesWarningFlag: c_int; + pub static mut Py_UseClassExceptionsFlag: c_int; + pub static mut Py_FrozenFlag: c_int; + pub static mut Py_IgnoreEnvironmentFlag: c_int; + pub static mut Py_DontWriteBytecodeFlag: c_int; + pub static mut Py_NoUserSiteDirectory: c_int; + pub static mut Py_UnbufferedStdioFlag: c_int; + pub static mut Py_HashRandomizationFlag: c_int; + #[cfg(Py_3_4)] + pub static mut Py_IsolatedFlag: c_int; +} + diff --git a/python3-sys/src/pyhash.rs b/python3-sys/src/pyhash.rs new file mode 100644 index 00000000..9fee0956 --- /dev/null +++ b/python3-sys/src/pyhash.rs @@ -0,0 +1,24 @@ +use libc::{c_void, c_char, c_int}; +use pyport::{Py_ssize_t, Py_hash_t}; + +#[repr(C)] +#[derive(Copy)] +pub struct PyHash_FuncDef { + pub hash: Option Py_hash_t>, + pub name: *const c_char, + pub hash_bits: c_int, + pub seed_bits: c_int, +} +impl Clone for PyHash_FuncDef { + #[inline] fn clone(&self) -> Self { *self } +} +impl Default for PyHash_FuncDef { + #[inline] fn default() -> Self { unsafe { ::std::mem::zeroed() } } +} + +extern "C" { + pub fn PyHash_GetFuncDef() -> *mut PyHash_FuncDef; +} + diff --git a/python3-sys/src/typeslots.rs b/python3-sys/src/typeslots.rs index cae554c4..93c8d775 100644 --- a/python3-sys/src/typeslots.rs +++ b/python3-sys/src/typeslots.rs @@ -72,4 +72,16 @@ pub const Py_tp_traverse : c_int = 71; pub const Py_tp_members : c_int = 72; pub const Py_tp_getset : c_int = 73; pub const Py_tp_free : c_int = 74; +#[cfg(Py_3_5)] +pub const Py_nb_matrix_multiply : c_int = 75; +#[cfg(Py_3_5)] +pub const Py_nb_inplace_matrix_multiply : c_int = 76; +#[cfg(Py_3_5)] +pub const Py_am_await : c_int = 77; +#[cfg(Py_3_5)] +pub const Py_am_aiter : c_int = 78; +#[cfg(Py_3_5)] +pub const Py_am_anext : c_int = 79; +#[cfg(Py_3_5)] +pub const Py_tp_finalize : c_int = 80;