diff --git a/python27-sys/src/ceval.rs b/python27-sys/src/ceval.rs index d1e16d72..02f5e549 100644 --- a/python27-sys/src/ceval.rs +++ b/python27-sys/src/ceval.rs @@ -1,7 +1,8 @@ use libc::{c_void, c_char, c_int}; use pyport::Py_ssize_t; use object::PyObject; -use pystate::{PyFrameObject, PyThreadState, Py_tracefunc}; +use frameobject::PyFrameObject; +use pystate::{PyThreadState, Py_tracefunc}; use pythonrun::PyCompilerFlags; extern "C" { diff --git a/python27-sys/src/code.rs b/python27-sys/src/code.rs index 012b8ee4..63e2bd26 100644 --- a/python27-sys/src/code.rs +++ b/python27-sys/src/code.rs @@ -1,8 +1,33 @@ -use libc::{c_char, c_int}; +use libc::{c_char, c_int, c_void}; +use pyport::Py_ssize_t; use object::*; -#[allow(missing_copy_implementations)] -pub enum PyCodeObject { /* hidden representation */ } +#[repr(C)] +#[derive(Copy, Clone)] +pub struct PyCodeObject { + #[cfg(py_sys_config="Py_TRACE_REFS")] + pub _ob_next: *mut PyObject, + #[cfg(py_sys_config="Py_TRACE_REFS")] + pub _ob_prev: *mut PyObject, + pub ob_refcnt: Py_ssize_t, + pub ob_type: *mut PyTypeObject, + pub co_argcount: c_int, + pub co_nlocals: c_int, + pub co_stacksize: c_int, + pub co_flags: c_int, + pub co_code: *mut PyObject, + pub co_consts: *mut PyObject, + pub co_names: *mut PyObject, + pub co_varnames: *mut PyObject, + pub co_freevars: *mut PyObject, + pub co_cellvars: *mut PyObject, + pub co_filename: *mut PyObject, + pub co_name: *mut PyObject, + pub co_firstlineno: c_int, + pub co_lnotab: *mut PyObject, + pub co_zombieframe: *mut c_void, + pub co_weakreflist: *mut PyObject, +} /* Masks for co_flags */ pub const CO_OPTIMIZED : c_int = 0x0001; @@ -24,6 +49,8 @@ pub const CO_FUTURE_WITH_STATEMENT : c_int = 0x8000; pub const CO_FUTURE_PRINT_FUNCTION : c_int = 0x10000; pub const CO_FUTURE_UNICODE_LITERALS : c_int = 0x20000; +pub const CO_MAXBLOCKS : usize = 20; + extern "C" { pub static mut PyCode_Type: PyTypeObject; @@ -50,7 +77,11 @@ extern "C" { #[inline(always)] pub unsafe fn PyCode_Check(op : *mut PyObject) -> c_int { - let u : *mut PyTypeObject = &mut PyCode_Type; - (Py_TYPE(op) == u) as c_int + (Py_TYPE(op) == &mut PyCode_Type) as c_int +} + +#[inline] +pub unsafe fn PyCode_GetNumFree(op : *mut PyCodeObject) -> Py_ssize_t { + ::tupleobject::PyTuple_GET_SIZE((*op).co_freevars) } diff --git a/python27-sys/src/frameobject.rs b/python27-sys/src/frameobject.rs new file mode 100644 index 00000000..6d8e2d3d --- /dev/null +++ b/python27-sys/src/frameobject.rs @@ -0,0 +1,82 @@ +use libc::c_int; +use object::*; +use pyport::Py_ssize_t; +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 { + #[cfg(py_sys_config="Py_TRACE_REFS")] + pub _ob_next: *mut PyObject, + #[cfg(py_sys_config="Py_TRACE_REFS")] + pub _ob_prev: *mut PyObject, + pub ob_refcnt: Py_ssize_t, + pub ob_type: *mut PyTypeObject, + pub ob_size: Py_ssize_t, + 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, + + pub f_tstate: *mut PyThreadState, + + 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 */ + 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 { + ((*op).ob_type == &mut PyFrame_Type) as c_int +} + +//#[inline] +//pub unsafe fn PyFrame_IsRestricted(f: *mut PyFrameObject) -> c_int { +// ((*f).f_builtins != (*(*(*f).f_tstate).interp).builtins) 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) -> (); + 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/python27-sys/src/genobject.rs b/python27-sys/src/genobject.rs index d503675d..c3110ffd 100644 --- a/python27-sys/src/genobject.rs +++ b/python27-sys/src/genobject.rs @@ -1,6 +1,7 @@ use libc::c_int; use pyport::Py_ssize_t; use object::*; +use frameobject::PyFrameObject; #[repr(C)] #[derive(Copy, Clone)] @@ -11,7 +12,7 @@ pub struct PyGenObject { pub _ob_prev: *mut PyObject, pub ob_refcnt: Py_ssize_t, pub ob_type: *mut PyTypeObject, - pub gi_frame: *mut ::PyFrameObject, + pub gi_frame: *mut PyFrameObject, pub gi_running: c_int, pub gi_code: *mut PyObject, pub gi_weakreflist: *mut PyObject @@ -32,7 +33,7 @@ pub unsafe fn PyGen_CheckExact(op: *mut PyObject) -> c_int { } extern "C" { - pub fn PyGen_New(frame: *mut ::PyFrameObject) -> *mut PyObject; + pub fn PyGen_New(frame: *mut PyFrameObject) -> *mut PyObject; pub fn PyGen_NeedsFinalizing(op: *mut PyGenObject) -> c_int; } diff --git a/python27-sys/src/lib.rs b/python27-sys/src/lib.rs index d6c4a67a..895ff1b6 100644 --- a/python27-sys/src/lib.rs +++ b/python27-sys/src/lib.rs @@ -53,6 +53,7 @@ pub use code::*; pub use compile::*; pub use eval::*; pub use structmember::PyMemberDef; +pub use frameobject::PyFrameObject; mod pyport; mod pymem; @@ -121,6 +122,7 @@ mod eval; // Additional headers that are not exported by Python.h pub mod structmember; +pub mod frameobject; pub const Py_single_input: libc::c_int = 256; pub const Py_file_input: libc::c_int = 257; diff --git a/python27-sys/src/pystate.rs b/python27-sys/src/pystate.rs index ea911e45..b7068bc1 100644 --- a/python27-sys/src/pystate.rs +++ b/python27-sys/src/pystate.rs @@ -1,12 +1,9 @@ use libc::{c_int, c_long}; use object::PyObject; +use frameobject::PyFrameObject; -#[allow(missing_copy_implementations)] pub enum PyInterpreterState { } -#[allow(missing_copy_implementations)] -pub enum PyFrameObject { } - pub type Py_tracefunc = unsafe extern "C" fn (arg1: *mut PyObject, arg2: *mut PyFrameObject, diff --git a/python27-sys/src/traceback.rs b/python27-sys/src/traceback.rs index 4732c8d4..0a53c459 100644 --- a/python27-sys/src/traceback.rs +++ b/python27-sys/src/traceback.rs @@ -1,6 +1,7 @@ use libc::c_int; use object::*; use pyport::Py_ssize_t; +use frameobject::PyFrameObject; #[repr(C)] #[derive(Copy, Clone)] @@ -12,13 +13,13 @@ pub struct PyTracebackObject { pub ob_refcnt: Py_ssize_t, pub ob_type: *mut PyTypeObject, pub tb_next: *mut PyTracebackObject, - pub tb_frame: *mut ::PyFrameObject, + pub tb_frame: *mut PyFrameObject, pub tb_lasti: c_int, pub tb_lineno: c_int } extern "C" { - pub fn PyTraceBack_Here(arg1: *mut ::PyFrameObject) -> c_int; + pub fn PyTraceBack_Here(arg1: *mut PyFrameObject) -> c_int; pub fn PyTraceBack_Print(arg1: *mut PyObject, arg2: *mut PyObject) -> c_int;