BinaryParser
class BinaryParser
Constructors
<init>
constructor(reader: InputStream, fileName: String)
Parameters
Name | Description |
---|---|
reader: InputStream
|
|
fileName: String
|
<init>
constructor(reader: InputStream, parseContext: ParseContext)
Tool for reading bytes from a reader while supporting position tracking for error reporting purposes.
Parameters
Name | Description |
---|---|
reader: InputStream
|
|
parseContext: ParseContext
|
Methods
readByte
fun readByte(): Byte
Reads a single Byte from the reader.
From the docs:
Bytes encode themselves.
byte ::= 0x00 => 0x00
0xFF => 0xFF
ReturnValue
Name | Description |
---|---|
Byte
|
readByteOrNull
fun readByteOrNull(): Byte?
Reads a single Byte from the reader, or returns null
if the reader is empty.
ReturnValue
Name | Description |
---|---|
Byte?
|
readFourBytes
fun readFourBytes(): Int
Reads the next four bytes from the reader as a little-endian-encoded Int.
ReturnValue
Name | Description |
---|---|
Int
|
readEightBytes
fun readEightBytes(): Long
Reads the next eight bytes from the reader as a little-endian-encoded Long.
ReturnValue
Name | Description |
---|---|
Long
|
readBytes
fun readBytes(size: Int): ByteArray
Reads size bytes from the reader into a new ByteArray.
Parameters
Name | Description |
---|---|
size: Int
|
ReturnValue
Name | Description |
---|---|
ByteArray
|
throwException
fun throwException(message: String, positionOffset: Int): Nothing
Throws a ParseException with the given message at the current position plus the provided positionOffset.
Parameters
Name | Description |
---|---|
message: String
|
|
positionOffset: Int
|
ReturnValue
Name | Description |
---|---|
Nothing
|
Extensions
readControlInstruction
fun BinaryParser.readControlInstruction(opcode: Int): ControlInstruction
From the docs:
Control instructions have varying encodings. For structured instructions, the instruction
sequences forming nested blocks are terminated with explicit opcodes for end
and else
.
Block types are encoded in special compressed form, by either the byte 0x40
indicating the
empty type, as a single value type, or as a type index encoded as a positive signed integer.
blocktype ::= 0x40 => ϵ
t:valtype => t
x:s33 => x (if x >= 0)
instr ::= 0x00 => unreachable
0x01 => nop
0x02 bt:blocktype (in:instr)* 0x0B => block bt in* end
0x03 bt:blocktype (in:instr)* 0x0B => loop bt in* end
0x04 bt:blocktype (in:instr)* 0x0B => if bt in* else ϵ end
0x04 bt:blocktype (in1:instr)* 0x05 (in2:instr)* 0x0B
=> if bt in1 else in2 end
0x0C l:labelidx => br l
0x0D l:labelidx => br_if l
0x0E l*:vec(labelidx) l_N:labelidx => br_table l* l_N
0x0F => return
0x10 x:funcidx => call x
0x11 x:typeidx 0x00 => call_indirect x
Note
The else
opcode 0x05
in the encoding of an if
instruction can be omitted if the following
instruction sequence is empty.
Unlike any other occurrence, the type index in a block type is encoded as a positive signed
integer, so that its signed LEB128 bit pattern cannot collide with the encoding of value types or
the special code 0x40
, which correspond to the LEB128 encoding of negative integers. To avoid
any loss in the range of allowed indices, it is treated as a 33 bit signed integer.
In future versions of WebAssembly, the zero byte occurring in the encoding of the call_indirect
instruction may be used to index additional tables.
Receiver
Name | Description |
---|---|
BinaryParser
|
Parameters
Name | Description |
---|---|
opcode: Int
|
ReturnValue
Name | Description |
---|---|
ControlInstruction
|
readExpression
fun BinaryParser.readExpression(): Expression
From the docs:
Expressions are encoded by their instruction sequence terminated with an explicit 0x0B
opcode for end.
expr ::= (in:instr)* 0x0B => in* end
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
Expression
|
readInstruction
fun BinaryParser.readInstruction(): Instruction?
Parses an instruction given the opcode byte provided, or throws a ParseException if no
instruction can be found for the provided opcode. Returns null if end
was read.
From the docs:
Instructions are encoded by opcodes. Each opcode is represented by a single byte, and is followed by the instruction’s immediate arguments, where present. The only exception are structured control instructions, which consist of several opcodes bracketing their nested instruction sequences.
Note
Gaps in the byte code ranges for encoding instructions are reserved for future extensions.
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
Instruction?
|
readMemoryInstruction
fun BinaryParser.readMemoryInstruction(opcode: Int): Instruction
From the docs:
Each variant of memory instruction is encoded with a different byte code. Loads and stores are
followed by the encoding of their memarg
immediate.
memarg ::= a:u32 o:u32 => {align a, offset o}
instr ::= 0x28 m:memarg => i32.load m
0x29 m:memarg => i64.load m
0x2A m:memarg => f32.load m
0x2B m:memarg => f64.load m
0x2C m:memarg => i32.load8_s m
0x2D m:memarg => i32.load8_u m
0x2E m:memarg => i32.load16_s m
0x2F m:memarg => i32.load16_u m
0x30 m:memarg => i64.load8_s m
0x31 m:memarg => i64.load8_u m
0x32 m:memarg => i64.load16_s m
0x33 m:memarg => i64.load16_u m
0x34 m:memarg => i64.load32_s m
0x35 m:memarg => i64.load32_u m
0x36 m:memarg => i32.store m
0x37 m:memarg => i64.store m
0x38 m:memarg => f32.store m
0x39 m:memarg => f64.store m
0x3A m:memarg => i32.store8 m
0x3B m:memarg => i32.store16 m
0x3C m:memarg => i64.store8 m
0x3D m:memarg => i64.store16 m
0x3E m:memarg => i64.store32 m
0x3F 0x00 => memory.size
0x40 0x00 => memory.grow
Note
In future versions of WebAssembly, the additional zero bytes occurring in the encoding of the
memory.size
and memory.grow
instructions may be used to index additional memories.
Receiver
Name | Description |
---|---|
BinaryParser
|
Parameters
Name | Description |
---|---|
opcode: Int
|
ReturnValue
Name | Description |
---|---|
Instruction
|
readMemoryArg
fun BinaryParser.readMemoryArg(): MemArg
Reads a MemArg node from the binary stream.
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
MemArg
|
readNumericInstruction
fun BinaryParser.readNumericInstruction(opcode: Int): Instruction
From the docs :
All variants of numeric instructions are represented by separate byte codes.
The const
instructions are followed by the respective literal.
instr ::= 0x41 n:i32 => i32.const n
0x42 n:i64 => i64.const n
0x43 z:f32 => f32.const z
0x44 z:f64 => f64.const z
All other numeric instructions are plain opcodes without any immediates.
instr ::= 0x45 => i32.eqz
0x46 => i32.eq
0x47 => i32.ne
0x48 => i32.lt_s
0x49 => i32.lt_u
0x4A => i32.gt_s
0x4B => i32.gt_u
0x4C => i32.le_s
0x4D => i32.le_u
0x4E => i32.ge_s
0x4F => i32.ge_u
0x50 => i64.eqz
0x51 => i64.eq
0x52 => i64.ne
0x53 => i64.lt_s
0x54 => i64.lt_u
0x55 => i64.gt_s
0x56 => i64.gt_u
0x57 => i64.le_s
0x58 => i64.le_u
0x59 => i64.ge_s
0x5A => i64.ge_u
0x5B => f32.eq
0x5C => f32.ne
0x5D => f32.lt
0x5E => f32.gt
0x5F => f32.le
0x60 => f32.ge
0x61 => f64.eq
0x62 => f64.ne
0x63 => f64.lt
0x64 => f64.gt
0x65 => f64.le
0x66 => f64.ge
0x67 => i32.clz
0x68 => i32.ctz
0x69 => i32.popcnt
0x6A => i32.add
0x6B => i32.sub
0x6C => i32.mul
0x6D => i32.div_s
0x6E => i32.div_u
0x6F => i32.rem_s
0x70 => i32.rem_u
0x71 => i32.and
0x72 => i32.or
0x73 => i32.xor
0x74 => i32.shl
0x75 => i32.shr_s
0x76 => i32.shr_u
0x77 => i32.rotl
0x78 => i32.rotr
0x79 => i64.clz
0x7A => i64.ctz
0x7B => i64.popcnt
0x7C => i64.add
0x7D => i64.sub
0x7E => i64.mul
0x7F => i64.div_s
0x80 => i64.div_u
0x81 => i64.rem_s
0x82 => i64.rem_u
0x83 => i64.and
0x84 => i64.or
0x85 => i64.xor
0x86 => i64.shl
0x87 => i64.shr_s
0x88 => i64.shr_u
0x89 => i64.rotl
0x8A => i64.rotr
0x8B => f32.abs
0x8C => f32.neg
0x8D => f32.ceil
0x8E => f32.floor
0x8F => f32.trunc
0x90 => f32.nearest
0x91 => f32.sqrt
0x92 => f32.add
0x93 => f32.sub
0x94 => f32.mul
0x95 => f32.div
0x96 => f32.min
0x97 => f32.max
0x98 => f32.copysign
0x99 => f64.abs
0x9A => f64.neg
0x9B => f64.ceil
0x9C => f64.floor
0x9D => f64.trunc
0x9E => f64.nearest
0x9F => f64.sqrt
0xA0 => f64.add
0xA1 => f64.sub
0xA2 => f64.mul
0xA3 => f64.div
0xA4 => f64.min
0xA5 => f64.max
0xA6 => f64.copysign
0xA7 => i32.wrap_i64
0xA8 => i32.trunc_f32_s
0xA9 => i32.trunc_f32_u
0xAA => i32.trunc_f64_s
0xAB => i32.trunc_f64_u
0xAC => i64.extend_i32_s
0xAD => i64.extend_i32_u
0xAE => i64.trunc_f32_s
0xAF => i64.trunc_f32_u
0xB0 => i64.trunc_f64_s
0xB1 => i64.trunc_f64_u
0xB2 => f32.convert_i32_s
0xB3 => f32.convert_i32_u
0xB4 => f32.convert_i64_s
0xB5 => f32.convert_i64_u
0xB6 => f32.demote_f64
0xB7 => f64.convert_i32_s
0xB8 => f64.convert_i32_u
0xB9 => f64.convert_i64_s
0xBA => f64.convert_i64_u
0xBB => f64.promote_f32
0xBC => i32.reinterpret_f32
0xBD => i64.reinterpret_f64
0xBE => f32.reinterpret_i32
0xBF => f64.reinterpret_i64
0xC0 => i32.extend8_s
0xC1 => i32.extend16_s
0xC2 => i64.extend8_s
0xC3 => i64.extend16_s
0xC4 => i64.extend32_s
The saturating truncation instructions all have a one byte prefix, whereas the actual opcode is encoded by a variable-length unsigned integer.
instr ::= 0xFC 0:u32 => i32.trunc_sat_f32_s
0xFC 1:u32 => i32.trunc_sat_f32_u
0xFC 2:u32 => i32.trunc_sat_f64_s
0xFC 3:u32 => i32.trunc_sat_f64_u
0xFC 4:u32 => i64.trunc_sat_f32_s
0xFC 5:u32 => i64.trunc_sat_f32_u
0xFC 6:u32 => i64.trunc_sat_f64_s
0xFC 7:u32 => i64.trunc_sat_f64_u
Receiver
Name | Description |
---|---|
BinaryParser
|
Parameters
Name | Description |
---|---|
opcode: Int
|
ReturnValue
Name | Description |
---|---|
Instruction
|
readParametricInstruction
fun BinaryParser.readParametricInstruction(opcode: Int): ParametricInstruction
From the docs:
Parametric instructions are represented by single byte codes.
instr ::= 0x1A => drop
0x1B => select
Receiver
Name | Description |
---|---|
BinaryParser
|
Parameters
Name | Description |
---|---|
opcode: Int
|
ReturnValue
Name | Description |
---|---|
ParametricInstruction
|
readVariableInstruction
fun BinaryParser.readVariableInstruction(opcode: Int): VariableInstruction
From the docs:
Variable instructions are represented by byte codes followed by the encoding of the respective index.
instr ::= 0x20 x:localidx => local.get x
0x21 x:localidx => local.set x
0x22 x:localidx => local.tee x
0x23 x:globalidx => global.get x
0x24 x:globalidx => global.set x
Receiver
Name | Description |
---|---|
BinaryParser
|
Parameters
Name | Description |
---|---|
opcode: Int
|
ReturnValue
Name | Description |
---|---|
VariableInstruction
|
readCodeSection
fun BinaryParser.readCodeSection(): CodeSection
From the docs:
The code section has the id 10. It decodes into a vector of code entries that are pairs of value
type vectors and expressions. They represent the locals
and body
field of the functions in
the funcs
component of a module. The type
fields of the respective functions are encoded
separately in the function section.
The encoding of each code entry consists of
- the
u32
size of the function code in bytes, - the actual function code, which in turn consists of
- the declaration of locals,
- the function body as an expression.
Local declarations are compressed into a vector whose entries consist of
- a
u32
count, - a value type, denoting count locals of the same value type.
codesec ::= code*:section_10(vec(code)) => code*
code ::= size:u32 code:func => code (if size = ||func||)
func ::= (t*):vec(locals) e:expr => concat((t)), e (if |concat((t*)*)| < 2^32)
locals ::= n:u32 t:valtype => t^n
Here, code
ranges over pairs (valtype*, expr)
. The meta function concat((t*)*)
concatenates all sequences t*_i
in (t*)*
. Any code for which the length of the resulting
sequence is out of bounds of the maximum size of a vector is malformed.
Note
Like with sections, the code size
is not needed for decoding, but can be used to skip functions
when navigating through a binary. The module is malformed if a size does not match the length of
the respective function code.
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
CodeSection
|
readCustomSection
fun BinaryParser.readCustomSection(totalSize: Int): CustomSection
From the docs:
Custom sections have the id 0. They are intended to be used for debugging information or third-party extensions, and are ignored by the WebAssembly semantics. Their contents consist of a name further identifying the custom section, followed by an uninterpreted sequence of bytes for custom use.
customsec ::= section_0(custom)
custom ::= name byte*
Note If an implementation interprets the data of a custom section, then errors in that data, or the placement of the section, must not invalidate the module.
Receiver
Name | Description |
---|---|
BinaryParser
|
Parameters
Name | Description |
---|---|
totalSize: Int
|
ReturnValue
Name | Description |
---|---|
CustomSection
|
readDataSection
fun BinaryParser.readDataSection(): DataSection
From the docs:
The data section has the id 11. It decodes into a vector of data segments that represent the
data
component of a module.
datasec ::= seg*:section_11(vec(data)) => seg
data ::= x:memidx e:expr b*:vec(byte) => {data x, offset e, init b*}
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
DataSection
|
readElementSection
fun BinaryParser.readElementSection(): ElementSection
From the docs:
The element section has the id 9. It decodes into a vector of element segments that represent
the elem
component of a module.
elemsec ::= seg*:section_9(vec(elem)) => seg
elem ::= x:tableidx e:expr y*:vec(funcidx) => {table x, offset e, init y*}
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
ElementSection
|
readElementSegment
fun BinaryParser.readElementSegment(): ElementSegment
Reads an ElementSegment from a binary-encoded WebAssembly module's ElementSection.
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
ElementSegment
|
readExportSection
fun BinaryParser.readExportSection(): ExportSection
From the docs:
The export section has the id 7. It decodes into a vector of exports that represent the exports
component of a module.
exportsec ::= ex*:section_7(vec(export)) => ex*
export ::= nm:name d:exportdesc => {name nm, desc d}
exportdesc ::= 0x00 x:funcidx => func x
0x01 x:tableidx => table x
0x02 x:memidx => mem x
0x03 x:globalidx => global x
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
ExportSection
|
readFunctionSection
fun BinaryParser.readFunctionSection(): FunctionSection
From the docs:
The function section has the id 3. It decodes into a vector of type indices that represent the
type
fields of the functions in the funcs
component of a module. The locals
and body
fields of the respective functions are encoded separately in the code section.
funcsec ::= x*:section_3(vec(typeidx)) => x*
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
FunctionSection
|
readGlobalSection
fun BinaryParser.readGlobalSection(): GlobalSection
From the docs:
The global section has the id 6. It decodes into a vector of globals that represent the globals
component of a module.
globalsec ::= glob*:section_6(vec(global)) => glob*
global ::= gt:globaltype e:expr => {type gt, init e}
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
GlobalSection
|
readImportSection
fun BinaryParser.readImportSection(): ImportSection
From the docs:
The import section has the id 2. It decodes into a vector of imports that represent the
imports
component of a module.
importsec ::= im*:section_2(vec(import)) => im*
import ::= mod:name nm:name d:importdesc => {module mod, name nm, desc d}
importdesc ::= 0x00 x:typeidx => func x
0x01 tt:tabletype => table tt
0x02 mt:memtype => mem mt
0x03 gt:globaltype => global gt
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
ImportSection
|
readIndex
fun <T : Identifier> BinaryParser.readIndex(): Index<T>
From the docs:
All indices are encoded with their respective value.
typeidx ::= x:u32 => x
funcidx ::= x:u32 => x
tableidx ::= x:u32 => x
memidx ::= x:u32 => x
globalidx ::= x:u32 => x
localidx ::= x:u32 => x
labelidx ::= l:u32 => l
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
Index<T>
|
readFuncLocals
fun BinaryParser.readFuncLocals(): List<Local>
From the code section docs:
Local declarations are compressed into a vector whose entries consist of
- a
u32
count, - a value type, denoting count locals of the same value type.
func ::= (t*):vec(locals) e:expr => concat((t)), e (if |concat((t*)*)| < 2^32)
locals ::= n:u32 t:valtype => tn
The meta function concat((t*)*)
concatenates all sequences t*_i
in (t*)*
.
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
List<Local>
|
readMemorySection
fun BinaryParser.readMemorySection(): MemorySection
From the docs:
The memory section has the id 5. It decodes into a vector of memories that represent the mems
component of a module.
memsec ::= mem*:section_5(vec(mem)) => mem*
mem ::= mt:memtype =>
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
MemorySection
|
readOffset
fun BinaryParser.readOffset(): Offset
Reads an Offset from a binary-encoded WebAssembly module.
Offsets are encoded as expressions.
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
Offset
|
readSection
fun BinaryParser.readSection(): Section?
From the docs:
Each section consists of
- a one-byte section id,
- the
u32
size of the contents, in bytes, - the actual contents, whose structure is depended on the section id.
Every section is optional; an omitted section is equivalent to the section being present with empty contents.
The following parameterized grammar rule defines the generic structure of a section with id N
and contents described by the grammar B
.
section_N(B) ::= N:byte size:u32 cont:B => cont (if size = ||B||)
ϵ => ϵ
Note
Other than for unknown custom sections, the size
is not required for decoding, but can be used
to skip sections when navigating through a binary. The module is malformed if the size does not
match the length of the binary contents B
.
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
Section?
|
readStartSection
fun BinaryParser.readStartSection(): StartSection
From the docs:
The start section has the id 8. It decodes into an optional start function that represents the
start
component of a module.
startsec ::= st?:section_8(start) => st?
start ::= x:funcidx =>
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
StartSection
|
readTableSection
fun BinaryParser.readTableSection(): TableSection
From the docs:
The table section has the id 4. It decodes into a vector of tables that represent the tables
component of a module.
tablesec ::= tab*:section_4(vec(table)) => tab*
table ::= tt:tabletype =>
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
TableSection
|
readTypeSection
fun BinaryParser.readTypeSection(): TypeSection
From the docs:
The type section has the id 1. It decodes into a vector of function types that represent the 𝗍𝗒𝗉𝖾𝗌 component of a module.
typesec ::= ft*:section_1(vec(functype)) => ft*
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
TypeSection
|
readModule
fun BinaryParser.readModule(): WasmModule
From the docs:
The encoding of a module starts with a preamble containing a 4-byte magic number (the string
‘∖0asm’
) and a version field. The current version of the WebAssembly binary format is 1.
The preamble is followed by a sequence of sections. Custom sections may be inserted at any place in this sequence, while other sections must occur at most once and in the prescribed order. All sections can be empty.
The lengths of vectors produced by the (possibly empty) function and code section must match up.
magic ::= 0x00 0x61 0x73 0x6D
version ::= 0x01 0x00 0x00 0x00
module ::= magic
version
customsec*
functype*:typesec
customsec*
import*:importsec
customsec*
typeidx^n:funcsec
customsec*
table*:tablesec
customsec*
mem*:memsec
customsec*
global*:globalsec
customsec*
export*:exportsec
customsec*
start?:startsec
customsec*
elem*:elemsec
customsec*
code^n:codesec
customsec*
data*:datasec
customsec* => {types functype*,
funcs func^n,
tables table*,
mems mem*,
globals global*,
elem elem*,
data data*,
start start?,
imports import*,
exports export*}
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
WasmModule
|
readFunctionType
fun BinaryParser.readFunctionType(): FunctionType
From the docs:
Function types are encoded by the byte 0x60
followed by the respective vectors of parameter
and result types.
functype ::= 0x60 rt1:resulttype rt2:resulttype => rt1 → rt2
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
FunctionType
|
readGlobalType
fun BinaryParser.readGlobalType(): GlobalType
From the docs:
Global types are encoded by their value type and a flag for their mutability.
globaltype ::= t:valtype m:mut => m
tmut ::= 0x00 => const
0x01 => var
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
GlobalType
|
readLimits
fun BinaryParser.readLimits(): Limits
From the docs:
Limits are encoded with a preceding flag indicating whether a maximum is present.
limits ::= 0x00 n:u32 => {min n, max ϵ}
0x01 n:u32 m:u32 => {min n, max m}
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
Limits
|
readMemoryType
fun BinaryParser.readMemoryType(): MemoryType
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
MemoryType
|
readResultType
fun BinaryParser.readResultType(): ResultType
From the docs:
Result types are encoded by the respective vectors of value types `.
resulttype ::= t*:vec(valtype) => [t*]
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
ResultType
|
readTableType
fun BinaryParser.readTableType(): TableType
From the docs:
Table types are encoded with their limits and a constant byte indicating their element type.
tabletype ::= et:elemtype lim:limits => lim et
elemtype ::= 0x70 => funcref
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
TableType
|
readValueType
fun BinaryParser.readValueType(): ValueType
From the docs:
Value types are encoded by a single byte.
valtype ::= 0x7F => i32
0x7E => i64
0x7D => f32
0x7C => f64
Note
Value types can occur in contexts where type indices are also allowed, such as in the case of
block types. Thus, the binary format for types corresponds to the signed LEB128 encoding of
small negative sN
values, so that they can coexist with (positive) type indices in the future.
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
ValueType
|
readFloat
fun BinaryParser.readFloat(): Float
From the docs:
Floating-point values are encoded directly by their IEEE 754-2019 (Section 3.4) bit pattern in little endian byte order:
fN ::= b∗:byte^N/8 => bytes^−1_fN(b∗)
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
Float
|
readDouble
fun BinaryParser.readDouble(): Double
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
Double
|
readUInt
fun BinaryParser.readUInt(): Int
From the docs:
All integers are encoded using the LEB128 variable-length integer encoding, in either unsigned or signed variant.
Unsigned integers are encoded in unsigned LEB128 format. As an additional constraint, the total number of bytes encoding a value of type uN must not exceed ceil(N/7) bytes.
uN ::= n:byte => n (if n < 2^7 and n < 2^N)
n:byte m:u(N−7) => 2^7 * m + (n - 2^7) (if n >= 2^7 and N > 7)
Signed integers are encoded in signed LEB128 format, which uses a two’s complement
representation. As an additional constraint, the total number of bytes encoding a value of type
sN
must not exceed ceil(N/7)
bytes.
sN ::= n:byte => n (if n<26 and n < 2^(N−1))
n:byte => n - 2^7 (if 26 <= n < 27 and n >= 2^7 - 2^(N−1))
n:byte m:s(N−7) => 2^7 * m + (n - 2^7) (if n >= 27 and N > 7)
Uninterpreted integers are encoded as signed integers.
iN ::= n:sN => i (if n = signed_iN(i))
**Note**
The side conditions `N > 7` in the productions for non-terminal bytes of the `u` and `s`
encodings restrict the encoding’s length. However, “trailing zeros” are still allowed within
these bounds. For example, `0x03` and `0x83 0x00` are both well-formed encodings for the value
`3` as a u8. Similarly, either of `0x7e` and `0xFE 0x7F` and `0xFE 0xFF 0x7F` are well-formed
encodings of the value `−2` as a `s16`.
The side conditions on the value `n` of terminal bytes further enforce that any unused bits in
these bytes must be `0` for positive values and 1 for negative ones. For example, `0x83 0x10` is
malformed as a `u8` encoding. Similarly, both `0x83 0x3E` and `0xFF 0x7B` are malformed as s8
encodings.
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
Int
|
readInt
fun BinaryParser.readInt(): Int
See BinaryParser.readUInt.
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
Int
|
readULong
fun BinaryParser.readULong(): Long
See BinaryParser.readUInt.
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
Long
|
readLong
fun BinaryParser.readLong(): Long
See BinaryParser.readUInt.
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
Long
|
readName
fun BinaryParser.readName(): String
From the docs:
Names are encoded as a vector of bytes containing the Unicode (Section 3.9) UTF-8 encoding of the name’s character sequence.
name ::= b∗:vec(byte) => name (if utf8(name)=b∗)
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
String
|
readVector
fun BinaryParser.readVector(): List<Byte>
From the docs:
Vectors are encoded with their u32 length followed by the encoding of their element sequence.
vec(B) ::= n:u32 (x:B)n => x^n
Receiver
Name | Description |
---|---|
BinaryParser
|
ReturnValue
Name | Description |
---|---|
List<Byte>
|
readVector
fun <T> BinaryParser.readVector(block: BinaryParser.()->T): List<T>
From the docs:
Vectors are encoded with their u32 length followed by the encoding of their element sequence.
vec(B) ::= n:u32 (x:B)n => x^n
Receiver
Name | Description |
---|---|
BinaryParser
|
Parameters
Name | Description |
---|---|
block: BinaryParser.()->T
|
ReturnValue
Name | Description |
---|---|
List<T>
|
Tool for reading bytes from a reader while supporting position tracking for error reporting purposes.