Next: , Up: Toolchain reference   [Contents][Index]


5.1 Data types

The (wasm types) module contains all the core data types that comprise a Wasm module.

5.1.1 Modules

The Wasm module type is the top type, incorporating values of all the types that are to follow.

Procedure: wasm? obj

Return #t if obj is a Wasm module.

Procedure: wasm-id wasm

Return the symbolic ID of wasm.

Procedure: wasm-types wasm

Return the list of types in wasm.

Procedure: wasm-imports wasm

Return the list of imports in wasm.

Procedure: wasm-funcs wasm

Return the list of functions in wasm.

Procedure: wasm-tables wasm

Return the list of tables in wasm.

Procedure: wasm-memories wasm

Return the list of memories in wasm.

Procedure: wasm-globals wasm

Return the list of globals in wasm.

Procedure: wasm-exports wasm

Return the list of exports in wasm.

Procedure: wasm-elems wasm

Return the list of element segments in wasm.

Procedure: wasm-datas wasm

Return the list of data segments in wasm.

Procedure: wasm-tags wasm

Return the list of tags in wasm.

Procedure: wasm-strings wasm

Return the list of strings in wasm.

Procedure: wasm-custom wasm

Return the list of custom segments in wasm.

Procedure: wasm-start wasm

Return the start function index for wasm.

5.1.2 Types

Wasm has four numeric types:

  1. i32: 32-bit integer (signed or unsigned)
  2. i64: 64-bit integer (signed or unsigned)
  3. f32: 32-bit single precision IEEE floating point number.
  4. f64: 64-bit double precision IEEE floating point number.

There is also the v128 vector type, but it is currently unsupported.

Then there are a number of reference types that fall into 3 categories: function, external, and internal.

Function reference types:

  1. func: Function reference.
  2. nofunc: Bottom type for functions. No function is of type nofunc.

External reference types:

  1. extern: External reference introduced by the host.
  2. noextern: Bottom type for external references. No external reference is of type noextern.

Internal reference types:

  1. any: The top type of all internal reference types.
  2. eq: Structural equivalence type. Subtype of all.
  3. i31: Used for immediate references (such as the empty list or fixnums in Scheme.) Subtype of eq.
  4. array: Super type of all array types. Subtype of eq.
  5. struct: Super type of all struct types. Subtype of eq.
  6. none: The bottom type for internal references. No internal reference is of type none.

Of course, modules may specify their own compound types assembled from these primitives.

The type hierarchy looks like this:

              .-----.                         .-------.      .---------.
              | any |                         | func  |      | extern  |
              `-----'                         `-------'      `---------'
                 ↓                                ↓               ↓
              .-----.                        .-----------.  .-----------.
    .-------- | eq  | ------------.          | all funcs |  | noextern  |
    |         `-----'             |          `-----------'  `-----------'
    ↓            ↓                ↓               ↓
 .-----.  .-------------.    .---------.      .---------.
 | i31 |  | all arrays  |    | struct  |      | nofunc  |
 `-----'  `-------------'    `---------'      `---------'
                 ↓                ↓
              .-----.      .-------------.
              | any |      | all structs |
              `-----'      `-------------'

A collection of type descriptor objects form a type table that describes all non-primitive types used within a module. Type objects associate an identifier with a function signature or reference type descriptor.

Procedure: type? obj

Return #t if obj is a type.

Procedure: type-id type

Return the symbolic ID of type.

Procedure: type-val type

Return the type descriptor of type.

Types may also be nested within recursive type groups that allow for circular and self references to the types within the group. Types not within a group can be thought of as belonging to a group of one.

Procedure: rec-group? obj

Return #t if obj is a recursive type group.

Procedure: rec-group-types rec-group

Return the types within rec-group.

Note that while each Wasm module contains a full inventory of its types, structurally identical type groups across Wasm modules are canonicalized at runtime and are considered to be identical (eq? in Scheme terms.) This allows for passing references between modules.

Type uses refer to function signatures and are used for specifying the type of a block, loop, or if expression.

Procedure: type-use? obj

Return #t if obj is a type use.

Procedure: type-use-idx type-use

Return the type index of type-use.

Procedure: type-use-sig type-use

Return the function signature of type-use.

Procedure: ref-type? obj

Return #t if obj is a reference type.

Procedure: ref-type-nullable? ref-type

Return #t if ref-type is nullable.

Procedure: ref-type-heap-type ref-type

Return the heap type of ref-type.

As mentioned above, reference types support structural subtyping.

Procedure: sub-type? obj

Return #t if obj is a sub type.

Procedure: sub-type-final? sub-type

