• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <assert.h>
2 #include <stddef.h>
3 #include <stdio.h>
4 
println(const char * s)5 void println(const char* s) {
6     puts(s);
7     fflush(stdout);
8 }
9 
10 struct exception {};
11 struct rust_panic {};
12 
13 struct drop_check {
14     bool* ok;
~drop_checkdrop_check15     ~drop_check() {
16         println("~drop_check");
17 
18         if (ok)
19             *ok = true;
20     }
21 };
22 
23 extern "C" {
24     void rust_catch_callback(void (*cb)(), bool* rust_ok);
25 
throw_cxx_exception()26     void throw_cxx_exception() {
27         println("throwing C++ exception");
28         throw exception();
29     }
30 
test_cxx_exception()31     void test_cxx_exception() {
32         bool rust_ok = false;
33         try {
34             rust_catch_callback(throw_cxx_exception, &rust_ok);
35             assert(false && "unreachable");
36         } catch (exception e) {
37             println("caught C++ exception");
38             assert(rust_ok);
39             return;
40         }
41         assert(false && "did not catch thrown C++ exception");
42     }
43 
cxx_catch_callback(void (* cb)(),bool * cxx_ok)44     void cxx_catch_callback(void (*cb)(), bool* cxx_ok) {
45         drop_check x;
46         x.ok = NULL;
47         try {
48             cb();
49         } catch (rust_panic e) {
50             assert(false && "shouldn't be able to catch a rust panic");
51         } catch (...) {
52             println("caught foreign exception in catch (...)");
53             // Foreign exceptions are caught by catch (...). We only set the ok
54             // flag if we successfully caught the panic. The destructor of
55             // drop_check will then set the flag to true if it is executed.
56             x.ok = cxx_ok;
57             throw;
58         }
59     }
60 }
61