Rand Stats

Wasm::Emitter

zef:raku-community-modules

Actions Status Actions Status Actions Status

NAME

Wasm::Emitter - Emit the WebAssembly binary format

SYNOPSIS

use Wasm::Emitter;

DESCRIPTION

A Raku module to emit the WebAssembly binary format.

Example

This emits the "hello world" WebAssembly program using WASI (the WebAssembly System Interface) to provide I/O functions.

# Create an instance of the emitter, which can emit a module.
my $emitter = Wasm::Emitter.new;

# Import fd_write
my $fd-write-type = $emitter.function-type:
        functype(resulttype(i32(), i32(), i32(), i32()), resulttype(i32()));
my $fd-write-index = $emitter.import-function("wasi_unstable", "fd_write", $fd-write-type);

# Declare and export a memory.
$emitter.export-memory("memory", $emitter.memory(limitstype(1)));

# Write 'hello world\n' to memory at an offset of 8 bytes
my $offset-expression = Wasm::Emitter::Expression.new;
$offset-expression.i32-const(8);
$emitter.active-data("hello world\n".encode('utf-8'), $offset-expression);

# Generate code to call fd_write.
my $code = Wasm::Emitter::Expression.new;
given $code {
    # (i32.store (i32.const 0) (i32.const 8))
    .i32-const(0);
    .i32-const(8);
    .i32-store;
    # (i32.store (i32.const 4) (i32.const 12))
    .i32-const(4);
    .i32-const(12);
    .i32-store;
    # (call $fd_write
    #   (i32.const 1) ;; file_descriptor - 1 for stdout
    #   (i32.const 0) ;; *iovs - The pointer to the iov array, which is stored at memory location 0
    #   (i32.const 1) ;; iovs_len - We're printing 1 string stored in an iov - so one.
    #   (i32.const 20) ;; nwritten - A place in memory to store the number of bytes written
    # )
    .i32-const(1);
    .i32-const(0);
    .i32-const(1);
    .i32-const(20);
    .call($fd-write-index);
    # Drop return value
    .drop;
}

# Declare and export the start function.
my $start-type = $emitter.function-type: functype(resulttype(), resulttype());
my $start-func-index = $emitter.function: Wasm::Emitter::Function.new:
        :type-index($start-type), :expression($code);
$emitter.export-function('_start', $start-func-index);

# Assemble and write to a file, which can be run by, for example, wasmtime.
my $buf = $emitter.assemble();
spurt 'hello.wasm', $buf;

Functionality

To the best of my knowledge, this covers all of the WebAssembly 2.0 specified features except the vector instructions. None of the proposed specifications are currently implemented (although some of them are liable to attract my attention ahead of the vector instructions).

Support policy

This is a module developed for personal interest. I'm sharing it in case it's fun or useful to anybody else, not because I want yet another open source project to maintain. PRs that include tests and are provided in an easy to review form will likely be merged quite quickly, so long as no major flaws are noticed.

API Documentation

class Wasm::Emitter

Emitter for a binary Wasm module. An instance of this represents a module. Make the various declarations, and then call C to produce a C with the WebAssembly.

has Positional[Wasm::Emitter::Types::FunctionType] @!function-types

Function types, all distinct.

has Positional[Wasm::Emitter::FunctionImport] @!function-imports

Function imports.

has Positional[Wasm::Emitter::TableImport] @!table-imports

Table imports.

has Positional[Wasm::Emitter::MemoryImport] @!memory-imports

Memory imports.

has Positional[Wasm::Emitter::GlobalImport] @!global-imports

Global imports.

has Positional[Wasm::Emitter::Types::TableType] @!tables

Declared tables, with their table types.

has Positional[Wasm::Emitter::Types::LimitType] @!memories

Declared memories, with their limits.

has Positional[Wasm::Emitter::Export] @!exports

Declared exports.

has Positional[Wasm::Emitter::Data] @!data

Declared data sections.

has Positional[Wasm::Emitter::Global] @!globals

Declared globals.

has Positional[Wasm::Emitter::Elements] @!elements

Declared elements.

has Positional[Wasm::Emitter::Function] @!functions

Declared functions.

method function-type

method function-type(
    Wasm::Emitter::Types::FunctionType $type
) returns Int

Returns a type index for a function type. If the function type was already registered, returns the existing index; failing that, adds it under a new index.

method import-function

method import-function(
    Str $module,
    Str $name,
    Int $type-index
) returns Int

Add a function import.

method import-table

method import-table(
    Str $module,
    Str $name,
    Wasm::Emitter::Types::TableType $table-type
) returns Int

Add a table import.

method import-memory

method import-memory(
    Str $module,
    Str $name,
    Wasm::Emitter::Types::LimitType $memory-type
) returns Int

Add a memory import.

method import-global

method import-global(
    Str $module,
    Str $name,
    Wasm::Emitter::Types::GlobalType $global-type
) returns Int

Add a global import.

method table

method table(
    Wasm::Emitter::Types::TableType $table-type
) returns Int

Declare a table.

method memory

method memory(
    Wasm::Emitter::Types::LimitType $limits
) returns Int

Add a declaration of a memory.

method export-function

method export-function(
    Str $name,
    Int $function-index
) returns Nil

Export a function.

method export-memory

method export-memory(
    Str $name,
    Int $memory-index
) returns Nil

Export a memory.

method export-global

method export-global(
    Str $name,
    Int $global-index
) returns Nil

Export a global.

method export-table

method export-table(
    Str $name,
    Int $table-index
) returns Nil

Export a table.

method passive-data

method passive-data(
    Blob $data
) returns Int

Declare a passive data section.

method active-data

method active-data(
    Blob $data,
    Wasm::Emitter::Expression $offset
) returns Int

Declare an active data section.

method global

method global(
    Wasm::Emitter::Types::GlobalType $type,
    Wasm::Emitter::Expression $init
) returns Int

Declare a global.

method elements

method elements(
    Wasm::Emitter::Elements $elements
) returns Int

Declare an elements section.

method function

method function(
    Wasm::Emitter::Function $function
) returns Int

Declare a function.

method assemble

method assemble() returns Buf

Assemble the produced declarations into a final output.

AUTHOR

Jonathan Worthington

COPYRIGHT AND LICENSE

Copyright 2022 - 2024 Jonathan Worthington

Copyright 2024 Raku Community

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.