Content-Length: 423228 | pFad | http://github.com/micropython/micropython/commit/a053e639147d97c4a306ab272c12d9520a80e805

D6 webassembly/objjsproxy: Implement proxying of JS iterable protocol. · micropython/micropython@a053e63 · GitHub
Skip to content

Commit a053e63

Browse files
committed
webassembly/objjsproxy: Implement proxying of JS iterable protocol.
This allows Python to iterate over JavaScript objects that provide Symbol.iterator. Signed-off-by: Damien George <damien@micropython.org>
1 parent 2b0e64b commit a053e63

File tree

3 files changed

+36
-15
lines changed

3 files changed

+36
-15
lines changed

Diff for: ports/webassembly/objjsproxy.c

+18-15
Original file line numberDiff line numberDiff line change
@@ -153,14 +153,21 @@ EM_JS(void, js_reflect_construct, (int f_ref, uint32_t n_args, uint32_t * args,
153153
proxy_convert_js_to_mp_obj_jsside(ret, out);
154154
});
155155

156-
EM_JS(int, js_get_len, (int f_ref), {
157-
return proxy_js_ref[f_ref].length;
156+
EM_JS(void, js_get_iter, (int f_ref, uint32_t * out), {
157+
const f = proxy_js_ref[f_ref];
158+
const ret = f[Symbol.iterator]();
159+
proxy_convert_js_to_mp_obj_jsside(ret, out);
158160
});
159161

160-
EM_JS(void, js_subscr_int, (int f_ref, int idx, uint32_t * out), {
162+
EM_JS(bool, js_iter_next, (int f_ref, uint32_t * out), {
161163
const f = proxy_js_ref[f_ref];
162-
const ret = f[idx];
163-
proxy_convert_js_to_mp_obj_jsside(ret, out);
164+
const ret = f.next();
165+
if (ret.done) {
166+
return false;
167+
} else {
168+
proxy_convert_js_to_mp_obj_jsside(ret.value, out);
169+
return true;
170+
}
164171
});
165172

166173
EM_JS(void, js_subscr_load, (int f_ref, uint32_t * index_ref, uint32_t * out), {
@@ -320,17 +327,13 @@ void mp_obj_jsproxy_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
320327
typedef struct _jsproxy_it_t {
321328
mp_obj_base_t base;
322329
mp_fun_1_t iternext;
323-
mp_obj_jsproxy_t *obj;
324-
uint16_t cur;
325-
uint16_t len;
330+
mp_obj_jsproxy_t *iter;
326331
} jsproxy_it_t;
327332

328333
static mp_obj_t jsproxy_it_iternext(mp_obj_t self_in) {
329334
jsproxy_it_t *self = MP_OBJ_TO_PTR(self_in);
330-
if (self->cur < self->len) {
331-
uint32_t out[3];
332-
js_subscr_int(self->obj->ref, self->cur, out);
333-
self->cur += 1;
335+
uint32_t out[3];
336+
if (js_iter_next(self->iter->ref, out)) {
334337
return proxy_convert_js_to_mp_obj_cside(out);
335338
} else {
336339
return MP_OBJ_STOP_ITERATION;
@@ -343,9 +346,9 @@ static mp_obj_t jsproxy_new_it(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) {
343346
jsproxy_it_t *o = (jsproxy_it_t *)iter_buf;
344347
o->base.type = &mp_type_polymorph_iter;
345348
o->iternext = jsproxy_it_iternext;
346-
o->obj = self;
347-
o->cur = 0;
348-
o->len = js_get_len(self->ref);
349+
uint32_t out[3];
350+
js_get_iter(self->ref, out);
351+
o->iter = proxy_convert_js_to_mp_obj_cside(out);
349352
return MP_OBJ_FROM_PTR(o);
350353
}
351354

Diff for: tests/ports/webassembly/js_proxy_iterator.mjs

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Test accessing JavaScript iterables (objects with Symbol.iterator) from Python.
2+
3+
const mp = await (await import(process.argv[2])).loadMicroPython();
4+
5+
mp.runPython(`
6+
import js
7+
8+
for v in js.Set.new([1, 2]):
9+
print(v)
10+
11+
url_search_params = js.URLSearchParams.new("one=1&two=2")
12+
for key in url_search_params.keys():
13+
print(key, list(url_search_params.getAll(key)))
14+
`);

Diff for: tests/ports/webassembly/js_proxy_iterator.mjs.exp

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
1
2+
2
3+
one ['1']
4+
two ['2']

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/a053e639147d97c4a306ab272c12d9520a80e805

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy