Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

An experimental work-in-progress (WIP) WebAssembly runtime written in Gleam.

License

Notifications You must be signed in to change notification settings

BrendoCosta/gwr

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

99 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GWR - Gleam WebAssembly Runtime

Package Version Hex Docs Package License Package Total Downloads Count Test Status Available for the Erlang runtime Total Stars Count

Description

An experimental work-in-progress (WIP) WebAssembly runtime written in Gleam.

Purpose

Nowadays, many languages ​​support Wasm as a target, from mainstream ones like C++ and Rust, as well as newer ones like Odin and Grain. The purpose of this project is to use WebAssembly to create an alternative interoperability layer to Erlang's virtual machine NIFs.

Installation

gleam add gwr

Usage

Important

Currently the project is in an extremely early stage of development; it is only possible to run very simple functions (consisting of basic integer arithmetic, function calls, and control flows). Keep in mind that code and APIs may change dramatically.

Step 1 - Build code targeting Wasm

Example - Fibonacci sequence from Rust

// fib.rs

#![no_std]

#[panic_handler]
pub fn panic(_info: &core::panic::PanicInfo) -> !
{
    loop {}
}

#[unsafe(no_mangle)]
pub extern fn fib(value: i32) -> i32
{
    match value
    {
        v if v <= 0 => 0,
        v if v <= 2 => 1,
        _ => fib(value - 1) + fib(value - 2)
    }
}
rustc --crate-type cdylib --target wasm32-unknown-unknown -C debuginfo=none -C panic=abort -C strip=symbols -C opt-level=3 ./fib.rs -o ./fib.wasm

Example - Fibonacci sequence from WAT

Using the wat2wasm tool from wabt.

;; fib.wat

(module
    (func $fib (export "fib") (param $value i32) (result i32)
        local.get $value
        i32.const 0
        i32.le_s
        if
            i32.const 0
            return
        end
        local.get $value
        i32.const 2
        i32.le_s
        if
            i32.const 1
            return
        end
        local.get $value
        i32.const 1
        i32.sub
        call $fib
        local.get $value
        i32.const 2
        i32.sub
        call $fib
        i32.add
        return
    )
)
wat2wasm -o ./fib.wasm ./fib.wat

Step 2 - Run it from Gleam with GWR

Using the simplifile package to read the module file.

gleam add simplifile
import gwr/gwr
import gwr/execution/runtime
import simplifile

pub fn main()
{
    let assert Ok(data) = simplifile.read_bits(from: "fib.wasm")
    let assert Ok(binary) = gwr.load(from: data)
    let assert Ok(instance) = gwr.create(from: binary)
    let assert Ok(#(_instance, result)) = gwr.call(instance, "fib", [runtime.Integer32(18)])
    let assert [runtime.Integer32(2584)] = result
}

Building

Testing

To test the project, you must have Make and Docker (or Podman) installed in your environment. The project has a test suite written in Rust and WebAssembly text format intended to be built for the wasm target; the build process is containerized so there is no need to install additional toolchains.

make test

The above command is equivalent to make build-test-suite followed by gleam test. Of course, once you have built the test suite, you can simply invoke gleam test.

Contributing

Contributions are welcome! Feel free to submit either issues or PRs, but keep in mind that your code needs to be covered by tests.

License

GWR source code is avaliable under the MIT license.

About

An experimental work-in-progress (WIP) WebAssembly runtime written in Gleam.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages