Fix segfault due to POST_DROP_USIZE and update to latest nightly
This commit is contained in:
parent
dd20e00c77
commit
2a91b00abe
12
src/lib.rs
12
src/lib.rs
|
@ -1,11 +1,11 @@
|
|||
#![feature(core)]
|
||||
#![feature(unsafe_destructor)]
|
||||
#![feature(unsafe_no_drop_flag)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(slice_patterns)]
|
||||
#![feature(core)] // used for a lot of low-level stuff
|
||||
#![feature(unsafe_no_drop_flag)] // crucial so that PyObject<'p> is binary compatible with *mut ffi::PyObject
|
||||
#![feature(filling_drop)] // necessary to avoid segfault with unsafe_no_drop_flag
|
||||
#![feature(optin_builtin_traits)] // for opting out of Sync/Send
|
||||
#![feature(slice_patterns)] // for tuple_conversion macros
|
||||
#![feature(utf8_error)] // for translating Utf8Error to python exception
|
||||
#![allow(unused_imports, dead_code, unused_variables)]
|
||||
|
||||
extern crate core; // NonZero is not exposed in std?
|
||||
extern crate libc;
|
||||
extern crate python27_sys as ffi;
|
||||
pub use ffi::Py_ssize_t;
|
||||
|
|
|
@ -94,12 +94,8 @@ impl<'p> UnicodeDecodeError<'p> {
|
|||
}
|
||||
|
||||
pub fn new_utf8(py: Python<'p>, input: &[u8], err: Utf8Error) -> PyResult<'p, UnicodeDecodeError<'p>> {
|
||||
match err {
|
||||
Utf8Error::InvalidByte(pos) =>
|
||||
UnicodeDecodeError::new(py, cstr!("utf-8"), input, pos .. pos+1, cstr!("invalid byte")),
|
||||
Utf8Error::TooShort =>
|
||||
UnicodeDecodeError::new(py, cstr!("utf-8"), input, input.len() - 1 .. input.len(), cstr!("unexpected end of data")),
|
||||
}
|
||||
let pos = err.valid_up_to();
|
||||
UnicodeDecodeError::new(py, cstr!("utf-8"), input, pos .. input.len(), cstr!("invalid utf-8"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use core::nonzero::NonZero;
|
||||
use std::mem::{size_of, transmute};
|
||||
use std::mem::{size_of, transmute, POST_DROP_USIZE};
|
||||
use libc;
|
||||
use ffi;
|
||||
use python::{Python, PythonObject, PythonObjectWithCheckedDowncast, PythonObjectWithTypeObject, PythonObjectDowncastError, ToPythonPointer};
|
||||
|
@ -7,26 +6,28 @@ use objects::PyType;
|
|||
use err::{PyErr, PyResult};
|
||||
|
||||
#[unsafe_no_drop_flag]
|
||||
#[repr(C)]
|
||||
pub struct PyObject<'p> {
|
||||
// PyObject<'p> owns one reference to the *PyObject
|
||||
// ptr is not null (except possibly due to #[unsafe_no_drop_flag])
|
||||
ptr: NonZero<*mut ffi::PyObject>,
|
||||
ptr: *mut ffi::PyObject,
|
||||
py : Python<'p>
|
||||
}
|
||||
|
||||
#[unsafe_destructor]
|
||||
impl <'p> Drop for PyObject<'p> {
|
||||
#[inline]
|
||||
fn drop(&mut self) {
|
||||
// TODO: change from Py_XDECREF to Py_DECREF when #[unsafe_no_drop_flag] disappears
|
||||
unsafe { ffi::Py_XDECREF(*self.ptr); }
|
||||
// TODO: remove if and change Py_XDECREF to Py_DECREF when #[unsafe_no_drop_flag] disappears
|
||||
if self.ptr as usize != POST_DROP_USIZE {
|
||||
unsafe { ffi::Py_XDECREF(self.ptr); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl <'p> Clone for PyObject<'p> {
|
||||
#[inline]
|
||||
fn clone(&self) -> PyObject<'p> {
|
||||
unsafe { ffi::Py_INCREF(*self.ptr) };
|
||||
unsafe { ffi::Py_INCREF(self.ptr) };
|
||||
PyObject { ptr: self.ptr, py: self.py }
|
||||
}
|
||||
}
|
||||
|
@ -80,12 +81,12 @@ impl <'p> PythonObjectWithTypeObject<'p> for PyObject<'p> {
|
|||
impl <'p> ToPythonPointer for PyObject<'p> {
|
||||
#[inline]
|
||||
fn as_ptr(&self) -> *mut ffi::PyObject {
|
||||
*self.ptr
|
||||
self.ptr
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn steal_ptr(self) -> *mut ffi::PyObject {
|
||||
let ptr = *self.ptr;
|
||||
let ptr = self.ptr;
|
||||
unsafe { ::std::mem::forget(self); }
|
||||
ptr
|
||||
}
|
||||
|
@ -99,7 +100,7 @@ impl <'p> PyObject<'p> {
|
|||
#[inline]
|
||||
pub unsafe fn from_owned_ptr(py : Python<'p>, ptr : *mut ffi::PyObject) -> PyObject<'p> {
|
||||
debug_assert!(!ptr.is_null() && ffi::Py_REFCNT(ptr) > 0);
|
||||
PyObject { py: py, ptr: NonZero::new(ptr) }
|
||||
PyObject { py: py, ptr: ptr }
|
||||
}
|
||||
|
||||
/// Creates a PyObject instance for the given FFI pointer.
|
||||
|
@ -109,7 +110,7 @@ impl <'p> PyObject<'p> {
|
|||
pub unsafe fn from_borrowed_ptr(py : Python<'p>, ptr : *mut ffi::PyObject) -> PyObject<'p> {
|
||||
debug_assert!(!ptr.is_null() && ffi::Py_REFCNT(ptr) > 0);
|
||||
ffi::Py_INCREF(ptr);
|
||||
PyObject { py: py, ptr: NonZero::new(ptr) }
|
||||
PyObject { py: py, ptr: ptr }
|
||||
}
|
||||
|
||||
/// Creates a PyObject instance for the given FFI pointer.
|
||||
|
|
|
@ -18,7 +18,7 @@ impl !Sync for PythonInterpreterState {}
|
|||
/// For example, python constants like None have the type "&'p PyObject<'p>".
|
||||
/// You can imagine the GIL to be a giant "Mutex<AllPythonState>". This makes 'p the lifetime of the
|
||||
/// python state protected by that mutex.
|
||||
#[derive(Copy)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Python<'p>(PhantomData<&'p PythonInterpreterState>);
|
||||
|
||||
// Trait for converting from Self to *mut ffi::PyObject
|
||||
|
|
Loading…
Reference in New Issue