@@ -17,6 +17,63 @@ pub struct PtrLen {
17
17
pub len : usize ,
18
18
}
19
19
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
+
20
77
#[ repr( C ) ]
21
78
pub union Result {
22
79
err : PtrLen ,
0 commit comments