summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/webassembly/objjsproxy.c10
-rw-r--r--tests/ports/webassembly/js_proxy_attribute.mjs34
-rw-r--r--tests/ports/webassembly/js_proxy_attribute.mjs.exp9
3 files changed, 51 insertions, 2 deletions
diff --git a/ports/webassembly/objjsproxy.c b/ports/webassembly/objjsproxy.c
index cbfe8be49..167d4382b 100644
--- a/ports/webassembly/objjsproxy.c
+++ b/ports/webassembly/objjsproxy.c
@@ -46,8 +46,14 @@ EM_JS(bool, has_attr, (int jsref, const char *str), {
EM_JS(bool, lookup_attr, (int jsref, const char *str, uint32_t * out), {
const base = proxy_js_ref[jsref];
const attr = UTF8ToString(str);
- if (attr in base) {
- let value = base[attr];
+
+ // Attempt to lookup the requested attribute from the base object:
+ // - If the value is not `undefined` then the attribute exists with that value.
+ // - Otherwise if the value is `undefined` and the `in` operator returns true, then
+ // that attribute does exist and is intended to have a value of `undefined`.
+ // - Otherwise, the attribute does not exist.
+ let value = base[attr];
+ if (value !== undefined || attr in base) {
if (typeof value === "function") {
if (base !== globalThis) {
if ("_ref" in value) {
diff --git a/tests/ports/webassembly/js_proxy_attribute.mjs b/tests/ports/webassembly/js_proxy_attribute.mjs
new file mode 100644
index 000000000..5d9501227
--- /dev/null
+++ b/tests/ports/webassembly/js_proxy_attribute.mjs
@@ -0,0 +1,34 @@
+// Test lookup of attributes on JsProxy objects.
+
+const mp = await (await import(process.argv[2])).loadMicroPython();
+
+// Simple attribute names and values.
+globalThis.obj1 = { a: 1, b: 2 };
+
+// Unconventional attribute names and values.
+globalThis.obj2 = { undefined: "undefined", undef: undefined };
+
+// Dynamically created attribute names and values.
+globalThis.obj3 = new Proxy(new Map(), {
+ get(map, name) {
+ if (!map.has(name)) {
+ console.log("creating attribute", name);
+ map.set(name, name);
+ }
+ return map.get(name);
+ },
+});
+
+mp.runPython(`
+import js
+
+print(js.obj1.a, js.obj1.b)
+print(js.obj1["a"], js.obj1["b"])
+
+print(js.obj2.undefined, js.obj2.undef)
+
+print(js.obj3.c)
+print(js.obj3["c"])
+print(hasattr(js.obj3, "d"))
+print(js.obj3.d)
+`);
diff --git a/tests/ports/webassembly/js_proxy_attribute.mjs.exp b/tests/ports/webassembly/js_proxy_attribute.mjs.exp
new file mode 100644
index 000000000..7de85a566
--- /dev/null
+++ b/tests/ports/webassembly/js_proxy_attribute.mjs.exp
@@ -0,0 +1,9 @@
+1 2
+1 2
+undefined <undefined>
+creating attribute c
+c
+c
+creating attribute d
+True
+d