gl_wasm/wasm

Generate binary WebAssembly modules in pure Gleam.

WebAssembly types and instructions are represented by Gleam types and validation is performed as the WebAssembly is generated.

Types

BlockType represents the value produced by a block (or empty).

pub type BlockType {
  BlockEmpty
  BlockValue(ValueType)
}

Constructors

  • BlockEmpty
  • BlockValue(ValueType)
pub type BuildType {
  BuildFunction(
    function_index: Int,
    type_index: Int,
    name: Option(String),
  )
  BuildGlobal(
    global_index: Int,
    name: Option(String),
    mutable: Mutability,
    value_type: ValueType,
  )
}

Constructors

  • BuildFunction(
      function_index: Int,
      type_index: Int,
      name: Option(String),
    )
  • BuildGlobal(
      global_index: Int,
      name: Option(String),
      mutable: Mutability,
      value_type: ValueType,
    )

Builder to enable incremental construction of a function or expression.

pub opaque type CodeBuilder

Composite types are those composed from simpler types.

pub type CompositeType {
  Func(
    name: Option(String),
    params: List(ValueType),
    result: List(ValueType),
  )
  Array(name: Option(String), item_type: FieldType)
  Struct(name: Option(String), field_types: List(FieldType))
}

Constructors

  • Func(
      name: Option(String),
      params: List(ValueType),
      result: List(ValueType),
    )
  • Array(name: Option(String), item_type: FieldType)
  • Struct(name: Option(String), field_types: List(FieldType))

Error raised while emitting binary WebAssembly

pub type EmissionError(e) {
  ValidationError(String)
  OutputStreamError(e)
}

Constructors

  • ValidationError(String)
  • OutputStreamError(e)
pub type Export {
  ExportFunction(name: String, function_index: Int)
  ExportGlobal(name: String, global_index: Int)
}

Constructors

  • ExportFunction(name: String, function_index: Int)
  • ExportGlobal(name: String, global_index: Int)

Field types describe the components of aggregate types (arrays and structs).

pub type FieldType {
  PackedType(
    name: Option(String),
    mutable: Mutability,
    packed_type: PackedType,
  )
  ValueType(
    name: Option(String),
    mutable: Mutability,
    value_type: ValueType,
  )
}

Constructors

  • PackedType(
      name: Option(String),
      mutable: Mutability,
      packed_type: PackedType,
    )
  • ValueType(
      name: Option(String),
      mutable: Mutability,
      value_type: ValueType,
    )

Functions can be defined via import or implementation. While they are being constructed the FunctionMissing placeholder is used.

pub type FunctionDefinition {
  FunctionImport(
    type_index: Int,
    name: Option(String),
    from: ImportSource,
  )
  FunctionImplementation(
    type_index: Int,
    name: Option(String),
    local_names: List(Option(String)),
    locals: List(ValueType),
    code: List(Instruction),
  )
  FunctionMissing(
    type_index: Int,
    name: Option(String),
    local_names: List(Option(String)),
  )
}

Constructors

  • FunctionImport(
      type_index: Int,
      name: Option(String),
      from: ImportSource,
    )
  • FunctionImplementation(
      type_index: Int,
      name: Option(String),
      local_names: List(Option(String)),
      locals: List(ValueType),
      code: List(Instruction),
    )
  • FunctionMissing(
      type_index: Int,
      name: Option(String),
      local_names: List(Option(String)),
    )
pub type FunctionSignature {
  FunctionSignature(
    type_index: Int,
    name: Option(String),
    param_names: Option(List(String)),
  )
}

Constructors

  • FunctionSignature(
      type_index: Int,
      name: Option(String),
      param_names: Option(List(String)),
    )
pub type GlobalDefinition {
  GlobalImport(
    name: Option(String),
    mutable: Mutability,
    value_type: ValueType,
    from: ImportSource,
  )
  GlobalInitialization(
    name: Option(String),
    mutable: Mutability,
    value_type: ValueType,
    code: List(Instruction),
  )
  GlobalMissing(
    name: Option(String),
    mutable: Mutability,
    value_type: ValueType,
  )
}

Constructors

  • GlobalImport(
      name: Option(String),
      mutable: Mutability,
      value_type: ValueType,
      from: ImportSource,
    )
  • GlobalInitialization(
      name: Option(String),
      mutable: Mutability,
      value_type: ValueType,
      code: List(Instruction),
    )
  • GlobalMissing(
      name: Option(String),
      mutable: Mutability,
      value_type: ValueType,
    )

Heap types classify the objects in the runtime store. They may be abstract or concrete.

pub type HeapType {
  AbstractFunc
  AbstractNoFunc
  AbstractExtern
  AbstractNoExtern
  AbstractAny
  AbstractEq
  AbstractI31
  AbstractStruct
  AbstractArray
  AbstractNone
  ConcreteType(Int)
}

