blob: 66f0c2bc8460213876c329a22ef5e94d96fd9aca [file] [log] [blame] [edit]
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import '../serialize/printer.dart';
import '../serialize/serialize.dart';
import 'ir.dart';
abstract mixin class Instruction implements Serializable {
/// The [ValueType] types referenced by this instruction. Used to determine
/// which types need to be included in the module. Unused types will not be
/// emitted in the wasm output.
List<ValueType> get usedValueTypes => const [];
/// The [DefType] types referenced by this instruction. Used to determine
/// which types need to be included in the module. Unused types will not be
/// emitted in the wasm output.
List<DefType> get usedDefTypes => const [];
const Instruction();
/// Whether the instruction is a "constant instruction", as defined by the
/// Wasm spec.
///
/// Constant instructions can be used in global initializers, element
/// segments, data segments.
bool get isConstant => false;
/// The name of the instruction.
String get name;
/// Prints the text representation of this instruction to [p].
///
/// Instructions that have fields should override this.
void printTo(IrPrinter p) {
p.write(name);
}
static Instruction deserializeConst(
Deserializer d, Types types, Functions functions, Globals globals,
{bool isConstOnlyUse = true}) {
final byte = d.readByte();
switch (byte) {
case 0x0B:
return End.deserialize(d);
case 0x23:
return GlobalGet.deserialize(d, globals);
case 0x41:
return I32Const.deserialize(d);
case 0x42:
return I64Const.deserialize(d);
case 0x43:
return F32Const.deserialize(d);
case 0x44:
return F64Const.deserialize(d);
case 0xD0:
return RefNull.deserialize(d, types);
case 0xD2:
return RefFunc.deserialize(d, functions);
case 0xFB:
{
final byte2 = d.readByte();
return switch (byte2) {
0x00 => StructNew.deserialize(d, types),
0x01 => StructNewDefault.deserialize(d, types),
0x06 => ArrayNew.deserialize(d, types),
0x07 => ArrayNewDefault.deserialize(d, types),
0x08 => ArrayNewFixed.deserialize(d, types),
0x1A => ExternInternalize.deserialize(d),
0x1B => ExternExternalize.deserialize(d),
_ =>
throw "Invalid ${isConstOnlyUse ? 'const ' : ''}instruction byte: $byte $byte2"
};
}
default:
throw "Invalid ${isConstOnlyUse ? 'const ' : ''}instruction byte: $byte";
}
}
static Instruction deserialize(
Deserializer d,
Types types,
Tables tables,
Tags tags,
Globals globals,
DataSegments dataSegments,
Memories memories,
Functions functions,
) {
final instructionStart = d.offset;
final byte = d.readByte();
switch (byte) {
case 0x00:
return Unreachable.deserialize(d);
case 0x01:
return Nop.deserialize(d);
case 0x02:
return d.deserializeBlock(types, tags, BeginNoEffectBlock.deserialize,
BeginOneOutputBlock.deserialize, BeginFunctionBlock.deserialize);
case 0x03:
return d.deserializeBlock(types, tags, BeginNoEffectLoop.deserialize,
BeginOneOutputLoop.deserialize, BeginFunctionLoop.deserialize);
case 0x04:
return d.deserializeBlock(types, tags, BeginNoEffectIf.deserialize,
BeginOneOutputIf.deserialize, BeginFunctionIf.deserialize);
case 0x05:
return Else.deserialize(d);
case 0x06:
return d.deserializeBlock(types, tags, BeginNoEffectTry.deserialize,
BeginOneOutputTry.deserialize, BeginFunctionTry.deserialize);
case 0x07:
return CatchLegacy.deserialize(d, tags);
case 0x08:
return Throw.deserialize(d, tags);
case 0x09:
return Rethrow.deserialize(d);
case 0x0A:
return ThrowRef.deserialize(d);
case 0x0C:
return Br.deserialize(d);
case 0x0D:
return BrIf.deserialize(d);
case 0x0E:
return BrTable.deserialize(d);
case 0x0F:
return Return.deserialize(d);
case 0x10:
return Call.deserialize(d, functions);
case 0x11:
return CallIndirect.deserialize(d, types, tables);
case 0x14:
return CallRef.deserialize(d, types);
case 0x19:
return CatchAllLegacy.deserialize(d);
case 0x1A:
return Drop.deserialize(d);
case 0x1B:
return Select.deserialize(d);
case 0x1C:
return SelectWithType.deserialize(d, types);
case 0x1F:
return d.deserializeBlock(
types,
tags,
BeginNoEffectTryTable.deserialize,
BeginOneOutputTryTable.deserialize,
BeginFunctionTryTable.deserialize);
case 0x20:
return LocalGet.deserialize(d);
case 0x21:
return LocalSet.deserialize(d);
case 0x22:
return LocalTee.deserialize(d);
case 0x24:
return GlobalSet.deserialize(d, globals);
case 0x25:
return TableGet.deserialize(d, tables);
case 0x26:
return TableSet.deserialize(d, tables);
case 0x28:
return I32Load.deserialize(d, memories);
case 0x29:
return I64Load.deserialize(d, memories);
case 0x2A:
return F32Load.deserialize(d, memories);
case 0x2B:
return F64Load.deserialize(d, memories);
case 0x2C:
return I32Load8S.deserialize(d, memories);
case 0x2D:
return I32Load8U.deserialize(d, memories);
case 0x2E:
return I32Load16S.deserialize(d, memories);
case 0x2F:
return I32Load16U.deserialize(d, memories);
case 0x30:
return I64Load8S.deserialize(d, memories);
case 0x31:
return I64Load8U.deserialize(d, memories);
case 0x32:
return I64Load16S.deserialize(d, memories);
case 0x33:
return I64Load16U.deserialize(d, memories);
case 0x34:
return I64Load32S.deserialize(d, memories);
case 0x35:
return I64Load32U.deserialize(d, memories);
case 0x36:
return I32Store.deserialize(d, memories);
case 0x37:
return I64Store.deserialize(d, memories);
case 0x38:
return F32Store.deserialize(d, memories);
case 0x39:
return F64Store.deserialize(d, memories);
case 0x3A:
return I32Store8.deserialize(d, memories);
case 0x3B:
return I32Store16.deserialize(d, memories);
case 0x3C:
return I64Store8.deserialize(d, memories);
case 0x3D:
return I64Store16.deserialize(d, memories);
case 0x3E:
return I64Store32.deserialize(d, memories);
case 0x3F:
return MemorySize.deserialize(d, memories);
case 0x40:
return MemoryGrow.deserialize(d, memories);
case 0x45:
return I32Eqz.deserialize(d);
case 0x46:
return I32Eq.deserialize(d);
case 0x47:
return I32Ne.deserialize(d);
case 0x48:
return I32LtS.deserialize(d);
case 0x49:
return I32LtU.deserialize(d);
case 0x4A:
return I32GtS.deserialize(d);
case 0x4B:
return I32GtU.deserialize(d);
case 0x4C:
return I32LeS.deserialize(d);
case 0x4D:
return I32LeU.deserialize(d);
case 0x4E:
return I32GeS.deserialize(d);
case 0x4F:
return I32GeU.deserialize(d);
case 0x50:
return I64Eqz.deserialize(d);
case 0x51:
return I64Eq.deserialize(d);
case 0x52:
return I64Ne.deserialize(d);
case 0x53:
return I64LtS.deserialize(d);
case 0x54:
return I64LtU.deserialize(d);
case 0x55:
return I64GtS.deserialize(d);
case 0x56:
return I64GtU.deserialize(d);
case 0x57:
return I64LeS.deserialize(d);
case 0x58:
return I64LeU.deserialize(d);
case 0x59:
return I64GeS.deserialize(d);
case 0x5A:
return I64GeU.deserialize(d);
case 0x5B:
return F32Eq.deserialize(d);
case 0x5C:
return F32Ne.deserialize(d);
case 0x5D:
return F32Lt.deserialize(d);
case 0x5E:
return F32Gt.deserialize(d);
case 0x5F:
return F32Le.deserialize(d);
case 0x60:
return F32Ge.deserialize(d);
case 0x61:
return F64Eq.deserialize(d);
case 0x62:
return F64Ne.deserialize(d);
case 0x63:
return F64Lt.deserialize(d);
case 0x64:
return F64Gt.deserialize(d);
case 0x65:
return F64Le.deserialize(d);
case 0x66:
return F64Ge.deserialize(d);
case 0x67:
return I32Clz.deserialize(d);
case 0x68:
return I32Ctz.deserialize(d);
case 0x69:
return I32Popcnt.deserialize(d);
case 0x6A:
return I32Add.deserialize(d);
case 0x6B:
return I32Sub.deserialize(d);
case 0x6C:
return I32Mul.deserialize(d);
case 0x6D:
return I32DivS.deserialize(d);
case 0x6E:
return I32DivU.deserialize(d);
case 0x6F:
return I32RemS.deserialize(d);
case 0x70:
return I32RemU.deserialize(d);
case 0x71:
return I32And.deserialize(d);
case 0x72:
return I32Or.deserialize(d);
case 0x73:
return I32Xor.deserialize(d);
case 0x74:
return I32Shl.deserialize(d);
case 0x75:
return I32ShrS.deserialize(d);
case 0x76:
return I32ShrU.deserialize(d);
case 0x77:
return I32Rotl.deserialize(d);
case 0x78:
return I32Rotr.deserialize(d);
case 0x79:
return I64Clz.deserialize(d);
case 0x7A:
return I64Ctz.deserialize(d);
case 0x7B:
return I64Popcnt.deserialize(d);
case 0x7C:
return I64Add.deserialize(d);
case 0x7D:
return I64Sub.deserialize(d);
case 0x7E:
return I64Mul.deserialize(d);
case 0x7F:
return I64DivS.deserialize(d);
case 0x80:
return I64DivU.deserialize(d);
case 0x81:
return I64RemS.deserialize(d);
case 0x82:
return I64RemU.deserialize(d);
case 0x83:
return I64And.deserialize(d);
case 0x84:
return I64Or.deserialize(d);
case 0x85:
return I64Xor.deserialize(d);
case 0x86:
return I64Shl.deserialize(d);
case 0x87:
return I64ShrS.deserialize(d);
case 0x88:
return I64ShrU.deserialize(d);
case 0x89:
return I64Rotl.deserialize(d);
case 0x8A:
return I64Rotr.deserialize(d);
case 0x8B:
return F32Abs.deserialize(d);
case 0x8C:
return F32Neg.deserialize(d);
case 0x8D:
return F32Ceil.deserialize(d);
case 0x8E:
return F32Floor.deserialize(d);
case 0x8F:
return F32Trunc.deserialize(d);
case 0x90:
return F32Nearest.deserialize(d);
case 0x91:
return F32Sqrt.deserialize(d);
case 0x92:
return F32Add.deserialize(d);
case 0x93:
return F32Sub.deserialize(d);
case 0x94:
return F32Mul.deserialize(d);
case 0x95:
return F32Div.deserialize(d);
case 0x96:
return F32Min.deserialize(d);
case 0x97:
return F32Max.deserialize(d);
case 0x98:
return F32Copysign.deserialize(d);
case 0x99:
return F64Abs.deserialize(d);
case 0x9A:
return F64Neg.deserialize(d);
case 0x9B:
return F64Ceil.deserialize(d);
case 0x9C:
return F64Floor.deserialize(d);
case 0x9D:
return F64Trunc.deserialize(d);
case 0x9E:
return F64Nearest.deserialize(d);
case 0x9F:
return F64Sqrt.deserialize(d);
case 0xA0:
return F64Add.deserialize(d);
case 0xA1:
return F64Sub.deserialize(d);
case 0xA2:
return F64Mul.deserialize(d);
case 0xA3:
return F64Div.deserialize(d);
case 0xA4:
return F64Min.deserialize(d);
case 0xA5:
return F64Max.deserialize(d);
case 0xA6:
return F64Copysign.deserialize(d);
case 0xA7:
return I32WrapI64.deserialize(d);
case 0xA8:
return I32TruncF32S.deserialize(d);
case 0xA9:
return I32TruncF32U.deserialize(d);
case 0xAA:
return I32TruncF64S.deserialize(d);
case 0xAB:
return I32TruncF64U.deserialize(d);
case 0xAC:
return I64ExtendI32S.deserialize(d);
case 0xAD:
return I64ExtendI32U.deserialize(d);
case 0xAE:
return I64TruncF32S.deserialize(d);
case 0xAF:
return I64TruncF32U.deserialize(d);
case 0xB0:
return I64TruncF64S.deserialize(d);
case 0xB1:
return I64TruncF64U.deserialize(d);
case 0xB2:
return F32ConvertI32S.deserialize(d);
case 0xB3:
return F32ConvertI32U.deserialize(d);
case 0xB4:
return F32ConvertI64S.deserialize(d);
case 0xB5:
return F32ConvertI64U.deserialize(d);
case 0xB6:
return F32DemoteF64.deserialize(d);
case 0xB7:
return F64ConvertI32S.deserialize(d);
case 0xB8:
return F64ConvertI32U.deserialize(d);
case 0xB9:
return F64ConvertI64S.deserialize(d);
case 0xBA:
return F64ConvertI64U.deserialize(d);
case 0xBB:
return F64PromoteF32.deserialize(d);
case 0xBC:
return I32ReinterpretF32.deserialize(d);
case 0xBD:
return I64ReinterpretF64.deserialize(d);
case 0xBE:
return F32ReinterpretI32.deserialize(d);
case 0xBF:
return F64ReinterpretI64.deserialize(d);
case 0xC0:
return I32Extend8S.deserialize(d);
case 0xC1:
return I32Extend16S.deserialize(d);
case 0xC2:
return I64Extend8S.deserialize(d);
case 0xC3:
return I64Extend16S.deserialize(d);
case 0xC4:
return I64Extend32S.deserialize(d);
case 0xD1:
return RefIsNull.deserialize(d);
case 0xD3:
return RefEq.deserialize(d);
case 0xD4:
return RefAsNonNull.deserialize(d);
case 0xD5:
return BrOnNull.deserialize(d);
case 0xD6:
return BrOnNonNull.deserialize(d);
case 0xFB:
{
final opcode = d.readByte();
switch (opcode) {
case 0x02:
return StructGet.deserialize(d, types);
case 0x03:
return StructGetS.deserialize(d, types);
case 0x04:
return StructGetU.deserialize(d, types);
case 0x05:
return StructSet.deserialize(d, types);
case 0x09:
return ArrayNewData.deserialize(d, types, dataSegments);
case 0x0b:
return ArrayGet.deserialize(d, types);
case 0x0c:
return ArrayGetS.deserialize(d, types);
case 0x0d:
return ArrayGetU.deserialize(d, types);
case 0x0E:
return ArraySet.deserialize(d, types);
case 0x0F:
return ArrayLen.deserialize(d);
case 0x10:
return ArrayFill.deserialize(d, types);
case 0x11:
return ArrayCopy.deserialize(d, types);
case 0x14:
return RefTest.deserialize(d, types, false);
case 0x15:
return RefTest.deserialize(d, types, true);
case 0x16:
return RefCast.deserialize(d, types, false);
case 0x17:
return RefCast.deserialize(d, types, true);
case 0x18:
return BrOnCast.deserialize(d, types);
case 0x19:
return BrOnCastFail.deserialize(d, types);
case 0x1C:
return I31New.deserialize(d);
case 0x1D:
return I31GetS.deserialize(d);
case 0x1E:
return I31GetU.deserialize(d);
default:
d.offset = instructionStart;
return deserializeConst(d, types, functions, globals,
isConstOnlyUse: false);
}
}
case 0xFC:
{
final opcode = d.readByte();
return switch (opcode) {
0x00 => I32TruncSatF32S.deserialize(d),
0x01 => I32TruncSatF32U.deserialize(d),
0x02 => I32TruncSatF64S.deserialize(d),
0x03 => I32TruncSatF64U.deserialize(d),
0x04 => I64TruncSatF32S.deserialize(d),
0x05 => I64TruncSatF32U.deserialize(d),
0x06 => I64TruncSatF64S.deserialize(d),
0x07 => I64TruncSatF64U.deserialize(d),
0x0B => MemoryFill.deserialize(d, memories),
0x10 => TableSize.deserialize(d, tables),
0x11 => TableFill.deserialize(d, tables),
_ => throw "Invalid instruction byte: 0xFC $opcode"
};
}
case 0xFD:
{
final opcode = d.readUnsigned();
final instruction = V128Instruction.fromOpcode(opcode);
if (instruction != null) return instruction;
return switch (opcode) {
0x15 => I8x16ExtractLaneS.deserialize(d),
0x16 => I8x16ExtractLaneU.deserialize(d),
0x17 => I8x16ReplaceLane.deserialize(d),
0x18 => I16x8ExtractLaneS.deserialize(d),
0x19 => I16x8ExtractLaneU.deserialize(d),
0x1A => I16x8ReplaceLane.deserialize(d),
0x1B => I32x4ExtractLane.deserialize(d),
0x1C => I32x4ReplaceLane.deserialize(d),
0x1D => I64x2ExtractLane.deserialize(d),
0x1E => I64x2ReplaceLane.deserialize(d),
0x1F => F32x4ExtractLane.deserialize(d),
0x20 => F32x4ReplaceLane.deserialize(d),
0x21 => F64x2ExtractLane.deserialize(d),
0x22 => F64x2ReplaceLane.deserialize(d),
_ => throw "Invalid instruction byte: 0xFD $opcode"
};
}
default:
d.offset = instructionStart;
return deserializeConst(d, types, functions, globals,
isConstOnlyUse: false);
}
}
}
abstract class SingleByteInstruction extends Instruction {
final int byte;
const SingleByteInstruction(this.byte);
@override
void serialize(Serializer s) => s.writeByte(byte);
}
class Unreachable extends SingleByteInstruction {
const Unreachable() : super(0x00);
static Unreachable deserialize(Deserializer d) => const Unreachable();
@override
String get name => 'unreachable';
}
class Nop extends SingleByteInstruction {
const Nop() : super(0x01);
static Nop deserialize(Deserializer d) => const Nop();
@override
String get name => 'nop';
}
class BeginNoEffectBlock extends Instruction {
const BeginNoEffectBlock();
static BeginNoEffectBlock deserialize(Deserializer d, Tags _) {
d.readByte();
return const BeginNoEffectBlock();
}
@override
void serialize(Serializer s) {
s.writeByte(0x02);
s.writeByte(0x40);
}
@override
String get name => 'block';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeLabelDefinition(0);
}
}
class BeginOneOutputBlock extends Instruction {
final ValueType type;
@override
List<ValueType> get usedValueTypes => [type];
BeginOneOutputBlock(this.type);
static BeginOneOutputBlock deserialize(Deserializer d, Tags _, Types types) {
final type = ValueType.deserialize(d, types.defined);
assert(type is! FunctionType);
return BeginOneOutputBlock(type);
}
@override
void serialize(Serializer s) {
s.writeByte(0x02);
s.write(type);
}
@override
String get name => 'block';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeLabelDefinition(0);
p.write(' ');
p.write('(result ');
p.writeValueType(type);
p.write(')');
}
}
class BeginFunctionBlock extends Instruction {
final FunctionType type;
@override
List<DefType> get usedDefTypes => [type];
BeginFunctionBlock(this.type);
static BeginFunctionBlock deserialize(Deserializer d, Tags _, Types types) {
return BeginFunctionBlock(types.defined[d.readSigned()] as FunctionType);
}
@override
void serialize(Serializer s) {
s.writeByte(0x02);
s.write(type);
}
@override
String get name => 'block';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeLabelDefinition(0);
p.write(' ');
p.writeFunctionType(type);
}
}
class BeginNoEffectLoop extends Instruction {
const BeginNoEffectLoop();
@override
void serialize(Serializer s) {
s.writeByte(0x03);
s.writeByte(0x40);
}
static BeginNoEffectLoop deserialize(Deserializer d, Tags _) {
d.readByte();
return const BeginNoEffectLoop();
}
@override
String get name => 'loop';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeLabelDefinition(0);
}
}
class BeginOneOutputLoop extends Instruction {
final ValueType type;
@override
List<ValueType> get usedValueTypes => [type];
BeginOneOutputLoop(this.type);
static BeginOneOutputLoop deserialize(Deserializer d, Tags _, Types types) {
final type = ValueType.deserialize(d, types.defined);
return BeginOneOutputLoop(type);
}
@override
void serialize(Serializer s) {
s.writeByte(0x03);
s.write(type);
}
@override
String get name => 'loop';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeLabelDefinition(0);
p.write(' ');
p.writeValueType(type);
}
}
class BeginFunctionLoop extends Instruction {
final FunctionType type;
@override
List<DefType> get usedDefTypes => [type];
BeginFunctionLoop(this.type);
static BeginFunctionLoop deserialize(Deserializer d, Tags _, Types types) {
return BeginFunctionLoop(types.defined[d.readSigned()] as FunctionType);
}
@override
void serialize(Serializer s) {
s.writeByte(0x03);
s.write(type);
}
@override
String get name => 'loop';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeLabelDefinition(0);
p.write(' ');
p.writeFunctionType(type);
}
}
class BeginNoEffectIf extends Instruction {
const BeginNoEffectIf();
@override
void serialize(Serializer s) {
s.writeByte(0x04);
s.writeByte(0x40);
}
static BeginNoEffectIf deserialize(Deserializer d, Tags _) {
d.readByte();
return const BeginNoEffectIf();
}
@override
String get name => 'if';
}
class BeginOneOutputIf extends Instruction {
final ValueType type;
@override
List<ValueType> get usedValueTypes => [type];
BeginOneOutputIf(this.type);
static BeginOneOutputIf deserialize(Deserializer d, Tags _, Types types) {
final type = ValueType.deserialize(d, types.defined);
return BeginOneOutputIf(type);
}
@override
void serialize(Serializer s) {
s.writeByte(0x04);
s.write(type);
}
@override
String get name => 'if';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' (result ');
p.writeValueType(type);
p.write(')');
}
}
class BeginFunctionIf extends Instruction {
final FunctionType type;
@override
List<DefType> get usedDefTypes => [type];
BeginFunctionIf(this.type);
static BeginFunctionIf deserialize(Deserializer d, Tags _, Types types) {
return BeginFunctionIf(types.defined[d.readSigned()] as FunctionType);
}
@override
void serialize(Serializer s) {
s.writeByte(0x04);
s.write(type);
}
@override
String get name => 'if';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeFunctionType(type);
}
}
class Else extends SingleByteInstruction {
const Else() : super(0x05);
static Else deserialize(Deserializer d) => const Else();
@override
String get name => 'else';
}
class BeginNoEffectTry extends Instruction {
const BeginNoEffectTry();
static BeginNoEffectTry deserialize(Deserializer d, Tags _) {
d.readByte();
return const BeginNoEffectTry();
}
@override
void serialize(Serializer s) {
s.writeByte(0x06);
s.writeByte(0x40);
}
@override
String get name => 'try';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeLabelDefinition(0);
}
}
class BeginOneOutputTry extends Instruction {
final ValueType type;
@override
List<ValueType> get usedValueTypes => [type];
BeginOneOutputTry(this.type);
static BeginOneOutputTry deserialize(Deserializer d, Tags _, Types types) {
final type = ValueType.deserialize(d, types.defined);
assert(type is! FunctionType);
return BeginOneOutputTry(type);
}
@override
void serialize(Serializer s) {
s.writeByte(0x06);
s.write(type);
}
@override
String get name => 'try';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeLabelDefinition(0);
p.write(' ');
p.writeValueType(type);
}
}
class BeginFunctionTry extends Instruction {
final FunctionType type;
@override
List<DefType> get usedDefTypes => [type];
BeginFunctionTry(this.type);
static BeginFunctionTry deserialize(Deserializer d, Tags _, Types types) {
return BeginFunctionTry(types.defined[d.readSigned()] as FunctionType);
}
@override
void serialize(Serializer s) {
s.writeByte(0x06);
s.write(type);
}
@override
String get name => 'try';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeLabelDefinition(0);
p.write(' ');
p.writeFunctionType(type);
}
}
class CatchLegacy extends Instruction {
final Tag tag;
CatchLegacy(this.tag);
static CatchLegacy deserialize(Deserializer d, Tags tags) {
return CatchLegacy(tags[d.readUnsigned()]);
}
@override
void serialize(Serializer s) {
s.writeByte(0x07);
s.writeUnsigned(tag.index);
}
@override
String get name => 'catch';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeTagReference(tag);
}
}
class CatchAllLegacy extends SingleByteInstruction {
const CatchAllLegacy() : super(0x19);
static CatchAllLegacy deserialize(Deserializer d) => const CatchAllLegacy();
@override
String get name => 'catch_all';
}
class Throw extends Instruction {
final Tag tag;
Throw(this.tag);
static Throw deserialize(Deserializer d, Tags tags) {
return Throw(tags[d.readUnsigned()]);
}
@override
void serialize(Serializer s) {
s.writeByte(0x08);
s.writeUnsigned(tag.index);
}
@override
String get name => 'throw';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeTagReference(tag);
}
}
class ThrowRef extends Instruction {
const ThrowRef();
static ThrowRef deserialize(Deserializer d) => const ThrowRef();
@override
void serialize(Serializer s) {
s.writeByte(0x0a);
}
@override
String get name => 'throw_ref';
}
class Rethrow extends Instruction {
final int labelIndex;
Rethrow(this.labelIndex);
static Rethrow deserialize(Deserializer d) => Rethrow(d.readUnsigned());
@override
void serialize(Serializer s) {
s.writeByte(0x09);
s.writeUnsigned(labelIndex);
}
@override
String get name => 'rethrow';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeLabelReference(labelIndex);
}
}
class End extends SingleByteInstruction {
const End() : super(0x0B);
@override
bool get isConstant => true;
static End deserialize(Deserializer d) {
return const End();
}
@override
String get name => 'end';
}
class Br extends Instruction {
final int labelIndex;
Br(this.labelIndex);
static Br deserialize(Deserializer d) => Br(d.readUnsigned());
@override
void serialize(Serializer s) {
s.writeByte(0x0C);
s.writeUnsigned(labelIndex);
}
@override
String get name => 'br';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeLabelReference(labelIndex);
}
}
class BrIf extends Instruction {
final int labelIndex;
BrIf(this.labelIndex);
static BrIf deserialize(Deserializer d) => BrIf(d.readUnsigned());
@override
void serialize(Serializer s) {
s.writeByte(0x0D);
s.writeUnsigned(labelIndex);
}
@override
String get name => 'br_if';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeLabelReference(labelIndex);
}
}
class BrTable extends Instruction {
final List<int> labelIndices;
final int defaultLabelIndex;
BrTable(this.labelIndices, this.defaultLabelIndex);
static BrTable deserialize(Deserializer d) {
return BrTable(d.readList((d) => d.readUnsigned()), d.readUnsigned());
}
@override
void serialize(Serializer s) {
s.writeByte(0x0E);
s.writeUnsigned(labelIndices.length);
for (final labelIndex in labelIndices) {
s.writeUnsigned(labelIndex);
}
s.writeUnsigned(defaultLabelIndex);
}
@override
String get name => 'br_table';
@override
void printTo(IrPrinter p) {
p.write(name);
for (final labelIndex in labelIndices) {
p.write(' ');
p.writeLabelReference(labelIndex);
}
p.write(' ');
p.writeLabelReference(defaultLabelIndex);
}
}
class Return extends SingleByteInstruction {
const Return() : super(0x0F);
static Return deserialize(Deserializer d) => const Return();
@override
String get name => 'return';
}
class Call extends Instruction {
final BaseFunction function;
Call(this.function);
static Call deserialize(Deserializer d, Functions functions) {
return Call(functions[d.readUnsigned()]);
}
@override
void serialize(Serializer s) {
s.writeByte(0x10);
s.writeUnsigned(function.index);
}
@override
String get name => 'call';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeFunctionReference(function);
}
}
class CallIndirect extends Instruction {
final FunctionType type;
final Table? table;
@override
List<DefType> get usedDefTypes => [type];
CallIndirect(this.type, this.table);
static CallIndirect deserialize(Deserializer d, Types types, Tables tables) {
final type = types.defined[d.readTypeIndex()] as FunctionType;
final table = tables[d.readUnsigned()];
return CallIndirect(type, table);
}
@override
void serialize(Serializer s) {
s.writeByte(0x11);
s.writeTypeIndex(type);
s.writeUnsigned(table?.index ?? 0);
}
@override
String get name => 'call_indirect';
@override
void printTo(IrPrinter p) {
p.write(name);
p.writeTableReference(table);
p.write(' ');
p.writeFunctionType(type);
}
}
class CallRef extends Instruction {
final FunctionType type;
@override
List<DefType> get usedDefTypes => [type];
CallRef(this.type);
static CallRef deserialize(Deserializer d, Types types) {
return CallRef(types.defined[d.readTypeIndex()] as FunctionType);
}
@override
void serialize(Serializer s) {
s.writeByte(0x14);
s.writeTypeIndex(type);
}
@override
String get name => 'call_ref';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeDefTypeReference(type);
}
}
class Drop extends SingleByteInstruction {
const Drop() : super(0x1A);
static Drop deserialize(Deserializer d) => const Drop();
@override
String get name => 'drop';
}
class Select extends Instruction {
@override
List<ValueType> get usedValueTypes => [];
const Select();
static Select deserialize(Deserializer d) {
return const Select();
}
@override
void serialize(Serializer s) {
s.writeByte(0x1B);
}
@override
String get name => 'select';
}
class SelectWithType extends Instruction {
final ValueType type;
@override
List<ValueType> get usedValueTypes => [type];
SelectWithType(this.type);
static SelectWithType deserialize(Deserializer d, Types types) {
d.readUnsigned(); // vec_len
return SelectWithType(ValueType.deserialize(d, types.defined));
}
@override
void serialize(Serializer s) {
s.writeByte(0x1C);
s.writeUnsigned(1);
s.write(type);
}
@override
String get name => 'select';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeValueType(type);
}
}
class LocalGet extends Instruction {
final Local local;
LocalGet(this.local);
static LocalGet deserialize(Deserializer d) {
return LocalGet(Local(d.readUnsigned(), NumType.i32));
}
@override
void serialize(Serializer s) {
s.writeByte(0x20);
s.writeUnsigned(local.index);
}
@override
String get name => 'local.get';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeLocalReference(local);
}
}
class LocalSet extends Instruction {
final Local local;
LocalSet(this.local);
static LocalSet deserialize(Deserializer d) {
return LocalSet(Local(d.readUnsigned(), NumType.i32));
}
@override
void serialize(Serializer s) {
s.writeByte(0x21);
s.writeUnsigned(local.index);
}
@override
String get name => 'local.set';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeLocalReference(local);
}
}
class LocalTee extends Instruction {
final Local local;
LocalTee(this.local);
static LocalTee deserialize(Deserializer d) {
return LocalTee(Local(d.readUnsigned(), NumType.i32));
}
@override
void serialize(Serializer s) {
s.writeByte(0x22);
s.writeUnsigned(local.index);
}
@override
String get name => 'local.tee';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeLocalReference(local);
}
}
class GlobalGet extends Instruction {
final Global global;
GlobalGet(this.global);
static GlobalGet deserialize(Deserializer d, Globals globals) {
return GlobalGet(globals[d.readUnsigned()]);
}
@override
bool get isConstant => true;
@override
void serialize(Serializer s) {
s.writeByte(0x23);
s.writeUnsigned(global.index);
}
@override
String get name => 'global.get';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeGlobalReference(global);
}
}
class GlobalSet extends Instruction {
final Global global;
GlobalSet(this.global);
static GlobalSet deserialize(Deserializer d, Globals globals) {
return GlobalSet(globals[d.readUnsigned()]);
}
@override
void serialize(Serializer s) {
s.writeByte(0x24);
s.writeUnsigned(global.index);
}
@override
String get name => 'global.set';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeGlobalReference(global);
}
}
class TableSet extends Instruction {
final Table table;
TableSet(this.table);
static TableSet deserialize(Deserializer d, Tables tables) {
return TableSet(tables[d.readUnsigned()]);
}
@override
void serialize(Serializer s) {
s.writeByte(0x26);
s.writeUnsigned(table.index);
}
@override
String get name => 'table.set';
@override
void printTo(IrPrinter p) {
p.write(name);
p.writeTableReference(table);
}
}
class TableGet extends Instruction {
final Table table;
TableGet(this.table);
static TableGet deserialize(Deserializer d, Tables tables) {
return TableGet(tables[d.readUnsigned()]);
}
@override
void serialize(Serializer s) {
s.writeByte(0x25);
s.writeUnsigned(table.index);
}
@override
String get name => 'table.get';
@override
void printTo(IrPrinter p) {
p.write(name);
p.writeTableReference(table);
}
}
class TableFill extends Instruction {
final Table table;
TableFill(this.table);
static TableFill deserialize(Deserializer d, Tables tables) {
return TableFill(tables[d.readUnsigned()]);
}
@override
void serialize(Serializer s) {
s.writeByte(0xFC);
s.writeByte(0x11);
s.writeUnsigned(table.index);
}
@override
String get name => 'table.fill';
@override
void printTo(IrPrinter p) {
p.write(name);
p.writeTableReference(table);
}
}
class TableSize extends Instruction {
final Table table;
TableSize(this.table);
static TableSize deserialize(Deserializer d, Tables tables) {
return TableSize(tables[d.readUnsigned()]);
}
@override
void serialize(Serializer s) {
s.writeByte(0xFC);
s.writeByte(0x10);
s.writeUnsigned(table.index);
}
@override
String get name => 'table.size';
@override
void printTo(IrPrinter p) {
p.write(name);
p.writeTableReference(table);
}
}
class MemoryOffsetAlign implements Serializable {
final Memory memory;
final int offset;
final int align;
MemoryOffsetAlign(this.memory, {required this.offset, required this.align});
@override
void serialize(Serializer s) {
if (memory.index == 0) {
s.writeByte(align);
s.writeUnsigned(offset);
} else {
s.writeByte(64 + align);
s.writeUnsigned(offset);
s.writeUnsigned(memory.index);
}
}
static MemoryOffsetAlign deserialize(Deserializer d, Memories memories) {
final alignAndMemory = d.readByte();
final align = alignAndMemory & 0x3F;
final offset = d.readUnsigned();
final memoryIndex = (alignAndMemory & 0x40) != 0 ? d.readUnsigned() : 0;
return MemoryOffsetAlign(memories[memoryIndex],
offset: offset, align: align);
}
void printTo(IrPrinter p) {
if (memory.index != 0) {
p.writeMemoryReference(memory);
}
if (offset != 0) {
p.write(' offset=$offset');
}
if (align != 0) {
p.write(' align=${1 << align}');
}
}
}
abstract class MemoryInstruction extends Instruction {
final MemoryOffsetAlign memory;
final int encoding;
MemoryInstruction(this.memory, {required this.encoding});
@override
void serialize(Serializer s) {
s.writeByte(encoding);
memory.serialize(s);
}
}
class I32Load extends MemoryInstruction {
I32Load(super.memory) : super(encoding: 0x28);
static I32Load deserialize(Deserializer d, Memories memories) {
return I32Load(MemoryOffsetAlign.deserialize(d, memories));
}
@override
String get name => 'i32.load';
@override
void printTo(IrPrinter p) {
p.write(name);
memory.printTo(p);
}
}
class I64Load extends MemoryInstruction {
I64Load(super.memory) : super(encoding: 0x29);
static I64Load deserialize(Deserializer d, Memories memories) {
return I64Load(MemoryOffsetAlign.deserialize(d, memories));
}
@override
String get name => 'i64.load';
@override
void printTo(IrPrinter p) {
p.write(name);
memory.printTo(p);
}
}
class F32Load extends MemoryInstruction {
F32Load(super.memory) : super(encoding: 0x2A);
static F32Load deserialize(Deserializer d, Memories memories) {
return F32Load(MemoryOffsetAlign.deserialize(d, memories));
}
@override
String get name => 'f32.load';
@override
void printTo(IrPrinter p) {
p.write(name);
memory.printTo(p);
}
}
class F64Load extends MemoryInstruction {
F64Load(super.memory) : super(encoding: 0x2B);
static F64Load deserialize(Deserializer d, Memories memories) {
return F64Load(MemoryOffsetAlign.deserialize(d, memories));
}
@override
String get name => 'f64.load';
@override
void printTo(IrPrinter p) {
p.write(name);
memory.printTo(p);
}
}
class I32Load8S extends MemoryInstruction {
I32Load8S(super.memory) : super(encoding: 0x2C);
static I32Load8S deserialize(Deserializer d, Memories memories) {
return I32Load8S(MemoryOffsetAlign.deserialize(d, memories));
}
@override
String get name => 'i32.load8_s';
@override
void printTo(IrPrinter p) {
p.write(name);
memory.printTo(p);
}
}
class I32Load8U extends MemoryInstruction {
I32Load8U(super.memory) : super(encoding: 0x2D);
static I32Load8U deserialize(Deserializer d, Memories memories) {
return I32Load8U(MemoryOffsetAlign.deserialize(d, memories));
}
@override
String get name => 'i32.load8_u';
@override
void printTo(IrPrinter p) {
p.write(name);
memory.printTo(p);
}
}
class I32Load16S extends MemoryInstruction {
I32Load16S(super.memory) : super(encoding: 0x2E);
static I32Load16S deserialize(Deserializer d, Memories memories) {
return I32Load16S(MemoryOffsetAlign.deserialize(d, memories));
}
@override
String get name => 'i32.load16_s';
@override
void printTo(IrPrinter p) {
p.write(name);
memory.printTo(p);
}
}
class I32Load16U extends MemoryInstruction {
I32Load16U(super.memory) : super(encoding: 0x2F);
static I32Load16U deserialize(Deserializer d, Memories memories) {
return I32Load16U(MemoryOffsetAlign.deserialize(d, memories));
}
@override
String get name => 'i32.load16_u';
@override
void printTo(IrPrinter p) {
p.write(name);
memory.printTo(p);
}
}
class I64Load8S extends MemoryInstruction {
I64Load8S(super.memory) : super(encoding: 0x30);
static I64Load8S deserialize(Deserializer d, Memories memories) {
return I64Load8S(MemoryOffsetAlign.deserialize(d, memories));
}
@override
String get name => 'i64.load8_s';
@override
void printTo(IrPrinter p) {
p.write(name);
memory.printTo(p);
}
}
class I64Load8U extends MemoryInstruction {
I64Load8U(super.memory) : super(encoding: 0x31);
static I64Load8U deserialize(Deserializer d, Memories memories) {
return I64Load8U(MemoryOffsetAlign.deserialize(d, memories));
}
@override
String get name => 'i64.load8_u';
@override
void printTo(IrPrinter p) {
p.write(name);
memory.printTo(p);
}
}
class I64Load16S extends MemoryInstruction {
I64Load16S(super.memory) : super(encoding: 0x32);
static I64Load16S deserialize(Deserializer d, Memories memories) {
return I64Load16S(MemoryOffsetAlign.deserialize(d, memories));
}
@override
String get name => 'i64.load16_s';
@override
void printTo(IrPrinter p) {
p.write(name);
memory.printTo(p);
}
}
class I64Load16U extends MemoryInstruction {
I64Load16U(super.memory) : super(encoding: 0x33);
static I64Load16U deserialize(Deserializer d, Memories memories) {
return I64Load16U(MemoryOffsetAlign.deserialize(d, memories));
}
@override
String get name => 'i64.load16_u';
@override
void printTo(IrPrinter p) {
p.write(name);
memory.printTo(p);
}
}
class I64Load32S extends MemoryInstruction {
I64Load32S(super.memory) : super(encoding: 0x34);
static I64Load32S deserialize(Deserializer d, Memories memories) {
return I64Load32S(MemoryOffsetAlign.deserialize(d, memories));
}
@override
String get name => 'i64.load32_s';
@override
void printTo(IrPrinter p) {
p.write(name);
memory.printTo(p);
}
}
class I64Load32U extends MemoryInstruction {
I64Load32U(super.memory) : super(encoding: 0x35);
static I64Load32U deserialize(Deserializer d, Memories memories) {
return I64Load32U(MemoryOffsetAlign.deserialize(d, memories));
}
@override
String get name => 'i64.load32_u';
@override
void printTo(IrPrinter p) {
p.write(name);
memory.printTo(p);
}
}
class I32Store extends MemoryInstruction {
I32Store(super.memory) : super(encoding: 0x36);
static I32Store deserialize(Deserializer d, Memories memories) {
return I32Store(MemoryOffsetAlign.deserialize(d, memories));
}
@override
String get name => 'i32.store';
@override
void printTo(IrPrinter p) {
p.write(name);
memory.printTo(p);
}
}
class I64Store extends MemoryInstruction {
I64Store(super.memory) : super(encoding: 0x37);
static I64Store deserialize(Deserializer d, Memories memories) {
return I64Store(MemoryOffsetAlign.deserialize(d, memories));
}
@override
String get name => 'i64.store';
@override
void printTo(IrPrinter p) {
p.write(name);
memory.printTo(p);
}
}
class F32Store extends MemoryInstruction {
F32Store(super.memory) : super(encoding: 0x38);
static F32Store deserialize(Deserializer d, Memories memories) {
return F32Store(MemoryOffsetAlign.deserialize(d, memories));
}
@override
String get name => 'f32.store';
@override
void printTo(IrPrinter p) {
p.write(name);
memory.printTo(p);
}
}
class F64Store extends MemoryInstruction {
F64Store(super.memory) : super(encoding: 0x39);
static F64Store deserialize(Deserializer d, Memories memories) {
return F64Store(MemoryOffsetAlign.deserialize(d, memories));
}
@override
String get name => 'f64.store';
@override
void printTo(IrPrinter p) {
p.write(name);
memory.printTo(p);
}
}
class I32Store8 extends MemoryInstruction {
I32Store8(super.memory) : super(encoding: 0x3A);
static I32Store8 deserialize(Deserializer d, Memories memories) {
return I32Store8(MemoryOffsetAlign.deserialize(d, memories));
}
@override
String get name => 'i32.store8';
@override
void printTo(IrPrinter p) {
p.write(name);
memory.printTo(p);
}
}
class I32Store16 extends MemoryInstruction {
I32Store16(super.memory) : super(encoding: 0x3B);
static I32Store16 deserialize(Deserializer d, Memories memories) {
return I32Store16(MemoryOffsetAlign.deserialize(d, memories));
}
@override
String get name => 'i32.store16';
@override
void printTo(IrPrinter p) {
p.write(name);
memory.printTo(p);
}
}
class I64Store8 extends MemoryInstruction {
I64Store8(super.memory) : super(encoding: 0x3C);
static I64Store8 deserialize(Deserializer d, Memories memories) {
return I64Store8(MemoryOffsetAlign.deserialize(d, memories));
}
@override
String get name => 'i64.store8';
@override
void printTo(IrPrinter p) {
p.write(name);
memory.printTo(p);
}
}
class I64Store16 extends MemoryInstruction {
I64Store16(super.memory) : super(encoding: 0x3D);
static I64Store16 deserialize(Deserializer d, Memories memories) {
return I64Store16(MemoryOffsetAlign.deserialize(d, memories));
}
@override
String get name => 'i64.store16';
@override
void printTo(IrPrinter p) {
p.write(name);
memory.printTo(p);
}
}
class I64Store32 extends MemoryInstruction {
I64Store32(super.memory) : super(encoding: 0x3E);
static I64Store32 deserialize(Deserializer d, Memories memories) {
return I64Store32(MemoryOffsetAlign.deserialize(d, memories));
}
@override
String get name => 'i64.store32';
@override
void printTo(IrPrinter p) {
p.write(name);
memory.printTo(p);
}
}
class MemorySize extends Instruction {
final Memory memory;
MemorySize(this.memory);
static MemorySize deserialize(Deserializer d, Memories memories) {
return MemorySize(memories[d.readUnsigned()]);
}
@override
void serialize(Serializer s) {
s.writeByte(0x3F);
s.writeUnsigned(memory.index);
}
@override
String get name => 'memory.size';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeMemoryReference(memory);
}
}
class MemoryGrow extends Instruction {
final Memory memory;
MemoryGrow(this.memory);
static MemoryGrow deserialize(Deserializer d, Memories memories) {
return MemoryGrow(memories[d.readUnsigned()]);
}
@override
void serialize(Serializer s) {
s.writeByte(0x40);
s.writeUnsigned(memory.index);
}
@override
String get name => 'memory.grow';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeMemoryReference(memory);
}
}
class MemoryFill extends Instruction {
final Memory memory;
MemoryFill(this.memory);
static MemoryFill deserialize(Deserializer d, Memories memories) {
return MemoryFill(memories[d.readUnsigned()]);
}
@override
void serialize(Serializer s) {
s.writeByte(0xFC);
s.writeUnsigned(0x0B);
s.writeUnsigned(memory.index);
}
@override
String get name => 'memory.fill';
@override
void printTo(IrPrinter p) {
p.write(name);
p.writeMemoryReference(memory);
}
}
class RefNull extends Instruction {
final HeapType heapType;
@override
List<DefType> get usedDefTypes {
final type = heapType;
return type is DefType ? [type] : const [];
}
RefNull(this.heapType);
static RefNull deserialize(Deserializer d, Types types) {
return RefNull(HeapType.deserialize(d, types.defined));
}
@override
bool get isConstant => true;
@override
void serialize(Serializer s) {
s.writeByte(0xD0);
s.write(heapType);
}
@override
String get name => 'ref.null';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeHeapTypeReference(heapType);
}
}
class RefIsNull extends SingleByteInstruction {
const RefIsNull() : super(0xD1);
static RefIsNull deserialize(Deserializer d) => const RefIsNull();
@override
String get name => 'ref.is_null';
}
class RefFunc extends Instruction {
final BaseFunction function;
RefFunc(this.function);
static RefFunc deserialize(Deserializer d, Functions functions) {
final index = d.readUnsigned();
final function = functions[index];
return RefFunc(function);
}
@override
bool get isConstant => true;
@override
void serialize(Serializer s) {
s.writeByte(0xD2);
s.writeUnsigned(function.index);
}
@override
String get name => 'ref.func';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeFunctionReference(function);
}
}
class RefAsNonNull extends SingleByteInstruction {
const RefAsNonNull() : super(0xD4);
static RefAsNonNull deserialize(Deserializer d) => const RefAsNonNull();
@override
String get name => 'ref.as_non_null';
}
class BrOnNull extends Instruction {
final int labelIndex;
BrOnNull(this.labelIndex);
static BrOnNull deserialize(Deserializer d) => BrOnNull(d.readUnsigned());
@override
void serialize(Serializer s) {
s.writeByte(0xD5);
s.writeUnsigned(labelIndex);
}
@override
String get name => 'br_on_null';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeLabelReference(labelIndex);
}
}
class RefEq extends SingleByteInstruction {
const RefEq() : super(0xD3);
static RefEq deserialize(Deserializer d) => const RefEq();
@override
String get name => 'ref.eq';
}
class BrOnNonNull extends Instruction {
final int labelIndex;
BrOnNonNull(this.labelIndex);
static BrOnNonNull deserialize(Deserializer d) =>
BrOnNonNull(d.readUnsigned());
@override
void serialize(Serializer s) {
s.writeByte(0xD6);
s.writeUnsigned(labelIndex);
}
@override
String get name => 'br_on_non_null';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeLabelReference(labelIndex);
}
}
class StructGet extends Instruction {
final StructType structType;
final int fieldIndex;
@override
List<DefType> get usedDefTypes => [structType];
StructGet(this.structType, this.fieldIndex);
static StructGet deserialize(Deserializer d, Types types) {
return StructGet(
types.defined[d.readTypeIndex()] as StructType, d.readUnsigned());
}
@override
void serialize(Serializer s) {
s.writeByte(0xFB);
s.writeByte(0x02);
s.writeTypeIndex(structType);
s.writeUnsigned(fieldIndex);
}
@override
String get name => 'struct.get';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeFieldReference(structType, fieldIndex);
}
}
class StructGetS extends Instruction {
final StructType structType;
final int fieldIndex;
@override
List<DefType> get usedDefTypes => [structType];
StructGetS(this.structType, this.fieldIndex);
static StructGetS deserialize(Deserializer d, Types types) {
return StructGetS(
types.defined[d.readTypeIndex()] as StructType, d.readUnsigned());
}
@override
void serialize(Serializer s) {
s.writeByte(0xFB);
s.writeByte(0x03);
s.writeTypeIndex(structType);
s.writeUnsigned(fieldIndex);
}
@override
String get name => 'struct.get_s';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeFieldReference(structType, fieldIndex);
}
}
class StructGetU extends Instruction {
final StructType structType;
final int fieldIndex;
@override
List<DefType> get usedDefTypes => [structType];
StructGetU(this.structType, this.fieldIndex);
static StructGetU deserialize(Deserializer d, Types types) {
return StructGetU(
types.defined[d.readTypeIndex()] as StructType, d.readUnsigned());
}
@override
void serialize(Serializer s) {
s.writeByte(0xFB);
s.writeByte(0x04);
s.writeTypeIndex(structType);
s.writeUnsigned(fieldIndex);
}
@override
String get name => 'struct.get_u';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeFieldReference(structType, fieldIndex);
}
}
class StructSet extends Instruction {
final StructType structType;
final int fieldIndex;
@override
List<DefType> get usedDefTypes => [structType];
StructSet(this.structType, this.fieldIndex);
static StructSet deserialize(Deserializer d, Types types) {
return StructSet(
types.defined[d.readTypeIndex()] as StructType, d.readUnsigned());
}
@override
void serialize(Serializer s) {
s.writeByte(0xFB);
s.writeByte(0x05);
s.writeTypeIndex(structType);
s.writeUnsigned(fieldIndex);
}
@override
String get name => 'struct.set';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeFieldReference(structType, fieldIndex);
}
}
class StructNew extends Instruction {
final StructType structType;
@override
List<DefType> get usedDefTypes => [structType];
StructNew(this.structType);
static StructNew deserialize(Deserializer d, Types types) {
return StructNew(types.defined[d.readTypeIndex()] as StructType);
}
@override
bool get isConstant => true;
@override
void serialize(Serializer s) {
s.writeByte(0xFB);
s.writeByte(0x00);
s.writeTypeIndex(structType);
}
@override
String get name => 'struct.new';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeDefTypeReference(structType);
}
}
class StructNewDefault extends Instruction {
final StructType structType;
@override
List<DefType> get usedDefTypes => [structType];
StructNewDefault(this.structType);
static StructNewDefault deserialize(Deserializer d, Types types) {
return StructNewDefault(types.defined[d.readTypeIndex()] as StructType);
}
@override
bool get isConstant => true;
@override
void serialize(Serializer s) {
s.writeByte(0xFB);
s.writeByte(0x01);
s.writeTypeIndex(structType);
}
@override
String get name => 'struct.new_default';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeDefTypeReference(structType);
}
}
class ArrayGet extends Instruction {
final ArrayType arrayType;
@override
List<DefType> get usedDefTypes => [arrayType];
ArrayGet(this.arrayType);
static ArrayGet deserialize(Deserializer d, Types types) {
return ArrayGet(types.defined[d.readTypeIndex()] as ArrayType);
}
@override
void serialize(Serializer s) {
s.writeByte(0xFB);
s.writeByte(0x0b);
s.writeTypeIndex(arrayType);
}
@override
String get name => 'array.get';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeDefTypeReference(arrayType);
}
}
class ArrayGetS extends Instruction {
final ArrayType arrayType;
@override
List<DefType> get usedDefTypes => [arrayType];
ArrayGetS(this.arrayType);
static ArrayGetS deserialize(Deserializer d, Types types) {
return ArrayGetS(types.defined[d.readTypeIndex()] as ArrayType);
}
@override
void serialize(Serializer s) {
s.writeByte(0xFB);
s.writeByte(0x0c);
s.writeTypeIndex(arrayType);
}
@override
String get name => 'array.get_s';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeDefTypeReference(arrayType);
}
}
class ArrayGetU extends Instruction {
final ArrayType arrayType;
@override
List<DefType> get usedDefTypes => [arrayType];
ArrayGetU(this.arrayType);
static ArrayGetU deserialize(Deserializer d, Types types) {
return ArrayGetU(types.defined[d.readTypeIndex()] as ArrayType);
}
@override
void serialize(Serializer s) {
s.writeByte(0xFB);
s.writeByte(0x0d);
s.writeTypeIndex(arrayType);
}
@override
String get name => 'array.get_u';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeDefTypeReference(arrayType);
}
}
class ArraySet extends Instruction {
final ArrayType arrayType;
@override
List<DefType> get usedDefTypes => [arrayType];
ArraySet(this.arrayType);
static ArraySet deserialize(Deserializer d, Types types) {
return ArraySet(types.defined[d.readTypeIndex()] as ArrayType);
}
@override
void serialize(Serializer s) {
s.writeByte(0xFB);
s.writeByte(0x0E);
s.writeTypeIndex(arrayType);
}
@override
String get name => 'array.set';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeDefTypeReference(arrayType);
}
}
class ArrayLen extends Instruction {
const ArrayLen();
static ArrayLen deserialize(Deserializer d) => const ArrayLen();
@override
void serialize(Serializer s) {
s.writeByte(0xFB);
s.writeByte(0x0F);
}
@override
String get name => 'array.len';
}
class ArrayNewFixed extends Instruction {
final ArrayType arrayType;
final int length;
@override
List<DefType> get usedDefTypes => [arrayType];
ArrayNewFixed(this.arrayType, this.length);
static ArrayNewFixed deserialize(Deserializer d, Types types) {
return ArrayNewFixed(
types.defined[d.readTypeIndex()] as ArrayType, d.readUnsigned());
}
@override
bool get isConstant => true;
@override
void serialize(Serializer s) {
s.writeByte(0xFB);
s.writeByte(0x08);
s.writeTypeIndex(arrayType);
s.writeUnsigned(length);
}
@override
String get name => 'array.new_fixed';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeDefTypeReference(arrayType);
p.write(' $length');
}
}
class ArrayNew extends Instruction {
final ArrayType arrayType;
@override
List<DefType> get usedDefTypes => [arrayType];
ArrayNew(this.arrayType);
static ArrayNew deserialize(Deserializer d, Types types) {
return ArrayNew(types.defined[d.readTypeIndex()] as ArrayType);
}
@override
bool get isConstant => true;
@override
void serialize(Serializer s) {
s.writeByte(0xFB);
s.writeByte(0x06);
s.writeTypeIndex(arrayType);
}
@override
String get name => 'array.new';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeDefTypeReference(arrayType);
}
}
class ArrayNewDefault extends Instruction {
final ArrayType arrayType;
@override
List<DefType> get usedDefTypes => [arrayType];
ArrayNewDefault(this.arrayType);
static ArrayNewDefault deserialize(Deserializer d, Types types) {
return ArrayNewDefault(types.defined[d.readTypeIndex()] as ArrayType);
}
@override
bool get isConstant => true;
@override
void serialize(Serializer s) {
s.writeByte(0xFB);
s.writeByte(0x07);
s.writeTypeIndex(arrayType);
}
@override
String get name => 'array.new_default';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeDefTypeReference(arrayType);
}
}
class ArrayNewData extends Instruction {
final ArrayType arrayType;
final BaseDataSegment data;
@override
List<DefType> get usedDefTypes => [arrayType];
ArrayNewData(this.arrayType, this.data);
static ArrayNewData deserialize(
Deserializer d, Types types, DataSegments dataSegments) {
return ArrayNewData(types.defined[d.readTypeIndex()] as ArrayType,
dataSegments.defined[d.readUnsigned()]);
}
@override
void serialize(Serializer s) {
s.writeByte(0xFB);
s.writeByte(0x09);
s.writeTypeIndex(arrayType);
s.writeUnsigned(data.index);
}
@override
String get name => 'array.new_data';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeDefTypeReference(arrayType);
p.writeDataReference(data);
}
}
class ArrayCopy extends Instruction {
final ArrayType destArrayType;
final ArrayType sourceArrayType;
@override
List<DefType> get usedDefTypes => [destArrayType, sourceArrayType];
ArrayCopy({required this.destArrayType, required this.sourceArrayType});
static ArrayCopy deserialize(Deserializer d, Types types) {
return ArrayCopy(
destArrayType: types.defined[d.readTypeIndex()] as ArrayType,
sourceArrayType: types.defined[d.readTypeIndex()] as ArrayType);
}
@override
void serialize(Serializer s) {
s.writeByte(0xFB);
s.writeByte(0x11);
s.writeTypeIndex(destArrayType);
s.writeTypeIndex(sourceArrayType);
}
@override
String get name => 'array.copy';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeDefTypeReference(destArrayType);
p.write(' ');
p.writeDefTypeReference(sourceArrayType);
}
}
class ArrayFill extends Instruction {
final ArrayType arrayType;
@override
List<DefType> get usedDefTypes => [arrayType];
ArrayFill(this.arrayType);
static ArrayFill deserialize(Deserializer d, Types types) {
return ArrayFill(types.defined[d.readTypeIndex()] as ArrayType);
}
@override
void serialize(Serializer s) {
s.writeByte(0xFB);
s.writeByte(0x10);
s.writeTypeIndex(arrayType);
}
@override
String get name => 'array.fill';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeDefTypeReference(arrayType);
}
}
class I31New extends Instruction {
const I31New();
static I31New deserialize(Deserializer d) => const I31New();
@override
void serialize(Serializer s) {
s.writeByte(0xFB);
s.writeByte(0x1C);
}
@override
String get name => 'i31.new';
}
class I31GetS extends Instruction {
const I31GetS();
static I31GetS deserialize(Deserializer d) => const I31GetS();
@override
void serialize(Serializer s) {
s.writeByte(0xFB);
s.writeByte(0x1D);
}
@override
String get name => 'i31.get_s';
}
class I31GetU extends Instruction {
const I31GetU();
static I31GetU deserialize(Deserializer d) => const I31GetU();
@override
void serialize(Serializer s) {
s.writeByte(0xFB);
s.writeByte(0x1E);
}
@override
String get name => 'i31.get_u';
}
class RefTest extends Instruction {
final RefType targetType;
RefTest(this.targetType);
static RefTest deserialize(Deserializer d, Types types, bool nullable) {
return RefTest(
RefType(HeapType.deserialize(d, types.defined), nullable: nullable));
}
@override
void serialize(Serializer s) {
s.writeByte(0xFB);
s.writeByte(targetType.nullable ? 0x15 : 0x14);
s.write(targetType.heapType);
}
@override
String get name => 'ref.test';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeRefTypeReference(targetType);
}
}
class RefCast extends Instruction {
final RefType targetType;
@override
List<ValueType> get usedValueTypes => [targetType];
RefCast(this.targetType);
static RefCast deserialize(Deserializer d, Types types, bool nullable) {
return RefCast(
RefType(HeapType.deserialize(d, types.defined), nullable: nullable));
}
@override
void serialize(Serializer s) {
s.writeByte(0xFB);
s.writeByte(targetType.nullable ? 0x17 : 0x16);
s.write(targetType.heapType);
}
@override
String get name => 'ref.cast';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeRefTypeReference(targetType);
}
}
class BrOnCast extends Instruction {
final int labelIndex;
final RefType inputType;
final RefType targetType;
@override
List<ValueType> get usedValueTypes => [inputType, targetType];
BrOnCast(this.labelIndex, this.inputType, this.targetType);
static BrOnCast deserialize(Deserializer d, Types types) {
final flags = d.readByte();
final labelIndex = d.readUnsigned();
final inputHeapType = HeapType.deserialize(d, types.defined);
final targetHeapType = HeapType.deserialize(d, types.defined);
final inputType = RefType(inputHeapType, nullable: (flags & 0x01) != 0);
final targetType = RefType(targetHeapType, nullable: (flags & 0x01) != 0);
return BrOnCast(labelIndex, inputType, targetType);
}
@override
void serialize(Serializer s) {
int flags = (inputType.nullable ? 0x01 : 0x00) |
(targetType.nullable ? 0x02 : 0x00);
s.writeByte(0xFB);
s.writeByte(0x18);
s.writeByte(flags);
s.writeUnsigned(labelIndex);
s.write(inputType.heapType);
s.write(targetType.heapType);
}
@override
String get name => 'br_on_cast';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeLabelReference(labelIndex);
p.write(' ');
p.writeValueType(inputType);
p.write(' ');
p.writeValueType(targetType);
}
}
class BrOnCastFail extends Instruction {
final int labelIndex;
final RefType inputType;
final RefType targetType;
@override
List<ValueType> get usedValueTypes => [inputType, targetType];
BrOnCastFail(this.labelIndex, this.inputType, this.targetType);
static BrOnCastFail deserialize(Deserializer d, Types types) {
final flags = d.readByte();
final labelIndex = d.readUnsigned();
final inputHeapType = HeapType.deserialize(d, types.defined);
final targetHeapType = HeapType.deserialize(d, types.defined);
final inputType = RefType(inputHeapType, nullable: (flags & 0x01) != 0);
final targetType = RefType(targetHeapType, nullable: (flags & 0x01) != 0);
return BrOnCastFail(labelIndex, inputType, targetType);
}
@override
void serialize(Serializer s) {
int flags = (inputType.nullable ? 0x01 : 0x00) |
(targetType.nullable ? 0x02 : 0x00);
s.writeByte(0xFB);
s.writeByte(0x19);
s.writeByte(flags);
s.writeUnsigned(labelIndex);
s.write(inputType.heapType);
s.write(targetType.heapType);
}
@override
String get name => 'br_on_cast_fail';
@override
void printTo(IrPrinter p) {
p.write(name);
p.write(' ');
p.writeLabelReference(labelIndex);
p.write(' ');
p.writeValueType(inputType);
p.write(' ');
p.writeValueType(targetType);
}
}
class ExternInternalize extends Instruction {
const ExternInternalize();
static ExternInternalize deserialize(Deserializer d) {
return const ExternInternalize();
}
@override
void serialize(Serializer s) {
s.writeByte(0xFB);
s.writeByte(0x1A);
}
@override
bool get isConstant => true;
@override
String get name => 'any.convert_extern';
}
class ExternExternalize extends Instruction {
const ExternExternalize();
static ExternExternalize deserialize(Deserializer d) {
return const ExternExternalize();
}
@override
void serialize(Serializer s) {
s.writeByte(0xFB);
s.writeByte(0x1B);
}
@override
bool get isConstant => true;
@override
String get name => 'extern.externalize';
}
class I32Const extends Instruction {
final int value;
I32Const(this.value);
static I32Const deserialize(Deserializer d) {
return I32Const(d.readSigned());
}
@override
bool get isConstant => true;
@override
void serialize(Serializer s) {
s.writeByte(0x41);
s.writeSigned(value);
}
@override
String get name => 'i32.const $value';
}
class I64Const extends Instruction {
final int value;
I64Const(this.value);
static I64Const deserialize(Deserializer d) {
return I64Const(d.readSigned());
}
@override
bool get isConstant => true;
@override
void serialize(Serializer s) {
s.writeByte(0x42);
s.writeSigned(value);
}
@override
String get name => 'i64.const $value';
}
class F32Const extends Instruction {
final double value;
F32Const(this.value);
static F32Const deserialize(Deserializer d) {
return F32Const(d.readF32());
}
@override
bool get isConstant => true;
@override
void serialize(Serializer s) {
s.writeByte(0x43);
s.writeF32(value);
}
@override
String get name => 'f32.const $value';
}
class F64Const extends Instruction {
final double value;
F64Const(this.value);
static F64Const deserialize(Deserializer d) {
return F64Const(d.readF64());
}
@override
bool get isConstant => true;
@override
void serialize(Serializer s) {
s.writeByte(0x44);
s.writeF64(value);
}
@override
String get name => 'f64.const $value';
}
class I32Eqz extends SingleByteInstruction {
const I32Eqz() : super(0x45);
static I32Eqz deserialize(Deserializer d) => const I32Eqz();
@override
String get name => 'i32.eqz';
}
class I32Eq extends SingleByteInstruction {
const I32Eq() : super(0x46);
static I32Eq deserialize(Deserializer d) => const I32Eq();
@override
String get name => 'i32.eq';
}
class I32Ne extends SingleByteInstruction {
const I32Ne() : super(0x47);
static I32Ne deserialize(Deserializer d) => const I32Ne();
@override
String get name => 'i32.ne';
}
class I32LtS extends SingleByteInstruction {
const I32LtS() : super(0x48);
static I32LtS deserialize(Deserializer d) => const I32LtS();
@override
String get name => 'i32.lt_s';
}
class I32LtU extends SingleByteInstruction {
const I32LtU() : super(0x49);
static I32LtU deserialize(Deserializer d) => const I32LtU();
@override
String get name => 'i32.lt_u';
}
class I32GtS extends SingleByteInstruction {
const I32GtS() : super(0x4A);
static I32GtS deserialize(Deserializer d) => const I32GtS();
@override
String get name => 'i32.gt_s';
}
class I32GtU extends SingleByteInstruction {
const I32GtU() : super(0x4B);
static I32GtU deserialize(Deserializer d) => const I32GtU();
@override
String get name => 'i32.gt_u';
}
class I32LeS extends SingleByteInstruction {
const I32LeS() : super(0x4C);
static I32LeS deserialize(Deserializer d) => const I32LeS();
@override
String get name => 'i32.le_s';
}
class I32LeU extends SingleByteInstruction {
const I32LeU() : super(0x4D);
static I32LeU deserialize(Deserializer d) => const I32LeU();
@override
String get name => 'i32.le_u';
}
class I32GeS extends SingleByteInstruction {
const I32GeS() : super(0x4E);
static I32GeS deserialize(Deserializer d) => const I32GeS();
@override
String get name => 'i32.ge_s';
}
class I32GeU extends SingleByteInstruction {
const I32GeU() : super(0x4F);
static I32GeU deserialize(Deserializer d) => const I32GeU();
@override
String get name => 'i32.ge_u';
}
class I64Eqz extends SingleByteInstruction {
const I64Eqz() : super(0x50);
static I64Eqz deserialize(Deserializer d) => const I64Eqz();
@override
String get name => 'i64.eqz';
}
class I64Eq extends SingleByteInstruction {
const I64Eq() : super(0x51);
static I64Eq deserialize(Deserializer d) => const I64Eq();
@override
String get name => 'i64.eq';
}
class I64Ne extends SingleByteInstruction {
const I64Ne() : super(0x52);
static I64Ne deserialize(Deserializer d) => const I64Ne();
@override
String get name => 'i64.ne';
}
class I64LtS extends SingleByteInstruction {
const I64LtS() : super(0x53);
static I64LtS deserialize(Deserializer d) => const I64LtS();
@override
String get name => 'i64.lt_s';
}
class I64LtU extends SingleByteInstruction {
const I64LtU() : super(0x54);
static I64LtU deserialize(Deserializer d) => const I64LtU();
@override
String get name => 'i64.lt_u';
}
class I64GtS extends SingleByteInstruction {
const I64GtS() : super(0x55);
static I64GtS deserialize(Deserializer d) => const I64GtS();
@override
String get name => 'i64.gt_s';
}
class I64GtU extends SingleByteInstruction {
const I64GtU() : super(0x56);
static I64GtU deserialize(Deserializer d) => const I64GtU();
@override
String get name => 'i64.gt_u';
}
class I64LeS extends SingleByteInstruction {
const I64LeS() : super(0x57);
static I64LeS deserialize(Deserializer d) => const I64LeS();
@override
String get name => 'i64.le_s';
}
class I64LeU extends SingleByteInstruction {
const I64LeU() : super(0x58);
static I64LeU deserialize(Deserializer d) => const I64LeU();
@override
String get name => 'i64.le_u';
}
class I64GeS extends SingleByteInstruction {
const I64GeS() : super(0x59);
static I64GeS deserialize(Deserializer d) => const I64GeS();
@override
String get name => 'i64.ge_s';
}
class I64GeU extends SingleByteInstruction {
const I64GeU() : super(0x5A);
static I64GeU deserialize(Deserializer d) => const I64GeU();
@override
String get name => 'i64.ge_u';
}
class F32Eq extends SingleByteInstruction {
const F32Eq() : super(0x5B);
static F32Eq deserialize(Deserializer d) => const F32Eq();
@override
String get name => 'f32.eq';
}
class F32Ne extends SingleByteInstruction {
const F32Ne() : super(0x5C);
static F32Ne deserialize(Deserializer d) => const F32Ne();
@override
String get name => 'f32.ne';
}
class F32Lt extends SingleByteInstruction {
const F32Lt() : super(0x5D);
static F32Lt deserialize(Deserializer d) => const F32Lt();
@override
String get name => 'f32.lt';
}
class F32Gt extends SingleByteInstruction {
const F32Gt() : super(0x5E);
static F32Gt deserialize(Deserializer d) => const F32Gt();
@override
String get name => 'f32.gt';
}
class F32Le extends SingleByteInstruction {
const F32Le() : super(0x5F);
static F32Le deserialize(Deserializer d) => const F32Le();
@override
String get name => 'f32.le';
}
class F32Ge extends SingleByteInstruction {
const F32Ge() : super(0x60);
static F32Ge deserialize(Deserializer d) => const F32Ge();
@override
String get name => 'f32.ge';
}
class F64Eq extends SingleByteInstruction {
const F64Eq() : super(0x61);
static F64Eq deserialize(Deserializer d) => const F64Eq();
@override
String get name => 'f64.eq';
}
class F64Ne extends SingleByteInstruction {
const F64Ne() : super(0x62);
static F64Ne deserialize(Deserializer d) => const F64Ne();
@override
String get name => 'f64.ne';
}
class F64Lt extends SingleByteInstruction {
const F64Lt() : super(0x63);
static F64Lt deserialize(Deserializer d) => const F64Lt();
@override
String get name => 'f64.lt';
}
class F64Gt extends SingleByteInstruction {
const F64Gt() : super(0x64);
static F64Gt deserialize(Deserializer d) => const F64Gt();
@override
String get name => 'f64.gt';
}
class F64Le extends SingleByteInstruction {
const F64Le() : super(0x65);
static F64Le deserialize(Deserializer d) => const F64Le();
@override
String get name => 'f64.le';
}
class F64Ge extends SingleByteInstruction {
const F64Ge() : super(0x66);
static F64Ge deserialize(Deserializer d) => const F64Ge();
@override
String get name => 'f64.ge';
}
class I32Clz extends SingleByteInstruction {
const I32Clz() : super(0x67);
static I32Clz deserialize(Deserializer d) => const I32Clz();
@override
String get name => 'i32.clz';
}
class I32Ctz extends SingleByteInstruction {
const I32Ctz() : super(0x68);
static I32Ctz deserialize(Deserializer d) => const I32Ctz();
@override
String get name => 'i32.ctz';
}
class I32Popcnt extends SingleByteInstruction {
const I32Popcnt() : super(0x69);
static I32Popcnt deserialize(Deserializer d) => const I32Popcnt();
@override
String get name => 'i32.popcnt';
}
class I32Add extends SingleByteInstruction {
const I32Add() : super(0x6A);
static I32Add deserialize(Deserializer d) => const I32Add();
@override
String get name => 'i32.add';
}
class I32Sub extends SingleByteInstruction {
const I32Sub() : super(0x6B);
static I32Sub deserialize(Deserializer d) => const I32Sub();
@override
String get name => 'i32.sub';
}
class I32Mul extends SingleByteInstruction {
const I32Mul() : super(0x6C);
static I32Mul deserialize(Deserializer d) => const I32Mul();
@override
String get name => 'i32.mul';
}
class I32DivS extends SingleByteInstruction {
const I32DivS() : super(0x6D);
static I32DivS deserialize(Deserializer d) => const I32DivS();
@override
String get name => 'i32.div_s';
}
class I32DivU extends SingleByteInstruction {
const I32DivU() : super(0x6E);
static I32DivU deserialize(Deserializer d) => const I32DivU();
@override
String get name => 'i32.div_u';
}
class I32RemS extends SingleByteInstruction {
const I32RemS() : super(0x6F);
static I32RemS deserialize(Deserializer d) => const I32RemS();
@override
String get name => 'i32.rem_s';
}
class I32RemU extends SingleByteInstruction {
const I32RemU() : super(0x70);
static I32RemU deserialize(Deserializer d) => const I32RemU();
@override
String get name => 'i32.rem_u';
}
class I32And extends SingleByteInstruction {
const I32And() : super(0x71);
static I32And deserialize(Deserializer d) => const I32And();
@override
String get name => 'i32.and';
}
class I32Or extends SingleByteInstruction {
const I32Or() : super(0x72);
static I32Or deserialize(Deserializer d) => const I32Or();
@override
String get name => 'i32.or';
}
class I32Xor extends SingleByteInstruction {
const I32Xor() : super(0x73);
static I32Xor deserialize(Deserializer d) => const I32Xor();
@override
String get name => 'i32.xor';
}
class I32Shl extends SingleByteInstruction {
const I32Shl() : super(0x74);
static I32Shl deserialize(Deserializer d) => const I32Shl();
@override
String get name => 'i32.shl';
}
class I32ShrS extends SingleByteInstruction {
const I32ShrS() : super(0x75);
static I32ShrS deserialize(Deserializer d) => const I32ShrS();
@override
String get name => 'i32.shr_s';
}
class I32ShrU extends SingleByteInstruction {
const I32ShrU() : super(0x76);
static I32ShrU deserialize(Deserializer d) => const I32ShrU();
@override
String get name => 'i32.shr_u';
}
class I32Rotl extends SingleByteInstruction {
const I32Rotl() : super(0x77);
static I32Rotl deserialize(Deserializer d) => const I32Rotl();
@override
String get name => 'i32.rotl';
}
class I32Rotr extends SingleByteInstruction {
const I32Rotr() : super(0x78);
static I32Rotr deserialize(Deserializer d) => const I32Rotr();
@override
String get name => 'i32.rotr';
}
class I64Clz extends SingleByteInstruction {
const I64Clz() : super(0x79);
static I64Clz deserialize(Deserializer d) => const I64Clz();
@override
String get name => 'i64.clz';
}
class I64Ctz extends SingleByteInstruction {
const I64Ctz() : super(0x7A);
static I64Ctz deserialize(Deserializer d) => const I64Ctz();
@override
String get name => 'i64.ctz';
}
class I64Popcnt extends SingleByteInstruction {
const I64Popcnt() : super(0x7B);
static I64Popcnt deserialize(Deserializer d) => const I64Popcnt();
@override
String get name => 'i64.popcnt';
}
class I64Add extends SingleByteInstruction {
const I64Add() : super(0x7C);
static I64Add deserialize(Deserializer d) => const I64Add();
@override
String get name => 'i64.add';
}
class I64Sub extends SingleByteInstruction {
const I64Sub() : super(0x7D);
static I64Sub deserialize(Deserializer d) => const I64Sub();
@override
String get name => 'i64.sub';
}
class I64Mul extends SingleByteInstruction {
const I64Mul() : super(0x7E);
static I64Mul deserialize(Deserializer d) => const I64Mul();
@override
String get name => 'i64.mul';
}
class I64DivS extends SingleByteInstruction {
const I64DivS() : super(0x7F);
static I64DivS deserialize(Deserializer d) => const I64DivS();
@override
String get name => 'i64.div_s';
}
class I64DivU extends SingleByteInstruction {
const I64DivU() : super(0x80);
static I64DivU deserialize(Deserializer d) => const I64DivU();
@override
String get name => 'i64.div_u';
}
class I64RemS extends SingleByteInstruction {
const I64RemS() : super(0x81);
static I64RemS deserialize(Deserializer d) => const I64RemS();
@override
String get name => 'i64.rem_s';
}
class I64RemU extends SingleByteInstruction {
const I64RemU() : super(0x82);
static I64RemU deserialize(Deserializer d) => const I64RemU();
@override
String get name => 'i64.rem_u';
}
class I64And extends SingleByteInstruction {
const I64And() : super(0x83);
static I64And deserialize(Deserializer d) => const I64And();
@override
String get name => 'i64.and';
}
class I64Or extends SingleByteInstruction {
const I64Or() : super(0x84);
static I64Or deserialize(Deserializer d) => const I64Or();
@override
String get name => 'i64.or';
}
class I64Xor extends SingleByteInstruction {
const I64Xor() : super(0x85);
static I64Xor deserialize(Deserializer d) => const I64Xor();
@override
String get name => 'i64.xor';
}
class I64Shl extends SingleByteInstruction {
const I64Shl() : super(0x86);
static I64Shl deserialize(Deserializer d) => const I64Shl();
@override
String get name => 'i64.shl';
}
class I64ShrS extends SingleByteInstruction {
const I64ShrS() : super(0x87);
static I64ShrS deserialize(Deserializer d) => const I64ShrS();
@override
String get name => 'i64.shr_s';
}
class I64ShrU extends SingleByteInstruction {
const I64ShrU() : super(0x88);
static I64ShrU deserialize(Deserializer d) => const I64ShrU();
@override
String get name => 'i64.shr_u';
}
class I64Rotl extends SingleByteInstruction {
const I64Rotl() : super(0x89);
static I64Rotl deserialize(Deserializer d) => const I64Rotl();
@override
String get name => 'i64.rotl';
}
class I64Rotr extends SingleByteInstruction {
const I64Rotr() : super(0x8A);
static I64Rotr deserialize(Deserializer d) => const I64Rotr();
@override
String get name => 'i64.rotr';
}
class F32Abs extends SingleByteInstruction {
const F32Abs() : super(0x8B);
static F32Abs deserialize(Deserializer d) => const F32Abs();
@override
String get name => 'f32.abs';
}
class F32Neg extends SingleByteInstruction {
const F32Neg() : super(0x8C);
static F32Neg deserialize(Deserializer d) => const F32Neg();
@override
String get name => 'f32.neg';
}
class F32Ceil extends SingleByteInstruction {
const F32Ceil() : super(0x8D);
static F32Ceil deserialize(Deserializer d) => const F32Ceil();
@override
String get name => 'f32.ceil';
}
class F32Floor extends SingleByteInstruction {
const F32Floor() : super(0x8E);
static F32Floor deserialize(Deserializer d) => const F32Floor();
@override
String get name => 'f32.floor';
}
class F32Trunc extends SingleByteInstruction {
const F32Trunc() : super(0x8F);
static F32Trunc deserialize(Deserializer d) => const F32Trunc();
@override
String get name => 'f32.trunc';
}
class F32Nearest extends SingleByteInstruction {
const F32Nearest() : super(0x90);
static F32Nearest deserialize(Deserializer d) => const F32Nearest();
@override
String get name => 'f32.nearest';
}
class F32Sqrt extends SingleByteInstruction {
const F32Sqrt() : super(0x91);
static F32Sqrt deserialize(Deserializer d) => const F32Sqrt();
@override
String get name => 'f32.sqrt';
}
class F32Add extends SingleByteInstruction {
const F32Add() : super(0x92);
static F32Add deserialize(Deserializer d) => const F32Add();
@override
String get name => 'f32.add';
}
class F32Sub extends SingleByteInstruction {
const F32Sub() : super(0x93);
static F32Sub deserialize(Deserializer d) => const F32Sub();
@override
String get name => 'f32.sub';
}
class F32Mul extends SingleByteInstruction {
const F32Mul() : super(0x94);
static F32Mul deserialize(Deserializer d) => const F32Mul();
@override
String get name => 'f32.mul';
}
class F32Div extends SingleByteInstruction {
const F32Div() : super(0x95);
static F32Div deserialize(Deserializer d) => const F32Div();
@override
String get name => 'f32.div';
}
class F32Min extends SingleByteInstruction {
const F32Min() : super(0x96);
static F32Min deserialize(Deserializer d) => const F32Min();
@override
String get name => 'f32.min';
}
class F32Max extends SingleByteInstruction {
const F32Max() : super(0x97);
static F32Max deserialize(Deserializer d) => const F32Max();
@override
String get name => 'f32.max';
}
class F32Copysign extends SingleByteInstruction {
const F32Copysign() : super(0x98);
static F32Copysign deserialize(Deserializer d) => const F32Copysign();
@override
String get name => 'f32.copysign';
}
class F64Abs extends SingleByteInstruction {
const F64Abs() : super(0x99);
static F64Abs deserialize(Deserializer d) => const F64Abs();
@override
String get name => 'f64.abs';
}
class F64Neg extends SingleByteInstruction {
const F64Neg() : super(0x9A);
static F64Neg deserialize(Deserializer d) => const F64Neg();
@override
String get name => 'f64.neg';
}
class F64Ceil extends SingleByteInstruction {
const F64Ceil() : super(0x9B);
static F64Ceil deserialize(Deserializer d) => const F64Ceil();
@override
String get name => 'f64.ceil';
}
class F64Floor extends SingleByteInstruction {
const F64Floor() : super(0x9C);
static F64Floor deserialize(Deserializer d) => const F64Floor();
@override
String get name => 'f64.floor';
}
class F64Trunc extends SingleByteInstruction {
const F64Trunc() : super(0x9D);
static F64Trunc deserialize(Deserializer d) => const F64Trunc();
@override
String get name => 'f64.trunc';
}
class F64Nearest extends SingleByteInstruction {
const F64Nearest() : super(0x9E);
static F64Nearest deserialize(Deserializer d) => const F64Nearest();
@override
String get name => 'f64.nearest';
}
class F64Sqrt extends SingleByteInstruction {
const F64Sqrt() : super(0x9F);
static F64Sqrt deserialize(Deserializer d) => const F64Sqrt();
@override
String get name => 'f64.sqrt';
}
class F64Add extends SingleByteInstruction {
const F64Add() : super(0xA0);
static F64Add deserialize(Deserializer d) => const F64Add();
@override
String get name => 'f64.add';
}
class F64Sub extends SingleByteInstruction {
const F64Sub() : super(0xA1);
static F64Sub deserialize(Deserializer d) => const F64Sub();
@override
String get name => 'f64.sub';
}
class F64Mul extends SingleByteInstruction {
const F64Mul() : super(0xA2);
static F64Mul deserialize(Deserializer d) => const F64Mul();
@override
String get name => 'f64.mul';
}
class F64Div extends SingleByteInstruction {
const F64Div() : super(0xA3);
static F64Div deserialize(Deserializer d) => const F64Div();
@override
String get name => 'f64.div';
}
class F64Min extends SingleByteInstruction {
const F64Min() : super(0xA4);
static F64Min deserialize(Deserializer d) => const F64Min();
@override
String get name => 'f64.min';
}
class F64Max extends SingleByteInstruction {
const F64Max() : super(0xA5);
static F64Max deserialize(Deserializer d) => const F64Max();
@override
String get name => 'f64.max';
}
class F64Copysign extends SingleByteInstruction {
const F64Copysign() : super(0xA6);
static F64Copysign deserialize(Deserializer d) => const F64Copysign();
@override
String get name => 'f64.copysign';
}
class I32WrapI64 extends SingleByteInstruction {
const I32WrapI64() : super(0xA7);
static I32WrapI64 deserialize(Deserializer d) => const I32WrapI64();
@override
String get name => 'i32.wrap_i64';
}
class I32TruncF32S extends SingleByteInstruction {
const I32TruncF32S() : super(0xA8);
static I32TruncF32S deserialize(Deserializer d) => const I32TruncF32S();
@override
String get name => 'i32.trunc_f32_s';
}
class I32TruncF32U extends SingleByteInstruction {
const I32TruncF32U() : super(0xA9);
static I32TruncF32U deserialize(Deserializer d) => const I32TruncF32U();
@override
String get name => 'i32.trunc_f32_u';
}
class I32TruncF64S extends SingleByteInstruction {
const I32TruncF64S() : super(0xAA);
static I32TruncF64S deserialize(Deserializer d) => const I32TruncF64S();
@override
String get name => 'i32.trunc_f64_s';
}
class I32TruncF64U extends SingleByteInstruction {
const I32TruncF64U() : super(0xAB);
static I32TruncF64U deserialize(Deserializer d) => const I32TruncF64U();
@override
String get name => 'i32.trunc_f64_u';
}
class I64ExtendI32S extends SingleByteInstruction {
const I64ExtendI32S() : super(0xAC);
static I64ExtendI32S deserialize(Deserializer d) => const I64ExtendI32S();
@override
String get name => 'i64.extend_i32_s';
}
class I64ExtendI32U extends SingleByteInstruction {
const I64ExtendI32U() : super(0xAD);
static I64ExtendI32U deserialize(Deserializer d) => const I64ExtendI32U();
@override
String get name => 'i64.extend_i32_u';
}
class I64TruncF32S extends SingleByteInstruction {
const I64TruncF32S() : super(0xAE);
static I64TruncF32S deserialize(Deserializer d) => const I64TruncF32S();
@override
String get name => 'i64.trunc_f32_s';
}
class I64TruncF32U extends SingleByteInstruction {
const I64TruncF32U() : super(0xAF);
static I64TruncF32U deserialize(Deserializer d) => const I64TruncF32U();
@override
String get name => 'i64.trunc_f32_u';
}
class I64TruncF64S extends SingleByteInstruction {
const I64TruncF64S() : super(0xB0);
static I64TruncF64S deserialize(Deserializer d) => const I64TruncF64S();
@override
String get name => 'i64.trunc_f64_s';
}
class I64TruncF64U extends SingleByteInstruction {
const I64TruncF64U() : super(0xB1);
static I64TruncF64U deserialize(Deserializer d) => const I64TruncF64U();
@override
String get name => 'i64.trunc_f64_u';
}
class F32ConvertI32S extends SingleByteInstruction {
const F32ConvertI32S() : super(0xB2);
static F32ConvertI32S deserialize(Deserializer d) => const F32ConvertI32S();
@override
String get name => 'f32.convert_i32_s';
}
class F32ConvertI32U extends SingleByteInstruction {
const F32ConvertI32U() : super(0xB3);
static F32ConvertI32U deserialize(Deserializer d) => const F32ConvertI32U();
@override
String get name => 'f32.convert_i32_u';
}
class F32ConvertI64S extends SingleByteInstruction {
const F32ConvertI64S() : super(0xB4);
static F32ConvertI64S deserialize(Deserializer d) => const F32ConvertI64S();
@override
String get name => 'f32.convert_i64_s';
}
class F32ConvertI64U extends SingleByteInstruction {
const F32ConvertI64U() : super(0xB5);
static F32ConvertI64U deserialize(Deserializer d) => const F32ConvertI64U();
@override
String get name => 'f32.convert_i64_u';
}
class F32DemoteF64 extends SingleByteInstruction {
const F32DemoteF64() : super(0xB6);
static F32DemoteF64 deserialize(Deserializer d) => const F32DemoteF64();
@override
String get name => 'f32.demote_f64';
}
class F64ConvertI32S extends SingleByteInstruction {
const F64ConvertI32S() : super(0xB7);
static F64ConvertI32S deserialize(Deserializer d) => const F64ConvertI32S();
@override
String get name => 'f64.convert_i32_s';
}
class F64ConvertI32U extends SingleByteInstruction {
const F64ConvertI32U() : super(0xB8);
static F64ConvertI32U deserialize(Deserializer d) => const F64ConvertI32U();
@override
String get name => 'f64.convert_i32_u';
}
class F64ConvertI64S extends SingleByteInstruction {
const F64ConvertI64S() : super(0xB9);
static F64ConvertI64S deserialize(Deserializer d) => const F64ConvertI64S();
@override
String get name => 'f64.convert_i64_s';
}
class F64ConvertI64U extends SingleByteInstruction {
const F64ConvertI64U() : super(0xBA);
static F64ConvertI64U deserialize(Deserializer d) => const F64ConvertI64U();
@override
String get name => 'f64.convert_i64_u';
}
class F64PromoteF32 extends SingleByteInstruction {
const F64PromoteF32() : super(0xBB);
static F64PromoteF32 deserialize(Deserializer d) => const F64PromoteF32();
@override
String get name => 'f64.promote_f32';
}
class I32ReinterpretF32 extends SingleByteInstruction {
const I32ReinterpretF32() : super(0xBC);
static I32ReinterpretF32 deserialize(Deserializer d) =>
const I32ReinterpretF32();
@override
String get name => 'i32.reinterpret_f32';
}
class I64ReinterpretF64 extends SingleByteInstruction {
const I64ReinterpretF64() : super(0xBD);
static I64ReinterpretF64 deserialize(Deserializer d) =>
const I64ReinterpretF64();
@override
String get name => 'i64.reinterpret_f64';
}
class F32ReinterpretI32 extends SingleByteInstruction {
const F32ReinterpretI32() : super(0xBE);
static F32ReinterpretI32 deserialize(Deserializer d) =>
const F32ReinterpretI32();
@override
String get name => 'f32.reinterpret_i32';
}
class F64ReinterpretI64 extends SingleByteInstruction {
const F64ReinterpretI64() : super(0xBF);
static F64ReinterpretI64 deserialize(Deserializer d) =>
const F64ReinterpretI64();
@override
String get name => 'f64.reinterpret_i64';
}
class I32Extend8S extends SingleByteInstruction {
const I32Extend8S() : super(0xC0);
static I32Extend8S deserialize(Deserializer d) => const I32Extend8S();
@override
String get name => 'i32.extend8_s';
}
class I32Extend16S extends SingleByteInstruction {
const I32Extend16S() : super(0xC1);
static I32Extend16S deserialize(Deserializer d) => const I32Extend16S();
@override
String get name => 'i32.extend16_s';
}
class I64Extend8S extends SingleByteInstruction {
const I64Extend8S() : super(0xC2);
static I64Extend8S deserialize(Deserializer d) => const I64Extend8S();
@override
String get name => 'i64.extend8_s';
}
class I64Extend16S extends SingleByteInstruction {
const I64Extend16S() : super(0xC3);
static I64Extend16S deserialize(Deserializer d) => const I64Extend16S();
@override
String get name => 'i64.extend16_s';
}
class I64Extend32S extends SingleByteInstruction {
const I64Extend32S() : super(0xC4);
static I64Extend32S deserialize(Deserializer d) => const I64Extend32S();
@override
String get name => 'i64.extend32_s';
}
class I32TruncSatF32S extends Instruction {
const I32TruncSatF32S();
@override
void serialize(Serializer s) {
s.writeByte(0xFC);
s.writeByte(0x00);
}
static I32TruncSatF32S deserialize(Deserializer d) => const I32TruncSatF32S();
@override
String get name => 'i32.trunc_sat_f32_s';
}
class I32TruncSatF32U extends Instruction {
const I32TruncSatF32U();
@override
void serialize(Serializer s) {
s.writeByte(0xFC);
s.writeByte(0x01);
}
static I32TruncSatF32U deserialize(Deserializer d) => const I32TruncSatF32U();
@override
String get name => 'i32.trunc_sat_f32_u';
}
class I32TruncSatF64S extends Instruction {
const I32TruncSatF64S();
@override
void serialize(Serializer s) {
s.writeByte(0xFC);
s.writeByte(0x02);
}
static I32TruncSatF64S deserialize(Deserializer d) => const I32TruncSatF64S();
@override
String get name => 'i32.trunc_sat_f64_s';
}
class I32TruncSatF64U extends Instruction {
const I32TruncSatF64U();
@override
void serialize(Serializer s) {
s.writeByte(0xFC);
s.writeByte(0x03);
}
static I32TruncSatF64U deserialize(Deserializer d) => const I32TruncSatF64U();
@override
String get name => 'i32.trunc_sat_f64_u';
}
class I64TruncSatF32S extends Instruction {
const I64TruncSatF32S();
@override
void serialize(Serializer s) {
s.writeByte(0xFC);
s.writeByte(0x04);
}
static I64TruncSatF32S deserialize(Deserializer d) => const I64TruncSatF32S();
@override
String get name => 'i64.trunc_sat_f32_s';
}
class I64TruncSatF32U extends Instruction {
const I64TruncSatF32U();
@override
void serialize(Serializer s) {
s.writeByte(0xFC);
s.writeByte(0x05);
}
static I64TruncSatF32U deserialize(Deserializer d) => const I64TruncSatF32U();
@override
String get name => 'i64.trunc_sat_f32_u';
}
class I64TruncSatF64S extends Instruction {
const I64TruncSatF64S();
@override
void serialize(Serializer s) {
s.writeByte(0xFC);
s.writeByte(0x06);
}
static I64TruncSatF64S deserialize(Deserializer d) => const I64TruncSatF64S();
@override
String get name => 'i64.trunc_sat_f64_s';
}
class I64TruncSatF64U extends Instruction {
const I64TruncSatF64U();
@override
void serialize(Serializer s) {
s.writeByte(0xFC);
s.writeByte(0x07);
}
static I64TruncSatF64U deserialize(Deserializer d) => const I64TruncSatF64U();
@override
String get name => 'i64.trunc_sat_f64_u';
}
enum V128Instruction with Instruction {
i8x16Splat(0x0F, 'i8x16.splat'),
i16x8Splat(0x10, 'i16x8.splat'),
i32x4Splat(0x11, 'i32x4.splat'),
i64x2Splat(0x12, 'i64x2.splat'),
f32x4Splat(0x13, 'f32x4.splat'),
f64x2Splat(0x14, 'f64x2.splat'),
i8x16Eq(0x23, 'i8x16.eq'),
i16x8Eq(0x2D, 'i16x8.eq'),
i32x4Eq(0x37, 'i32x4.eq'),
f32x4Eq(0x41, 'f32x4.eq'),
f32x4Ne(0x42, 'f32x4.ne'),
f32x4Lt(0x43, 'f32x4.lt'),
f32x4Gt(0x44, 'f32x4.gt'),
f32x4Le(0x45, 'f32x4.le'),
f32x4Ge(0x46, 'f32x4.ge'),
f64x2Eq(0x47, 'f64x2.eq'),
f64x2Ne(0x48, 'f64x2.ne'),
f64x2Lt(0x49, 'f64x2.lt'),
f64x2Gt(0x4A, 'f64x2.gt'),
f64x2Le(0x4B, 'f64x2.le'),
f64x2Ge(0x4C, 'f64x2.ge'),
v128Not(0x4D, 'v128.not'),
v128And(0x4E, 'v128.and'),
v128AndNot(0x4F, 'v128.andnot'),
v128Or(0x50, 'v128.or'),
v128Xor(0x51, 'v128.xor'),
v128BitSelect(0x52, 'v128.bitselect'),
i8x16Neg(0x61, 'i8x16.neg'),
f32x4Ceil(0x67, 'f32x4.ceil'),
f32x4Floor(0x68, 'f32x4.floor'),
f32x4Trunc(0x69, 'f32x4.trunc'),
f32x4Nearest(0x6A, 'f32x4.nearest'),
i8x16Add(0x6E, 'i8x16.add'),
i8x16Sub(0x71, 'i8x16.sub'),
f64x2Ceil(0x74, 'f64x2.ceil'),
f64x2Floor(0x75, 'f64x2.floor'),
f64x2Trunc(0x7A, 'f64x2.trunc'),
f64x2Nearest(0x94, 'f64x2.nearest'),
i16x8Neg(0x81, 'i16x8.neg'),
i16x8Add(0x8E, 'i16x8.add'),
i16x8Sub(0x91, 'i16x8.sub'),
i16x8Mul(0x95, 'i16x8.mul'),
i32x4Neg(0xA1, 'i32x4.neg'),
i32x4Add(0xAE, 'i32x4.add'),
i32x4Sub(0xB1, 'i32x4.sub'),
i32x4Mul(0xB5, 'i32x4.mul'),
i32x4DotI16x8(0xBA, 'i32x4.dot_i16x8_s'),
i64x2Neg(0xC1, 'i64x2.neg'),
i64x2Add(0xCE, 'i64x2.add'),
i64x2Sub(0xD1, 'i64x2.sub'),
i64x2Mul(0xD5, 'i64x2.mul'),
i64x2Eq(0xD6, 'i64x2.eq'),
f32x4Abs(0xE0, 'f32x4.abs'),
f32x4Neg(0xE1, 'f32x4.neg'),
f32x4Sqrt(0xE3, 'f32x4.sqrt'),
f32x4Add(0xE4, 'f32x4.add'),
f32x4Sub(0xE5, 'f32x4.sub'),
f32x4Mul(0xE6, 'f32x4.mul'),
f32x4Div(0xE7, 'f32x4.div'),
f32x4Min(0xE8, 'f32x4.min'),
f32x4Max(0xE9, 'f32x4.max'),
f32x4PMin(0xEA, 'f32x4.pmin'),
f32x4PMax(0xEB, 'f32x4.pmax'),
f64x2Abs(0xEC, 'f64x2.abs'),
f64x2Neg(0xED, 'f64x2.neg'),
f64x2Sqrt(0xEF, 'f64x2.sqrt'),
f64x2Add(0xF0, 'f64x2.add'),
f64x2Sub(0xF1, 'f64x2.sub'),
f64x2Mul(0xF2, 'f64x2.mul'),
f64x2Div(0xF3, 'f64x2.div'),
f64x2Min(0xF4, 'f64x2.min'),
f64x2Max(0xF5, 'f64x2.max'),
f64x2PMin(0xF6, 'f64x2.pmin'),
f64x2PMax(0xF7, 'f64x2.pmax');
final int opcode;
@override
final String name;
const V128Instruction(this.opcode, this.name);
static List<V128Instruction?> _lookup = (() {
final lookup = List<V128Instruction?>.filled(256, null);
for (final v in values) {
lookup[v.opcode] = v;
}
return lookup;
})();
static V128Instruction? fromOpcode(int opcode) => _lookup[opcode];
@override
void serialize(Serializer s) {
s.writeByte(0xFD);
s.writeUnsigned(opcode);
}
}
class I8x16ExtractLaneS extends Instruction {
const I8x16ExtractLaneS(this.lane);
final int lane;
@override
void serialize(Serializer s) {
s.writeByte(0xFD);
s.writeUnsigned(0x15);
s.writeByte(lane);
}
static I8x16ExtractLaneS deserialize(Deserializer d) =>
I8x16ExtractLaneS(d.readByte());
@override
String get name => 'i8x16.extract_lane_s';
}
class I8x16ExtractLaneU extends Instruction {
const I8x16ExtractLaneU(this.lane);
final int lane;
@override
void serialize(Serializer s) {
s.writeByte(0xFD);
s.writeUnsigned(0x16);
s.writeByte(lane);
}
static I8x16ExtractLaneU deserialize(Deserializer d) =>
I8x16ExtractLaneU(d.readByte());
@override
String get name => 'i8x16.extract_lane_u';
}
class I8x16ReplaceLane extends Instruction {
const I8x16ReplaceLane(this.lane);
final int lane;
@override
void serialize(Serializer s) {
s.writeByte(0xFD);
s.writeUnsigned(0x17);
s.writeByte(lane);
}
static I8x16ReplaceLane deserialize(Deserializer d) =>
I8x16ReplaceLane(d.readByte());
@override
String get name => 'i8x16.replace_lane';
}
class I16x8ExtractLaneS extends Instruction {
const I16x8ExtractLaneS(this.lane);
final int lane;
@override
void serialize(Serializer s) {
s.writeByte(0xFD);
s.writeUnsigned(0x18);
s.writeByte(lane);
}
static I16x8ExtractLaneS deserialize(Deserializer d) =>
I16x8ExtractLaneS(d.readByte());
@override
String get name => 'i16x8.extract_lane_s';
}
class I16x8ExtractLaneU extends Instruction {
const I16x8ExtractLaneU(this.lane);
final int lane;
@override
void serialize(Serializer s) {
s.writeByte(0xFD);
s.writeUnsigned(0x19);
s.writeByte(lane);
}
static I16x8ExtractLaneU deserialize(Deserializer d) =>
I16x8ExtractLaneU(d.readByte());
@override
String get name => 'i16x8.extract_lane_u';
}
class I16x8ReplaceLane extends Instruction {
const I16x8ReplaceLane(this.lane);
final int lane;
@override
void serialize(Serializer s) {
s.writeByte(0xFD);
s.writeUnsigned(0x1A);
s.writeByte(lane);
}
static I16x8ReplaceLane deserialize(Deserializer d) =>
I16x8ReplaceLane(d.readByte());
@override
String get name => 'i16x8.replace_lane';
}
class I32x4ExtractLane extends Instruction {
const I32x4ExtractLane(this.lane);
final int lane;
@override
void serialize(Serializer s) {
s.writeByte(0xFD);
s.writeUnsigned(0x1B);
s.writeByte(lane);
}
static I32x4ExtractLane deserialize(Deserializer d) =>
I32x4ExtractLane(d.readByte());
@override
String get name => 'i32x4.extract_lane';
}
class I32x4ReplaceLane extends Instruction {
const I32x4ReplaceLane(this.lane);
final int lane;
@override
void serialize(Serializer s) {
s.writeByte(0xFD);
s.writeUnsigned(0x1C);
s.writeByte(lane);
}
static I32x4ReplaceLane deserialize(Deserializer d) =>
I32x4ReplaceLane(d.readByte());
@override
String get name => 'i32x4.replace_lane';
}
class I64x2ExtractLane extends Instruction {
const I64x2ExtractLane(this.lane);
final int lane;
@override
void serialize(Serializer s) {
s.writeByte(0xFD);
s.writeUnsigned(0x1D);
s.writeByte(lane);
}
static I64x2ExtractLane deserialize(Deserializer d) =>
I64x2ExtractLane(d.readByte());
@override
String get name => 'i64x2.extract_lane';
}
class I64x2ReplaceLane extends Instruction {
const I64x2ReplaceLane(this.lane);
final int lane;
@override
void serialize(Serializer s) {
s.writeByte(0xFD);
s.writeUnsigned(0x1E);
s.writeByte(lane);
}
static I64x2ReplaceLane deserialize(Deserializer d) =>
I64x2ReplaceLane(d.readByte());
@override
String get name => 'i64x2.replace_lane';
}
class F32x4ExtractLane extends Instruction {
const F32x4ExtractLane(this.lane);
final int lane;
@override
void serialize(Serializer s) {
s.writeByte(0xFD);
s.writeUnsigned(0x1F);
s.writeByte(lane);
}
static F32x4ExtractLane deserialize(Deserializer d) =>
F32x4ExtractLane(d.readByte());
@override
String get name => 'f32x4.extract_lane';
}
class F32x4ReplaceLane extends Instruction {
const F32x4ReplaceLane(this.lane);
final int lane;
@override
void serialize(Serializer s) {
s.writeByte(0xFD);
s.writeUnsigned(0x20);
s.writeByte(lane);
}
static F32x4ReplaceLane deserialize(Deserializer d) =>
F32x4ReplaceLane(d.readByte());
@override
String get name => 'f32x4.replace_lane';
}
class F64x2ExtractLane extends Instruction {
const F64x2ExtractLane(this.lane);
final int lane;
@override
void serialize(Serializer s) {
s.writeByte(0xFD);
s.writeUnsigned(0x21);
s.writeByte(lane);
}
static F64x2ExtractLane deserialize(Deserializer d) =>
F64x2ExtractLane(d.readByte());
@override
String get name => 'f64x2.extract_lane';
}
class F64x2ReplaceLane extends Instruction {
const F64x2ReplaceLane(this.lane);
final int lane;
@override
void serialize(Serializer s) {
s.writeByte(0xFD);
s.writeUnsigned(0x22);
s.writeByte(lane);
}
static F64x2ReplaceLane deserialize(Deserializer d) =>
F64x2ReplaceLane(d.readByte());
@override
String get name => 'f64x2.replace_lane';
}
class BeginNoEffectTryTable extends Instruction {
final List<TryTableCatch> catches;
BeginNoEffectTryTable(this.catches);
static BeginNoEffectTryTable deserialize(Deserializer d, Tags tags) {
d.readByte();
final catches = d.readList((d) => TryTableCatch.deserialize(d, tags));
return BeginNoEffectTryTable(catches);
}
@override
void serialize(Serializer s) {
s.writeByte(0x1F);
s.writeByte(0x40);
s.writeUnsigned(catches.length);
for (final catch_ in catches) {
catch_.serialize(s);
}
}
@override
String get name => 'try_table';
}
class BeginOneOutputTryTable extends Instruction {
final ValueType type;
final List<TryTableCatch> catches;
@override
List<ValueType> get usedValueTypes => [type];
BeginOneOutputTryTable(this.type, this.catches);
static BeginOneOutputTryTable deserialize(
Deserializer d, Tags tags, Types types) {
final type = ValueType.deserialize(d, types.defined);
final catches = d.readList((d) => TryTableCatch.deserialize(d, tags));
return BeginOneOutputTryTable(type, catches);
}
@override
void serialize(Serializer s) {
s.writeByte(0x1F);
s.write(type);
s.writeUnsigned(catches.length);
for (final catch_ in catches) {
catch_.serialize(s);
}
}
@override
String get name => 'try_table';
}
class BeginFunctionTryTable extends Instruction {
final FunctionType type;
final List<TryTableCatch> catches;
BeginFunctionTryTable(this.type, this.catches);
static BeginFunctionTryTable deserialize(
Deserializer d, Tags tags, Types types) {
final type = types.defined[d.readSigned()] as FunctionType;
final catches = d.readList((d) => TryTableCatch.deserialize(d, tags));
return BeginFunctionTryTable(type, catches);
}
@override
List<DefType> get usedDefTypes => [type];
@override
void serialize(Serializer s) {
s.writeByte(0x1F);
s.write(type);
s.writeUnsigned(catches.length);
for (final catch_ in catches) {
catch_.serialize(s);
}
}
@override
String get name => 'try_table';
}
abstract class TryTableCatch {
final int labelIndex;
TryTableCatch(this.labelIndex);
void serialize(Serializer s);
static TryTableCatch deserialize(Deserializer d, Tags tags) {
final kind = d.readByte();
switch (kind) {
case 0x00:
final tag = tags[d.readUnsigned()];
final label = d.readUnsigned();
return Catch(tag, label);
case 0x01:
final tag = tags[d.readUnsigned()];
final label = d.readUnsigned();
return CatchRef(tag, label);
case 0x02:
final label = d.readUnsigned();
return CatchAll(label);
case 0x03:
final label = d.readUnsigned();
return CatchAllRef(label);
default:
throw "Invalid TryTableCatch kind: $kind";
}
}
}
class Catch extends TryTableCatch {
final Tag tag;
Catch(this.tag, super.labelIndex);
@override
void serialize(Serializer s) {
s.writeByte(0x00);
s.writeUnsigned(tag.index);
s.writeUnsigned(labelIndex);
}
}
class CatchRef extends TryTableCatch {
final Tag tag;
CatchRef(this.tag, super.labelIndex);
@override
void serialize(Serializer s) {
s.writeByte(0x01);
s.writeUnsigned(tag.index);
s.writeUnsigned(labelIndex);
}
}
class CatchAll extends TryTableCatch {
CatchAll(super.labelIndex);
@override
void serialize(Serializer s) {
s.writeByte(0x02);
s.writeUnsigned(labelIndex);
}
}
class CatchAllRef extends TryTableCatch {
CatchAllRef(super.labelIndex);
@override
void serialize(Serializer s) {
s.writeByte(0x03);
s.writeUnsigned(labelIndex);
}
}
extension on Serializer {
void writeTypeIndex(DefType type) => writeUnsigned(type.index);
}
extension on Deserializer {
int readTypeIndex() => readUnsigned();
Instruction deserializeBlock(
Types types,
Tags tags,
Instruction Function(Deserializer, Tags) deserializeNoInputNoOutput,
Instruction Function(Deserializer, Tags, Types) deserializeOneOutput,
Instruction Function(Deserializer, Tags, Types) deserializeGeneral) {
if (peekByte() == 0x40) {
// 0x40 means empty type, the block has neither inputs nor outputs.
return deserializeNoInputNoOutput(this, tags);
}
final oldOffset = offset;
final value = readSigned();
offset = oldOffset;
if (value < 0) {
// not positive signed integer, the block has no inputs and exactly one
// output.
return deserializeOneOutput(this, tags, types);
}
// positive signed integer is index into defined types and must be a
// function type representing the input & output types.
return deserializeGeneral(this, tags, types);
}
}