# w2c2-rs
[](https://crates.io/crates/w2c2)
[](https://opensource.org/licenses/MIT)
`w2c2-rs` is a Rust wrapper for `w2c2`, a WebAssembly to C compiler. This project provides low-level bindings (`w2c2-sys`) to the underlying C library, enabling Rust applications to compile WebAssembly modules into C code.
## Workspace Crates
This repository is a Cargo workspace containing the following crates:
* `w2c2`: A high-level, safe Rust wrapper for `w2c2` (currently under development).
* `w2c2-sys`: Low-level, unsafe bindings to the `w2c2` C library, generated using `bindgen`.
* `example-simple`: A basic example demonstrating how to use the `w2c2-sys` crate to compile a WebAssembly module.
## Features
The `w2c2-sys` crate provides the following Cargo features:
* `bindgen`: Enables the automatic regeneration of Rust bindings from the C source code. This is useful for developers who want to update the underlying C library or customize the bindings.
## Usage
Here is a basic example of how to use `w2c2-sys` to compile a WebAssembly module to C code. This example is based on the `example-simple` crate.
### 1. Add `w2c2-sys` to your `Cargo.toml`
```toml
[dependencies]
w2c2-sys = { version = "0.1.0", path = "path/to/w2c2-sys" }
```
### 2. Compile a WebAssembly Module
The following Rust code demonstrates how to load a WebAssembly module, parse it, and compile it into a C source file named `test.c`.
```rust
use std::{ffi::CStr, ptr::null_mut};
use const_default::ConstDefault;
use w2c2_sys::{
Buffer, WasmCWriteModuleOptions, WasmFunctionIDs, WasmModuleReader, WasmModuleReaderError,
wasmCWriteModule, wasmModuleRead, wasmModuleReaderErrorMessage,
};
macro_rules! const_wat2wasm {
($e:expr) => {
crabtime::eval! {
#![dependency(wat = "1.234.0")]
crabtime::output_str!("{}", format!("{:?}", wat::parse_str($e).unwrap()))
}
};
}
const WASM: &[u8] = &const_wat2wasm!(
r#"(module
(func $foo)
(func (export "bar")
call $foo
)
)"#
);
fn main() {
unsafe {
let mut error: *mut WasmModuleReaderError = null_mut();
let reader = WasmModuleReader::builder()
.buffer(
Buffer::builder()
.data(WASM.as_ptr() as *mut _)
.length(WASM.len())
.build(),
)
.debug(false)
.module(null_mut())
.build();
wasmModuleRead(&reader as *const _ as *mut _, &mut error);
if error != null_mut() {
println!(
"w2c2: failed to read module: {:?}",
CStr::from_ptr(wasmModuleReaderErrorMessage(error))
)
}
let mut output_path = b"test.c".to_vec();
output_path.resize(1024, 0);
wasmCWriteModule(
reader.module,
c"test".as_ptr(),
WasmCWriteModuleOptions {
outputPath: output_path.as_ptr() as *const _,
..WasmCWriteModuleOptions::DEFAULT
},
WasmFunctionIDs::DEFAULT,
WasmFunctionIDs::DEFAULT,
);
}
}
```
### Workflow
The following diagram illustrates the compilation workflow:
```mermaid
graph TD
A[Start] --> B{Load .wasm bytes};
B --> C{Create Buffer};
C --> D{Instantiate WasmModuleReader};
D --> E{Call wasmModuleRead};
E --> F{Check for errors};
F -- No errors --> G{Call wasmCWriteModule};
G --> H[Output test.c];
F -- Error --> I[Print error message];
H --> J[End];
I --> J;
```
## Building from Source
The `w2c2` C library is automatically compiled and linked by the `build.rs` script in the `w2c2-sys` crate. No manual compilation of the C source code is required.
## License
This project is licensed under the [MIT License](https://opensource.org/licenses/MIT).