This repository provides a demo Android application that creates a WASM Micro Runtime (WAMR) instance and uses it to run CoreMark v1.
A copy of WAMR is checked in to app/src/main/cpp/third_party
. It is
statically linked into a native library that exports a single entry point. This
entry point takes a byte array representing the WASM image to run and currently
returns nothing. See app/src/main/cpp/native-lib.cpp
.
The native library implementation creates a WAMR runtime using
wamr_runtime_load
and wamr_runtime_instantiate
. Details can be found in the
Embedding
WAMR
page in the WAMR docs.
The CoreMark v1 WASM image is loaded from raw Android resources on the JVM side
and passed to WAMR through the JNI bridge (see
app/src/main/java/com/example/myapplication/MainActivity.kt
). The _start
symbol from this image is invoked from inside the native library, though this
could easily be exposed through JNI.
Standard input/output is handled by the WAMR libc WASI implementation
(WAMR_BUILD_LIBC_WASI
in CMakeLists.txt
). CoreMark writes to standard
output, flows through the libc WASI implementation to a custom vnsprintf
implementation provided by the JNI native library (see WAMR_BH_VPRINTF
in
CMakeLists.txt). This version of vnsprintf
will produce Android logcat logs
via __android_log_write
.
Log messages generated by the WAMR runtime itself are similarly routed to logcat.
Standard input is not handled yet, but could be similarly routed through the libc WASI interface.
I had to disable hardware bounds checking in WAMR:
// wasm-micro-runtime/core/shared/platform/linux/platform_internal.h
#undef OS_ENABLE_HW_BOUND_CHECK
It causes crashes in touch_pages
somewhere in pthreads, I am still
investigating.
I have tested this only on the Android x86 emulator so far. More platforms to come.
The demo is currently statically linked against WAMR, but there should be no impediment to using a WAMR implementation in a shared library.