This document describes format produced by the pack-asmjs utility.
For sake of simplicity let's define WASM file as binary data packed using this format.
The following data types is used in a WASM file. All integer and float numbers are using little endian byte ordering.
Data Type | Description |
---|---|
u8 | 8-bit unsigned integer. |
u32 | 32-bit unsigned integer. |
i32 | 32-bit signed integer. |
f32 | 32-bit float number. |
f64 | 64-bit float number. |
imm_u32 | Unsigned LEB128 packed integer. |
imm_s32 | Signed LEB128 packed integer. |
c_str | UTF-8 encoded string, terminated by '\x00' character. |
The sqaure brackets ([]) near the field name denotes sequence/array of items of the specified data type.
A WASM file has the following structure.
Type | Name | Description |
---|---|---|
u32 | magicNumber | 4-byte identifier that reads "wasm". |
u32 | unpackedAsmJsSize | Size of the unpacked asm.js source file. |
ConstantPoolSection | constantPoolSection | Tables of i32, f32, and f64 constants. |
SignatureSection | signatureSection | Function signatures. |
FunctionImportSection | functionImportSection | Descriptions of imported functions. |
GlobalSection | globalSection | TODO |
FunctionDeclarationSection | functionDeclarationSection | Declarations of functions. |
FunctionPointerTableSection | functionPointerTableSection | Lookup tables for indirect function calls. |
FunctionDefinitionSection | functionDefinitionSection | Function implementations. |
ExportSection | exportSection | Table of exported functions. |
The ConstantPoolSection record contains:
Type | Name | Description |
---|---|---|
imm_u32 | i32s_size | Amount of i32 constants in the i32s table. |
imm_u32 | f32s_size | Amount of f32 constants in the f32s table. |
imm_u32 | f64s_size | Amount of f64 constants in the f64s table. |
i32 | i32s[i32s_size] | i32 constants. |
f32 | f32s[f32s_size] | f32 constants. |
f64 | f64s[f64s_size] | f64 constants. |
The section defines various signatures used by the functions defined in the FunctionImportSection and FunctionDeclarationSection sections.
The SignatureSection record contains:
Type | Name | Description |
---|---|---|
imm_u32 | sigs_size | Amount of signatures in the sig table. |
Signature | sigs[sigs_size] | Signatures table. |
The Signature record contains:
Type | Name | Description |
---|---|---|
u8 | returnType | Return type code. |
imm_u32 | args_size | Amount of arguments. |
u8 | args | Type codes for arguments. |
The FunctionImportSection record contains:
Type | Name | Description |
---|---|---|
imm_u32 | func_imps_size | Amount of function imports. |
imm_u32 | num_func_imps_sigs | TODO |
FunctionImport | func_imps[func_imps_size] | Function imports. |
The FunctionImport record contains:
Type | Name | Description |
---|---|---|
c_str | name | External function name |
imm_u32 | sigs_size | Amount of function signatures. |
imm_u32 | sig_index[sigs_index] | Function signatures. |
This is initial allocation for global variables.
The GlobalSectionRecord record contains:
Type | Name | Description |
---|---|---|
imm_u32 | num_global_i32_zero | TODO |
imm_u32 | num_global_f32_zero | TODO |
imm_u32 | num_global_f64_zero | TODO |
imm_u32 | global_i32_imports_size | TODO |
imm_u32 | global_f32_imports_size | TODO |
imm_u32 | global_f64_imports_size | TODO |
c_str | global_i32_imports[global_i32_imports_size] | TODO |
c_str | global_f32_imports[global_f32_imports_size] | TODO |
c_str | global_f64_imports[global_f64_imports_size] | TODO |
They will be allocated in the following order: num_global_i32_zero variables with i32 value 0, num_global_f32_zero variables with f32 value 0.0f, num_global_f64_zero variable with f64 value 0.0, global_i32_imports_size variables initialized to i32 values from global_i32_imports, etc.
The FunctionDeclarationSection record contains:
Type | Name | Description |
---|---|---|
imm_u32 | funcs_size | Amount of function declarations. |
imm_u32 | funcs_sig_index[funcs_size] | Functions signatures. |
A function might call other function using external lookup table.
The FunctionPointerTableSection record contains:
Type | Name | Description |
---|---|---|
imm_u32 | func_pointer_tables_size | Amount of tables. |
FunctionPointerTable | func_pointer_tables[func_pointer_tables_size] | Lookup tables. |
The FunctionPointerTable record contains:
Type | Name | Description |
---|---|---|
imm_u32 | sig_index | Function signature. |
imm_u32 | elems_size | Amount of function indices. |
imm_u32 | elems[elems_size] | Function indices/references. |
The FunctionDefinitionSection record contains:
Type | Name | Description |
---|---|---|
FunctionDefinition | funcs[funcs_size] | Function definitions. (funcs_size is defined in FunctionDeclarationSection) |
The FunctionDefinition record can defined two ways (based on first byte): FunctionDefinitionShort and FunctionDefinitionLong. The FunctionDefinitionShort record contains:
Type | Name | Description |
---|---|---|
u8 | only_i32_locals_size | Bit-packed VarTypesWithImm structure. |
StatementList | body | Function body. |
The VarTypesWithImm structure has msb (bit 7) set and bits 4 through 0 contain size field. (The bits 6 through 5 contain reserver and shall contain 0 for OnlyI32 type information).
The FunctionDefinitionLong record contains:
Type | Name | Description |
---|---|---|
u8 | has_locals_of_type | Bit-packed VarTypes flags. |
imm_u32 | num_i32_vars | The field present if has_locals_of_type has VarTypes::I32 bit (mask 1), otherwise 0 is assumed |
imm_u32 | num_f32_vars | The field present if has_locals_of_type has VarTypes::F32 bit (mask 2), otherwise 0 is assumed |
imm_u32 | num_f64_vars | The field present if has_locals_of_type has VarTypes::F64 bit (mask 4), otherwise 0 is assumed |
StatementList | body | Function body. |
The ExportSection record can be defined two ways as: ExportSectionDefault and ExportSectionRecord.
The ExportSectionDefault record contains:
Type | Name | Description |
---|---|---|
u8 | type | Export section type. 0 - for Default. |
imm_u32 | func_index | Default function index. |
The ExportSectionRecord record contains:
Type | Name | Description |
---|---|---|
u8 | type | Export section type. 1 - for Record. |
imm_u32 | exports_size | Amount of exported functions. |
FunctionExport | exports[exports_size] | Function exports. |
The FunctionExport record contains:
Type | Name | Description |
---|---|---|
c_str | name | Exported function name. |
imm_u32 | func_index | Function index. |
The StatementList record contains:
Type | Name | Description |
---|---|---|
imm_u32 | statements_size | Amount of statements. |
Statement | statements[statements_size] | Statements. |
The Statement record is a base for different nodes and contains at least:
Type | Name | Description |
---|---|---|
u8 | type_or_record | Statement type or packed statement record. |
where statement type is one of the integer values, if type_or_record has no msb set (mask 0x80):
Value | Name | Description |
---|---|---|
0 | SetLoc | |
1 | SetGlo | |
2 | I32Store8 | |
3 | I32StoreOff8 | |
4 | I32Store16 | |
5 | I32StoreOff16 | |
6 | I32Store32 | |
7 | I32StoreOff32 | |
8 | F32Store | |
9 | F32StoreOff | |
10 | F64Store | |
11 | F64StoreOff | |
12 | CallInt | |
13 | CallInd | |
14 | CallImp | |
15 | Ret | |
16 | Block | |
17 | IfThen | |
18 | IfElse | |
19 | While | |
20 | Do | |
21 | Label | |
22 | Break | |
23 | BreakLabel | |
24 | Continue | |
25 | ContinueLabel | |
26 | Switch |
If type_or_record has mbs set, bits 6 through 5 define packed record type and bits 4 through 0 define first argument of the operation, the packed record types:
Value | Name | Description |
---|---|---|
0 | SetLoc | |
1 | SetGlo |
The statements may contain other Statement, StatementList or Expression as children. TODO
Also the statements will define data type for the expressions e.g. SetLoc into i32 local will use the Expression_i32 record.
Expressions have a type, which allows only encode operations applicable to the specified type, e.g. bitwise or is applicable only to i32 type, and float division to float types.
TODO Expression_i32, Expression_f32, Expression_f64