mirror of
https://github.com/micropython/micropython.git
synced 2026-01-04 19:20:22 +01:00
Commit ffa98cb014 improved equality for
`JsProxy` objects so that, eg, `js.Object == js.Object` is true.
As mentioned in #17758, a further optimisation is to make identity work in
that case, eg `js.Object is js.Object` should be true (on the Python side).
This commit implements that, by keeping track of all `JsProxy` Python
objects and reusing them where possible: where the underlying JS ref is
equal, ie they point to the same JS object. That reduces memory churn and
gives better identity behaviour of JS objects proxied over to Python.
As part of this, a bug is fixed where JS objects can be freed while there's
still a `JsProxy` referring to that JS object. A test is added for that
exact scenario, and the test now passes.
Signed-off-by: Damien George <damien@micropython.org>
49 lines
1.2 KiB
JavaScript
49 lines
1.2 KiB
JavaScript
// Test reuse of JsProxy references and freeing of JsProxy objects.
|
|
// This ensures that a Python-side JsProxy that refers to a JavaScript object retains
|
|
// the correct JavaScript object in the case that another JsProxy that refers to the
|
|
// same JavaScript object is freed.
|
|
|
|
const mp = await (await import(process.argv[2])).loadMicroPython();
|
|
|
|
globalThis.obj = [1, 2];
|
|
globalThis.obj2 = [3, 4];
|
|
|
|
console.log("JS obj:", globalThis.obj);
|
|
|
|
mp.runPython(`
|
|
import gc
|
|
import js
|
|
|
|
# Create 2 proxies of the same JS object.
|
|
# They should refer to the same underlying JS-side reference.
|
|
obj = js.obj
|
|
obj_copy = js.obj
|
|
print(obj, obj_copy, obj == obj_copy)
|
|
|
|
# Print out the object.
|
|
js.console.log("Py obj:", obj)
|
|
|
|
# Forget obj_copy and trigger a GC when the Python code finishes.
|
|
obj_copy = None
|
|
gc.collect()
|
|
`);
|
|
|
|
console.log("JS obj:", globalThis.obj);
|
|
|
|
mp.runPython(`
|
|
# Create a new proxy of a different object.
|
|
# It should not clobber the existing obj proxy reference.
|
|
obj2 = js.obj2
|
|
|
|
# Create a copy of the existing obj proxy.
|
|
obj_copy = js.obj
|
|
|
|
# Print the JS proxy, it should be the same reference as before.
|
|
print(obj, obj_copy, obj == obj_copy)
|
|
|
|
# Print out the object.
|
|
js.console.log("Py obj:", obj)
|
|
`);
|
|
|
|
console.log("JS obj:", globalThis.obj);
|