All the dependencies for wasm2brs are installed within a Docker image that can be run with ./run.sh
.
To build our repo:
git submodule update --init --recursive
./run.sh make
To run make
without the Docker image (not recommended) be sure to install the same dependencies as listed in the Dockerfile
.
./run.sh make doom
This will place all the output files in project/
. To run, either side load the project manually or use vscode with the BrightScript Language extension. When opening our repository in vscode, running the debugger will run project/
.
The samples we have are:
cmake
doom
files
mandelbrot
javascript
rust
The easiest way to get started is to look in our samples directory. Specifically the cmake sample is setup to be used as a template.
If you wish to use libc/libc++, then you should use install wasienv, which comes with wasi-libc
as well as helpful scripts that run clang/make/cmake/etc with the correct compiler flags and directories.
The mandelbrot sample shows how to use clang directly without wasienv and no standard libraries. Note that wasm-ld
is required.
In general the process looks like:
.wasm
file, typicaly in Release mode with -Oz
wasm-opt
to perform wasm specific optimizations that reduce goto/labels and stack variables. This is located in build/wasm2brs/third_party/binaryen/bin/wasm-opt
. The recommended optimization level is -O4
wasm2brs
to convert into a .brs
file. This is located in build/wasm2brs/wasm2brs
Rust is considerably easier to setup and involves changing the target of the project to wasm32-wasi
and compiling with optimization level z
:
opt-level = "z"
rustup target add wasm32-wasi
cargo build --target wasm32-wasi
Or
rustc -C opt-level=z --target wasm32-wasi yourfile.rs
As mentioned above, you'll want to run wasm-opt
on the output wasm file and finally wasm2brs
to convert into a .brs
file.
Note: Some Rust libraries depend upon crates that do not have a target built for wasm32-wasi
, such as the unix crate. The easiest path is to fork those libraries and remove their dependence upon those crates.
setjmp.h
does not exist, but we provide a stub that aborts)Error loading file. (compile error &hb9) in pkg:/source/test.brs(NaN)
If
/Else If
blocks in a functionInternal limit size exceeded. (compile error &hae) in pkg:/source/test.brs(...)
Else
clause does not contribute to this limitVariable table size exceeded. (compile error &hb0)
Label/Line Not Found. (compile error &h0e) in pkg:/source/test.brs(NaN)'label256'
Function external_append_stdin(bytesOrString as Dynamic) as Void
roByteArray
or String
to stdinm.external_print_line = custom_print_line
:
Function custom_print_line(fd as Integer, str as String) as Void
m.external_output
, however the helper function PrintAndConsumeLines
can emulate the same behavior.m.external_output = custom_output
:
Function custom_output(fd as Integer, bytes as Object) as Void
roByteArray
m.external_print_line
from being called, however the helper function PrintAndConsumeLines
can emulate the same behavior.m.external_wait_for_stdin = custom_wait_for_stdin
:
Function custom_wait_for_stdin() as Void
external_append_stdin
.Run all the tests, this will auto discover your device with a default password of rokudev
.
./run.sh make run_test
To run a specific test you can specify the .wast file as an absolute path, otherwise it assumes it's in the third_part/testsuite/
directory, for example i32.wast
:
./run.sh make run_test ARGS="wast i32.wast"
To use a non-default password:
./run.sh make run_test ARGS="password ..."
To deploy to a specific device (e.g. 1.2.3.4
):
./run.sh make run_test ARGS="deploy 1.2.3.4"
To provide multiple arguments:
./run.sh make run_test ARGS="password ... deploy 1.2.3.4 wast i32.wast"