diff options
Diffstat (limited to 'py/objexcept.c')
-rw-r--r-- | py/objexcept.c | 67 |
1 files changed, 37 insertions, 30 deletions
diff --git a/py/objexcept.c b/py/objexcept.c index 160cf09fd4..abf56ab036 100644 --- a/py/objexcept.c +++ b/py/objexcept.c @@ -2,12 +2,13 @@ #include <stdarg.h> #include <assert.h> +#include "mpconfig.h" #include "nlr.h" #include "misc.h" -#include "mpconfig.h" #include "qstr.h" #include "obj.h" #include "objtuple.h" +#include "objtype.h" #include "runtime.h" #include "runtime0.h" @@ -30,12 +31,17 @@ const mp_obj_exception_t mp_const_GeneratorExit_obj = {{&mp_type_GeneratorExit}, STATIC void mp_obj_exception_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) { mp_obj_exception_t *o = o_in; - if (kind == PRINT_REPR) { + mp_print_kind_t k = kind & ~PRINT_EXC_SUBCLASS; + bool is_subclass = kind & PRINT_EXC_SUBCLASS; + if (!is_subclass && (k == PRINT_REPR || k == PRINT_EXC)) { print(env, "%s", qstr_str(o->base.type->name)); - } else if (kind == PRINT_EXC) { - print(env, "%s: ", qstr_str(o->base.type->name)); } - if (kind == PRINT_STR || kind == PRINT_EXC) { + + if (k == PRINT_EXC) { + print(env, ": "); + } + + if (k == PRINT_STR || k == PRINT_EXC) { if (o->args == NULL || o->args->len == 0) { print(env, ""); return; @@ -47,7 +53,7 @@ STATIC void mp_obj_exception_print(void (*print)(void *env, const char *fmt, ... tuple_print(print, env, o->args, kind); } -STATIC mp_obj_t mp_obj_exception_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { +mp_obj_t mp_obj_exception_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { mp_obj_type_t *type = type_in; if (n_kw != 0) { @@ -266,38 +272,39 @@ bool mp_obj_exception_match(mp_obj_t exc, const mp_obj_type_t *exc_type) { return mp_binary_op(MP_BINARY_OP_EXCEPTION_MATCH, exc, (mp_obj_t)exc_type) == mp_const_true; } -void mp_obj_exception_clear_traceback(mp_obj_t self_in) { - // make sure self_in is an exception instance - // TODO add traceback information to user-defined exceptions (need proper builtin subclassing for that) - if (mp_obj_get_type(self_in)->make_new == mp_obj_exception_make_new) { - mp_obj_exception_t *self = self_in; - - // just set the traceback to the null object - // we don't want to call any memory management functions here - self->traceback = MP_OBJ_NULL; +// traceback handling functions + +#define GET_NATIVE_EXCEPTION(self, self_in) \ + /* make sure self_in is an exception instance */ \ + assert(mp_obj_is_exception_instance(self_in)); \ + mp_obj_exception_t *self; \ + if (mp_obj_is_native_exception_instance(self_in)) { \ + self = self_in; \ + } else { \ + self = ((mp_obj_instance_t*)self_in)->subobj[0]; \ } + +void mp_obj_exception_clear_traceback(mp_obj_t self_in) { + GET_NATIVE_EXCEPTION(self, self_in); + // just set the traceback to the null object + // we don't want to call any memory management functions here + self->traceback = MP_OBJ_NULL; } void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, machine_uint_t line, qstr block) { - // make sure self_in is an exception instance - // TODO add traceback information to user-defined exceptions (need proper builtin subclassing for that) - if (mp_obj_get_type(self_in)->make_new == mp_obj_exception_make_new && self_in != &mp_emergency_exception_obj) { - mp_obj_exception_t *self = self_in; - - // for traceback, we are just using the list object for convenience, it's not really a list of Python objects - if (self->traceback == MP_OBJ_NULL) { - self->traceback = mp_obj_new_list(0, NULL); - } - mp_obj_list_append(self->traceback, (mp_obj_t)(machine_uint_t)file); - mp_obj_list_append(self->traceback, (mp_obj_t)(machine_uint_t)line); - mp_obj_list_append(self->traceback, (mp_obj_t)(machine_uint_t)block); + GET_NATIVE_EXCEPTION(self, self_in); + + // for traceback, we are just using the list object for convenience, it's not really a list of Python objects + if (self->traceback == MP_OBJ_NULL) { + self->traceback = mp_obj_new_list(0, NULL); } + mp_obj_list_append(self->traceback, (mp_obj_t)(machine_uint_t)file); + mp_obj_list_append(self->traceback, (mp_obj_t)(machine_uint_t)line); + mp_obj_list_append(self->traceback, (mp_obj_t)(machine_uint_t)block); } void mp_obj_exception_get_traceback(mp_obj_t self_in, machine_uint_t *n, machine_uint_t **values) { - // make sure self_in is an exception instance - assert(mp_obj_get_type(self_in)->make_new == mp_obj_exception_make_new); - mp_obj_exception_t *self = self_in; + GET_NATIVE_EXCEPTION(self, self_in); if (self->traceback == MP_OBJ_NULL) { *n = 0; |