Content-Length: 467264 | pFad | http://github.com/micropython/micropython/commit/5c7a414574f06cf50ee9edec449f35f6740a1261

C7 webassembly: Add C-level finaliser to JsProxy object. · micropython/micropython@5c7a414 · GitHub
Skip to content

Commit 5c7a414

Browse files
committed
webassembly: Add C-level finaliser to JsProxy object.
And clear the corresponding `proxy_js_ref[js_ref]` entry when the finaliser runs. This then allows the JavaScript side to (eventually) free the corresponding JavaScript object. Signed-off-by: Damien George <damien@micropython.org>
1 parent c0ca4bb commit 5c7a414

File tree

2 files changed

+49
-6
lines changed

2 files changed

+49
-6
lines changed

Diff for: ports/webassembly/objjsproxy.c

+22-2
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,22 @@ static mp_obj_t jsproxy_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const
234234
}
235235
}
236236

237+
EM_JS(void, proxy_js_free_obj, (int js_ref), {
238+
if (js_ref >= PROXY_JS_REF_NUM_STATIC) {
239+
proxy_js_ref[js_ref] = undefined;
240+
if (js_ref < proxy_js_ref_next) {
241+
proxy_js_ref_next = js_ref;
242+
}
243+
}
244+
});
245+
246+
static mp_obj_t jsproxy___del__(mp_obj_t self_in) {
247+
mp_obj_jsproxy_t *self = MP_OBJ_TO_PTR(self_in);
248+
proxy_js_free_obj(self->ref);
249+
return mp_const_none;
250+
}
251+
static MP_DEFINE_CONST_FUN_OBJ_1(jsproxy___del___obj, jsproxy___del__);
252+
237253
static mp_obj_t jsproxy_reflect_construct(size_t n_args, const mp_obj_t *args) {
238254
int arg0 = mp_obj_jsproxy_get_ref(args[0]);
239255
n_args -= 1;
@@ -274,7 +290,11 @@ void mp_obj_jsproxy_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
274290
if (dest[0] == MP_OBJ_NULL) {
275291
// Load attribute.
276292
uint32_t out[PVN];
277-
if (lookup_attr(self->ref, qstr_str(attr), out)) {
293+
if (attr == MP_QSTR___del__) {
294+
// For finaliser.
295+
dest[0] = MP_OBJ_FROM_PTR(&jsproxy___del___obj);
296+
dest[1] = self_in;
297+
} else if (lookup_attr(self->ref, qstr_str(attr), out)) {
278298
dest[0] = proxy_convert_js_to_mp_obj_cside(out);
279299
} else if (attr == MP_QSTR_new) {
280300
// Special case to handle construction of JS objects.
@@ -515,7 +535,7 @@ MP_DEFINE_CONST_OBJ_TYPE(
515535
);
516536

517537
mp_obj_t mp_obj_new_jsproxy(int ref) {
518-
mp_obj_jsproxy_t *o = mp_obj_malloc(mp_obj_jsproxy_t, &mp_type_jsproxy);
538+
mp_obj_jsproxy_t *o = mp_obj_malloc_with_finaliser(mp_obj_jsproxy_t, &mp_type_jsproxy);
519539
o->ref = ref;
520540
return MP_OBJ_FROM_PTR(o);
521541
}

Diff for: ports/webassembly/proxy_js.js

+27-4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
* THE SOFTWARE.
2525
*/
2626

27+
// Number of static entries at the start of proxy_js_ref.
28+
const PROXY_JS_REF_NUM_STATIC = 2;
29+
2730
// These constants should match the constants in proxy_c.c.
2831

2932
const PROXY_KIND_MP_EXCEPTION = -1;
@@ -57,6 +60,28 @@ class PythonError extends Error {
5760

5861
function proxy_js_init() {
5962
globalThis.proxy_js_ref = [globalThis, undefined];
63+
globalThis.proxy_js_ref_next = PROXY_JS_REF_NUM_STATIC;
64+
}
65+
66+
// js_obj cannot be undefined
67+
function proxy_js_add_obj(js_obj) {
68+
// Search for the first free slot in proxy_js_ref.
69+
while (proxy_js_ref_next < proxy_js_ref.length) {
70+
if (proxy_js_ref[proxy_js_ref_next] === undefined) {
71+
// Free slot found, reuse it.
72+
const id = proxy_js_ref_next;
73+
++proxy_js_ref_next;
74+
proxy_js_ref[id] = js_obj;
75+
return id;
76+
}
77+
++proxy_js_ref_next;
78+
}
79+
80+
// No free slots, so grow proxy_js_ref by one (append at the end of the array).
81+
const id = proxy_js_ref.length;
82+
proxy_js_ref[id] = js_obj;
83+
proxy_js_ref_next = proxy_js_ref.length;
84+
return id;
6085
}
6186

6287
function proxy_call_python(target, argumentsList) {
@@ -147,8 +172,7 @@ function proxy_convert_js_to_mp_obj_jsside(js_obj, out) {
147172
Module.setValue(out + 4, js_obj._ref, "i32");
148173
} else {
149174
kind = PROXY_KIND_JS_OBJECT;
150-
const id = proxy_js_ref.length;
151-
proxy_js_ref[id] = js_obj;
175+
const id = proxy_js_add_obj(js_obj);
152176
Module.setValue(out + 4, id, "i32");
153177
}
154178
Module.setValue(out + 0, kind, "i32");
@@ -161,8 +185,7 @@ function proxy_convert_js_to_mp_obj_jsside_force_double_proxy(js_obj, out) {
161185
js_obj instanceof PyProxyThenable
162186
) {
163187
const kind = PROXY_KIND_JS_OBJECT;
164-
const id = proxy_js_ref.length;
165-
proxy_js_ref[id] = js_obj;
188+
const id = proxy_js_add_obj(js_obj);
166189
Module.setValue(out + 4, id, "i32");
167190
Module.setValue(out + 0, kind, "i32");
168191
} else {

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/5c7a414574f06cf50ee9edec449f35f6740a1261

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy