Content-Length: 438594 | pFad | http://github.com/micropython/micropython/commit/57a9ffa6320bc9e5c7979a7f35c7de7a18f74720

E1 webassembly: Register PyProxy objects for JS-side finalisation. · micropython/micropython@57a9ffa · GitHub
Skip to content

Commit 57a9ffa

Browse files
committed
webassembly: Register PyProxy objects for JS-side finalisation.
And clear the corresponding `proxy_c_ref[c_ref]` entry when the finaliser runs. This then allows the C side to (eventually) garbage collect the corresponding Python object. Signed-off-by: Damien George <damien@micropython.org>
1 parent 5c7a414 commit 57a9ffa

File tree

3 files changed

+38
-1
lines changed

3 files changed

+38
-1
lines changed

Diff for: ports/webassembly/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ EXPORTED_FUNCTIONS_EXTRA += ,\
5454
_mp_js_do_exec_async,\
5555
_mp_js_do_import,\
5656
_mp_js_register_js_module,\
57+
_proxy_c_free_obj,\
5758
_proxy_c_init,\
5859
_proxy_c_to_js_call,\
5960
_proxy_c_to_js_delete_attr,\

Diff for: ports/webassembly/proxy_c.c

+31-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@
3232
#include "py/runtime.h"
3333
#include "proxy_c.h"
3434

35+
// Number of static entries at the start of proxy_c_ref.
36+
#define PROXY_C_REF_NUM_STATIC (1)
37+
3538
// These constants should match the constants in proxy_js.js.
3639

3740
enum {
@@ -71,23 +74,50 @@ static const mp_obj_base_t mp_const_undefined_obj = {&mp_type_undefined};
7174

7275
MP_DEFINE_EXCEPTION(JsException, Exception)
7376

77+
// Index to start searching for the next available slot in proxy_c_ref.
78+
static size_t proxy_c_ref_next;
79+
7480
void proxy_c_init(void) {
7581
MP_STATE_PORT(proxy_c_ref) = mp_obj_new_list(0, NULL);
7682
mp_obj_list_append(MP_STATE_PORT(proxy_c_ref), MP_OBJ_NULL);
83+
proxy_c_ref_next = PROXY_C_REF_NUM_STATIC;
7784
}
7885

7986
MP_REGISTER_ROOT_POINTER(mp_obj_t proxy_c_ref);
8087

88+
// obj cannot be MP_OBJ_NULL.
8189
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;
83105
mp_obj_list_append(MP_STATE_PORT(proxy_c_ref), obj);
106+
proxy_c_ref_next = l->len;
84107
return id;
85108
}
86109

87110
static inline mp_obj_t proxy_c_get_obj(uint32_t c_ref) {
88111
return ((mp_obj_list_t *)MP_OBJ_TO_PTR(MP_STATE_PORT(proxy_c_ref)))->items[c_ref];
89112
}
90113

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+
91121
mp_obj_t proxy_convert_js_to_mp_obj_cside(uint32_t *value) {
92122
if (value[0] == PROXY_KIND_JS_UNDEFINED) {
93123
return mp_const_undefined;

Diff for: ports/webassembly/proxy_js.js

+6
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ class PythonError extends Error {
6161
function proxy_js_init() {
6262
globalThis.proxy_js_ref = [globalThis, undefined];
6363
globalThis.proxy_js_ref_next = PROXY_JS_REF_NUM_STATIC;
64+
globalThis.pyProxyFinalizationRegistry = new FinalizationRegistry(
65+
(cRef) => {
66+
Module.ccall("proxy_c_free_obj", "null", ["number"], [cRef]);
67+
},
68+
);
6469
}
6570

6671
// js_obj cannot be undefined
@@ -251,6 +256,7 @@ function proxy_convert_mp_to_js_obj_jsside(value) {
251256
const target = new PyProxy(id);
252257
obj = new Proxy(target, py_proxy_handler);
253258
}
259+
globalThis.pyProxyFinalizationRegistry.register(obj, id);
254260
}
255261
return obj;
256262
}

0 commit comments

Comments
 (0)








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/micropython/micropython/commit/57a9ffa6320bc9e5c7979a7f35c7de7a18f74720

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy