Ruby WebAssembly code generator DSL. https://rubygems.org/gems/wag
Find a file
Renovate Bot 16447e3507
All checks were successful
continuous-integration/drone/push Build is passing
chore: Configure Renovate (#190)
Welcome to [Renovate](https://github.com/renovatebot/renovate)! This is an onboarding PR to help you understand and configure settings before regular Pull Requests begin.

🚦 To activate Renovate, merge this Pull Request. To disable Renovate, simply close this Pull Request unmerged.

---
### Detected Package Files

 * `.tool-versions` (asdf)
 * `Gemfile` (bundler)
 * `.drone.yml` (droneci)

### Configuration Summary

Based on the default config's presets, Renovate will:

  - Start dependency updates only once this onboarding PR is merged
  - Enable Renovate Dependency Dashboard creation.
  - Use semantic commit type `fix` for dependencies and `chore` for all others if semantic commits are in use.
  - Ignore `node_modules`, `bower_components`, `vendor` and various test/tests directories.
  - Group known monorepo packages together.
  - Use curated list of recommended non-monorepo package groupings.
  - Apply crowd-sourced package replacement rules.
  - Apply crowd-sourced workarounds for known problems with packages.
  - Use semantic prefixes for commit messages and PR titles.
  - Use `chore` as semantic commit type for commit messages and PR titles.
  - Removes rate limit for PR creation per hour.
  - Remove limit for open PRs at any time.
  - Automerge all upgrades (including `major`) if they pass tests.
  - Assign PRs to `james`.
  - Rebase existing PRs any time the base branch has been updated.
  - Raise PR when vulnerability alerts are detected.
  - Disable Renovate Dependency Dashboard creation.

🔡 Would you like to change the way Renovate is upgrading your dependencies? Simply edit the `renovate.json` in this branch with your custom config and the list of Pull Requests in the "What to Expect" section below will be updated the next time Renovate runs.

---

### What to Expect

With your current configuration, Renovate will create 3 Pull Requests:

<details>
<summary>chore(deps): update dependency rubocop to '~> 1.55.0'</summary>

  - Schedule: ["at any time"]
  - Branch name: `renovate/rubocop-1.x`
  - Merge into: `main`
  - Upgrade [rubocop](https://github.com/rubocop/rubocop) to `'~> 1.55.0'`

</details>

<details>
<summary>chore(deps): update dependency ruby to v3.2.2</summary>

  - Schedule: ["at any time"]
  - Branch name: `renovate/ruby-3.x`
  - Merge into: `main`
  - Upgrade [ruby](https://github.com/ruby/ruby) to `3.2.2`

</details>

<details>
<summary>chore(deps): lock file maintenance</summary>

  - Branch name: `renovate/lock-file-maintenance`
  - Merge into: `main`
  - Regenerate lock files to use latest dependency versions

</details>

---

 Got questions? Check out Renovate's [Docs](https://docs.renovatebot.com/), particularly the Getting Started section.
If you need any further assistance then you can also [request help here](https://github.com/renovatebot/renovate/discussions).

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).

Co-authored-by: Renovate Bot <bot@harton.nz>
Reviewed-on: https://code.harton.nz/james/wag/pulls/190
Co-authored-by: Renovate Bot <renovate@noreply.localhost>
Co-committed-by: Renovate Bot <renovate@noreply.localhost>
2023-07-28 10:26:51 +12:00
bin FIRST POST 2020-03-28 16:35:21 +13:00
lib chore: Release version 0.2.1. 2023-07-28 08:52:25 +12:00
spec chore: Rubocop fixes. 2023-07-28 08:44:34 +12:00
.drone.yml chore: migrate to local. 2023-07-28 08:32:26 +12:00
.gitignore FIRST POST 2020-03-28 16:35:21 +13:00
.rspec FIRST POST 2020-03-28 16:35:21 +13:00
.rubocop.yml chore: Rubocop fixes. 2023-07-28 08:44:34 +12:00
.tool-versions chore: migrate to local. 2023-07-28 08:32:26 +12:00
.travis.yml FIRST POST 2020-03-28 16:35:21 +13:00
Gemfile chore(deps): update dependency rubocop to '~> 1.52.0' 2023-06-02 21:58:07 +12:00
Gemfile.lock chore: Release version 0.2.1. 2023-07-28 08:52:25 +12:00
LICENSE.md chore: fix copyright notice. 2023-01-17 10:48:22 +13:00
Rakefile FIRST POST 2020-03-28 16:35:21 +13:00
README.md chore: migrate to local. 2023-07-28 08:32:26 +12:00
renovate.json chore: Configure Renovate (#190) 2023-07-28 10:26:51 +12:00
wag.gemspec chore: Rubocop fixes. 2023-07-28 08:44:34 +12:00

WAG - The WebAssembly Code Generator

This Ruby gem allows you to generate WebAssembly programs programmatically using a DSL.

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 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 language. As an example here are two implementations of Euclid's Greatest Common Divisor algorithm:

Example of unfolded generation

unfolded = WAG::Module.new.build do
  func(:gcd) do
    param(:a, :i32)
    param(:b, :i32)
    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_
  end
  export("gcd").func(:gcd)
end

Example of folded generation

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)
  end
end

Both modules emit identical WASM bytecode and produce the same answers:

folded.to_wasm.save("folded.wasm")
unfolded.to_wasm.save("unfolded.wasm")
$ 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

Installation

Add this line to your application's Gemfile:

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.

Contributing

Bug reports and pull requests are welcome at https://code.harton.nz/james/wag.

License

This software is licensed under the terms of the HL3-FULL, see the LICENSE.md file included with this package for the terms.

This license actively proscribes this software being used by and for some industries, countries and activities. If your usage of this software doesn't comply with the terms of this license, then contact me 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.