Constructors

  • AbstractFunc
  • AbstractNoFunc
  • AbstractExtern
  • AbstractNoExtern
  • AbstractAny
  • AbstractEq
  • AbstractI31
  • AbstractStruct
  • AbstractArray
  • AbstractNone
  • ConcreteType(Int)

Represents the source (module and name) of an import.

pub type ImportSource {
  ImportSource(module: String, name: String)
}

Constructors

  • ImportSource(module: String, name: String)

WebAssembly instructions (code).

pub type Instruction {
  Unreachable
  Nop
  Block(block_type: BlockType)
  Loop(block_type: BlockType)
  If(block_type: BlockType)
  Else
  Break(label_index: Int)
  Branch(label_index: Int)
  BreakIf(label_index: Int)
  BranchIf(label_index: Int)
  Return
  Call(function_index: Int)
  ReturnCall(function_index: Int)
  CallRef(type_index: Int)
  ReturnCallRef(type_index: Int)
  BreakOnNull(label_index: Int)
  BranchOnNull(label_index: Int)
  BreakOnNonNull(label_index: Int)
  BranchOnNonNull(label_index: Int)
  End
  RefNull(heap_type: HeapType)
  RefFunc(function_index: Int)
  RefIsNull
  RefAsNonNull
  RefEq
  RefTest(ref_type: RefType)
  RefCast(ref_type: RefType)
  StructNew(type_index: Int)
  StructNewDefault(type_index: Int)
  StructGet(type_index: Int, field_index: Int)
  StructGetS(type_index: Int, field_index: Int)
  StructGetU(type_index: Int, field_index: Int)
  StructSet(type_index: Int, field_index: Int)
  Drop
  Select(List(ValueType))
  LocalGet(local_index: Int)
  LocalSet(local_index: Int)
  LocalTee(local_index: Int)
  GlobalGet(global_index: Int)
  GlobalSet(global_index: Int)
  I32Const(value: Int32)
  I64Const(value: Int64)
  F32Const(value: IEEEFloat)
  F64Const(value: IEEEFloat)
  I32EqZ
  I32Eq
  I32NE
  I32LtS
  I32LtU
  I32GtS
  I32GtU
  I32LeS
  I32LeU
  I32GeS
  I32GeU
  I64EqZ
  I64Eq
  I64NE
  I64LtS
  I64LtU
  I64GtS
  I64GtU
  I64LeS
  I64LeU
  I64GeS
  I64GeU
  F32Eq
  F32NE
  F32Lt
  F32Gt
  F32Le
  F32Ge
  F64Eq
  F64NE
  F64Lt
  F64Gt
  F64Le
  F64Ge
  I32CntLZ
  I32CntTZ
  I32PopCnt
  I32Add
  I32Sub
  I32Mul
  I32DivS
  I32DivU
  I32RemS
  I32RemU
  I32And
  I32Or
  I32Xor
  I32ShL
  I32ShRS
  I32ShLU
  I32RotL
  I32RotR
  I64CntLZ
  I64CntTZ
  I64PopCnt
  I64Add
  I64Sub
  I64Mul
  I64DivS
  I64DivU
  I64RemS
  I64RemU
  I64And
  I64Or
  I64Xor
  I64ShL
  I64ShRS
  I64ShLU
  I64RotL
  I64RotR
  F32Abs
  F32Neg
  F32Ceil
  F32Floor
  F32Trunc
  F32Nearest
  F32Sqrt
  F32Add
  F32Sub
  F32Mul
  F32Div
  F32Min
  F32Max
  F32CopySign
  F64Abs
  F64Neg
  F64Ceil
  F64Floor
  F64Trunc
  F64Nearest
  F64Sqrt
  F64Add
  F64Sub
  F64Mul
  F64Div
  F64Min
  F64Max
  F64CopySign
}

