Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "wasm3"
version = "0.5.0"
authors = ["Lukas Tobias Wirth <[email protected]>"]
edition = "2018"
edition = "2021"
description = "Rust bindings for wasm3"
homepage = "https://github.com/wasm3/wasm3-rs"
repository = "https://github.com/wasm3/wasm3-rs"
Expand All @@ -15,12 +15,9 @@ exclude = ["examples/*", "tests/*"]
members = ["wasm3-sys"]

[features]
default = ["wasi", "std", "use-32bit-slots"]

default = ["wasi", "use-32bit-slots"]
wasi = ["ffi/wasi"]
std = []
use-32bit-slots = ["ffi/use-32bit-slots"]

build-bindgen = ["ffi/build-bindgen"]

[dependencies]
Expand Down
2 changes: 1 addition & 1 deletion src/environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ impl Environment {

impl core::cmp::Eq for Environment {}
impl core::cmp::PartialEq for Environment {
fn eq(&self, &Environment(ref other): &Environment) -> bool {
fn eq(&self, Environment(other): &Environment) -> bool {
alloc::rc::Rc::ptr_eq(&self.0, other)
}
}
Expand Down
9 changes: 3 additions & 6 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ impl cmp::PartialEq<Wasm3Error> for Trap {
}
}

#[cfg(feature = "std")]
impl std::error::Error for Trap {}
impl core::error::Error for Trap {}
impl fmt::Display for Trap {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(unsafe { cstr_to_str(self.as_ptr()) }, f)
Expand All @@ -85,8 +84,7 @@ impl cmp::PartialEq<Trap> for Wasm3Error {
}
}

#[cfg(feature = "std")]
impl std::error::Error for Wasm3Error {}
impl core::error::Error for Wasm3Error {}
impl fmt::Debug for Wasm3Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(unsafe { cstr_to_str(self.0) }, f)
Expand Down Expand Up @@ -129,8 +127,7 @@ impl Error {
}
}

#[cfg(feature = "std")]
impl std::error::Error for Error {}
impl core::error::Error for Error {}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Expand Down
10 changes: 5 additions & 5 deletions src/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,14 @@ pub struct Function<'rt, Args, Ret> {
_pd: PhantomData<*const (Args, Ret)>,
}

impl<'rt, Args, Ret> Eq for Function<'rt, Args, Ret> {}
impl<'rt, Args, Ret> PartialEq for Function<'rt, Args, Ret> {
impl<Args, Ret> Eq for Function<'_, Args, Ret> {}
impl<Args, Ret> PartialEq for Function<'_, Args, Ret> {
fn eq(&self, other: &Self) -> bool {
self.raw == other.raw
}
}

impl<'rt, Args, Ret> Hash for Function<'rt, Args, Ret> {
impl<Args, Ret> Hash for Function<'_, Args, Ret> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.raw.hash(state);
}
Expand Down Expand Up @@ -173,7 +173,7 @@ macro_rules! func_call_impl {
}
func_call_impl!(A, B, C, D, E, F, G, H, J, K, L, M, N, O, P, Q);

impl<'rt, ARG, Ret> Function<'rt, ARG, Ret>
impl<ARG, Ret> Function<'_, ARG, Ret>
where
Ret: WasmType,
ARG: WasmArg,
Expand All @@ -188,7 +188,7 @@ where
}
}

