in

dtolnay / watt, Hacker News

dtolnay / watt, Hacker News


                    

        

Build StatusLatest VersionRust Documentation

Watt*is a runtime for executing Rust procedural macros compiled as WebAssembly.

*optional but entertaining pronunciation:Wahteetee

[dependencies]watt=" (0.1)  "

Compiler support: requires rustc 1. 35

Getting started

Start by implementing and testing your proc macro as you normally would, using whatever dependencies you want (syn, quote, etc). You will end up with something that looks like:

externcrateproc_macro;useproc_macro::TokenStream;  # [proc_macro]pubFNmy_macro(input: TokenStream) ->TokenStream {     / * ... * /}

# [proc_macro_derive]and# [proc_macro_attribute]are supported as well; everything is analogous to what will be shown here for# [proc_macro].

When your macro is ready, there are just a few changes we need to make to the signature and the Cargo.toml. In your lib.rs, change each of your macro entry points to a no_mangle extern “C” function, and change the TokenStream in the signature from proc_macro to proc_macro2. Finally, add a call toproc_macro2 :: set_wasm_panic_hook ()at the top of your macro to ensure panics get printed to the console; this is optional but helpful!

It will look like:

useproc_macro2::TokenStream;  # [no_mangle]pubextern"C"fnmy_macro(input: TokenStream) ->TokenStream {     proc_macro2::set_wasm_panic_hook();      / * same as before * /}

Now in your macro’s Cargo.toml which used to contain this:

change it instead to say:

[lib]crate-type=["cdylib","rlib"]  [patch.crates-io]proc-macro2={git="https : //github.com/dtolnay/watt"}}

This crate will be the binary that we compile to Wasm. Compile it by running:

$cargo build --release --target wasm 32 - unknown-unknown

Next we need to make a small proc-macro shim crate to hand off the compiled Wasm bytes into the Watt runtime. In a new Cargo.toml, put:

[lib]proc-macro=true[dependencies]watt=" (0.1)  "

And in its src / lib.rs put:

externcrateproc_macro;useproc_macro::TokenStream;staticWASM:&[u8]=include_bytes!("my_macro.wasm");  # [proc_macro]pubfn(input: TokenStream)->TokenStream {     watt::proc_macro("my_macro", input, WASM) }

Finally, copy the compiled Wasm binary from target / wasm 32 – unknown -unknown / release / my_macro.wasm under your implementation crate, to the src directory of your shim crate, and it’s ready to publish!

Remaining work

  • Performance.Watt compiles pretty fast, but so far I have not put any effort toward optimizing the runtime. That means macro expansion can potentially take longer than with a natively compiled proc macro.

    Note that the performance overhead of the Wasm environment is partially offset by the fact that our proc macros are compiled to Wasm in release mode, so Downstreamcargo buildwill be running a release-mode macro when it would have been running debug-mode for a traditional proc macro.

    There is a great deal of low-hanging fruit in the runtime; as I said, it hasn’t been optimized. In particular I am doing something silly with how strings are handed off one character at a time instead of in bulk in memory. I. would love contributions from people who have a better idea of ​​how this stuff is intended to work in Wasm in general.

    As another idea, maybe there could be some kind ofcargo install watt-runtimewhich installs an optimized Wasm runtime locally, which the Watt crate can detect and hand off code to if available. That way we avoid running things in a debug-mode runtime altogether.

  • Tooling.The getting started section shows there are a lot of steps to building a macro for Watt, and a pretty hacky patching in of proc-macro2. Ideally this would all be more straightforward, including easy tooling for doing reproducible builds of the Wasm artifact for confirming that it was indeed compiled from the publicly available sources.

  • RFCs.The advantages of fast compile time, isolation, and determinism may make it worthwhile to build first-class support for Wasm proc macros into rustc and Cargo. The toolchain could ship its own high performance Wasm runtime, which is an even better outcome than Watt because that runtime can be heavily optimized and consumers of macros don’t need to compile it.

This can’t be real

To assist in convincing you that this is real,here is serde_derive compiled to Wasm. It was compiled from the commitserde-rs / @ serde 217 BA (e) . Feel free to try it out as:

// [dependencies]// serde="1.0"// serde_json="1.0"// wa-serde-derive="0.1"usewa_serde_derive::Serialize;  # [derive(Serialize)]structWatt{     msg: &'static(str) , }FNmain() {     letw=Watt {msg:"hello from wasm!"};     println!("{}", serde_json::to_string(&  (w).unwrap()); }

Acknowledgments

The current underlying Wasm runtime is a fork of the Rust-WASM

project by Yoann Blein and Hugo Guiroux, a simple and spec-compliant WebAssembly interpreter.

Apache License, Version 2.0orMIT licenseat your option. The `runtime` directory is licensed under theISC license.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

  

Brave Browser
(Read More)
Payeer

What do you think?

Leave a Reply

Your email address will not be published. Required fields are marked *

GIPHY App Key not set. Please check settings

New drug-pricing data shows stunning hikes — one whopping 667% increase, Hacker News

New drug-pricing data shows stunning hikes — one whopping 667% increase, Hacker News

The world’s oldest leftovers, left in Pleistocene storage containers, Ars Technica

The world’s oldest leftovers, left in Pleistocene storage containers, Ars Technica