Constructors

  • Unreachable
  • Nop
  • Block(block_type: BlockType)
  • Loop(block_type: BlockType)
  • If(block_type: BlockType)
  • Else
  • Break(label_index: Int)
  • Branch(label_index: Int)
  • BreakIf(label_index: Int)
  • BranchIf(label_index: Int)
  • Return
  • Call(function_index: Int)
  • ReturnCall(function_index: Int)
  • CallRef(type_index: Int)
  • ReturnCallRef(type_index: Int)
  • BreakOnNull(label_index: Int)
  • BranchOnNull(label_index: Int)
  • BreakOnNonNull(label_index: Int)
  • BranchOnNonNull(label_index: Int)
  • End
  • RefNull(heap_type: HeapType)
  • RefFunc(function_index: Int)
  • RefIsNull
  • RefAsNonNull
  • RefEq
  • RefTest(ref_type: RefType)
  • RefCast(ref_type: RefType)
  • StructNew(type_index: Int)
  • StructNewDefault(type_index: Int)
  • StructGet(type_index: Int, field_index: Int)
  • StructGetS(type_index: Int, field_index: Int)
  • StructGetU(type_index: Int, field_index: Int)
  • StructSet(type_index: Int, field_index: Int)
  • Drop
  • Select(List(ValueType))
  • LocalGet(local_index: Int)
  • LocalSet(local_index: Int)
  • LocalTee(local_index: Int)
  • GlobalGet(global_index: Int)
  • GlobalSet(global_index: Int)
  • I32Const(value: Int32)
  • I64Const(value: Int64)
  • F32Const(value: IEEEFloat)
  • F64Const(value: IEEEFloat)
  • I32EqZ
  • I32Eq
  • I32NE
  • I32LtS
  • I32LtU
  • I32GtS
  • I32GtU
  • I32LeS
  • I32LeU
  • I32GeS
  • I32GeU
  • I64EqZ
  • I64Eq
  • I64NE
  • I64LtS
  • I64LtU
  • I64GtS
  • I64GtU
  • I64LeS
  • I64LeU
  • I64GeS
  • I64GeU
  • F32Eq
  • F32NE
  • F32Lt
  • F32Gt
  • F32Le
  • F32Ge
  • F64Eq
  • F64NE
  • F64Lt
  • F64Gt
  • F64Le
  • F64Ge
  • I32CntLZ
  • I32CntTZ
  • I32PopCnt
  • I32Add
  • I32Sub
  • I32Mul
  • I32DivS
  • I32DivU
  • I32RemS
  • I32RemU
  • I32And
  • I32Or
  • I32Xor
  • I32ShL
  • I32ShRS
  • I32ShLU
  • I32RotL
  • I32RotR
  • I64CntLZ
  • I64CntTZ
  • I64PopCnt
  • I64Add
  • I64Sub
  • I64Mul
  • I64DivS
  • I64DivU
  • I64RemS
  • I64RemU
  • I64And
  • I64Or
  • I64Xor
  • I64ShL
  • I64ShRS
  • I64ShLU
  • I64RotL
  • I64RotR
  • F32Abs
  • F32Neg
  • F32Ceil
  • F32Floor
  • F32Trunc
  • F32Nearest
  • F32Sqrt
  • F32Add
  • F32Sub
  • F32Mul
  • F32Div
  • F32Min
  • F32Max
  • F32CopySign
  • F64Abs
  • F64Neg
  • F64Ceil
  • F64Floor
  • F64Trunc
  • F64Nearest
  • F64Sqrt
  • F64Add
  • F64Sub
  • F64Mul
  • F64Div
  • F64Min
  • F64Max
  • F64CopySign

Represents a 32-bit sign-agnostic int.

pub opaque type Int32

Represents a 64-bit sign-agnostic int.

It is currently not possible to create the full range of possible Int64 values on the JavaScript target.

pub opaque type Int64

Builder to enable incremental construction of a module.

pub opaque type ModuleBuilder

Indicates wheter a field is mutable.

pub type Mutability {
  Mutable
  Immutable
}

Constructors

  • Mutable
  • Immutable

Output stream abstraction.

pub type OutputStream(s, e) {
  OutputStream(
    stream: s,
    write_bytes: fn(s, BitArray) -> Result(s, e),
    close: fn(s) -> Result(s, e),
  )
}

Constructors

  • OutputStream(
      stream: s,
      write_bytes: fn(s, BitArray) -> Result(s, e),
      close: fn(s) -> Result(s, e),
    )

Packed types cannot exist as standalone values but can be fields.

pub type PackedType {
  I8
  I16
}

Constructors

  • I8
  • I16

Reference type.

pub type RefType {
  NonNull(HeapType)
  Nullable(HeapType)
}

Constructors

  • NonNull(HeapType)
  • Nullable(HeapType)
pub type SubType {
  SubOpen(super_types: List(Int), definition: CompositeType)
  SubFinal(super_types: List(Int), definition: CompositeType)
}

Constructors

  • SubOpen(super_types: List(Int), definition: CompositeType)
  • SubFinal(super_types: List(Int), definition: CompositeType)

Value types are the types that a variable accepts.

pub type ValueType {
  I32
  I64
  F32
  F64
  V128
  Ref(RefType)
}

Constructors

  • I32
  • I64
  • F32
  • F64
  • V128
  • Ref(RefType)

Values

pub fn add_export(
  mb: ModuleBuilder,
  export: Export,
) -> Result(ModuleBuilder, String)

Mark something for export.

pub fn add_instruction(
  fb: CodeBuilder,
  instr: Instruction,
) -> Result(CodeBuilder, String)

Add an instruction to the CodeBuilder.

Validates the stack contains the value types the instruction requires.

