mirror of
https://github.com/micropython/micropython.git
synced 2025-12-16 09:50:15 +01:00
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>
This commit is contained in:
@@ -153,14 +153,21 @@ EM_JS(void, js_reflect_construct, (int f_ref, uint32_t n_args, uint32_t * args,
|
|||||||
proxy_convert_js_to_mp_obj_jsside(ret, out);
|
proxy_convert_js_to_mp_obj_jsside(ret, out);
|
||||||
});
|
});
|
||||||
|
|
||||||
EM_JS(int, js_get_len, (int f_ref), {
|
EM_JS(void, js_get_iter, (int f_ref, uint32_t * out), {
|
||||||
return proxy_js_ref[f_ref].length;
|
const f = proxy_js_ref[f_ref];
|
||||||
|
const ret = f[Symbol.iterator]();
|
||||||
|
proxy_convert_js_to_mp_obj_jsside(ret, out);
|
||||||
});
|
});
|
||||||
|
|
||||||
EM_JS(void, js_subscr_int, (int f_ref, int idx, uint32_t * out), {
|
EM_JS(bool, js_iter_next, (int f_ref, uint32_t * out), {
|
||||||
const f = proxy_js_ref[f_ref];
|
const f = proxy_js_ref[f_ref];
|
||||||
const ret = f[idx];
|
const ret = f.next();
|
||||||
proxy_convert_js_to_mp_obj_jsside(ret, out);
|
if (ret.done) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
proxy_convert_js_to_mp_obj_jsside(ret.value, out);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
EM_JS(void, js_subscr_load, (int f_ref, uint32_t * index_ref, uint32_t * out), {
|
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) {
|
|||||||
typedef struct _jsproxy_it_t {
|
typedef struct _jsproxy_it_t {
|
||||||
mp_obj_base_t base;
|
mp_obj_base_t base;
|
||||||
mp_fun_1_t iternext;
|
mp_fun_1_t iternext;
|
||||||
mp_obj_jsproxy_t *obj;
|
mp_obj_jsproxy_t *iter;
|
||||||
uint16_t cur;
|
|
||||||
uint16_t len;
|
|
||||||
} jsproxy_it_t;
|
} jsproxy_it_t;
|
||||||
|
|
||||||
static mp_obj_t jsproxy_it_iternext(mp_obj_t self_in) {
|
static mp_obj_t jsproxy_it_iternext(mp_obj_t self_in) {
|
||||||
jsproxy_it_t *self = MP_OBJ_TO_PTR(self_in);
|
jsproxy_it_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
if (self->cur < self->len) {
|
uint32_t out[3];
|
||||||
uint32_t out[3];
|
if (js_iter_next(self->iter->ref, out)) {
|
||||||
js_subscr_int(self->obj->ref, self->cur, out);
|
|
||||||
self->cur += 1;
|
|
||||||
return proxy_convert_js_to_mp_obj_cside(out);
|
return proxy_convert_js_to_mp_obj_cside(out);
|
||||||
} else {
|
} else {
|
||||||
return MP_OBJ_STOP_ITERATION;
|
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) {
|
|||||||
jsproxy_it_t *o = (jsproxy_it_t *)iter_buf;
|
jsproxy_it_t *o = (jsproxy_it_t *)iter_buf;
|
||||||
o->base.type = &mp_type_polymorph_iter;
|
o->base.type = &mp_type_polymorph_iter;
|
||||||
o->iternext = jsproxy_it_iternext;
|
o->iternext = jsproxy_it_iternext;
|
||||||
o->obj = self;
|
uint32_t out[3];
|
||||||
o->cur = 0;
|
js_get_iter(self->ref, out);
|
||||||
o->len = js_get_len(self->ref);
|
o->iter = proxy_convert_js_to_mp_obj_cside(out);
|
||||||
return MP_OBJ_FROM_PTR(o);
|
return MP_OBJ_FROM_PTR(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
14
tests/ports/webassembly/js_proxy_iterator.mjs
Normal file
14
tests/ports/webassembly/js_proxy_iterator.mjs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
// Test accessing JavaScript iterables (objects with Symbol.iterator) from Python.
|
||||||
|
|
||||||
|
const mp = await (await import(process.argv[2])).loadMicroPython();
|
||||||
|
|
||||||
|
mp.runPython(`
|
||||||
|
import js
|
||||||
|
|
||||||
|
for v in js.Set.new([1, 2]):
|
||||||
|
print(v)
|
||||||
|
|
||||||
|
url_search_params = js.URLSearchParams.new("one=1&two=2")
|
||||||
|
for key in url_search_params.keys():
|
||||||
|
print(key, list(url_search_params.getAll(key)))
|
||||||
|
`);
|
||||||
4
tests/ports/webassembly/js_proxy_iterator.mjs.exp
Normal file
4
tests/ports/webassembly/js_proxy_iterator.mjs.exp
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
1
|
||||||
|
2
|
||||||
|
one ['1']
|
||||||
|
two ['2']
|
||||||
Reference in New Issue
Block a user