Skip to content
Snippets Groups Projects
Commit b4edc3ca authored by Eelco Dolstra's avatar Eelco Dolstra
Browse files

Don't leak exceptions

parent e6bd8887
No related branches found
No related tags found
No related merge requests found
......@@ -76,7 +76,7 @@ impl From<Error> for CppException {
fn from(err: Error) -> Self {
match err {
Error::Foreign(ex) => ex,
_ => unsafe { make_error(&err.to_string()) },
_ => CppException::new(&err.to_string()),
}
}
}
......@@ -85,7 +85,23 @@ impl From<Error> for CppException {
#[derive(Debug)]
pub struct CppException(*const libc::c_void); // == std::exception_ptr*
impl CppException {
fn new(s: &str) -> Self {
Self(unsafe { make_error(s) })
}
}
impl Drop for CppException {
fn drop(&mut self) {
unsafe {
destroy_error(self.0);
}
}
}
extern "C" {
#[allow(improper_ctypes)] // YOLO
fn make_error(s: &str) -> CppException;
fn make_error(s: &str) -> *const libc::c_void;
fn destroy_error(exc: *const libc::c_void);
}
......@@ -3,10 +3,14 @@
extern "C" std::exception_ptr * make_error(rust::StringSlice s)
{
// FIXME: leak
return new std::exception_ptr(std::make_exception_ptr(nix::Error(std::string(s.ptr, s.size))));
}
extern "C" void destroy_error(std::exception_ptr * ex)
{
free(ex);
}
namespace rust {
std::ostream & operator << (std::ostream & str, const String & s)
......
......@@ -152,28 +152,47 @@ struct Source
template<typename T>
struct Result
{
unsigned int tag;
enum { Ok = 0, Err = 1, Uninit = 2 } tag;
union {
T data;
std::exception_ptr * exc;
};
Result() : tag(Uninit) { }; // FIXME: remove
Result(const Result &) = delete;
Result(Result && other)
: tag(other.tag)
{
other.tag = Uninit;
if (tag == Ok)
data = std::move(other.data);
else if (tag == Err)
exc = other.exc;
}
~Result()
{
if (tag == 0)
if (tag == Ok)
data.~T();
else if (tag == 1)
// FIXME: don't leak exc
else if (tag == Err)
free(exc);
else if (tag == Uninit)
;
else
abort();
}
/* Rethrow the wrapped exception or return the wrapped value. */
T unwrap()
{
if (tag == 0)
if (tag == Ok) {
tag = Uninit;
return std::move(data);
else if (tag == 1)
}
else if (tag == Err)
std::rethrow_exception(*exc);
else
abort();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment