Giter Site home page Giter Site logo

wasm-float-transpiler's Introduction

Wasm Float Transpiler

Converts a wasm file with floating point instructions (f32, f64) to one without such instructions. The instructions are replaced with deterministic software implementations of these instructions.

Usage

In order to include the softfloat implementation in your project, choose one of the wasm-soft-float-* backend crates as a dependency and include it in your build by adding a pub use wasm_soft_floats_*::*; to your project.

Check out the backends folder for the complete set of backend options and their supported operations. Your best bet is probably wasm-soft-float-bs based on the Berkeley Softfloat library. It covers almost all instructions.

Example lib.rs:

pub use wasm_soft_float_bs::*;

#[no_mangle]
pub extern "C" fn test(a: f32, b: f32) -> f32 {
    a + b
}

Then compile your project and call wasm-float-transpiler on your wasm file, like this:

wasm-float-transpiler my_project.wasm output.wasm

The resulting output.wasm file now contains your finished WebAssembly without any trace of floating point operations and with only the softfloat functions that you actually use.

Example

Check out the examples folder. To compile the examples run:

cd examples
cargo build --target wasm32-unknown-unknown --release --workspace
cd ..

To then transpile the resulting wasm, run:

cargo run -p wasm-float-transpiler -- ./examples/target/wasm32-unknown-unknown/release/basic_wasm_float.wasm output.wasm

wasm-float-transpiler's People

Contributors

chipshort avatar

Stargazers

Belsy avatar dzmitry-lahoda avatar Maciej Zieliński avatar Vlad J avatar

Watchers

 avatar  avatar

wasm-float-transpiler's Issues

Add more documentation

Currently the README is very basic. A bit more info might be good.

We should add some info about:

  • determinism: This crate is deterministic irrespective of host platform
  • what is considered a breaking change (I think basically any change of result for the same inputs is breaking, since that might break contract logic, but I'm open to discuss that)
  • how to use different backends

Compare backends

We should benchmark the backends against each other in terms of speed, but mostly in terms of size, since that's probably the most limiting factor.
Also see #5 for some more backends to check.

Add CI

  • Run tests
  • Rustfmt
  • Clippy
  • Coverage?

Use separate crates instead of feature flags

Cargo features are supposed to be additive, not mutually exclusive.
Currently the back-end for wasm-soft-float is selected using a feature. Instead they should be split up (maybe with a common lib for the general stuff)

Investigate more possible backends

Here are some more possible backends, I found:

simple-soft-float
rug # uses mpfr under the hood
softfloat-wrapper / softfloat-sys # uses berkeley softfloat under the hood
dashu-float # arbitrary base and has much higher precision than we actually need, so probably not interesting
astro-float # arbitrary precision
https://github.com/huonw/float # haven't checked yet, but is very old and has deprecated dependency
amplify_apfloat # looks like a fork of rustc_apfloat, has more downloads on crates.io

Note on C libraries

rug and softfloat-wrapper would be great candidates if we could get the underlying c libraries to compile on wasm, since they are widely known and battle proven. mpfr might be somewhat problematic for some projects because of GPL, but a note on that somewhere should be fine. I have tried getting a wasm project to compile with them, but had no luck until now.

Add tests

There are a few tests already, but I think a different approach might be good:

  • Either the transpiler or the soft-float crate need to be validated against the float-releated wasm-spec tests. walrus has these already, so it's probably possible to borrow from them. Still, this is tricky in either case, since the tests are written in wast (wat + assertions), so it is hard to inject the softfloat functions. On the other hand, we could try to translate the tests to Rust, but that's probably even harder (at least in an automated way). For most of the tests, it should be doable though to inject the softfloat wasm, since they contain literally just a few functions, no memory or table, etc.
    As an alternative, we could use wasmer here, include the soft-float crate in the wasmer build and "reimplement" the translation of wasm instructions to function calls in there (that would only test the soft-float crate, not the transpiler and would also be quite a bit of work).
  • If the above cannot be done or is too complicated, then the soft-float crate at the very least needs to be tested against the requirements of the wasm spec. The spec also contains some properties that should hold for some operations (see e.g. this note). These could be implemented as quickcheck tests (I have already done so for a few)
  • The soft-float crate should ideally even test the results of operations that are non-deterministic in the spec, to make sure that its behaviour does not change when upgrading the underlying backend
  • Ideally these tests would even be run on different host platforms to check that they really are the same on different platforms, but in theory this should not be necessary, since the compiler does not know what platform the wasm will run on, so it cannot introduce differences at compile-time and the wasm contains only deterministic instructions at the end and has no way of knowing what it is running on.

Finish implementing float operations

It should be possible to implement all of them for rustc_apfloat. sqrt might have to be implemented manually in terms of the other operations (mul, div, etc.), but the algorithms for that are pretty easy and short. Might want to do some benchmarking on code size and performance for those algorithms, but probably not that important for now.

For softfp, not all instructions will be supported. Make sure to comment the ones that are not available out, because then the transpiler will throw a compile-time error when encountering such an instruction instead of a runtime error like the todo macro.

Since softfp does not fully support everything, we might want to make rustc_apfloat the default feature instead.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.