From 082db89aa69743a6da448f8e59e8dae8af26bffb Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Sat, 24 Jun 2017 12:57:18 -0700 Subject: [PATCH] do not modify ref counter for borrowed ptr --- src/pointer.rs | 4 ++-- src/python.rs | 60 ++++++++++++++++++++++++++---------------------- src/pythonrun.rs | 34 ++++++++++++--------------- 3 files changed, 49 insertions(+), 49 deletions(-) diff --git a/src/pointer.rs b/src/pointer.rs index 6fd39eea..1b212d36 100644 --- a/src/pointer.rs +++ b/src/pointer.rs @@ -91,7 +91,7 @@ impl PyObject { if ptr.is_null() { Err(PyErr::fetch(py)) } else { - Ok(unsafe{PyObject::from_owned_ptr(py, ptr)}) + Ok(unsafe{PyObject::from_borrowed_ptr(py, ptr)}) } } @@ -104,7 +104,7 @@ impl PyObject { if ptr.is_null() { None } else { - Some(unsafe{PyObject::from_owned_ptr(py, ptr)}) + Some(unsafe{PyObject::from_borrowed_ptr(py, ptr)}) } } diff --git a/src/python.rs b/src/python.rs index 156efc01..509d3af2 100644 --- a/src/python.rs +++ b/src/python.rs @@ -274,7 +274,7 @@ impl<'p> Python<'p> { where T: PyDowncastFrom { unsafe { - let p = pythonrun::register_owned(self, obj); + let p = pythonrun::register_owned(self, obj.into_ptr()); ::downcast_from(p) } } @@ -283,7 +283,7 @@ impl<'p> Python<'p> { pub unsafe fn cast_as(self, obj: PyObject) -> &'p T where T: PyDowncastFrom { - let p = pythonrun::register_owned(self, obj); + let p = pythonrun::register_owned(self, obj.into_ptr()); ::unchecked_downcast_from(p) } @@ -292,9 +292,12 @@ impl<'p> Python<'p> { pub unsafe fn cast_from_ptr(self, ptr: *mut ffi::PyObject) -> &'p T where T: PyDowncastFrom { - let obj = PyObject::from_owned_ptr_or_panic(self, ptr); - let p = pythonrun::register_owned(self, obj); - ::unchecked_downcast_from(p) + if ptr.is_null() { + ::err::panic_after_error(); + } else { + let p = pythonrun::register_owned(self, ptr); + ::unchecked_downcast_from(p) + } } /// Register `ffi::PyObject` pointer in release pool, @@ -302,20 +305,24 @@ impl<'p> Python<'p> { pub unsafe fn mut_cast_from_ptr(self, ptr: *mut ffi::PyObject) -> &'p mut T where T: PyDowncastFrom { - let obj = PyObject::from_owned_ptr_or_panic(self, ptr); - let p = pythonrun::register_owned(self, obj); - ::unchecked_mut_downcast_from(p) + if ptr.is_null() { + ::err::panic_after_error(); + } else { + let p = pythonrun::register_owned(self, ptr); + ::unchecked_mut_downcast_from(p) + } } /// Register owned `ffi::PyObject` pointer in release pool. /// Returns `Err(PyErr)` if the pointer is `null`. /// do unchecked downcast to specific Python object. - pub fn cast_from_ptr_or_err(self, ptr: *mut ffi::PyObject) -> PyResult<&'p T> + pub unsafe fn cast_from_ptr_or_err(self, ptr: *mut ffi::PyObject) -> PyResult<&'p T> where T: PyDowncastFrom { - let obj = PyObject::from_owned_ptr_or_err(self, ptr)?; - unsafe { - let p = pythonrun::register_owned(self, obj); + if ptr.is_null() { + Err(PyErr::fetch(self)) + } else { + let p = pythonrun::register_owned(self, ptr); Ok(::unchecked_downcast_from(p)) } } @@ -323,17 +330,14 @@ impl<'p> Python<'p> { /// Register owned `ffi::PyObject` pointer in release pool. /// Returns `None` if the pointer is `null`. /// do unchecked downcast to specific Python object. - pub fn cast_from_ptr_or_opt(self, ptr: *mut ffi::PyObject) -> Option<&'p T> + pub unsafe fn cast_from_ptr_or_opt(self, ptr: *mut ffi::PyObject) -> Option<&'p T> where T: PyDowncastFrom { if ptr.is_null() { None } else { - unsafe { - let obj = PyObject::from_owned_ptr(self, ptr); - let p = pythonrun::register_owned(self, obj); - Some(::unchecked_downcast_from(p)) - } + let p = pythonrun::register_owned(self, ptr); + Some(::unchecked_downcast_from(p)) } } @@ -343,8 +347,7 @@ impl<'p> Python<'p> { pub unsafe fn cast_from_borrowed_ptr(self, ptr: *mut ffi::PyObject) -> &'p T where T: PyDowncastFrom { - let obj = PyObject::from_borrowed_ptr(self, ptr); - let p = pythonrun::register_borrowed(self, obj); + let p = pythonrun::register_borrowed(self, ptr); ::unchecked_downcast_from(p) } @@ -355,9 +358,12 @@ impl<'p> Python<'p> { -> PyResult<&'p T> where T: PyDowncastFrom { - let obj = PyObject::from_borrowed_ptr_or_err(self, ptr)?; - let p = pythonrun::register_borrowed(self, obj); - Ok(::unchecked_downcast_from(p)) + if ptr.is_null() { + Err(PyErr::fetch(self)) + } else { + let p = pythonrun::register_borrowed(self, ptr); + Ok(::unchecked_downcast_from(p)) + } } /// Register borrowed `ffi::PyObject` pointer in release pool. @@ -370,8 +376,7 @@ impl<'p> Python<'p> { if ptr.is_null() { None } else { - let obj = PyObject::from_borrowed_ptr(self, ptr); - let p = pythonrun::register_borrowed(self, obj); + let p = pythonrun::register_borrowed(self, ptr); Some(::unchecked_downcast_from(p)) } } @@ -382,14 +387,13 @@ impl<'p> Python<'p> { pub unsafe fn mut_cast_from_borrowed_ptr(self, ptr: *mut ffi::PyObject) -> &'p mut T where T: PyDowncastFrom { - let obj = PyObject::from_borrowed_ptr(self, ptr); - let p = pythonrun::register_borrowed(self, obj); + let p = pythonrun::register_borrowed(self, ptr); ::unchecked_mut_downcast_from(p) } pub fn track_object(self, obj: PyObject) -> &'p PyObjectRef { - unsafe { pythonrun::register_owned(self, obj) } + unsafe { pythonrun::register_owned(self, obj.into_ptr()) } } /// Release PyObject reference. diff --git a/src/pythonrun.rs b/src/pythonrun.rs index 1ef363ba..ccc5a24e 100644 --- a/src/pythonrun.rs +++ b/src/pythonrun.rs @@ -4,8 +4,7 @@ use std::{sync, rc, marker, mem}; use ffi; -use python::{Python, ToPyPointer}; -use pointer::PyObject; +use python::Python; use objects::PyObjectRef; static START: sync::Once = sync::ONCE_INIT; @@ -106,8 +105,8 @@ impl Drop for GILGuard { } } -static mut OWNED: *mut Vec = 0 as *mut _; -static mut BORROWED: *mut Vec = 0 as *mut _; +static mut OWNED: *mut Vec<*mut ffi::PyObject> = 0 as *mut _; +static mut BORROWED: *mut Vec<*mut ffi::PyObject> = 0 as *mut _; pub struct Pool { owned: usize, @@ -118,8 +117,8 @@ pub struct Pool { impl Pool { #[inline] pub unsafe fn new() -> Pool { - let owned: &'static mut Vec = mem::transmute(OWNED); - let borrowed: &'static mut Vec = mem::transmute(BORROWED); + let owned: &'static mut Vec<*mut ffi::PyObject> = mem::transmute(OWNED); + let borrowed: &'static mut Vec<*mut ffi::PyObject> = mem::transmute(BORROWED); Pool{ owned: owned.len(), borrowed: borrowed.len(), no_send: marker::PhantomData } @@ -139,35 +138,32 @@ impl Drop for Pool { } } -pub unsafe fn register_owned<'p>(_py: Python<'p>, obj: PyObject) -> &'p PyObjectRef { - let pool: &'static mut Vec = mem::transmute(OWNED); +pub unsafe fn register_owned<'p>(_py: Python<'p>, obj: *mut ffi::PyObject) -> &'p PyObjectRef { + let pool: &'static mut Vec<*mut ffi::PyObject> = mem::transmute(OWNED); pool.push(obj); mem::transmute(&pool[pool.len()-1]) } -pub unsafe fn register_borrowed<'p>(_py: Python<'p>, obj: PyObject) -> &'p PyObjectRef { - let pool: &'static mut Vec = mem::transmute(BORROWED); +pub unsafe fn register_borrowed<'p>(_py: Python<'p>, obj: *mut ffi::PyObject) -> &'p PyObjectRef { + let pool: &'static mut Vec<*mut ffi::PyObject> = mem::transmute(BORROWED); pool.push(obj); mem::transmute(&pool[pool.len()-1]) } pub unsafe fn drain(owned: usize, borrowed: usize) { - let owned_pool: &'static mut Vec = mem::transmute(OWNED); + let owned_pool: &'static mut Vec<*mut ffi::PyObject> = mem::transmute(OWNED); let len = owned_pool.len(); if owned < len { - for ob in &mut owned_pool[owned..len] { - ffi::Py_DECREF(ob.as_ptr()); + for ptr in &mut owned_pool[owned..len] { + ffi::Py_DECREF(*ptr); } owned_pool.set_len(owned); } - let borrowed_pool: &'static mut Vec = mem::transmute(BORROWED); + let borrowed_pool: &'static mut Vec<*mut ffi::PyObject> = mem::transmute(BORROWED); let len = borrowed_pool.len(); if borrowed < len { - for ob in &mut borrowed_pool[borrowed..len] { - ffi::Py_DECREF(ob.as_ptr()); - } borrowed_pool.set_len(borrowed); } @@ -184,8 +180,8 @@ impl GILGuard { unsafe { let gstate = ffi::PyGILState_Ensure(); // acquire GIL - let owned: &'static mut Vec = mem::transmute(OWNED); - let borrowed: &'static mut Vec = mem::transmute(BORROWED); + let owned: &'static mut Vec<*mut ffi::PyObject> = mem::transmute(OWNED); + let borrowed: &'static mut Vec<*mut ffi::PyObject> = mem::transmute(BORROWED); GILGuard { owned: owned.len(), borrowed: borrowed.len(),