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