w2c2

Crates.iow2c2
lib.rsw2c2
version0.1.0
created_at2025-06-11 17:26:32.46487+00
updated_at2025-06-11 17:26:32.46487+00
descriptionHigh level crate for w2c2-sys
homepage
repositoryhttps://github.com/stevefan1999-personal/w2c2-rs
max_upload_size
id1708874
size21,412
Steve Fan (stevefan1999-personal)

documentation

README

w2c2-rs

Crate License: 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

[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.

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:

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.

Commit count: 1

cargo fmt