objexcept: Optimize traceback allocation for exception.

Traceback allocation for exception will now never lead to recursive
MemoryError exception - if there's no memory for traceback, it simply
won't be created.
This commit is contained in:
Paul Sokolovsky 2015-02-15 22:24:03 +03:00
parent 29c4f92e13
commit fa3b895145
3 changed files with 29 additions and 4 deletions

View File

@ -436,11 +436,15 @@ void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, mp_uint_t line,
// 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);
self->traceback = mp_obj_new_list_maybe(3);
if (self->traceback == MP_OBJ_NULL) {
return;
}
}
mp_obj_list_append(self->traceback, (mp_obj_t)(mp_uint_t)file);
mp_obj_list_append(self->traceback, (mp_obj_t)(mp_uint_t)line);
mp_obj_list_append(self->traceback, (mp_obj_t)(mp_uint_t)block);
mp_obj_list_t *list = self->traceback;
list->items[0] = (mp_obj_t)(mp_uint_t)file;
list->items[1] = (mp_obj_t)(mp_uint_t)line;
list->items[2] = (mp_obj_t)(mp_uint_t)block;
}
void mp_obj_exception_get_traceback(mp_obj_t self_in, mp_uint_t *n, mp_uint_t **values) {

View File

@ -477,6 +477,25 @@ mp_obj_t mp_obj_new_list(mp_uint_t n, mp_obj_t *items) {
return o;
}
// Special method for usage with exceptions
// Doesn't initialize items, assumes they will be initialized by client.
mp_obj_t mp_obj_new_list_maybe(mp_uint_t n) {
mp_obj_list_t *o = m_new_obj_maybe(mp_obj_list_t);
if (!o) {
return o;
}
o->items = m_new_maybe(mp_obj_t, n);
if (!o->items) {
m_del_obj(mp_obj_list_t, o);
return MP_OBJ_NULL;
}
o->base.type = &mp_type_list;
o->len = o->alloc = n;
return o;
}
void mp_obj_list_get(mp_obj_t self_in, mp_uint_t *len, mp_obj_t **items) {
mp_obj_list_t *self = self_in;
*len = self->len;

View File

@ -35,4 +35,6 @@ typedef struct _mp_obj_list_t {
mp_obj_t *items;
} mp_obj_list_t;
mp_obj_t mp_obj_new_list_maybe(mp_uint_t n);
#endif // __MICROPY_INCLUDED_PY_OBJLIST_H__