diff --git a/ports/webassembly/README.md b/ports/webassembly/README.md index abd2864a56..af395778a7 100644 --- a/ports/webassembly/README.md +++ b/ports/webassembly/README.md @@ -6,22 +6,22 @@ MicroPython for [WebAssembly](https://webassembly.org/). Dependencies ------------ -Building webassembly port bears the same requirements as the standard -MicroPython ports with the addition of Emscripten (and uglify-js for the -minified file). +Building the webassembly port bears the same requirements as the standard +MicroPython ports with the addition of Emscripten, and optionally terser for +the minified file. -The output includes `micropython.js` (a JavaScript wrapper for the -MicroPython runtime) and `firmware.wasm` (actual MicroPython compiled to +The output includes `micropython.mjs` (a JavaScript wrapper for the +MicroPython runtime) and `micropython.wasm` (actual MicroPython compiled to WASM). Build instructions ------------------ -In order to build micropython.js, run: +In order to build `micropython.mjs`, run: $ make -To generate the minified file micropython.min.js, run: +To generate the minified file `micropython.min.mjs`, run: $ make min @@ -30,55 +30,90 @@ Running with Node.js Access the repl with: - $ node build/micropython.js + $ make repl -Stack size may be modified using: +This is the same as running: - $ node build/micropython.js -X stack=64K + $ node build-standard/micropython.mjs -Where stack size may be represented in Bytes, KiB or MiB. +The initial MicroPython GC heap size may be modified using: + + $ node build-standard/micropython.mjs -X heapsize=64k + +Where stack size may be represented in bytes, or have a `k` or `m` suffix. MicroPython scripts may be executed using: - $ node build/micropython.js hello.py + $ node build-standard/micropython.mjs hello.py -Alternatively micropython.js may by accessed by other javascript programs in node +Alternatively `micropython.mjs` may by accessed by other JavaScript programs in node using the require command and the general API outlined below. For example: ```javascript -var mp_js = require('./build/micropython.js'); +const mp_mjs = await import("micropython.mjs"); +const mp = await mp_mjs.loadMicroPython(); -mp_js_init(64 * 1024); -await mp_js_do_str("print('hello world')\n"); +mp.runPython("print('hello world')"); +``` + +Or without await notation: + +```javascript +import("micropython.mjs").then((mp_mjs) => { + mp_mjs.loadMicroPython().then((mp) => { + mp.runPython("print('hello world')"); + }); +}); ``` Running with HTML ----------------- -The prerequisite for browser operation of micropython.js is to listen to the -`micropython-print` event, which is passed data when MicroPython code prints -something to stdout. The following code demonstrates basic functionality: +The following code demonstrates the simplest way to load `micropython.mjs` in a +browser, create an interpreter context, and run some Python code: ```html
- + + + + + + +``` + +The output in the above example will go to the JavaScript console. It's possible +to instead capture the output and print it somewhere else, for example in an +HTML element. The following example shows how to do this, and also demonstrates +the use of top-level await and the `js` module: + +```html + + + + - @@ -98,31 +133,41 @@ Run the test suite using: API --- -The following functions have been exposed to javascript. +The following functions have been exposed to JavaScript through the interpreter +context, created and returned by `loadMicroPython()`. -``` -mp_js_init(stack_size) -``` +- `PyProxy`: the type of the object that proxies Python objects. -Initialize MicroPython with the given stack size in bytes. This must be -called before attempting to interact with MicroPython. +- `FS`: the Emscripten filesystem object. -``` -await mp_js_do_str(code) -``` +- `globals`: an object exposing the globals from the Python `__main__` module, + with methods `get(key)`, `set(key, value)` and `delete(key)`. -Execute the input code. `code` must be a `string`. +- `registerJsModule(name, module)`: register a JavaScript object as importable + from Python with the given name. -``` -mp_js_init_repl() -``` +- `pyimport`: import a Python module and return it. -Initialize MicroPython repl. Must be called before entering characters into -the repl. +- `runPython(code)`: execute Python code and return the result. -``` -await mp_js_process_char(char) -``` +- `runPythonAsync(code)`: execute Python code and return the result, allowing for + top-level await expressions (this call must be await'ed on the JavaScript side). -Input character into MicroPython repl. `char` must be of type `number`. This -will execute MicroPython code when necessary. +- `replInit()`: initialise the REPL. + +- `replProcessChar(chr)`: process an incoming character at the REPL. + +- `replProcessCharWithAsyncify(chr)`: process an incoming character at the REPL, + for use when ASYNCIFY is enabled. + +Proxying +-------- + +A Python `dict` instance is proxied such that: + + for (const key in dict) { + print(key, dict[key]); + } + +works as expected on the JavaScript side and iterates through the keys of the +Python `dict`.