|
32 | 32 | #include "py/runtime.h"
|
33 | 33 | #include "proxy_c.h"
|
34 | 34 |
|
| 35 | +// Number of static entries at the start of proxy_c_ref. |
| 36 | +#define PROXY_C_REF_NUM_STATIC (1) |
| 37 | + |
35 | 38 | // These constants should match the constants in proxy_js.js.
|
36 | 39 |
|
37 | 40 | enum {
|
@@ -71,23 +74,50 @@ static const mp_obj_base_t mp_const_undefined_obj = {&mp_type_undefined};
|
71 | 74 |
|
72 | 75 | MP_DEFINE_EXCEPTION(JsException, Exception)
|
73 | 76 |
|
| 77 | +// Index to start searching for the next available slot in proxy_c_ref. |
| 78 | +static size_t proxy_c_ref_next; |
| 79 | + |
74 | 80 | void proxy_c_init(void) {
|
75 | 81 | MP_STATE_PORT(proxy_c_ref) = mp_obj_new_list(0, NULL);
|
76 | 82 | mp_obj_list_append(MP_STATE_PORT(proxy_c_ref), MP_OBJ_NULL);
|
| 83 | + proxy_c_ref_next = PROXY_C_REF_NUM_STATIC; |
77 | 84 | }
|
78 | 85 |
|
79 | 86 | MP_REGISTER_ROOT_POINTER(mp_obj_t proxy_c_ref);
|
80 | 87 |
|
| 88 | +// obj cannot be MP_OBJ_NULL. |
81 | 89 | static inline size_t proxy_c_add_obj(mp_obj_t obj) {
|
82 |
| - size_t id = ((mp_obj_list_t *)MP_OBJ_TO_PTR(MP_STATE_PORT(proxy_c_ref)))->len; |
| 90 | + // Search for the first free slot in proxy_c_ref. |
| 91 | + mp_obj_list_t *l = (mp_obj_list_t *)MP_OBJ_TO_PTR(MP_STATE_PORT(proxy_c_ref)); |
| 92 | + while (proxy_c_ref_next < l->len) { |
| 93 | + if (l->items[proxy_c_ref_next] == MP_OBJ_NULL) { |
| 94 | + // Free slot found, reuse it. |
| 95 | + size_t id = proxy_c_ref_next; |
| 96 | + ++proxy_c_ref_next; |
| 97 | + l->items[id] = obj; |
| 98 | + return id; |
| 99 | + } |
| 100 | + ++proxy_c_ref_next; |
| 101 | + } |
| 102 | + |
| 103 | + // No free slots, so grow proxy_c_ref by one (append at the end of the list). |
| 104 | + size_t id = l->len; |
83 | 105 | mp_obj_list_append(MP_STATE_PORT(proxy_c_ref), obj);
|
| 106 | + proxy_c_ref_next = l->len; |
84 | 107 | return id;
|
85 | 108 | }
|
86 | 109 |
|
87 | 110 | static inline mp_obj_t proxy_c_get_obj(uint32_t c_ref) {
|
88 | 111 | return ((mp_obj_list_t *)MP_OBJ_TO_PTR(MP_STATE_PORT(proxy_c_ref)))->items[c_ref];
|
89 | 112 | }
|
90 | 113 |
|
| 114 | +void proxy_c_free_obj(uint32_t c_ref) { |
| 115 | + if (c_ref >= PROXY_C_REF_NUM_STATIC) { |
| 116 | + ((mp_obj_list_t *)MP_OBJ_TO_PTR(MP_STATE_PORT(proxy_c_ref)))->items[c_ref] = MP_OBJ_NULL; |
| 117 | + proxy_c_ref_next = MIN(proxy_c_ref_next, c_ref); |
| 118 | + } |
| 119 | +} |
| 120 | + |
91 | 121 | mp_obj_t proxy_convert_js_to_mp_obj_cside(uint32_t *value) {
|
92 | 122 | if (value[0] == PROXY_KIND_JS_UNDEFINED) {
|
93 | 123 | return mp_const_undefined;
|
|
0 commit comments