From 9c7f0659e2a6db37125fa092ebe5150125eb14b3 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 17 Apr 2024 14:25:48 +1000 Subject: [PATCH] webassembly/api: Allocate code data on C heap when running Python code. Otherwise Emscripten allocates it on the Emscripten C stack, which will overflow for large amounts of code. Fixes issue #14307. Signed-off-by: Damien George --- ports/webassembly/api.js | 16 ++++++++++++---- ports/webassembly/main.c | 8 ++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/ports/webassembly/api.js b/ports/webassembly/api.js index 2459075fc5..2f2ad95221 100644 --- a/ports/webassembly/api.js +++ b/ports/webassembly/api.js @@ -127,23 +127,31 @@ export async function loadMicroPython(options) { }, pyimport: pyimport, runPython(code) { + const len = Module.lengthBytesUTF8(code); + const buf = Module._malloc(len + 1); + Module.stringToUTF8(code, buf, len + 1); const value = Module._malloc(3 * 4); Module.ccall( "mp_js_do_exec", "number", - ["string", "pointer"], - [code, value], + ["pointer", "number", "pointer"], + [buf, len, value], ); + Module._free(buf); return proxy_convert_mp_to_js_obj_jsside_with_free(value); }, runPythonAsync(code) { + const len = Module.lengthBytesUTF8(code); + const buf = Module._malloc(len + 1); + Module.stringToUTF8(code, buf, len + 1); const value = Module._malloc(3 * 4); Module.ccall( "mp_js_do_exec_async", "number", - ["string", "pointer"], - [code, value], + ["pointer", "number", "pointer"], + [buf, len, value], ); + Module._free(buf); return proxy_convert_mp_to_js_obj_jsside_with_free(value); }, replInit() { diff --git a/ports/webassembly/main.c b/ports/webassembly/main.c index 441c6d67e3..23d12b6dbb 100644 --- a/ports/webassembly/main.c +++ b/ports/webassembly/main.c @@ -104,7 +104,7 @@ void mp_js_do_import(const char *name, uint32_t *out) { } } -void mp_js_do_exec(const char *src, uint32_t *out) { +void mp_js_do_exec(const char *src, size_t len, uint32_t *out) { // Collect at the top-level, where there are no root pointers from stack/registers. gc_collect_start(); gc_collect_end(); @@ -112,7 +112,7 @@ void mp_js_do_exec(const char *src, uint32_t *out) { mp_parse_input_kind_t input_kind = MP_PARSE_FILE_INPUT; nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { - mp_lexer_t *lex = mp_lexer_new_from_str_len_dedent(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0); + mp_lexer_t *lex = mp_lexer_new_from_str_len_dedent(MP_QSTR__lt_stdin_gt_, src, len, 0); qstr source_name = lex->source_name; mp_parse_tree_t parse_tree = mp_parse(lex, input_kind); mp_obj_t module_fun = mp_compile(&parse_tree, source_name, false); @@ -125,9 +125,9 @@ void mp_js_do_exec(const char *src, uint32_t *out) { } } -void mp_js_do_exec_async(const char *src, uint32_t *out) { +void mp_js_do_exec_async(const char *src, size_t len, uint32_t *out) { mp_compile_allow_top_level_await = true; - mp_js_do_exec(src, out); + mp_js_do_exec(src, len, out); mp_compile_allow_top_level_await = false; }