Revision 33912
- Date:
- 2008/12/15 06:11:01
- Files:
Legend:
- Added
- Removed
- Modified
-
trunk/docs/pdds/pdd23_exceptions.pod
166 166 execution). Whether to resume or die when an exception isn't handled is 167 167 determined by the severity of the exception. 168 168 169 {{NOTE: Not yet implemented, but should be easy}} 170 171 169 =item 6 172 170 Otherwise terminate the program like C<die>. 173 171 -
trunk/src/exceptions.c
42 42 43 43 PARROT_WARN_UNUSED_RESULT 44 44 PARROT_CAN_RETURN_NULL 45 static PMC * find_exception_handler(PARROT_INTERP, ARGIN(PMC *exception)) 45 static PMC * die_from_exception(PARROT_INTERP, ARGIN(PMC *exception)) 46 46 __attribute__nonnull__(1) 47 47 __attribute__nonnull__(2); 48 48 … … 89 89 90 90 /* 91 91 92 =item C<static PMC * find_exception_handler> 92 =item C<static PMC * die_from_exception> 93 93 94 Find the exception handler for C<exception>. 94 Print a stack trace for C<exception>, a message if there is one, and then exit. 95 95 96 96 =cut 97 97 … … 100 100 PARROT_WARN_UNUSED_RESULT 101 101 PARROT_CAN_RETURN_NULL 102 102 static PMC * 103 find_exception_handler(PARROT_INTERP, ARGIN(PMC *exception)) 103 die_from_exception(PARROT_INTERP, ARGIN(PMC *exception)) 104 104 { 105 PMC * const handler = Parrot_cx_find_handler_local(interp, exception); 106 if (!PMC_IS_NULL(handler)) { 107 return handler; 108 } 109 else { 110 STRING * const message = VTABLE_get_string(interp, exception); 111 INTVAL exit_status = 1; 112 const INTVAL severity = VTABLE_get_integer_keyed_str(interp, exception, CONST_STRING(interp, "severity")); 105 STRING * const message = VTABLE_get_string(interp, exception); 106 INTVAL exit_status = 1; 107 const INTVAL severity = VTABLE_get_integer_keyed_str(interp, exception, CONST_STRING(interp, "severity")); 113 108 114 /* flush interpreter output to get things printed in order */ 115 Parrot_io_flush(interp, Parrot_io_STDOUT(interp)); 116 Parrot_io_flush(interp, Parrot_io_STDERR(interp)); 109 /* flush interpreter output to get things printed in order */ 110 Parrot_io_flush(interp, Parrot_io_STDOUT(interp)); 111 Parrot_io_flush(interp, Parrot_io_STDERR(interp)); 117 112 118 if (interp->debugger) { 119 Parrot_io_flush(interp->debugger, Parrot_io_STDOUT(interp->debugger)); 120 Parrot_io_flush(interp->debugger, Parrot_io_STDERR(interp->debugger)); 121 } 113 if (interp->debugger) { 114 Parrot_io_flush(interp->debugger, Parrot_io_STDOUT(interp->debugger)); 115 Parrot_io_flush(interp->debugger, Parrot_io_STDERR(interp->debugger)); 116 } 122 117 123 if (string_equal(interp, message, CONST_STRING(interp, "")) == 1) { 124 Parrot_io_eprintf(interp, "%S\n", message); 118 if (string_equal(interp, message, CONST_STRING(interp, "")) == 1) { 119 Parrot_io_eprintf(interp, "%S\n", message); 125 120 126 /* caution against output swap (with PDB_backtrace) */ 127 fflush(stderr); 128 PDB_backtrace(interp); 129 } 130 else if (severity == EXCEPT_exit) { 131 /* TODO: get exit status based on type */ 132 exit_status = VTABLE_get_integer_keyed_str(interp, exception, CONST_STRING(interp, "exit_code")); 133 } 134 else { 135 Parrot_io_eprintf(interp, "No exception handler and no message\n"); 136 /* caution against output swap (with PDB_backtrace) */ 137 fflush(stderr); 138 PDB_backtrace(interp); 139 } 121 /* caution against output swap (with PDB_backtrace) */ 122 fflush(stderr); 123 PDB_backtrace(interp); 124 } 125 else if (severity == EXCEPT_exit) { 126 /* TODO: get exit status based on type */ 127 exit_status = VTABLE_get_integer_keyed_str(interp, exception, CONST_STRING(interp, "exit_code")); 128 } 129 else { 130 Parrot_io_eprintf(interp, "No exception handler and no message\n"); 131 /* caution against output swap (with PDB_backtrace) */ 132 fflush(stderr); 133 PDB_backtrace(interp); 134 } 140 135 141 /* 142 * returning NULL from here returns resume address NULL to the 143 * runloop, which will terminate the thread function finally 144 * 145 * RT #45917 this check should better be in Parrot_exit 146 */ 136 /* 137 * returning NULL from here returns resume address NULL to the 138 * runloop, which will terminate the thread function finally 139 * 140 * RT #45917 this check should better be in Parrot_exit 141 */ 147 142 148 /* no exception handler, but this is not the main thread */ 149 if (interp->thread_data && interp->thread_data->tid) 150 pt_thread_detach(interp->thread_data->tid); 143 /* no exception handler, but this is not the main thread */ 144 if (interp->thread_data && interp->thread_data->tid) 145 pt_thread_detach(interp->thread_data->tid); 151 146 152 /* 153 * only main should run the destroy functions - exit handler chain 154 * is freed during Parrot_exit 155 */ 156 Parrot_exit(interp, exit_status); 157 } 158 147 /* 148 * only main should run the destroy functions - exit handler chain 149 * is freed during Parrot_exit 150 */ 151 Parrot_exit(interp, exit_status); 159 152 } 160 153 161 154 /* … … 197 190 Parrot_ex_throw_from_op(PARROT_INTERP, ARGIN(PMC *exception), ARGIN_NULLOK(void *dest)) 198 191 { 199 192 opcode_t *address; 200 PMC * const handler = find_exception_handler(interp, exception); 193 PMC * const handler = Parrot_cx_find_handler_local(interp, exception); 194 if (PMC_IS_NULL(handler)) { 195 STRING * const message = VTABLE_get_string(interp, exception); 196 const INTVAL severity = VTABLE_get_integer_keyed_str(interp, exception, CONST_STRING(interp, "severity")); 197 if (severity < EXCEPT_error) { 198 PMC *resume = VTABLE_get_attr_str(interp, exception, 199 CONST_STRING(interp, "resume")); 200 if (string_equal(interp, message, CONST_STRING(interp, "")) == 1) { 201 Parrot_io_eprintf(interp, "%S\n", message); 202 } 203 else { 204 Parrot_io_eprintf(interp, "%S\n", CONST_STRING(interp,"Warning")); 205 } 201 206 202 if (!handler) 203 return NULL; 207 /* caution against output swap (with PDB_backtrace) */ 208 fflush(stderr); 209 //PDB_backtrace(interp); 204 210 211 if (!PMC_IS_NULL(resume)) { 212 return VTABLE_invoke(interp, resume, NULL); 213 } 214 } 215 die_from_exception(interp, exception); 216 } 217 205 218 address = VTABLE_invoke(interp, handler, dest); 206 219 207 220 /* Set up the continuation context of the handler in the interpreter. */ … … 275 288 void 276 289 Parrot_ex_throw_from_c(PARROT_INTERP, ARGIN(PMC *exception)) 277 290 { 278 PMC * const handler = find_exception_handler(interp, exception); 291 PMC * const handler = Parrot_cx_find_handler_local(interp, exception); 279 292 RunProfile * const profile = interp->profile; 280 293 Parrot_runloop *return_point = interp->current_runloop; 294 if (PMC_IS_NULL(handler)) { 295 die_from_exception(interp, exception); 296 } 281 297 282 298 /* If profiling, remember end time of lastop and generate entry for 283 299 * exception. */ -
trunk/src/pmc/exception.pmc
50 50 */ 51 51 52 52 #include "parrot/parrot.h" 53 #include "parrot/exceptions.h" 53 54 54 55 pmclass Exception { 55 56 … … 90 91 91 92 /* Set up the core struct and default values for the exception object. */ 92 93 PMC_data(SELF) = core_struct; 93 core_struct->severity = 0; 94 core_struct->severity = EXCEPT_error; 94 95 core_struct->handled = 0; 95 96 core_struct->message = CONST_STRING(interp, ""); 96 97 core_struct->payload = PMCNULL; … … 122 123 PMC_data(SELF) = core_struct; 123 124 core_struct->severity = ishash ? 124 125 VTABLE_get_integer_keyed_str(interp, values, CONST_STRING(interp, 'severity')) : 125 0; 126 EXCEPT_error; 126 127 core_struct->handled = 0; 127 128 core_struct->message = ishash ? 128 129 VTABLE_get_string_keyed_str(interp, values, CONST_STRING(interp, 'message')) :