Return #t if sub-type is marked as final.

Procedure: sub-type-supers sub-type

Return super types of sub-type.

Procedure: sub-type-type sub-type

Return the concrete type descriptor of sub-type.

Compound types take the form of arrays and structs.

Procedure: array-type? obj

Return #t if obj is an array type.

Procedure: array-type-mutable? array-type

Return #t if array-type is mutable.

Procedure: array-type-type array-type

Retun the element type descriptor of array-type.

Procedure: struct-type? obj

Return #t if obj is a struct type.

Procedure: struct-type-fields struct-type

Return the field descriptors of struct-type.

Struct types are composed of several fields.

Procedure: field? obj

Return #t if obj is a struct field.

Procedure: field-id field

Return the symbolic ID of field.

Procedure: field-mutable? field

Return #t if field is mutable.

Procedure: field-type field

Return the type descriptor of field.

Both arrays and struct fields allow for packed data using the special i8 and i16 data types.

5.1.3 Globals

Wasm supports both mutable and immutable global variables.

Procedure: global? obj

Return #t if obj is a global.

Procedure: global-id global

Return the symbloc ID of global.

Procedure: global-type global

Return the type of global.

Procedure: global-init global

Return the initialization instructions of global. Only constant instructions are allowed.

Procedure: global-type? obj

Return #t if obj is a global type.

Procedure: global-type-mutable? global-type

Return #t if global-type is mutable.

Procedure: global-type-type global-type

Return the type descriptor of global-type.

5.1.4 Functions

Procedure: func? obj

Return #t if obj is a function.

Procedure: func-id func

Return the symbolic ID of func.

Procedure: func-type func

Return the signature of func.

Procedure: func-locals func

Return the locals of func.

Procedure: func-body func

Return the body instructions of func.

The type of a function is its signature. Notably, Wasm supports multiple return values, just like Scheme.

Procedure: func-sig? obj

Return #t if obj is a function signature.

Procedure: func-sig-params func

Return the parameters of func.

Procedure: func-sig-results func

Return the result types of func.

Function parameters pair a local identifier with its type.

Procedure: param? obj

Return #t if obj is a param.

Procedure: param-id param

Return the symbolic ID of param.

Procedure: param-type param

Return the type descriptor of param.

Locals provide additional mutable variables scoped to the body of a function.

Procedure: local? obj

Return #t if obj is a function local.

Procedure: local-id local

Return the symbolic ID of local.

Procedure: local-type local

Return the type descriptor of local.

5.1.5 Imports/exports

Functions, globals, memories, and tables can be imported from the host or another Wasm module. They are organized into a two layer hierarchy. An import module groups many imports under an umbrella name, and then the individual item names distinguish imported data within a module.

Procedure: import? obj

Return #t if obj is an import.

Procedure: import-mod import

Return the module name string of import.

Procedure: import-name import

Return the name string of import.

Procedure: import-kind import

Return the kind of import. Either func, global, memory, or table.

Procedure: import-id import

Return the symbolic ID of import.

Procedure: import-type import

Return the type descriptor of import.

Likewise, functions, globals, memories, and tables can be exported from a module to be used by the host or by other modules.

Procedure: export? obj

Return #t if obj is an export.

Procedure: export-name export

Return the name string of export.

Procedure: export-kind export

Return the kind of export. Either func, global, memory, or table.

Procedure: export-idx export

Return the index of export.

5.1.6 Linear memory

Memory objects specify linear chunks of bytes that a module can write to/read from at runtime. The size of a memory is specified in terms of 64KiB pages. While many memory objects coud be included in a module, the Wasm specification currently only allows the use of a single memory at index 0.

Procedure: memory? obj

Return #t if obj is a memory.

Procedure: memory-id memory

Return the symbolic ID of memory.

The type of a memory currently just specifies the size limitations.

Procedure: memory-type memory

Return the type of memory.

Procedure: mem-type? obj

Return #t if obj is a memory type.

Procedure: mem-type-limits mem-type

Return the limits of mem-type.

Instructions that manipulate linear memory use the memory argument type to point to a specific offset within a memory.

Procedure: mem-arg? obj

Return #t if obj is a memory argument.

Procedure: mem-arg-id mem-arg

Return the symbolic ID of mem-arg.

Procedure: mem-arg-offset mem-arg

Return the offset of mem-arg.

Procedure: mem-arg-align mem-arg

Return the alignment of mem-arg.

5.1.7 Data segments

Data segments are static chunks of data used to initialize regions of memory. They have two possible modes of use:

  1. Active: The data segment is copied into memory during instantiation.
  2. Passive: The data segment is copied into memory using the memory.init instruction.
