183
183
#define TRACE_TICK (current_ip , current_sp , is_exception )
184
184
#endif // MICROPY_PY_SYS_SETTRACE
185
185
186
+ STATIC mp_obj_t get_active_exception (mp_exc_stack_t * exc_sp , mp_exc_stack_t * exc_stack ) {
187
+ for (mp_exc_stack_t * e = exc_sp ; e >= exc_stack ; -- e ) {
188
+ if (e -> prev_exc != NULL ) {
189
+ return MP_OBJ_FROM_PTR (e -> prev_exc );
190
+ }
191
+ }
192
+ return MP_OBJ_NULL ;
193
+ }
194
+
186
195
// fastn has items in reverse order (fastn[0] is local[0], fastn[-1] is local[1], etc)
187
196
// sp points to bottom of stack which grows up
188
197
// returns:
@@ -1129,13 +1138,7 @@ unwind_jump:;
1129
1138
ENTRY (MP_BC_RAISE_LAST ): {
1130
1139
MARK_EXC_IP_SELECTIVE ();
1131
1140
// search for the inner-most previous exception, to reraise it
1132
- mp_obj_t obj = MP_OBJ_NULL ;
1133
- for (mp_exc_stack_t * e = exc_sp ; e >= exc_stack ; -- e ) {
1134
- if (e -> prev_exc != NULL ) {
1135
- obj = MP_OBJ_FROM_PTR (e -> prev_exc );
1136
- break ;
1137
- }
1138
- }
1141
+ mp_obj_t obj = get_active_exception (exc_sp , exc_stack );
1139
1142
if (obj == MP_OBJ_NULL ) {
1140
1143
obj = mp_obj_new_exception_msg (& mp_type_RuntimeError , MP_ERROR_TEXT ("no active exception to reraise" ));
1141
1144
}
@@ -1145,14 +1148,30 @@ unwind_jump:;
1145
1148
ENTRY (MP_BC_RAISE_OBJ ): {
1146
1149
MARK_EXC_IP_SELECTIVE ();
1147
1150
mp_obj_t obj = mp_make_raise_obj (TOP ());
1151
+ #if MICROPY_CPYTHON_EXCEPTION_CHAIN
1152
+ mp_obj_t active_exception = get_active_exception (exc_sp , exc_stack );
1153
+ if (active_exception != MP_OBJ_NULL ) {
1154
+ mp_store_attr (obj , MP_QSTR___context__ , active_exception );
1155
+ }
1156
+ #endif
1148
1157
RAISE (obj );
1149
1158
}
1150
1159
1151
1160
ENTRY (MP_BC_RAISE_FROM ): {
1152
1161
MARK_EXC_IP_SELECTIVE ();
1153
- mp_warning (NULL , "exception chaining not supported" );
1154
- sp -- ; // ignore (pop) "from" argument
1162
+ mp_obj_t cause = POP ();
1155
1163
mp_obj_t obj = mp_make_raise_obj (TOP ());
1164
+ #if MICROPY_CPYTHON_EXCEPTION_CHAIN
1165
+ // search for the inner-most previous exception, to chain it
1166
+ mp_obj_t active_exception = get_active_exception (exc_sp , exc_stack );
1167
+ if (active_exception != MP_OBJ_NULL ) {
1168
+ mp_store_attr (obj , MP_QSTR___context__ , active_exception );
1169
+ }
1170
+ mp_store_attr (obj , MP_QSTR___cause__ , cause );
1171
+ #else
1172
+ (void )cause ;
1173
+ mp_warning (NULL , "exception chaining not supported" );
1174
+ #endif
1156
1175
RAISE (obj );
1157
1176
}
1158
1177
0 commit comments