3434
3535#if  MICROPY_PY_ATEXIT 
3636
37- typedef  struct  _m_atexit_node_t  {
38-     struct  _m_atexit_node_t  * prev ;
39-     struct  _m_atexit_node_t  * next ;
40-     mp_obj_t  fn ;
41- } m_atexit_node_t ;
42- 
43- // atexit.register(function): Functions are called LIFO when soft-reset / exit is called. 
4437mp_obj_t  mp_atexit_register (mp_obj_t  function ) {
4538    if  (!mp_obj_is_callable (function )) {
4639        mp_raise_ValueError (MP_ERROR_TEXT ("function not callable" ));
4740    }
48-     m_atexit_node_t  * node  =  m_malloc (sizeof (m_atexit_node_t ));
49-     if  (MP_STATE_VM (atexit ) !=  NULL ) {
50-         MP_STATE_VM (atexit )-> prev  =  node ;
41+     if  (MP_STATE_VM (atexit ) ==  NULL ) {
42+         MP_STATE_VM (atexit ) =  mp_obj_new_list (0 , NULL );
5143    }
52-     node -> fn  =  function ;
53-     node -> prev  =  NULL ;
54-     node -> next  =  MP_STATE_VM (atexit );
55-     MP_STATE_VM (atexit ) =  node ;
44+     mp_obj_list_append (MP_OBJ_FROM_PTR (MP_STATE_VM (atexit )), function );
5645    // return the passed in function so this can be used as a decorator 
5746    return  function ;
5847}
5948static  MP_DEFINE_CONST_FUN_OBJ_1 (mp_atexit_register_obj , mp_atexit_register )
6049
6150#if  MICROPY_PY_ATEXIT_UNREGISTER 
6251mp_obj_t  mp_atexit_unregister (mp_obj_t  function ) {
63-     m_atexit_node_t  * node  =  MP_STATE_VM (atexit );
64-     while  (node  !=  NULL ) {
65-         if  (mp_obj_equal (node -> fn , function )) {
66-             if  (node -> next  !=  NULL ) {
67-                 node -> next -> prev  =  node -> prev ;
68-             }
69-             if  (node -> prev  !=  NULL ) {
70-                 node -> prev -> next  =  node -> next ;
71-             } else  {
72-                 MP_STATE_VM (atexit ) =  node -> next ;
73-             }
52+     nlr_buf_t  nlr ;
53+     // ValueError is thrown when function is no longer in the list 
54+     if  (nlr_push (& nlr ) ==  0 ) {
55+         while  (MP_STATE_VM (atexit ) !=  NULL ) {
56+             mp_obj_list_remove (MP_OBJ_FROM_PTR (MP_STATE_VM (atexit )), function );
7457        }
75-         node  =  node -> next ;
7658    }
7759    return  mp_const_none ;
7860}
@@ -86,30 +68,30 @@ static const mp_rom_map_elem_t mp_module_atexit_globals_table[] = {
8668    { MP_ROM_QSTR (MP_QSTR_unregister ), MP_ROM_PTR (& mp_atexit_unregister_obj ) },
8769    #endif 
8870};
89- 
9071static  MP_DEFINE_CONST_DICT (mp_module_atexit_globals , mp_module_atexit_globals_table )
9172
9273const  mp_obj_module_t  mp_module_atexit  =  {
9374    .base  =  { & mp_type_module  },
9475    .globals  =  (mp_obj_dict_t  * )& mp_module_atexit_globals ,
9576};
9677
97- MP_REGISTER_ROOT_POINTER (struct   _m_atexit_node_t   * atexit );
78+ MP_REGISTER_ROOT_POINTER (mp_obj_list_t   *   atexit );
9879MP_REGISTER_MODULE (MP_QSTR_atexit , mp_module_atexit );
9980
10081int  mp_atexit_execute (void ) {
10182    int  exit_code  =  0 ;
102-     // This function is intended to be run by a port during its soft-reset / exit. 
103-     // walk down linked list last in / first out and execute each function. 
104-     // Beware, the sys.settrace function should be disabled before running sys.atexit. 
105-     while  (MP_STATE_VM (atexit ) !=  NULL ) {
106-         nlr_buf_t  nlr ;
107-         if  (nlr_push (& nlr ) ==  0 ) {
108-             mp_call_function_0 (MP_STATE_VM (atexit )-> fn );
109-         } else  {
110-             exit_code  =  pyexec_handle_uncaught_exception (nlr .ret_val );
83+     if  (MP_STATE_VM (atexit ) !=  NULL ) {
84+         mp_obj_list_t  * list  =  MP_STATE_VM (atexit );
85+         for  (size_t  i  =  0 ; i  <  list -> len ; i ++ ) {
86+             mp_obj_t  function  =  list -> items [i ];
87+ 
88+             nlr_buf_t  nlr ;
89+             if  (nlr_push (& nlr ) ==  0 ) {
90+                 mp_call_function_0 (function );
91+             } else  {
92+                 exit_code  =  pyexec_handle_uncaught_exception (nlr .ret_val );
93+             }
11194        }
112-         MP_STATE_VM (atexit ) =  MP_STATE_VM (atexit )-> next ;
11395    }
11496    return  exit_code ;
11597}
0 commit comments