pub fn add_local(
  fb: CodeBuilder,
  t: ValueType,
  name: Option(String),
) -> Result(#(CodeBuilder, Int), String)

Add a local to the CodeBuilder.

Can be done any time before the local is used.

pub fn add_sub_type_group(
  mb: ModuleBuilder,
  group: List(SubType),
) -> Result(#(ModuleBuilder, List(Int)), String)

Adds a type recursion group with subtypes to the module.

Can be done any time before creating a function that uses it.

pub fn add_type(
  mb: ModuleBuilder,
  t: CompositeType,
) -> Result(#(ModuleBuilder, Int), String)

Adds a type to the module.

Can be done any time before creating a function that uses it.

pub fn add_type_group(
  mb: ModuleBuilder,
  group: List(CompositeType),
) -> Result(#(ModuleBuilder, List(Int)), String)

Adds a type recursion group to the module.

Can be done any time before creating a function that uses it.

pub fn builds(cb: CodeBuilder) -> BuildType

Get the build type for a CodeBuilder.

pub fn create_function_builder(
  mb: ModuleBuilder,
  signature: FunctionSignature,
) -> Result(#(ModuleBuilder, CodeBuilder), String)

Register a function placeholder with the ModuleBuilder and create a CodeBuilder for it.

Multiple function implementations can be generated in parallel, to be finalized into the ModuleBuilder when ready.

pub fn create_function_builders(
  mb: ModuleBuilder,
  signatures: List(FunctionSignature),
) -> Result(#(ModuleBuilder, List(CodeBuilder)), String)

Register function placeholders for a group of potentially mutually recursive functions in the ModuleBuilder and create a CodeBuilder for each.

Multiple function implementations can be generated in parallel, to be finalized into the ModuleBuilder when ready.

pub fn create_global_builder(
  mb: ModuleBuilder,
  name: Option(String),
  mutable: Mutability,
  value_type: ValueType,
) -> Result(#(ModuleBuilder, CodeBuilder), String)

Add a global to the ModuleBuilder.

Can be done any time before creating a function that uses it.

NOTE: the names sub-section for global names is not part of the current draft specification. Omit global names if you do not want to emit this sub-section.

pub fn create_module_builder(
  name: Option(String),
) -> ModuleBuilder

Creates a ModuleBuilder.

pub fn emit_module(
  mb: ModuleBuilder,
  os: OutputStream(a, b),
) -> Result(a, EmissionError(b))

Convert the WebAssembly to binary and output to file.

Assumes the WebAssembly module is valid.

pub fn finalize_function(
  mb: ModuleBuilder,
  fb: CodeBuilder,
) -> Result(ModuleBuilder, String)

Complete the CodeBuilder and replace the corresponding placeholder in ModuleBuilder by the validated function code.

pub fn finalize_global(
  mb: ModuleBuilder,
  fb: CodeBuilder,
) -> Result(ModuleBuilder, String)

Complete the CodeBuilder and replace the corresponding placeholder in ModuleBuilder by the validated global initalization code.

pub fn get_function_by_index(
  mb: ModuleBuilder,
  function_index: Int,
) -> Result(FunctionDefinition, String)

Get a function definition by index.

pub fn get_global_by_index(
  mb: ModuleBuilder,
  global_index: Int,
) -> Result(GlobalDefinition, String)

Get a global definition by index.

pub fn get_sub_type_by_index(
  mb: ModuleBuilder,
  index: Int,
) -> Result(SubType, String)
pub fn get_type_by_index(
  mb: ModuleBuilder,
  index: Int,
) -> Result(CompositeType, String)

Get a type definition by index.

pub fn import_function(
  mb: ModuleBuilder,
  type_index: Int,
  name: Option(String),
  from: ImportSource,
) -> Result(ModuleBuilder, String)

Import a function.

pub fn import_global(
  mb: ModuleBuilder,
  name: Option(String),
  mutable: Mutability,
  value_type: ValueType,
  from: ImportSource,
) -> Result(ModuleBuilder, String)

Import a global.

NOTE: the names sub-section for global names is not part of the current draft specification. Omit global names if you do not want to emit this sub-section.

pub fn int32_signed(n: Int) -> Result(Int32, String)

Create an Int32 (interpreting the number as signed).

pub fn int32_unsigned(n: Int) -> Result(Int32, String)

Create an Int32 (interpreting the number as unsigned).

pub fn int64_signed(n: Int) -> Result(Int64, String)

Create an Int64 (interpreting the number as signed).

Assumes Gleam’s Int has at most 64-bit precision.

pub fn int64_unsigned(n: Int) -> Result(Int64, String)

Create an Int64 (interpreting the number as unsigned).

Assumes Gleam’s Int has at most 64-bit precision.

pub fn set_start_function(
  mb: ModuleBuilder,
  function_index: Int,
) -> Result(ModuleBuilder, String)

Set the start function by index. It must take no arguments and produce no results.

Search Document