|
8 | 8 | #include "qstr.h" |
9 | 9 | #include "obj.h" |
10 | 10 | #include "objtuple.h" |
| 11 | +#include "objtype.h" |
11 | 12 | #include "runtime.h" |
12 | 13 | #include "runtime0.h" |
13 | 14 |
|
@@ -271,38 +272,39 @@ bool mp_obj_exception_match(mp_obj_t exc, const mp_obj_type_t *exc_type) { |
271 | 272 | return mp_binary_op(MP_BINARY_OP_EXCEPTION_MATCH, exc, (mp_obj_t)exc_type) == mp_const_true; |
272 | 273 | } |
273 | 274 |
|
274 | | -void mp_obj_exception_clear_traceback(mp_obj_t self_in) { |
275 | | - // make sure self_in is an exception instance |
276 | | - // TODO add traceback information to user-defined exceptions (need proper builtin subclassing for that) |
277 | | - if (mp_obj_get_type(self_in)->make_new == mp_obj_exception_make_new) { |
278 | | - mp_obj_exception_t *self = self_in; |
279 | | - |
280 | | - // just set the traceback to the null object |
281 | | - // we don't want to call any memory management functions here |
282 | | - self->traceback = MP_OBJ_NULL; |
| 275 | +// traceback handling functions |
| 276 | + |
| 277 | +#define GET_NATIVE_EXCEPTION(self, self_in) \ |
| 278 | + /* make sure self_in is an exception instance */ \ |
| 279 | + assert(mp_obj_is_exception_instance(self_in)); \ |
| 280 | + mp_obj_exception_t *self; \ |
| 281 | + if (mp_obj_is_native_exception_instance(self_in)) { \ |
| 282 | + self = self_in; \ |
| 283 | + } else { \ |
| 284 | + self = ((mp_obj_instance_t*)self_in)->subobj[0]; \ |
283 | 285 | } |
| 286 | + |
| 287 | +void mp_obj_exception_clear_traceback(mp_obj_t self_in) { |
| 288 | + GET_NATIVE_EXCEPTION(self, self_in); |
| 289 | + // just set the traceback to the null object |
| 290 | + // we don't want to call any memory management functions here |
| 291 | + self->traceback = MP_OBJ_NULL; |
284 | 292 | } |
285 | 293 |
|
286 | 294 | void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, machine_uint_t line, qstr block) { |
287 | | - // make sure self_in is an exception instance |
288 | | - // TODO add traceback information to user-defined exceptions (need proper builtin subclassing for that) |
289 | | - if (mp_obj_get_type(self_in)->make_new == mp_obj_exception_make_new && self_in != &mp_emergency_exception_obj) { |
290 | | - mp_obj_exception_t *self = self_in; |
291 | | - |
292 | | - // for traceback, we are just using the list object for convenience, it's not really a list of Python objects |
293 | | - if (self->traceback == MP_OBJ_NULL) { |
294 | | - self->traceback = mp_obj_new_list(0, NULL); |
295 | | - } |
296 | | - mp_obj_list_append(self->traceback, (mp_obj_t)(machine_uint_t)file); |
297 | | - mp_obj_list_append(self->traceback, (mp_obj_t)(machine_uint_t)line); |
298 | | - mp_obj_list_append(self->traceback, (mp_obj_t)(machine_uint_t)block); |
| 295 | + GET_NATIVE_EXCEPTION(self, self_in); |
| 296 | + |
| 297 | + // for traceback, we are just using the list object for convenience, it's not really a list of Python objects |
| 298 | + if (self->traceback == MP_OBJ_NULL) { |
| 299 | + self->traceback = mp_obj_new_list(0, NULL); |
299 | 300 | } |
| 301 | + mp_obj_list_append(self->traceback, (mp_obj_t)(machine_uint_t)file); |
| 302 | + mp_obj_list_append(self->traceback, (mp_obj_t)(machine_uint_t)line); |
| 303 | + mp_obj_list_append(self->traceback, (mp_obj_t)(machine_uint_t)block); |
300 | 304 | } |
301 | 305 |
|
302 | 306 | void mp_obj_exception_get_traceback(mp_obj_t self_in, machine_uint_t *n, machine_uint_t **values) { |
303 | | - // make sure self_in is an exception instance |
304 | | - assert(mp_obj_get_type(self_in)->make_new == mp_obj_exception_make_new); |
305 | | - mp_obj_exception_t *self = self_in; |
| 307 | + GET_NATIVE_EXCEPTION(self, self_in); |
306 | 308 |
|
307 | 309 | if (self->traceback == MP_OBJ_NULL) { |
308 | 310 | *n = 0; |
|
0 commit comments