wag/README.md

179 lines
4.2 KiB
Markdown
Raw Permalink Normal View History

2020-03-29 20:09:00 +13:00
# WAG - The WebAssembly Code Generator
2020-03-28 16:28:17 +13:00
This Ruby gem allows you to generate WebAssembly programs programmatically using
a DSL.
2020-03-28 16:28:17 +13:00
It is closely modeled after WAT, the WebAssembly text format, and at this stage
generates WAT and compiles and validates it using [the WebAssembly Binary Toolkit][1].
Due to the flexibility of WAT this library is very flexible in what structures
2023-07-28 07:57:02 +12:00
it allows you to create. Be aware that you can build modules which are not
valid WASM. Always validate your modules by using `#to_wasm.valid?`.
## Keyword conflict
Any WASM instructions whose name conflicts with a Ruby keyword (eg `loop`,
`return`, etc) are also aliased with a underscore suffix for use in the DSL. The
methods defining the original names are also there, so can be used by the likes
of `public_send`, etc.
## Folding
WAG supports generating both the "folded" and "unfolded" variants of the WAT
2023-07-28 07:57:02 +12:00
language. As an example here are two implementations of Euclid's Greatest
Common Divisor algorithm:
### Example of unfolded generation
2020-03-29 20:09:00 +13:00
```ruby
unfolded = WAG::Module.new.build do
func(:gcd) do
param(:a, :i32)
param(:b, :i32)
2020-03-29 20:09:00 +13:00
result(:i32)
local(:r, :i32)
block
loop_
# let r = a % b
local.get(:a)
local.get(:b)
i32.rem_s
local.set(:r)
# let a = b and b = R
local.get(:b)
local.set(:a)
local.get(:r)
local.set(:b)
# if a % b == 0, return b
local.get(:a)
local.get(:b)
i32.rem_s
i32.eqz
br_if 1
br 0
end_
end_
local.get(:b)
return_
2020-03-29 20:09:00 +13:00
end
export("gcd").func(:gcd)
end
```
### Example of folded generation
2023-07-28 07:57:02 +12:00
```ruby
folded = WAG::Module.new.build do
func(:gcd) do
param(:a, :i32)
param(:b, :i32)
result(:i32)
local(:r, :i32)
block do
loop_ do
# let r = a % b
local.set(:r) do
i32.rem_s do
local.get(:a)
local.get(:b)
end
end
# let a = b and b = R
local.set(:a) do
local.get(:b)
end
local.set(:b) do
local.get(:r)
end
# if a % b == 0, return b
br_if(1) do
i32.eqz do
i32.rem_s do
local.get(:a)
local.get(:b)
end
end
end
br 0
end
end
return_ do
local.get(:b)
end
end
export("gcd") do
func(:gcd)
2020-03-29 20:09:00 +13:00
end
end
```
2020-03-28 16:28:17 +13:00
Both modules emit identical WASM bytecode and produce the same answers:
```ruby
folded.to_wasm.save("folded.wasm")
unfolded.to_wasm.save("unfolded.wasm")
```
```bash
$ sha256sum folded.wasm unfolded.wasm
0023ef97eba001226401e432912f2e644a6cbef107ba183546c51177eee46e2c folded.wasm
0023ef97eba001226401e432912f2e644a6cbef107ba183546c51177eee46e2c unfolded.wasm
$ wasmtime folded.wasm --invoke gcd 270 192
6
$ wasmtime unfolded.wasm --invoke gcd 270 192
6
```
1: https://github.com/WebAssembly/wabt
2020-03-28 16:28:17 +13:00
## Installation
Add this line to your application's `Gemfile`:
2020-03-28 16:28:17 +13:00
```ruby
gem 'wag'
```
And then execute:
$ bundle install
Or install it yourself as:
$ gem install wag
## Development
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
## Contributing
2024-02-05 14:56:03 +13:00
Bug reports and pull requests are welcome at https://harton.dev/james/wag.
2020-03-28 16:28:17 +13:00
## License
2023-01-17 10:31:11 +13:00
This software is licensed under the terms of the
[HL3-FULL](https://firstdonoharm.dev), see the `LICENSE.md` file included with
this package for the terms.
This license actively proscribes this software being used by and for some
2023-07-28 07:57:02 +12:00
industries, countries and activities. If your usage of this software doesn't
2023-01-17 10:31:11 +13:00
comply with the terms of this license, then [contact me](mailto:james@harton.nz)
with the details of your use-case to organise the purchase of a license - the
cost of which may include a donation to a suitable charity or NGO.