1313#include < stdio.h>
1414#include < stdint.h>
1515#include < stdlib.h>
16+ #include < string.h>
1617
1718#if !defined(__USING_WASM_EXCEPTIONS__)
1819// Until recently, Rust's `rust_eh_personality` for emscripten referred to this
@@ -71,7 +72,14 @@ void* __thrown_object_from_unwind_exception(
7172 return thrown_object_from_unwind_exception (unwind_exception);
7273}
7374
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) {
7583 __cxa_exception* exception_header =
7684 cxa_exception_from_thrown_object (thrown_object);
7785 const __shim_type_info* thrown_type =
@@ -81,38 +89,44 @@ char* __get_exception_message(void* thrown_object, bool terminate=false) {
8189 int status = 0 ;
8290 char * demangled_buf = __cxa_demangle (type_name, 0 , 0 , &status);
8391 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);
8599 }
86100
101+ *message = NULL ;
87102 const __shim_type_info* catch_type =
88103 static_cast <const __shim_type_info*>(&typeid (std::exception));
89104 int can_catch = catch_type->can_catch (thrown_type, thrown_object);
90- char * result = NULL ;
91105 if (can_catch) {
92106 const char * what =
93107 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);
104110 }
111+ }
105112
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);
108126 }
127+ free (type);
109128 return result;
110129}
111-
112- char * __get_exception_terminate_message (void *thrown_object) {
113- return __get_exception_message (thrown_object, true );
114- }
115-
116130}
117131
118132#endif // __USING_EMSCRIPTEN_EXCEPTIONS__ || __USING_WASM_EXCEPTIONS__
0 commit comments