webassembly: Update README.md to describe latest changes.

Signed-off-by: Damien George <damien@micropython.org>
pull/13583/head
Damien George 2024-03-06 10:27:54 +11:00
rodzic b9eb74e73b
commit 26d6969fef
1 zmienionych plików z 96 dodań i 51 usunięć

Wyświetl plik

@ -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
<!doctype html>
<html>
<head>
<script src="build/micropython.js"></script>
<script src="build-standard/micropython.mjs" type="module"></script>
</head>
<body>
<script type="module">
const mp = await loadMicroPython();
mp.runPython("print('hello world')");
</script>
</body>
</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
<!doctype html>
<html>
<head>
<script src="build-standard/micropython.mjs" type="module"></script>
</head>
<body>
<pre id="micropython-stdout"></pre>
<script>
document.addEventListener("micropython-print", function(e) {
let output = document.getElementById("micropython-stdout");
output.innerText += new TextDecoder().decode(e.detail);
}, false);
var mp_js_startup = Module["onRuntimeInitialized"];
Module["onRuntimeInitialized"] = async function() {
mp_js_startup();
mp_js_init(64 * 1024);
await mp_js_do_str("print('hello world')");
<script type="module">
const stdoutWriter = (line) => {
document.getElementById("micropython-stdout").innerText += line + "\n";
};
const mp = await loadMicroPython({stdout:stdoutWriter});
await mp.runPythonAsync(`
import js
url = "https://api.github.com/users/micropython"
print(f"fetching {url}...")
res = await js.fetch(url)
json = await res.json()
for i in dir(json):
print(f"{i}: {json[i]}")
`);
</script>
</body>
</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`.