13
13
#include < stdio.h>
14
14
#include < stdint.h>
15
15
#include < stdlib.h>
16
+ #include < string.h>
16
17
17
18
#if !defined(__USING_WASM_EXCEPTIONS__)
18
19
// Until recently, Rust's `rust_eh_personality` for emscripten referred to this
@@ -71,7 +72,14 @@ void* __thrown_object_from_unwind_exception(
71
72
return thrown_object_from_unwind_exception (unwind_exception);
72
73
}
73
74
74
- char * __get_exception_message (void * thrown_object, bool terminate=false ) {
75
+ // Given a thrown_object, puts the information about its type and message into
76
+ // 'type' and 'message' output parameters. 'type' will contain the string
77
+ // representation of the type of the exception, e.g., 'int'. 'message' will
78
+ // contain the result of 'std::exception::what()' method if the type of the
79
+ // exception is a subclass of std::exception; otherwise it will be NULL. The
80
+ // caller is responsible for freeing 'type' buffer and also 'message' buffer, if
81
+ // it is not NULL.
82
+ void __get_exception_message (void * thrown_object, char ** type, char ** message) {
75
83
__cxa_exception* exception_header =
76
84
cxa_exception_from_thrown_object (thrown_object);
77
85
const __shim_type_info* thrown_type =
@@ -81,38 +89,44 @@ char* __get_exception_message(void* thrown_object, bool terminate=false) {
81
89
int status = 0 ;
82
90
char * demangled_buf = __cxa_demangle (type_name, 0 , 0 , &status);
83
91
if (status == 0 && demangled_buf) {
84
- type_name = demangled_buf;
92
+ *type = demangled_buf;
93
+ } else {
94
+ if (demangled_buf) {
95
+ free (demangled_buf);
96
+ }
97
+ *type = (char *)malloc (strlen (type_name) + 1 );
98
+ strcpy (*type, type_name);
85
99
}
86
100
101
+ *message = NULL ;
87
102
const __shim_type_info* catch_type =
88
103
static_cast <const __shim_type_info*>(&typeid (std::exception));
89
104
int can_catch = catch_type->can_catch (thrown_type, thrown_object);
90
- char * result = NULL ;
91
105
if (can_catch) {
92
106
const char * what =
93
107
static_cast <const std::exception*>(thrown_object)->what ();
94
- asprintf (&result,
95
- (terminate ? " terminating with uncaught exception of type %s: %s"
96
- : " exception of type %s: %s" ),
97
- type_name,
98
- what);
99
- } else {
100
- asprintf (&result,
101
- (terminate ? " terminating with uncaught exception of type %s"
102
- : " exception of type %s" ),
103
- type_name);
108
+ *message = (char *)malloc (strlen (what) + 1 );
109
+ strcpy (*message, what);
104
110
}
111
+ }
105
112
106
- if (demangled_buf) {
107
- free (demangled_buf);
113
+ // Returns a message saying that execution was terminated due to an exception.
114
+ // This message is freshly malloc'd and should be freed.
115
+ char * __get_exception_terminate_message (void * thrown_object) {
116
+ char * type;
117
+ char * message;
118
+ __get_exception_message (thrown_object, &type, &message);
119
+ char * result;
120
+ if (message != NULL ) {
121
+ asprintf (
122
+ &result, " terminating with uncaught exception %s: %s" , type, message);
123
+ free (message);
124
+ } else {
125
+ asprintf (&result, " terminating with uncaught exception of type %s" , type);
108
126
}
127
+ free (type);
109
128
return result;
110
129
}
111
-
112
- char * __get_exception_terminate_message (void *thrown_object) {
113
- return __get_exception_message (thrown_object, true );
114
- }
115
-
116
130
}
117
131
118
132
#endif // __USING_EMSCRIPTEN_EXCEPTIONS__ || __USING_WASM_EXCEPTIONS__
0 commit comments