@@ -17,6 +17,63 @@ pub struct PtrLen {
1717 pub len : usize ,
1818}
1919
20+ extern "C" {
21+ /// Helper to construct the default exception from the error message.
22+ #[ link_name = "cxxbridge1$default_exception" ]
23+ fn default_exception ( ptr : * const u8 , len : usize ) -> * mut u8 ;
24+ /// Helper to clone the instance of `std::exception_ptr` on the C++ side.
25+ #[ link_name = "cxxbridge1$clone_exception" ]
26+ fn clone_exception ( ptr : * const u8 ) -> * mut u8 ;
27+ /// Helper to drop the instance of `std::exception_ptr` on the C++ side.
28+ #[ link_name = "cxxbridge1$drop_exception" ]
29+ fn drop_exception ( ptr : * mut u8 ) ;
30+ }
31+
32+ /// C++ exception containing `std::exception_ptr`.
33+ ///
34+ /// This object is the Rust wrapper over `std::exception_ptr`, so it owns the exception pointer.
35+ /// I.e., the exception is either referenced by a `std::exception_ptr` on the C++ side or the
36+ /// reference is moved to this object on the Rust side.
37+ #[ repr( C ) ]
38+ #[ must_use]
39+ pub struct CxxException ( NonNull < u8 > ) ;
40+
41+ impl CxxException {
42+ /// Construct the default `rust::Error` exception from the specified `exc_text`.
43+ pub fn new_default ( exc_text : & str ) -> Self {
44+ let exception_ptr = unsafe {
45+ default_exception ( exc_text. as_ptr ( ) , exc_text. len ( ) )
46+ } ;
47+ CxxException (
48+ NonNull :: new ( exception_ptr)
49+ . expect ( "Exception conversion returned a null pointer" )
50+ )
51+ }
52+ }
53+
54+ impl Clone for CxxException {
55+ fn clone ( & self ) -> Self {
56+ let clone_ptr = unsafe { clone_exception ( self . 0 . as_ptr ( ) ) } ;
57+ Self (
58+ NonNull :: new ( clone_ptr)
59+ . expect ( "Exception cloning returned a null pointer" )
60+ )
61+ }
62+ }
63+
64+ impl Drop for CxxException {
65+ fn drop ( & mut self ) {
66+ unsafe { drop_exception ( self . 0 . as_ptr ( ) ) } ;
67+ }
68+ }
69+
70+ // SAFETY: This is safe, since the C++ exception referenced by `std::exception_ptr`
71+ // is not thread-local.
72+ unsafe impl Send for CxxException { }
73+ // SAFETY: This is safe, since the C++ exception referenced by `std::exception_ptr`
74+ // can be shared across threads read-only.
75+ unsafe impl Sync for CxxException { }
76+
2077#[ repr( C ) ]
2178pub union Result {
2279 err : PtrLen ,
0 commit comments