webassembly: Simplify proxy_c_to_js_get_type interface.

If the Python object is a known type (tuple, list, dict) then the caller
always wants to follow up with a call to get the associated data for that
object.  So simplify things to just a single call that gets both the type
and object data (if the type is known).

Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
Damien George
2026-04-23 14:04:36 +10:00
parent b8d43d8dea
commit 44780be7cd
3 changed files with 34 additions and 55 deletions
+1 -3
View File
@@ -59,10 +59,8 @@ EXPORTED_FUNCTIONS_EXTRA += ,\
_proxy_c_to_js_call,\
_proxy_c_to_js_delete_attr,\
_proxy_c_to_js_dir,\
_proxy_c_to_js_get_array,\
_proxy_c_to_js_get_dict,\
_proxy_c_to_js_get_iter,\
_proxy_c_to_js_get_type,\
_proxy_c_to_js_get_type_and_data,\
_proxy_c_to_js_has_attr,\
_proxy_c_to_js_iternext,\
_proxy_c_to_js_lookup_attr,\
+17 -30
View File
@@ -35,25 +35,20 @@ class PyProxy {
return js_obj;
}
const obj_data = Module._malloc(2 * 4);
const type = Module.ccall(
"proxy_c_to_js_get_type",
"proxy_c_to_js_get_type_and_data",
"number",
["number"],
[js_obj._ref],
["number", "pointer"],
[js_obj._ref, obj_data],
);
let js_obj_out;
if (type === 1 || type === 2) {
// List or tuple.
const array_ref = Module._malloc(2 * 4);
const item = Module._malloc(3 * 4);
Module.ccall(
"proxy_c_to_js_get_array",
"null",
["number", "pointer"],
[js_obj._ref, array_ref],
);
const len = Module.getValue(array_ref, "i32");
const items_ptr = Module.getValue(array_ref + 4, "i32");
const len = Module.getValue(obj_data, "i32");
const items_ptr = Module.getValue(obj_data + 4, "i32");
const js_array = [];
for (let i = 0; i < len; ++i) {
Module.ccall(
@@ -65,23 +60,13 @@ class PyProxy {
const js_item = proxy_convert_mp_to_js_obj_jsside(item);
js_array.push(PyProxy.toJs(js_item));
}
Module._free(array_ref);
Module._free(item);
return js_array;
}
if (type === 3) {
js_obj_out = js_array;
} else if (type === 3) {
// Dict.
const map_ref = Module._malloc(2 * 4);
const item = Module._malloc(3 * 4);
Module.ccall(
"proxy_c_to_js_get_dict",
"null",
["number", "pointer"],
[js_obj._ref, map_ref],
);
const alloc = Module.getValue(map_ref, "i32");
const table_ptr = Module.getValue(map_ref + 4, "i32");
const alloc = Module.getValue(obj_data, "i32");
const table_ptr = Module.getValue(obj_data + 4, "i32");
const js_dict = {};
for (let i = 0; i < alloc; ++i) {
const mp_key = Module.getValue(table_ptr + i * 8, "i32");
@@ -112,13 +97,15 @@ class PyProxy {
js_dict[js_key] = PyProxy.toJs(js_value);
}
}
Module._free(map_ref);
Module._free(item);
return js_dict;
js_obj_out = js_dict;
} else {
// Cannot convert to JS, leave as a PyProxy.
js_obj_out = js_obj;
}
// Cannot convert to JS, leave as a PyProxy.
return js_obj;
Module._free(obj_data);
return js_obj_out;
}
}
+16 -22
View File
@@ -387,36 +387,30 @@ bool proxy_c_to_js_delete_attr(uint32_t c_ref, const char *attr_in) {
return proxy_c_to_js_store_helper(c_ref, attr_in, NULL);
}
uint32_t proxy_c_to_js_get_type(uint32_t c_ref) {
uint32_t proxy_c_to_js_get_type_and_data(uint32_t c_ref, uint32_t *out) {
mp_obj_t obj = proxy_c_get_obj(c_ref);
const mp_obj_type_t *type = mp_obj_get_type(obj);
if (type == &mp_type_tuple) {
return 1;
} else if (type == &mp_type_list) {
return 2;
if (type == &mp_type_tuple || type == &mp_type_list) {
size_t len;
mp_obj_t *items;
mp_obj_get_array(obj, &len, &items);
out[0] = len;
out[1] = (uintptr_t)items;
if (type == &mp_type_tuple) {
return 1;
} else {
return 2;
}
} else if (type == &mp_type_dict) {
mp_map_t *map = mp_obj_dict_get_map(obj);
out[0] = map->alloc;
out[1] = (uintptr_t)map->table;
return 3;
} else {
return 4;
return 0;
}
}
void proxy_c_to_js_get_array(uint32_t c_ref, uint32_t *out) {
mp_obj_t obj = proxy_c_get_obj(c_ref);
size_t len;
mp_obj_t *items;
mp_obj_get_array(obj, &len, &items);
out[0] = len;
out[1] = (uintptr_t)items;
}
void proxy_c_to_js_get_dict(uint32_t c_ref, uint32_t *out) {
mp_obj_t obj = proxy_c_get_obj(c_ref);
mp_map_t *map = mp_obj_dict_get_map(obj);
out[0] = map->alloc;
out[1] = (uintptr_t)map->table;
}
EM_JS(void, js_get_error_info, (int jsref, uint32_t * out_name, uint32_t * out_message), {
const error = proxy_js_ref[jsref];
proxy_convert_js_to_mp_obj_jsside(error.name, out_name);