impl<'rt, Ret> Function<'rt, (), Ret>
impl<Ret> Function<'_, (), Ret>
where
Ret: WasmType,
{
Expand Down
17 changes: 8 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![no_std]
#![warn(missing_docs)]
//! A rust wrapper for [WASM3](https://github.com/wasm3/wasm3).

extern crate alloc;

pub mod error;

mod environment;
pub use self::environment::Environment;
pub mod error;
mod function;
pub use self::function::{CallContext, Function, RawCall};
mod macros;
pub use self::macros::*;
mod module;
pub use self::module::{Module, ParsedModule};
mod runtime;
pub use self::runtime::Runtime;
mod ty;
pub use self::ty::{WasmArg, WasmArgs, WasmType};
mod utils;

pub use self::environment::Environment;
pub use self::function::{CallContext, Function, RawCall};
pub use self::module::{Module, ParsedModule};
pub use self::runtime::Runtime;
pub use self::ty::{WasmArg, WasmArgs, WasmType};
pub use ffi as wasm3_sys;
7 changes: 6 additions & 1 deletion src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ impl<'rt> Module<'rt> {

/// Links the given function to the corresponding module and function name.
/// This allows linking a more verbose function, as it gets access to the unsafe
/// runtime parts. For easier use the [`make_func_wrapper`] should be used to create
/// runtime parts. For easier use the [`crate::make_func_wrapper`] should be used to create
/// the unsafe facade for your function that then can be passed to this.
///
/// For a simple API see [`link_closure`] which takes a closure instead.
Expand Down Expand Up @@ -221,6 +221,11 @@ impl<'rt> Module<'rt> {
unsafe { cstr_to_str(ffi::m3_GetModuleName(self.raw)) }
}

/// Compile all functions in the module.
pub fn compile(&mut self) -> Result<()> {
unsafe { Error::from_ffi_res(ffi::m3_CompileModule(self.raw)) }
}

/// Links wasi to this module.
#[cfg(feature = "wasi")]
pub fn link_wasi(&mut self) -> Result<()> {
Expand Down
2 changes: 1 addition & 1 deletion src/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ macro_rules! args_impl {
};
(@do_impl) => {/* catch the () case, since its implementation differs slightly */};
(@do_impl $($types:ident,)*) => {
#[allow(clippy::eval_order_dependence)]
#[allow(clippy::mixed_read_write_in_expression)]
#[allow(unused_assignments)]
impl<$($types,)*> WasmArgs for ($($types,)*)
where $($types: WasmArg,)* {
Expand Down
7 changes: 4 additions & 3 deletions src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use alloc::vec::Vec;
use core::{slice, str};

pub unsafe fn bytes_till_null<'a>(ptr: *const cty::c_char) -> &'a [u8] {
if ptr.is_null() {
Expand All @@ -11,15 +12,15 @@ pub unsafe fn bytes_till_null<'a>(ptr: *const cty::c_char) -> &'a [u8] {
ptr = ptr.add(1);
len += 1;
}
core::slice::from_raw_parts(start, len)
slice::from_raw_parts(start, len)
}

pub unsafe fn cstr_to_str<'a>(ptr: *const cty::c_char) -> &'a str {
core::str::from_utf8_unchecked(bytes_till_null(ptr))
str::from_utf8_unchecked(bytes_till_null(ptr))
}

pub fn str_to_cstr_owned(str: &str) -> Vec<cty::c_char> {
let mut cstr = Vec::with_capacity(str.as_bytes().len() + 1);
let mut cstr = Vec::with_capacity(str.len() + 1);
cstr.extend(str.bytes().map(|c| c as cty::c_char));
cstr.push(0 as cty::c_char);
cstr
Expand Down
6 changes: 3 additions & 3 deletions wasm3-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "wasm3-sys"
version = "0.5.0"
authors = ["Lukas Tobias Wirth <[email protected]>"]
edition = "2018"
edition = "2021"
description = "Raw ffi bindings for wasm3"
homepage = "https://github.com/wasm3/wasm3-rs"
repository = "https://github.com/wasm3/wasm3-rs"
Expand All @@ -22,10 +22,10 @@ cty = "0.2"

[build-dependencies]
cc = "1"
shlex = "0.1.1"
shlex = "1.3.0"

[build-dependencies.bindgen]
version = "0.59"
version = "0.71.1"
optional = true

[package.metadata.docs.rs]
Expand Down
96 changes: 44 additions & 52 deletions wasm3-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,28 +27,28 @@ fn gen_wrapper(out_path: &Path) -> PathBuf {

#[cfg(not(feature = "build-bindgen"))]
fn gen_bindings() {
use std::process::Command;
let out_path = PathBuf::from(&env::var("OUT_DIR").unwrap());

let wrapper_file = gen_wrapper(&out_path);

let mut bindgen = std::process::Command::new("bindgen");
bindgen
.arg(wrapper_file)
.arg("--use-core")
.arg("--ctypes-prefix")
.arg("cty")
.arg("--no-layout-tests")
.arg("--default-enum-style=moduleconsts")
.arg("--no-doc-comments")
.arg("--whitelist-function")
.arg(WHITELIST_REGEX_FUNCTION)
.arg("--whitelist-type")
.arg(WHITELIST_REGEX_TYPE)
.arg("--whitelist-var")
.arg(WHITELIST_REGEX_VAR)
.arg("--no-derive-debug");
for &ty in PRIMITIVES.iter() {
bindgen.arg("--blacklist-type").arg(ty);
let mut bindgen = Command::new("bindgen");
bindgen.arg(wrapper_file);
bindgen.args([
"--use-core",
"--ctypes-prefix",
"cty",
"--no-layout-tests",
"--default-enum-style=moduleconsts",
"--no-doc-comments",
"--allowlist-function",
WHITELIST_REGEX_FUNCTION,
"--allowlist-type",
WHITELIST_REGEX_TYPE,
"--allowlist-var",
WHITELIST_REGEX_VAR,
"--no-derive-debug",
]);
for &ty in PRIMITIVES {
bindgen.arg("--blocklist-type").arg(ty);
}
bindgen
.arg("-o")
Expand All @@ -57,26 +57,23 @@ fn gen_bindings() {
.arg("--")
.arg(format!(
"-Dd_m3Use32BitSlots={}",
if cfg!(feature = "use-32bit-slots") {
1
} else {
0
}
cfg!(feature = "use-32bit-slots") as u8,
))
.arg("-Dd_m3LogOutput=0")
.arg("-Iwasm3/source");
let status = bindgen.status().expect("Unable to generate bindings");
let status = match bindgen.status() {
Ok(status) => status,
Err(error) => panic!("wasm3: unable to generate bindings: {error}"),
};
if !status.success() {
panic!("Failed to run bindgen: {:?}", status);
panic!("wasm3: failed to run bindgen: {:?}", status);
}
}

#[cfg(feature = "build-bindgen")]
fn gen_bindings() {
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());

let wrapper_file = gen_wrapper(&out_path);

let mut bindgen = bindgen::builder()
.header(wrapper_file.to_str().unwrap())
.use_core()
Expand All @@ -91,26 +88,22 @@ fn gen_bindings() {
bindgen = PRIMITIVES
.iter()
.fold(bindgen, |bindgen, ty| bindgen.blocklist_type(ty));
let bindgen = bindgen.clang_args(
[
&format!(
"-Dd_m3Use32BitSlots={}",
cfg!(feature = "use-32bit-slots") as u8,
),
"-Dd_m3LogOutput=0",
"-Iwasm3/source",
]
.iter(),
);
bindgen
.clang_args(
[
&format!(
"-Dd_m3Use32BitSlots={}",
if cfg!(feature = "use-32bit-slots") {
1
} else {
0
}
),
"-Dd_m3LogOutput=0",
"-Iwasm3/source",
]
.iter(),
)
.generate()
.expect("Failed to generate bindings")
.unwrap_or_else(|error| panic!("bindgen: failed to generate bindings: {error}"))
.write_to_file(out_path.join("bindings.rs").to_str().unwrap())
.expect("Failed to write bindings");
.unwrap_or_else(|error| panic!("bindgen: failed to write bindings: {error}"));
}

fn main() {
Expand All @@ -120,7 +113,7 @@ fn main() {

cfg.files(
fs::read_dir(WASM3_SOURCE)
.unwrap_or_else(|_| panic!("failed to read {} directory", WASM3_SOURCE))
.unwrap_or_else(|error| panic!("failed to read {WASM3_SOURCE} directory: {error}"))
.filter_map(Result::ok)
.map(|entry| entry.path())
.filter(|p| p.extension().and_then(OsStr::to_str) == Some("c")),
Expand Down Expand Up @@ -150,11 +143,10 @@ fn main() {

cfg.define(
"d_m3Use32BitSlots",
if cfg!(feature = "use-32bit-slots") {
Some("1")
} else {
Some("0")
},
match cfg!(feature = "use-32bit-slots") {
true => Some("1"),
false => Some("0"),
}
);
cfg.compile("wasm3");
}
2 changes: 1 addition & 1 deletion wasm3-sys/wasm3
Submodule wasm3 updated 82 files
+109 −77 .github/workflows/tests.yml
+1 −0 .gitignore
+19 −7 CMakeLists.txt
+56 −44 README.md
+181 −0 build-cross.py
+39 −0 build.zig
+53 −0 docs/Cookbook.md
+3 −1 docs/Demos.md
+31 −1 docs/Development.md
+5 −5 docs/Interpreter.md
+ extra/logos/blynk.png
+0 −0 extra/logos/iden3.svg
+ extra/logos/losant.png
+ extra/logos/scailable.png
+0 −0 extra/logos/shareup_app.svg
+ extra/logos/wasmcloud.png
+ extra/logos/wowcube.png
+ extra/screenshot-android.png
+ extra/screenshot-ios.png
+ extra/txiki_js.png
+3 −3 platforms/android/README.md
+6 −6 platforms/android/app/build.gradle
+3 −3 platforms/android/build.gradle
+ platforms/android/gradle/wrapper/gradle-wrapper.jar
+1 −1 platforms/android/gradle/wrapper/gradle-wrapper.properties
+154 −103 platforms/android/gradlew
+4 −18 platforms/android/gradlew.bat
+15 −3 platforms/app/main.c
+1 −1 platforms/cosmopolitan/build.sh
+25 −4 platforms/cpp/README.md
+31 −8 platforms/cpp/main.cpp
+17 −0 platforms/cpp/wasm/test_prog.c
+ platforms/cpp/wasm/test_prog.wasm
+65 −22 platforms/cpp/wasm/test_prog.wasm.h
+90 −53 platforms/cpp/wasm3_cpp/include/wasm3_cpp.h
+1 −1 platforms/embedded/esp32-idf-wasi/README.md
+2 −2 platforms/embedded/esp32-idf-wasi/main/CMakeLists.txt
+229 −149 platforms/embedded/esp32-idf-wasi/main/m3_api_esp_wasi.c
+12 −7 platforms/embedded/esp32-idf-wasi/main/m3_api_esp_wasi.h
+9 −2 platforms/embedded/esp32-idf-wasi/main/main.cpp
+0 −0 platforms/embedded/esp32-idf-wasi/main/wasm3
+1 −0 platforms/embedded/particle/src/main.ino
+1 −1 platforms/ios/README.md
+2 −8 platforms/ios/wasm3.xcodeproj/project.pbxproj
+12 −43 platforms/ios/wasm3/main.c
+1 −1 platforms/openwrt/build/Makefile
+0 −3 source/CMakeLists.txt
+0 −2 source/m3_api_defs.h
+6 −1 source/m3_api_libc.c
+426 −59 source/m3_api_meta_wasi.c
+243 −59 source/m3_api_uvwasi.c
+19 −9 source/m3_api_wasi.c
+11 −1 source/m3_api_wasi.h
+11 −37 source/m3_bind.c
+23 −10 source/m3_code.c
+1 −1 source/m3_code.h
+300 −185 source/m3_compile.c
+28 −11 source/m3_compile.h
+19 −10 source/m3_config.h
+39 −12 source/m3_config_platforms.h
+41 −27 source/m3_core.c
+65 −14 source/m3_core.h
+0 −111 source/m3_emit.c
+0 −28 source/m3_emit.h
+137 −45 source/m3_env.c
+12 −1 source/m3_env.h
+4 −5 source/m3_exception.h
+1 −62 source/m3_exec.c
+101 −75 source/m3_exec.h
+24 −6 source/m3_exec_defs.h
+1 −1 source/m3_function.c
+1 −0 source/m3_function.h
+135 −84 source/m3_info.c
+2 −1 source/m3_info.h
+21 −21 source/m3_math_utils.h
+13 −6 source/m3_module.c
+0 −12 source/m3_optimize.c
+42 −17 source/m3_parse.c
+28 −12 source/wasm3.h
+24 −13 source/wasm3_defs.h
+3 −2 test/run-spec-test.py
+4 −7 test/run-wasi-test.py