1111#include "runtime.h"
1212#include "runtime0.h"
1313
14- // This is unified class for C-level and Python-level exceptions
15- // Python-level exceptions have empty ->msg and all arguments are in
16- // args tuple. C-level exceptions likely have ->msg set, and args is empty.
1714typedef struct _mp_obj_exception_t {
1815 mp_obj_base_t base ;
1916 mp_obj_t traceback ; // a list object, holding (file,line,block) as numbers (not Python objects); a hack for now
20- vstr_t * msg ;
2117 mp_obj_tuple_t args ;
2218} mp_obj_exception_t ;
2319
2420// Instance of GeneratorExit exception - needed by generator.close()
2521// This would belong to objgenerator.c, but to keep mp_obj_exception_t
2622// definition module-private so far, have it here.
27- const mp_obj_exception_t mp_const_GeneratorExit_obj = {{& mp_type_GeneratorExit }, MP_OBJ_NULL , NULL , {{& mp_type_tuple }, 0 }};
23+ const mp_obj_exception_t mp_const_GeneratorExit_obj = {{& mp_type_GeneratorExit }, MP_OBJ_NULL , {{& mp_type_tuple }, 0 }};
2824
2925STATIC void mp_obj_exception_print (void (* print )(void * env , const char * fmt , ...), void * env , mp_obj_t o_in , mp_print_kind_t kind ) {
3026 mp_obj_exception_t * o = o_in ;
31- if (o -> msg != NULL ) {
32- print (env , "%s: %s" , qstr_str (o -> base .type -> name ), vstr_str (o -> msg ));
33- } else {
34- // Yes, that's how CPython has it
35- // TODO now that exceptions are classes and instances, I think this needs to be changed to match CPython
36- if (kind == PRINT_REPR ) {
37- print (env , "%s" , qstr_str (o -> base .type -> name ));
38- }
39- if (kind == PRINT_STR ) {
40- if (o -> args .len == 0 ) {
41- print (env , "" );
42- return ;
43- } else if (o -> args .len == 1 ) {
44- mp_obj_print_helper (print , env , o -> args .items [0 ], PRINT_STR );
45- return ;
46- }
27+ if (kind == PRINT_REPR ) {
28+ print (env , "%s" , qstr_str (o -> base .type -> name ));
29+ } else if (kind == PRINT_EXC ) {
30+ print (env , "%s: " , qstr_str (o -> base .type -> name ));
31+ }
32+ if (kind == PRINT_STR || kind == PRINT_EXC ) {
33+ if (o -> args .len == 0 ) {
34+ print (env , "" );
35+ return ;
36+ } else if (o -> args .len == 1 ) {
37+ mp_obj_print_helper (print , env , o -> args .items [0 ], PRINT_STR );
38+ return ;
4739 }
48- tuple_print (print , env , & o -> args , kind );
4940 }
41+ tuple_print (print , env , & o -> args , kind );
5042}
5143
5244STATIC mp_obj_t mp_obj_exception_make_new (mp_obj_t type_in , uint n_args , uint n_kw , const mp_obj_t * args ) {
@@ -59,7 +51,6 @@ STATIC mp_obj_t mp_obj_exception_make_new(mp_obj_t type_in, uint n_args, uint n_
5951 mp_obj_exception_t * o = m_new_obj_var (mp_obj_exception_t , mp_obj_t , n_args );
6052 o -> base .type = type ;
6153 o -> traceback = MP_OBJ_NULL ;
62- o -> msg = NULL ;
6354 o -> args .base .type = & mp_type_tuple ;
6455 o -> args .len = n_args ;
6556 memcpy (o -> args .items , args , n_args * sizeof (mp_obj_t ));
@@ -185,7 +176,7 @@ MP_DEFINE_EXCEPTION(Exception, BaseException)
185176 */
186177
187178mp_obj_t mp_obj_new_exception (const mp_obj_type_t * exc_type ) {
188- return mp_obj_new_exception_msg_varg (exc_type , NULL );
179+ return mp_obj_new_exception_args (exc_type , 0 , NULL );
189180}
190181
191182mp_obj_t mp_obj_new_exception_args (const mp_obj_type_t * exc_type , uint n_args , const mp_obj_t * args ) {
@@ -202,22 +193,25 @@ mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const char
202193 assert (exc_type -> make_new == mp_obj_exception_make_new );
203194
204195 // make exception object
205- mp_obj_exception_t * o = m_new_obj_var (mp_obj_exception_t , mp_obj_t , 0 );
196+ mp_obj_exception_t * o = m_new_obj_var (mp_obj_exception_t , mp_obj_t , 1 );
206197 o -> base .type = exc_type ;
207198 o -> traceback = MP_OBJ_NULL ;
208199 o -> args .base .type = & mp_type_tuple ;
209- o -> args .len = 0 ;
200+ o -> args .len = 1 ;
210201
211202 if (fmt == NULL ) {
212203 // no message
213- o -> msg = NULL ;
204+ assert ( 0 ) ;
214205 } else {
215- // render exception message
216- o -> msg = vstr_new ();
206+ // render exception message and store as .args[0]
207+ // TODO: optimize bufferbloat
208+ vstr_t * vstr = vstr_new ();
217209 va_list ap ;
218210 va_start (ap , fmt );
219- vstr_vprintf (o -> msg , fmt , ap );
211+ vstr_vprintf (vstr , fmt , ap );
220212 va_end (ap );
213+ o -> args .items [0 ] = mp_obj_new_str ((byte * )vstr -> buf , vstr -> len , false);
214+ vstr_free (vstr );
221215 }
222216
223217 return o ;
0 commit comments