Procedure: data? obj

Return #t if obj is a data segment.

Procedure: data-id data

Return the symbolic ID of data.

Procedure: data-mode data

Return the mode of data. Either passive or active.

Procedure: data-mem data

Return the memory associated with data.

Procedure: data-offset data

Return the instructions that compute the offset of data. Only constant instructions are allowed.

Procedure: data-init data

Return a bytevector containing the initialization data of data.

5.1.8 Tables

Tables specify a vector of heap object references of a particular reference type.

Procedure: table? obj

Return #t if obj is a reference table.

Procedure: table-id table

Return the symbolic ID of table.

Procedure: table-type table

Return the type of table.

Table types specify the reference type of the elements as well as the size limitations.

Procedure: table-type? obj

Return #t if obj is a table type.

Procedure: table-type-limits table-type

Return the limts of table-type.

Procedure: table-type-elem-type table-type

Return the element type of table-type.

5.1.9 Element segments

Element segments are static vectors of references used to initialize regions of tables (well, mostly.) They have three possible modes of use:

  1. Active: The element segment is copied into its associated table during instantiation.
  2. Passive: The element segment is copied into its associated table using the table.init instruction.
  3. Declarative: The element segment is unavailable at runtime and is instead used for forward declarations of types that are used elsewhere in the code.
Procedure: elem? obj

Return #t if obj is an element segment.

Procedure: elem-id elem

Return the symoblic ID of elem.

Procedure: elem-mode elem

Return the mode of elem.

Procedure: elem-table elem

Return the table associated with elem.

Procedure: elem-type elem

Return the type of elem.

Procedure: elem-offset elem

Return the instructions that compute the offset of elem. Only constant instructions are allowed.

Procedure: elem-inits elem

Return a list of initializer instructions for the items of elem. Only constant instructions are allowed.

5.1.10 Limits

Both memories and tables use limits to constrain their minimum and maximum size. A valid limit must have a minimum of at least 1, but the maximum may be #f if unbounded growth is allowed.

Procedure: limits? obj

Return #t if obj is a limits.

Procedure: limits-min limits

Return the minimum value of limits.

Procedure: limits-max limits

Return the maximum value of limits or #f if there is no maximum.

5.1.11 Tags

Tag segments specify types of runtime errors that may be raised.

Procedure: tag? obj

Return #t if obj is a tag.

Procedure: tag-id tag

Return the symbolic ID of tag.

Procedure: tag-type tag

Return the type of tag.

Tag types specify the function signature of the tags. Since tags are not truly functions, their signatures must only have parameters and no results.

Procedure: tag-type? obj

Return #t if obj is a tag type.

Procedure: tag-type-attribute tag-type

Return the symbolic attribute of tag-type. Currently, there is only one valid attribute: exception.

Procedure: tag-type-type tag-type

Return the type of tag-type. This is expected to be a type use object that refers to a function signature.

5.1.12 Custom sections

Custom sections specify arbitrary data that is not covered by the Wasm specification.

Procedure: custom? obj

Return #t if obj is a custom segment.

Procedure: custom-name custom

Return the name of custom.

Procedure: custom-bytes custom

Return the bytevector of custom.

There is, however, one custom section that is specified: the name section. This section contains various “name maps” that can be used to translate integer identifiers to (hopefully) human-readable names for the purposes of debugging.

Hoot supports the name subsections described in the Wasm core specification, the Wasm GC specification, and the extended names proposal:

  1. Module name
  2. Function name map
  3. Function local indirect name map
  4. Block label indirect name map
  5. Type name map
  6. Table name map
  7. Memory name map
  8. Global name map
  9. Element name map
  10. Data name map
  11. Struct field indirect name map
  12. Tag name map

Name maps are represented as association lists mapping integers to strings. Indirect name maps are represented as association lists mapping integers to name maps.

Procedure: names? obj

Return #t if obj is a name section object.

Procedure: names-module names

Return the module name of names.

Procedure: names-func names

Return the function name map of names.

Procedure: names-local names

Return the function local indirect name map of names.

Procedure: names-label names

Return the block label indirect name map of names.

Procedure: names-type names

Return the type name map of names.

Procedure: names-table names

Return the table name map of names.

Procedure: names-memory names

Return the memory name map of names.

Procedure: names-global names

Return the global name map of names.

Procedure: names-elem names

Return the element name map of names.

Procedure: names-data names

Return the data name map of names.

Procedure: names-fields names

Return the struct field indirect name map of names.

Procedure: names-tag names

Return the tag name map of names.


Next: GWAT, Up: Toolchain reference   [Contents][Index]