micropython/ports/webassembly
Angus Gratton decf8e6a8b all: Remove the "STATIC" macro and just use "static" instead.
The STATIC macro was introduced a very long time ago in commit
d5df6cd44a.  The original reason for this was
to have the option to define it to nothing so that all static functions
become global functions and therefore visible to certain debug tools, so
one could do function size comparison and other things.

This STATIC feature is rarely (if ever) used.  And with the use of LTO and
heavy inline optimisation, analysing the size of individual functions when
they are not static is not a good representation of the size of code when
fully optimised.

So the macro does not have much use and it's simpler to just remove it.
Then you know exactly what it's doing.  For example, newcomers don't have
to learn what the STATIC macro is and why it exists.  Reading the code is
also less "loud" with a lowercase static.

One other minor point in favour of removing it, is that it stops bugs with
`STATIC inline`, which should always be `static inline`.

Methodology for this commit was:

1) git ls-files | egrep '\.[ch]$' | \
   xargs sed -Ei "s/(^| )STATIC($| )/\1static\2/"

2) Do some manual cleanup in the diff by searching for the word STATIC in
   comments and changing those back.

3) "git-grep STATIC docs/", manually fixed those cases.

4) "rg -t python STATIC", manually fixed codegen lines that used STATIC.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
2024-03-07 14:20:42 +11:00
..
Makefile
README.md webassembly: Make mp_js_process_char asynchronous. 2023-06-27 15:27:29 +10:00
library.h
library.js
main.c all: Remove the "STATIC" macro and just use "static" instead. 2024-03-07 14:20:42 +11:00
mpconfigport.h
mphalport.c ports: Fix sys.stdout.buffer.write() return value. 2023-12-22 10:32:46 +11:00
mphalport.h
node_run.sh javascript: Rename this port to 'webassembly'. 2022-08-22 12:03:39 +01:00
qstrdefsport.h
wrapper.js webassembly: Make mp_js_process_char asynchronous. 2023-06-27 15:27:29 +10:00

README.md

MicroPython WebAssembly

MicroPython for WebAssembly.

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).

The output includes micropython.js (a JavaScript wrapper for the MicroPython runtime) and firmware.wasm (actual MicroPython compiled to WASM).

Build instructions

In order to build micropython.js, run:

$ make

To generate the minified file micropython.min.js, run:

$ make min

Running with Node.js

Access the repl with:

$ node build/micropython.js

Stack size may be modified using:

$ node build/micropython.js -X stack=64K

Where stack size may be represented in Bytes, KiB or MiB.

MicroPython scripts may be executed using:

$ node build/micropython.js hello.py

Alternatively micropython.js may by accessed by other javascript programs in node using the require command and the general API outlined below. For example:

var mp_js = require('./build/micropython.js');

mp_js_init(64 * 1024);
await mp_js_do_str("print('hello world')\n");

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:

<!doctype html>
<html>
  <head>
    <script src="build/micropython.js"></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>
  </body>
</html>

MicroPython code execution will suspend the browser so be sure to atomize usage within this environment. Unfortunately interrupts have not been implemented for the browser.

Testing

Run the test suite using:

$ make test

API

The following functions have been exposed to javascript.

mp_js_init(stack_size)

Initialize MicroPython with the given stack size in bytes. This must be called before attempting to interact with MicroPython.

await mp_js_do_str(code)

Execute the input code. code must be a string.

mp_js_init_repl()

Initialize MicroPython repl. Must be called before entering characters into the repl.

await mp_js_process_char(char)

Input character into MicroPython repl. char must be of type number. This will execute MicroPython code when necessary.