summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenry Gressmann <mail@henrygressmann.de>2024-01-26 01:26:09 +0100
committerHenry Gressmann <mail@henrygressmann.de>2024-01-26 01:26:09 +0100
commit461126ce309f99e4ad2a6ddcbc175ea01c5e8fee (patch)
tree30de8bcfec97f87d468191fb9959f90e7ee91100
parentb9a4e8788f374dac94e4f3f5b062dbe2a1d2a10c (diff)
feat: full no_std support
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
-rw-r--r--.github/workflows/test.yaml4
-rw-r--r--Cargo.lock101
-rw-r--r--Cargo.toml10
-rw-r--r--README.md2
-rw-r--r--crates/parser/src/conversion.rs6
-rw-r--r--crates/parser/src/lib.rs2
-rw-r--r--crates/parser/src/module.rs4
-rw-r--r--crates/tinywasm/Cargo.toml1
-rw-r--r--crates/tinywasm/src/func.rs6
-rw-r--r--crates/tinywasm/src/imports.rs2
-rw-r--r--crates/tinywasm/src/instance.rs5
-rw-r--r--crates/tinywasm/src/lib.rs6
-rw-r--r--crates/tinywasm/src/runtime/interpreter/mod.rs12
-rw-r--r--crates/tinywasm/src/runtime/interpreter/no_std_floats.rs77
-rw-r--r--crates/tinywasm/src/runtime/interpreter/traits.rs3
-rw-r--r--crates/tinywasm/src/runtime/stack/call_stack.rs1
-rw-r--r--crates/tinywasm/src/runtime/stack/value_stack.rs1
-rw-r--r--crates/tinywasm/src/store.rs8
-rw-r--r--crates/types/src/lib.rs17
-rw-r--r--examples/rust/Cargo.toml23
-rw-r--r--examples/rust/README.md1
-rw-r--r--examples/rust/src/hello.rs18
-rw-r--r--examples/rust/src/tinywasm.rs41
-rw-r--r--examples/wasm-rust.rs41
24 files changed, 362 insertions, 30 deletions
diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
index 41dd979..92d56f4 100644
--- a/.github/workflows/test.yaml
+++ b/.github/workflows/test.yaml
@@ -41,10 +41,10 @@ jobs:
run: rustup update nightly
- name: Build (nightly, no default features)
- run: cargo +nightly build --workspace --exclude wasm-testsuite --no-default-features
+ run: cargo +nightly build --workspace --exclude wasm-testsuite --exclude rust-wasm-examples --no-default-features
- name: Run tests (nightly, no default features)
- run: cargo +nightly test --workspace --exclude wasm-testsuite --no-default-features
+ run: cargo +nightly test --workspace --exclude wasm-testsuite --exclude rust-wasm-examples --no-default-features
- name: Run MVP testsuite (nightly)
run: cargo +nightly test-mvp
diff --git a/Cargo.lock b/Cargo.lock
index e13a9f1..84cd8cc 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -229,10 +229,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a667583cca8c4f8436db8de46ea8233c42a7d9ae424a82d338f2e4675229204"
dependencies = [
"backtrace",
+ "color-spantrace",
"eyre",
"indenter",
"once_cell",
"owo-colors 3.5.0",
+ "tracing-error",
+]
+
+[[package]]
+name = "color-spantrace"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2"
+dependencies = [
+ "once_cell",
+ "owo-colors 3.5.0",
+ "tracing-core",
+ "tracing-error",
]
[[package]]
@@ -685,6 +699,12 @@ dependencies = [
]
[[package]]
+name = "libm"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
+
+[[package]]
name = "libredox"
version = "0.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -779,6 +799,12 @@ dependencies = [
]
[[package]]
+name = "pin-project-lite"
+version = "0.2.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
+
+[[package]]
name = "pkg-config"
version = "0.3.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1117,6 +1143,15 @@ dependencies = [
]
[[package]]
+name = "sharded-slab"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
+dependencies = [
+ "lazy_static",
+]
+
+[[package]]
name = "simd-adler32"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1186,6 +1221,16 @@ dependencies = [
]
[[package]]
+name = "thread_local"
+version = "1.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152"
+dependencies = [
+ "cfg-if",
+ "once_cell",
+]
+
+[[package]]
name = "tinyvec"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1205,6 +1250,7 @@ name = "tinywasm"
version = "0.3.0-alpha.0"
dependencies = [
"eyre",
+ "libm",
"log",
"owo-colors 4.0.0",
"plotters",
@@ -1239,6 +1285,14 @@ dependencies = [
]
[[package]]
+name = "tinywasm-root"
+version = "0.0.0"
+dependencies = [
+ "color-eyre",
+ "tinywasm",
+]
+
+[[package]]
name = "tinywasm-types"
version = "0.3.0-alpha.0"
dependencies = [
@@ -1247,6 +1301,47 @@ dependencies = [
]
[[package]]
+name = "tracing"
+version = "0.1.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
+dependencies = [
+ "pin-project-lite",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-core"
+version = "0.1.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
+dependencies = [
+ "once_cell",
+ "valuable",
+]
+
+[[package]]
+name = "tracing-error"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e"
+dependencies = [
+ "tracing",
+ "tracing-subscriber",
+]
+
+[[package]]
+name = "tracing-subscriber"
+version = "0.3.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
+dependencies = [
+ "sharded-slab",
+ "thread_local",
+ "tracing-core",
+]
+
+[[package]]
name = "ttf-parser"
version = "0.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1277,6 +1372,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a"
[[package]]
+name = "valuable"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
+
+[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 0d5f97b..2be4dcc 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,5 @@
[workspace]
members=["crates/*"]
-default-members=["crates/cli"]
resolver="2"
[workspace.package]
@@ -9,3 +8,12 @@ edition="2021"
license="MIT OR Apache-2.0"
authors=["Henry Gressmann <mail@henrygressmann.de>"]
repository="https://github.com/explodingcamera/tinywasm"
+
+[package]
+name="tinywasm-root"
+publish=false
+edition="2021"
+
+[dev-dependencies]
+color-eyre="0.6"
+tinywasm={path="crates/tinywasm"}
diff --git a/README.md b/README.md
index ac755c7..3197cf1 100644
--- a/README.md
+++ b/README.md
@@ -55,7 +55,7 @@ $ cargo add tinywasm
- **`parser`**\
Enables the `tinywasm-parser` crate. This is enabled by default.
-With all these features disabled, TinyWasm does not depend on any external crates and can be used in `no_std` environments.
+With all these features disabled, TinyWasm only depends on `core`, `alloc` and `libm` and can be used in `no_std` environments.
<!-- # 🎯 Goals
diff --git a/crates/parser/src/conversion.rs b/crates/parser/src/conversion.rs
index 90dde8c..835842f 100644
--- a/crates/parser/src/conversion.rs
+++ b/crates/parser/src/conversion.rs
@@ -1,5 +1,5 @@
+use crate::log;
use alloc::{boxed::Box, format, string::ToString, vec::Vec};
-use log::debug;
use tinywasm_types::*;
use wasmparser::{FuncValidator, OperatorsReader, ValidatorResources};
@@ -239,7 +239,7 @@ pub fn process_operators<'a>(
let mut labels_ptrs = Vec::new(); // indexes into the instructions array
for op in ops {
- debug!("op: {:?}", op);
+ log::debug!("op: {:?}", op);
let op = op?;
validator.op(offset, &op)?;
@@ -274,7 +274,7 @@ pub fn process_operators<'a>(
}
End => {
if let Some(label_pointer) = labels_ptrs.pop() {
- debug!("ending block: {:?}", instructions[label_pointer]);
+ log::debug!("ending block: {:?}", instructions[label_pointer]);
let current_instr_ptr = instructions.len();
diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs
index aa76ea3..edcd280 100644
--- a/crates/parser/src/lib.rs
+++ b/crates/parser/src/lib.rs
@@ -14,7 +14,9 @@ use log;
#[cfg(not(feature = "logging"))]
mod log {
macro_rules! debug ( ($($tt:tt)*) => {{}} );
+ macro_rules! error ( ($($tt:tt)*) => {{}} );
pub(crate) use debug;
+ pub(crate) use error;
}
mod conversion;
diff --git a/crates/parser/src/module.rs b/crates/parser/src/module.rs
index 811c51f..e0fb0cc 100644
--- a/crates/parser/src/module.rs
+++ b/crates/parser/src/module.rs
@@ -181,9 +181,9 @@ impl ModuleReader {
validator.end(offset)?;
self.end_reached = true;
}
- CustomSection(reader) => {
+ CustomSection(_reader) => {
debug!("Found custom section");
- debug!("Skipping custom section: {:?}", reader.name());
+ debug!("Skipping custom section: {:?}", _reader.name());
}
// TagSection(tag) => {
// debug!("Found tag section");
diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml
index 9e336c8..f1a3242 100644
--- a/crates/tinywasm/Cargo.toml
+++ b/crates/tinywasm/Cargo.toml
@@ -16,6 +16,7 @@ path="src/lib.rs"
log={version="0.4", optional=true}
tinywasm-parser={version="0.3.0-alpha.0", path="../parser", default-features=false, optional=true}
tinywasm-types={version="0.3.0-alpha.0", path="../types", default-features=false}
+libm={version="0.2", default-features=false}
[dev-dependencies]
wasm-testsuite={path="../wasm-testsuite"}
diff --git a/crates/tinywasm/src/func.rs b/crates/tinywasm/src/func.rs
index 7a29e18..8433236 100644
--- a/crates/tinywasm/src/func.rs
+++ b/crates/tinywasm/src/func.rs
@@ -1,5 +1,5 @@
+use crate::log;
use alloc::{boxed::Box, format, string::String, string::ToString, vec, vec::Vec};
-use log::{debug, info};
use tinywasm_types::{FuncAddr, FuncType, ValType, WasmValue};
use crate::{
@@ -34,7 +34,7 @@ impl FuncHandle {
// 4. If the length of the provided argument values is different from the number of expected arguments, then fail
if func_ty.params.len() != params.len() {
- info!("func_ty.params: {:?}", func_ty.params);
+ log::info!("func_ty.params: {:?}", func_ty.params);
return Err(Error::Other(format!(
"param count mismatch: expected {}, got {}",
func_ty.params.len(),
@@ -62,7 +62,7 @@ impl FuncHandle {
};
// 6. Let f be the dummy frame
- debug!("locals: {:?}", locals);
+ log::debug!("locals: {:?}", locals);
let call_frame = CallFrame::new(func_inst, params, locals);
// 7. Push the frame f to the call stack
diff --git a/crates/tinywasm/src/imports.rs b/crates/tinywasm/src/imports.rs
index 0720d02..a640081 100644
--- a/crates/tinywasm/src/imports.rs
+++ b/crates/tinywasm/src/imports.rs
@@ -4,7 +4,7 @@ use core::fmt::Debug;
use crate::{
func::{FromWasmValueTuple, IntoWasmValueTuple, ValTypesFromTuple},
- LinkingError, Result,
+ log, LinkingError, Result,
};
use alloc::{
collections::BTreeMap,
diff --git a/crates/tinywasm/src/instance.rs b/crates/tinywasm/src/instance.rs
index 75d1f87..d750cd5 100644
--- a/crates/tinywasm/src/instance.rs
+++ b/crates/tinywasm/src/instance.rs
@@ -6,7 +6,7 @@ use tinywasm_types::{
use crate::{
func::{FromWasmValueTuple, IntoWasmValueTuple},
- Error, FuncHandle, FuncHandleTyped, Imports, Module, Result, Store,
+ log, Error, FuncHandle, FuncHandleTyped, Imports, Module, Result, Store,
};
/// An instanciated WebAssembly module
@@ -123,7 +123,8 @@ impl ModuleInstance {
&self.0.func_addrs
}
- pub(crate) fn func_tys(&self) -> &[FuncType] {
+ /// Get the module's function types
+ pub fn func_tys(&self) -> &[FuncType] {
&self.0.types
}
diff --git a/crates/tinywasm/src/lib.rs b/crates/tinywasm/src/lib.rs
index 5388c05..36270a7 100644
--- a/crates/tinywasm/src/lib.rs
+++ b/crates/tinywasm/src/lib.rs
@@ -78,7 +78,13 @@ use log;
#[cfg(not(feature = "logging"))]
pub(crate) mod log {
macro_rules! debug ( ($($tt:tt)*) => {{}} );
+ macro_rules! info ( ($($tt:tt)*) => {{}} );
+ macro_rules! trace ( ($($tt:tt)*) => {{}} );
+ macro_rules! error ( ($($tt:tt)*) => {{}} );
pub(crate) use debug;
+ pub(crate) use error;
+ pub(crate) use info;
+ pub(crate) use trace;
}
mod error;
diff --git a/crates/tinywasm/src/runtime/interpreter/mod.rs b/crates/tinywasm/src/runtime/interpreter/mod.rs
index 48ce21d..db013a0 100644
--- a/crates/tinywasm/src/runtime/interpreter/mod.rs
+++ b/crates/tinywasm/src/runtime/interpreter/mod.rs
@@ -1,16 +1,24 @@
-use core::ops::{BitAnd, BitOr, BitXor, Neg};
-
use super::{InterpreterRuntime, Stack};
+use crate::log;
use crate::{
log::debug,
runtime::{BlockType, CallFrame, LabelArgs, LabelFrame},
Error, FuncContext, ModuleInstance, Result, Store, Trap,
};
use alloc::{string::ToString, vec::Vec};
+use core::ops::{BitAnd, BitOr, BitXor, Neg};
use tinywasm_types::{ElementKind, Instruction, ValType};
+#[cfg(not(feature = "std"))]
+mod no_std_floats;
+
+#[cfg(not(feature = "std"))]
+#[allow(unused_imports)]
+use no_std_floats::FExt;
+
mod macros;
mod traits;
+
use macros::*;
use traits::*;
diff --git a/crates/tinywasm/src/runtime/interpreter/no_std_floats.rs b/crates/tinywasm/src/runtime/interpreter/no_std_floats.rs
new file mode 100644
index 0000000..095fe9f
--- /dev/null
+++ b/crates/tinywasm/src/runtime/interpreter/no_std_floats.rs
@@ -0,0 +1,77 @@
+pub(super) trait FExt {
+ fn round(self) -> Self;
+ fn abs(self) -> Self;
+ fn signum(self) -> Self;
+ fn ceil(self) -> Self;
+ fn floor(self) -> Self;
+ fn trunc(self) -> Self;
+ fn sqrt(self) -> Self;
+ fn copysign(self, other: Self) -> Self;
+}
+
+impl FExt for f64 {
+ fn round(self) -> Self {
+ libm::round(self)
+ }
+
+ fn abs(self) -> Self {
+ libm::fabs(self)
+ }
+
+ fn signum(self) -> Self {
+ libm::copysign(1.0, self)
+ }
+
+ fn ceil(self) -> Self {
+ libm::ceil(self)
+ }
+
+ fn floor(self) -> Self {
+ libm::floor(self)
+ }
+
+ fn trunc(self) -> Self {
+ libm::trunc(self)
+ }
+
+ fn sqrt(self) -> Self {
+ libm::sqrt(self)
+ }
+
+ fn copysign(self, other: Self) -> Self {
+ libm::copysign(self, other)
+ }
+}
+impl FExt for f32 {
+ fn round(self) -> Self {
+ libm::roundf(self)
+ }
+
+ fn abs(self) -> Self {
+ libm::fabsf(self)
+ }
+
+ fn signum(self) -> Self {
+ libm::copysignf(1.0, self)
+ }
+
+ fn ceil(self) -> Self {
+ libm::ceilf(self)
+ }
+
+ fn floor(self) -> Self {
+ libm::floorf(self)
+ }
+
+ fn trunc(self) -> Self {
+ libm::truncf(self)
+ }
+
+ fn sqrt(self) -> Self {
+ libm::sqrtf(self)
+ }
+
+ fn copysign(self, other: Self) -> Self {
+ libm::copysignf(self, other)
+ }
+}
diff --git a/crates/tinywasm/src/runtime/interpreter/traits.rs b/crates/tinywasm/src/runtime/interpreter/traits.rs
index 06aab2a..06a97e3 100644
--- a/crates/tinywasm/src/runtime/interpreter/traits.rs
+++ b/crates/tinywasm/src/runtime/interpreter/traits.rs
@@ -11,6 +11,9 @@ pub(crate) trait WasmFloatOps {
fn wasm_nearest(self) -> Self;
}
+#[cfg(not(feature = "std"))]
+use super::no_std_floats::FExt;
+
macro_rules! impl_wasm_float_ops {
($($t:ty)*) => ($(
impl WasmFloatOps for $t {
diff --git a/crates/tinywasm/src/runtime/stack/call_stack.rs b/crates/tinywasm/src/runtime/stack/call_stack.rs
index 098b918..20de728 100644
--- a/crates/tinywasm/src/runtime/stack/call_stack.rs
+++ b/crates/tinywasm/src/runtime/stack/call_stack.rs
@@ -1,3 +1,4 @@
+use crate::log;
use crate::{
runtime::{BlockType, RawWasmValue},
Error, FunctionInstance, Result, Trap,
diff --git a/crates/tinywasm/src/runtime/stack/value_stack.rs b/crates/tinywasm/src/runtime/stack/value_stack.rs
index e4467da..bb4e398 100644
--- a/crates/tinywasm/src/runtime/stack/value_stack.rs
+++ b/crates/tinywasm/src/runtime/stack/value_stack.rs
@@ -1,5 +1,6 @@
use core::ops::Range;
+use crate::log;
use crate::{runtime::RawWasmValue, Error, Result};
use alloc::vec::Vec;
use tinywasm_types::{ValType, WasmValue};
diff --git a/crates/tinywasm/src/store.rs b/crates/tinywasm/src/store.rs
index 4d3e326..d281b5c 100644
--- a/crates/tinywasm/src/store.rs
+++ b/crates/tinywasm/src/store.rs
@@ -1,9 +1,9 @@
+use crate::log;
+use alloc::{boxed::Box, format, rc::Rc, string::ToString, vec, vec::Vec};
use core::{
cell::RefCell,
sync::atomic::{AtomicUsize, Ordering},
};
-
-use alloc::{boxed::Box, format, rc::Rc, string::ToString, vec, vec::Vec};
use tinywasm_types::*;
use crate::{
@@ -581,7 +581,7 @@ impl TableInstance {
pub(crate) const PAGE_SIZE: usize = 65536;
pub(crate) const MAX_PAGES: usize = 65536;
-pub(crate) const MAX_SIZE: usize = PAGE_SIZE * MAX_PAGES;
+pub(crate) const MAX_SIZE: u64 = PAGE_SIZE as u64 * MAX_PAGES as u64;
/// A WebAssembly Memory Instance
///
@@ -660,7 +660,7 @@ impl MemoryInstance {
}
let new_size = new_pages as usize * PAGE_SIZE;
- if new_size > MAX_SIZE {
+ if new_size as u64 > MAX_SIZE {
return None;
}
diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs
index a467d7a..d0d854c 100644
--- a/crates/types/src/lib.rs
+++ b/crates/types/src/lib.rs
@@ -11,16 +11,15 @@
extern crate alloc;
// log for logging (optional).
-// #[cfg(feature = "logging")]
-// #[allow(unused_imports)]
-// use log;
+#[cfg(feature = "logging")]
+use log;
-// #[cfg(not(feature = "logging"))]
-// #[macro_use]
-// pub(crate) mod log {
-// // macro_rules! debug ( ($($tt:tt)*) => {{}} );
-// // pub(crate) use debug;
-// }
+#[cfg(not(feature = "logging"))]
+#[macro_use]
+pub(crate) mod log {
+ macro_rules! error ( ($($tt:tt)*) => {{}} );
+ pub(crate) use error;
+}
mod instructions;
use core::{fmt::Debug, ops::Range};
diff --git a/examples/rust/Cargo.toml b/examples/rust/Cargo.toml
new file mode 100644
index 0000000..91b6aed
--- /dev/null
+++ b/examples/rust/Cargo.toml
@@ -0,0 +1,23 @@
+cargo-features=["per-package-target"]
+
+[package]
+publish=false
+name="rust-wasm-examples"
+forced-target="wasm32-unknown-unknown"
+edition="2021"
+
+[dependencies]
+tinywasm={path="../../crates/tinywasm", default-features=false, features=["parser"]}
+embedded-alloc={version="0.5"}
+
+[[bin]]
+name="hello"
+path="src/hello.rs"
+
+[[bin]]
+name="tinywasm"
+path="src/tinywasm.rs"
+
+[profile.release]
+opt-level="z"
+panic="abort"
diff --git a/examples/rust/README.md b/examples/rust/README.md
new file mode 100644
index 0000000..8ecac52
--- /dev/null
+++ b/examples/rust/README.md
@@ -0,0 +1 @@
+# Examples using Rust compiled to WebAssembly
diff --git a/examples/rust/src/hello.rs b/examples/rust/src/hello.rs
new file mode 100644
index 0000000..34f3c7f
--- /dev/null
+++ b/examples/rust/src/hello.rs
@@ -0,0 +1,18 @@
+#![no_std]
+#![no_main]
+
+#[cfg(not(test))]
+#[panic_handler]
+fn panic(_info: &core::panic::PanicInfo) -> ! {
+ core::arch::wasm32::unreachable()
+}
+
+#[link(wasm_import_module = "env")]
+extern "C" {
+ fn printi32(x: i32);
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn add_and_print(lh: i32, rh: i32) {
+ printi32(lh + rh);
+}
diff --git a/examples/rust/src/tinywasm.rs b/examples/rust/src/tinywasm.rs
new file mode 100644
index 0000000..4edde66
--- /dev/null
+++ b/examples/rust/src/tinywasm.rs
@@ -0,0 +1,41 @@
+#![no_std]
+#![no_main]
+
+use embedded_alloc::Heap;
+// use tinywasm::{Extern, FuncContext};
+
+#[cfg(not(test))]
+#[panic_handler]
+fn panic(_info: &core::panic::PanicInfo) -> ! {
+ core::arch::wasm32::unreachable()
+}
+
+#[global_allocator]
+static HEAP: Heap = Heap::empty();
+
+#[no_mangle]
+pub unsafe extern "C" fn _start() {
+ // Initialize the allocator BEFORE you use it
+ {
+ use core::mem::MaybeUninit;
+ const HEAP_SIZE: usize = 1024;
+ static mut HEAP_MEM: [MaybeUninit<u8>; HEAP_SIZE] = [MaybeUninit::uninit(); HEAP_SIZE];
+ unsafe { HEAP.init(HEAP_MEM.as_ptr() as usize, HEAP_SIZE) }
+ }
+
+ // now the allocator is ready types like Box, Vec can be used.
+ let _ = run();
+}
+
+fn run() -> tinywasm::Result<()> {
+ // let module = tinywasm::Module::parse_bytes(include_bytes!("../out/hello.wasm"))?;
+ // let mut store = tinywasm::Store::default();
+
+ // let mut imports = tinywasm::Imports::new();
+ // imports.define("env", "printi32", Extern::typed_func(|_: FuncContext<'_>, _: i32| Ok(())))?;
+
+ // let instance = module.instantiate(&mut store, Some(imports))?;
+ // let add_and_print = instance.typed_func::<(i32, i32), ()>(&mut store, "add_and_print")?;
+ // add_and_print.call(&mut store, (1, 2))?;
+ Ok(())
+}
diff --git a/examples/wasm-rust.rs b/examples/wasm-rust.rs
new file mode 100644
index 0000000..21d3eb8
--- /dev/null
+++ b/examples/wasm-rust.rs
@@ -0,0 +1,41 @@
+use color_eyre::eyre::Result;
+use tinywasm::{Extern, FuncContext, Imports, Module, Store};
+
+fn main() -> Result<()> {
+ let args = std::env::args().collect::<Vec<_>>();
+ if args.len() < 2 {
+ println!("Usage: cargo run --example wasm-rust <rust_example>");
+ println!("Available examples:");
+ println!(" hello");
+ return Ok(());
+ }
+
+ match args[1].as_str() {
+ "hello" => hello()?,
+ _ => {}
+ }
+
+ Ok(())
+}
+
+fn hello() -> Result<()> {
+ // const HELLO_WASM: &[u8] = include_bytes!("./rust/out/hello.wasm");
+ // let module = Module::parse_bytes(&HELLO_WASM)?;
+ // let mut store = Store::default();
+
+ // let mut imports = Imports::new();
+ // imports.define(
+ // "env",
+ // "printi32",
+ // Extern::typed_func(|_: FuncContext<'_>, x: i32| {
+ // println!("{}", x);
+ // Ok(())
+ // }),
+ // )?;
+
+ // let instance = module.instantiate(&mut store, Some(imports))?;
+ // let add_and_print = instance.typed_func::<(i32, i32), ()>(&mut store, "add_and_print")?;
+ // add_and_print.call(&mut store, (1, 2))?;
+
+ Ok(())
+}