Changeset 209175 in webkit


Ignore:
Timestamp:
Nov 30, 2016 11:04:18 PM (7 years ago)
Author:
jfbastien@apple.com
Message:

WebAssembly: update binary format to 0xD version
https://bugs.webkit.org/show_bug.cgi?id=164724

Reviewed by Saam Barati.

As described in the following PR: https://github.com/WebAssembly/design/pull/836

JSTests:

  • wasm/Builder.js:

(const._normalizeFunctionSignature):

  • wasm/Builder_WebAssemblyBinary.js:

(const.emitters.Type):
(const.emitters.Code):

  • wasm/LowLevelBinary.js:

(export.default.LowLevelBinary.prototype.block_type):
(export.default.LowLevelBinary.prototype.inline_signature_type): Deleted.

  • wasm/WASM.js:
  • wasm/js-api/test_basic_api.js:
  • wasm/self-test/test_BuilderWebAssembly.js:

(EmptyModule):
(CustomSection):

  • wasm/self-test/test_WASM.js:
  • wasm/wasm.json:

Source/JavaScriptCore:

  • wasm/WasmB3IRGenerator.cpp:

(JSC::Wasm::B3IRGenerator::B3IRGenerator):
(JSC::Wasm::B3IRGenerator::zeroForType):
(JSC::Wasm::B3IRGenerator::addConstant):
(JSC::Wasm::createJSWrapper):

  • wasm/WasmCallingConvention.h:

(JSC::Wasm::CallingConvention::marshallArgument):

  • wasm/WasmFormat.cpp:

(JSC::Wasm::toString): Deleted.

  • wasm/WasmFormat.h:

(JSC::Wasm::isValueType):
(JSC::Wasm::toB3Type): Deleted.

  • wasm/WasmFunctionParser.h:

(JSC::Wasm::FunctionParser<Context>::parseExpression):

  • wasm/WasmModuleParser.cpp:

(JSC::Wasm::ModuleParser::parse):
(JSC::Wasm::ModuleParser::parseType):

  • wasm/WasmModuleParser.h:
  • wasm/WasmParser.h:

(JSC::Wasm::Parser::parseResultType):

  • wasm/generateWasm.py:

(Wasm.init):

  • wasm/generateWasmOpsHeader.py:

(cppMacro):
(typeMacroizer):
(opcodeMacroizer):

  • wasm/wasm.json:
Location:
trunk
Files:
22 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r209165 r209175  
     12016-11-30  JF Bastien  <jfbastien@apple.com>
     2
     3        WebAssembly: update binary format to 0xD version
     4        https://bugs.webkit.org/show_bug.cgi?id=164724
     5
     6        Reviewed by Saam Barati.
     7
     8        As described in the following PR: https://github.com/WebAssembly/design/pull/836
     9
     10        * wasm/Builder.js:
     11        (const._normalizeFunctionSignature):
     12        * wasm/Builder_WebAssemblyBinary.js:
     13        (const.emitters.Type):
     14        (const.emitters.Code):
     15        * wasm/LowLevelBinary.js:
     16        (export.default.LowLevelBinary.prototype.block_type):
     17        (export.default.LowLevelBinary.prototype.inline_signature_type): Deleted.
     18        * wasm/WASM.js:
     19        * wasm/js-api/test_basic_api.js:
     20        * wasm/self-test/test_BuilderWebAssembly.js:
     21        (EmptyModule):
     22        (CustomSection):
     23        * wasm/self-test/test_WASM.js:
     24        * wasm/wasm.json:
     25
    1262016-11-30  JF Bastien  <jfbastien@apple.com>
    227
  • trunk/JSTests/wasm/Builder.js

    r209165 r209175  
    5252        ret = "void";
    5353    assert.isNotArray(ret, `Multiple return values not supported by WebAssembly yet`);
    54     assert.falsy(ret !== "void" && !WASM.isValidValueType(ret), `Type return ${ret} must be valid value type`);
     54    assert.truthy(WASM.isValidBlockType(ret), `Type return ${ret} must be valid block type`);
    5555    return [params, ret];
    5656};
     
    157157const _checkStackArgs = (op, param) => {
    158158    for (let expect of param) {
    159         if (WASM.isValidValueType(expect)) {
     159        if (WASM.isValidType(expect)) {
    160160            // FIXME implement stack checks for arguments. https://bugs.webkit.org/show_bug.cgi?id=163421
    161161        } else {
     
    178178const _checkStackReturn = (op, ret) => {
    179179    for (let expect of ret) {
    180         if (WASM.isValidValueType(expect)) {
     180        if (WASM.isValidType(expect)) {
    181181            // FIXME implement stack checks for return. https://bugs.webkit.org/show_bug.cgi?id=163421
    182182        } else {
     
    222222        case "relative_depth": break; // improve checking https://bugs.webkit.org/show_bug.cgi?id=163421
    223223        case "sig":
    224             // FIXME this should be isValidBlockType https://bugs.webkit.org/show_bug.cgi?id=164724
    225             assert.truthy(imms[idx] === "void" || WASM.isValidValueType(imms[idx]), `Invalid block type on ${op}: "${imms[idx]}"`);
     224            assert.truthy(WASM.isValidBlockType(imms[idx]), `Invalid block type on ${op}: "${imms[idx]}"`);
    226225            break;
    227226        case "target_count": break; // improve checking https://bugs.webkit.org/show_bug.cgi?id=163421
  • trunk/JSTests/wasm/Builder_WebAssemblyBinary.js

    r209123 r209175  
    3434        put(bin, "varuint32", section.data.length);
    3535        for (const entry of section.data) {
    36             const funcTypeConstructor = -0x20; // FIXME Move this to wasm.json.
    37             put(bin, "varint7", funcTypeConstructor);
     36            put(bin, "varint7", WASM.typeValue["func"]);
    3837            put(bin, "varuint32", entry.params.length);
    3938            for (const param of entry.params)
    40                 put(bin, "uint8", WASM.valueTypeValue[param]);
     39                put(bin, "varint7", WASM.typeValue[param]);
    4140            if (entry.ret === "void")
    4241                put(bin, "varuint1", 0);
    4342            else {
    4443                put(bin, "varuint1", 1);
    45                 put(bin, "uint8", WASM.valueTypeValue[entry.ret]);
     44                put(bin, "varint7", WASM.typeValue[entry.ret]);
    4645            }
    4746        }
     
    108107            for (let i = func.parameterCount; i < func.locals.length; ++i) {
    109108                put(funcBin, "varuint32", 1);
    110                 put(funcBin, "uint8", WASM.valueTypeValue[func.locals[i]]);
     109                put(funcBin, "varint7", WASM.typeValue[func.locals[i]]);
    111110            }
    112111
  • trunk/JSTests/wasm/LowLevelBinary.js

    r209123 r209175  
    160160        this.varuint32(v);
    161161    }
    162     inline_signature_type(v) {
    163         this.varint7(WASM.valueTypeValue[v]);
     162    block_type(v) {
     163        if (!WASM.isValidBlockType(v))
     164            throw new Error(`Invalid block type ${v}`);
     165        this.varint7(WASM.typeValue[v]);
    164166    }
    165167    string(str) {
  • trunk/JSTests/wasm/WASM.js

    r208401 r209175  
    3434
    3535export const description = utilities.json("wasm.json");
    36 export const valueType = Object.keys(description.value_type);
    37 const _valueTypeSet = new Set(valueType);
     36export const type = Object.keys(description.type);
     37const _typeSet = new Set(type);
     38export const isValidType = v => _typeSet.has(v);
     39export const typeValue = _mapValues(description.type);
     40const _valueTypeSet = new Set(description.value_type);
    3841export const isValidValueType = v => _valueTypeSet.has(v);
    39 export const valueTypeValue = _mapValues(description.value_type);
     42const _blockTypeSet = new Set(description.block_type);
     43export const isValidBlockType = v => _blockTypeSet.has(v);
    4044export const externalKindValue = _mapValues(description.external_kind);
    4145export const sections = Object.keys(description.section);
  • trunk/JSTests/wasm/js-api/test_basic_api.js

    r209123 r209175  
    22import * as utilities from '../utilities.js';
    33
    4 const version = 0xC;
     4const version = 0x0D;
    55const emptyModuleArray = Uint8Array.of(0x0, 0x61, 0x73, 0x6d, version, 0x00, 0x00, 0x00);
    66const invalidConstructorInputs = [undefined, null, "", 1, {}, []];
  • trunk/JSTests/wasm/self-test/test_BuilderWebAssembly.js

    r209123 r209175  
    77    // Note: this will change as we update version number.
    88    assert.eq(bin.hexdump().trim(),
    9               "00000000 00 61 73 6d 0c 00 00 00                          |·asm····        |");
     9              "00000000 00 61 73 6d 0d 00 00 00                          |·asm····        |");
    1010})();
    1111
     
    2828        .WebAssembly();
    2929    assert.eq(bin.hexdump().trim(),
    30               ["00000000 00 61 73 6d 0c 00 00 00 00 0a 05 4f 48 48 41 49  |·asm·······OHHAI|",
     30              ["00000000 00 61 73 6d 0d 00 00 00 00 0a 05 4f 48 48 41 49  |·asm·······OHHAI|",
    3131               "00000010 de ad c0 fe                                      |····            |"].join("\n"));
    3232})();
  • trunk/JSTests/wasm/self-test/test_WASM.js

    r208401 r209175  
    33
    44assert.isNotUndef(WASM.description);
    5 assert.isNotUndef(WASM.valueType);
    6 assert.ge(WASM.valueType.length, 4);
     5assert.isNotUndef(WASM.type);
     6assert.ge(WASM.type.length, 7);
    77
    8 for (const v of WASM.valueType)
    9     if (!WASM.isValidValueType(v))
    10         throw new Error(`Expected value ${v} to be a valid value type`);
     8for (const v of WASM.type)
     9    if (!WASM.isValidType(v))
     10        throw new Error(`Expected value ${v} to be a valid type`);
    1111
    1212const expectedFields = [
    1313    "preamble",
    14     "value_type",
    15     "inline_signature_type",
     14    "type",
    1615    "external_kind",
    1716    "section",
  • trunk/JSTests/wasm/wasm.json

    r209083 r209175  
    11{
    22    "comments": ["This file describes the WebAssembly ISA.",
    3                  "Scripts in this folder auto-generate C++ code for JavaScriptCore as well as the testing DSL which WebKit's WebAssembly tests use.",
    4                  "When you update this file you need to re-generate the C++ code: jsc ./JSTests/stress/wasm/generate-wasmops-header.js > ./Source/JavaScriptCore/wasm/WASMOps.h"
     3                 "Scripts in this folder auto-generate C++ code for JavaScriptCore as well as the testing DSL which WebKit's WebAssembly tests use."
    54                ],
    65    "preamble": [
    76        { "name": "magic number", "type": "uint32", "value": 1836278016, "description": "NULL character followed by 'asm'" },
    8         { "name": "version",      "type": "uint32", "value":         12, "description": "Version number, will be reset to 1 for MVP" }
     7        { "name": "version",      "type": "uint32", "value":         13, "description": "Version number, will be reset to 1 for MVP" }
    98    ],
    10     "value_type" : {
    11         "i32": { "type": "uint8", "value": 1 },
    12         "i64": { "type": "uint8", "value": 2 },
    13         "f32": { "type": "uint8", "value": 3 },
    14         "f64": { "type": "uint8", "value": 4 }
     9    "type" : {
     10        "i32":     { "type": "varint7", "value":  -1, "b3type": "B3::Int32" },
     11        "i64":     { "type": "varint7", "value":  -2, "b3type": "B3::Int64" },
     12        "f32":     { "type": "varint7", "value":  -3, "b3type": "B3::Float" },
     13        "f64":     { "type": "varint7", "value":  -4, "b3type": "B3::Double" },
     14        "anyfunc": { "type": "varint7", "value": -16, "b3type": "B3::Void" },
     15        "func":    { "type": "varint7", "value": -32, "b3type": "B3::Void" },
     16        "void":    { "type": "varint7", "value": -64, "b3type": "B3::Void" }
    1517    },
    16     "inline_signature_type" : {
    17         "void": { "type": "uint8", "value": 0 },
    18         "i32":  { "type": "uint8", "value": 1 },
    19         "i64":  { "type": "uint8", "value": 2 },
    20         "f32":  { "type": "uint8", "value": 3 },
    21         "f64":  { "type": "uint8", "value": 4 }
    22     },
     18    "value_type": ["i32", "i64", "f32", "f64"],
     19    "block_type": ["i32", "i64", "f32", "f64", "void"],
     20    "elem_type": ["anyfunc"],
    2321    "external_kind": {
    2422        "Function": { "type": "uint8", "value": 0 },
     
    4240    "opcode": {
    4341        "unreachable":         { "category": "control",    "value":   0, "return": [],           "parameter": [],                      "immediate": [],                                                                                         "description": "trap immediately" },
    44         "block":               { "category": "control",    "value":   1, "return": ["control"],  "parameter": [],                      "immediate": [{"name": "sig", "type": "inline_signature_type"}],                                         "description": "begin a sequence of expressions, yielding 0 or 1 values" },
    45         "loop":                { "category": "control",    "value":   2, "return": ["control"],  "parameter": [],                      "immediate": [{"name": "sig", "type": "inline_signature_type"}],                                         "description": "begin a block which can also form control flow loops" },
    46         "if":                  { "category": "control",    "value":   3, "return": ["control"],  "parameter": ["bool"],                "immediate": [{"name": "sig", "type": "inline_signature_type"}],                                         "description": "begin if expression" },
    47         "else":                { "category": "control",    "value":   4, "return": ["control"],  "parameter": [],                      "immediate": [],                                                                                         "description": "begin else expression of if" },
    48         "select":              { "category": "control",    "value":   5, "return": ["prev"],     "parameter": ["any", "prev", "bool"], "immediate": [],                                                                                         "description": "select one of two values based on condition" },
    49         "br":                  { "category": "control",    "value":   6, "return": [],           "parameter": [],                      "immediate": [{"name": "relative_depth", "type": "varuint32"}],                                          "description": "break that targets an outer nested block" },
    50         "br_if":               { "category": "control",    "value":   7, "return": [],           "parameter": [],                      "immediate": [{"name": "relative_depth", "type": "varuint32"}],                                          "description": "conditional break that targets an outer nested block" },
    51         "br_table":            { "category": "control",    "value":   8, "return": [],           "parameter": [],                      "immediate": [{"name": "target_count",   "type": "varuint32",                                            "description": "number of entries in the target_table"},
     42        "block":               { "category": "control",    "value":   2, "return": ["control"],  "parameter": [],                      "immediate": [{"name": "sig", "type": "block_type"}],                                                    "description": "begin a sequence of expressions, yielding 0 or 1 values" },
     43        "loop":                { "category": "control",    "value":   3, "return": ["control"],  "parameter": [],                      "immediate": [{"name": "sig", "type": "block_type"}],                                                    "description": "begin a block which can also form control flow loops" },
     44        "if":                  { "category": "control",    "value":   4, "return": ["control"],  "parameter": ["bool"],                "immediate": [{"name": "sig", "type": "block_type"}],                                                    "description": "begin if expression" },
     45        "else":                { "category": "control",    "value":   5, "return": ["control"],  "parameter": [],                      "immediate": [],                                                                                         "description": "begin else expression of if" },
     46        "select":              { "category": "control",    "value":  27, "return": ["prev"],     "parameter": ["any", "prev", "bool"], "immediate": [],                                                                                         "description": "select one of two values based on condition" },
     47        "br":                  { "category": "control",    "value":  12, "return": [],           "parameter": [],                      "immediate": [{"name": "relative_depth", "type": "varuint32"}],                                          "description": "break that targets an outer nested block" },
     48        "br_if":               { "category": "control",    "value":  13, "return": [],           "parameter": [],                      "immediate": [{"name": "relative_depth", "type": "varuint32"}],                                          "description": "conditional break that targets an outer nested block" },
     49        "br_table":            { "category": "control",    "value":  14, "return": [],           "parameter": [],                      "immediate": [{"name": "target_count",   "type": "varuint32",                                            "description": "number of entries in the target_table"},
    5250                                                                                                                                                     {"name": "target_table",   "type": "varuint32*",                                           "description": "target entries that indicate an outer block or loop to which to break"},
    5351                                                                                                                                                     {"name": "default_target", "type": "varuint32",                                            "description": "an outer block or loop to which to break in the default case"}],
    5452                                                                                                                                                                                                                                                "description": "branch table control flow construct" },
    55         "return":              { "category": "control",    "value":   9, "return": [],           "parameter": [],                       "immediate": [],                                                                                         "description": "return zero or one value from this function" },
    56         "drop":                { "category": "control",    "value":  11, "return": [],           "parameter": ["any"],                  "immediate": [],                                                                                         "description": "ignore value" },
    57         "nop":                 { "category": "control",    "value":  10, "return": [],           "parameter": [],                       "immediate": [],                                                                                         "description": "no operation" },
    58         "end":                 { "category": "control",    "value":  15, "return": [],           "parameter": [],                       "immediate": [],                                                                                         "description": "end a block, loop, or if" },
    59         "i32.const":           { "category": "special",    "value":  16, "return": ["i32"],      "parameter": [],                       "immediate": [{"name": "value",          "type": "varint32"}],                                           "description": "a constant value interpreted as i32" },
    60         "i64.const":           { "category": "special",    "value":  17, "return": ["i64"],      "parameter": [],                       "immediate": [{"name": "value",          "type": "varint64"}],                                           "description": "a constant value interpreted as i64" },
    61         "f64.const":           { "category": "special",    "value":  18, "return": ["f64"],      "parameter": [],                       "immediate": [{"name": "value",          "type": "uint64"}],                                             "description": "a constant value interpreted as f64" },
    62         "f32.const":           { "category": "special",    "value":  19, "return": ["f32"],      "parameter": [],                       "immediate": [{"name": "value",          "type": "uint32"}],                                             "description": "a constant value interpreted as f32" },
    63         "get_local":           { "category": "special",    "value":  20, "return": ["local"],    "parameter": [],                       "immediate": [{"name": "local_index",    "type": "varuint32"}],                                          "description": "read a local variable or parameter" },
    64         "set_local":           { "category": "special",    "value":  21, "return": [],           "parameter": ["local"],                "immediate": [{"name": "local_index",    "type": "varuint32"}],                                          "description": "write a local variable or parameter" },
    65         "tee_local":           { "category": "special",    "value":  25, "return": ["prev"],     "parameter": ["any"],                  "immediate": [{"name": "local_index",    "type": "varuint32"}],                                          "description": "write a local variable or parameter and return the same value" },
    66         "get_global":          { "category": "special",    "value": 187, "return": ["global"],   "parameter": [],                       "immediate": [{"name": "global_index",   "type": "varuint32"}],                                          "description": "read a global variable" },
    67         "set_global":          { "category": "special",    "value": 188, "return": [""],         "parameter": ["global"],               "immediate": [{"name": "global_index",   "type": "varuint32"}],                                          "description": "write a global variable" },
    68         "call":                { "category": "call",       "value":  22, "return": ["call"],     "parameter": ["call"],                 "immediate": [{"name": "function_index", "type": "varuint32"}],                                          "description": "call a function by its index" },
    69         "call_indirect":       { "category": "call",       "value":  23, "return": ["call"],     "parameter": ["call"],                 "immediate": [{"name": "type_index",     "type": "varuint32"}],                                          "description": "call a function indirect with an expected signature" },
    70         "i32.load8_s":         { "category": "memory",     "value":  32, "return": ["i32"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
    71         "i32.load8_u":         { "category": "memory",     "value":  33, "return": ["i32"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
    72         "i32.load16_s":        { "category": "memory",     "value":  34, "return": ["i32"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
    73         "i32.load16_u":        { "category": "memory",     "value":  35, "return": ["i32"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
    74         "i64.load8_s":         { "category": "memory",     "value":  36, "return": ["i64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
    75         "i64.load8_u":         { "category": "memory",     "value":  37, "return": ["i64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
    76         "i64.load16_s":        { "category": "memory",     "value":  38, "return": ["i64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
    77         "i64.load16_u":        { "category": "memory",     "value":  39, "return": ["i64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
    78         "i64.load32_s":        { "category": "memory",     "value":  40, "return": ["i64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
    79         "i64.load32_u":        { "category": "memory",     "value":  41, "return": ["i64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
    80         "i32.load":            { "category": "memory",     "value":  42, "return": ["i32"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
    81         "i64.load":            { "category": "memory",     "value":  43, "return": ["i64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
    82         "f32.load":            { "category": "memory",     "value":  44, "return": ["f32"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
    83         "f64.load":            { "category": "memory",     "value":  45, "return": ["f64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
    84         "i32.store8":          { "category": "memory",     "value":  46, "return": [],           "parameter": ["addr", "i32"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
    85         "i32.store16":         { "category": "memory",     "value":  47, "return": [],           "parameter": ["addr", "i32"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
    86         "i64.store8":          { "category": "memory",     "value":  48, "return": [],           "parameter": ["addr", "i64"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
    87         "i64.store16":         { "category": "memory",     "value":  49, "return": [],           "parameter": ["addr", "i64"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
    88         "i64.store32":         { "category": "memory",     "value":  50, "return": [],           "parameter": ["addr", "i64"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
    89         "i32.store":           { "category": "memory",     "value":  51, "return": [],           "parameter": ["addr", "i32"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
    90         "i64.store":           { "category": "memory",     "value":  52, "return": [],           "parameter": ["addr", "i64"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
    91         "f32.store":           { "category": "memory",     "value":  53, "return": [],           "parameter": ["addr", "f32"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
    92         "f64.store":           { "category": "memory",     "value":  54, "return": [],           "parameter": ["addr", "f64"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
    93         "current_memory":      { "category": "operation",  "value":  59, "return": ["size"],     "parameter": [],                       "immediate": [],                                                                                         "description": "query the size of memory" },
    94         "grow_memory":         { "category": "operation",  "value":  57, "return": ["size"],     "parameter": ["size"],                 "immediate": [],                                                                                         "description": "grow the size of memory" },
    95         "i32.add":             { "category": "arithmetic", "value":  64, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Add"          },
    96         "i32.sub":             { "category": "arithmetic", "value":  65, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Sub"          },
    97         "i32.mul":             { "category": "arithmetic", "value":  66, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Mul"          },
    98         "i32.div_s":           { "category": "arithmetic", "value":  67, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Div"          },
    99         "i32.div_u":           { "category": "arithmetic", "value":  68, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "UDiv"         },
    100         "i32.rem_s":           { "category": "arithmetic", "value":  69, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Mod"          },
    101         "i32.rem_u":           { "category": "arithmetic", "value":  70, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "UMod"         },
    102         "i32.and":             { "category": "arithmetic", "value":  71, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "BitAnd"       },
    103         "i32.or":              { "category": "arithmetic", "value":  72, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "BitOr"        },
    104         "i32.xor":             { "category": "arithmetic", "value":  73, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "BitXor"       },
    105         "i32.shl":             { "category": "arithmetic", "value":  74, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Shl"          },
    106         "i32.shr_u":           { "category": "arithmetic", "value":  75, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "SShr"         },
    107         "i32.shr_s":           { "category": "arithmetic", "value":  76, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "ZShr"         },
    108         "i32.rotr":            { "category": "arithmetic", "value": 182, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "RotR"         },
    109         "i32.rotl":            { "category": "arithmetic", "value": 183, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "RotL"         },
    110         "i32.eq":              { "category": "comparison", "value":  77, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Equal"        },
    111         "i32.ne":              { "category": "comparison", "value":  78, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "NotEqual"     },
    112         "i32.lt_s":            { "category": "comparison", "value":  79, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "LessThan"     },
    113         "i32.le_s":            { "category": "comparison", "value":  80, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "LessEqual"    },
    114         "i32.lt_u":            { "category": "comparison", "value":  81, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Below"        },
    115         "i32.le_u":            { "category": "comparison", "value":  82, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "BelowEqual"   },
    116         "i32.gt_s":            { "category": "comparison", "value":  83, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "GreaterThan"  },
    117         "i32.ge_s":            { "category": "comparison", "value":  84, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "GreaterEqual" },
    118         "i32.gt_u":            { "category": "comparison", "value":  85, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Above"        },
    119         "i32.ge_u":            { "category": "comparison", "value":  86, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "AboveEqual"   },
    120         "i32.clz":             { "category": "arithmetic", "value":  87, "return": ["i32"],      "parameter": ["i32"],                  "immediate": [], "b3op": "Clz"          },
    121         "i32.ctz":             { "category": "arithmetic", "value":  88, "return": ["i32"],      "parameter": ["i32"],                  "immediate": []                         },
    122         "i32.popcnt":          { "category": "arithmetic", "value":  89, "return": ["i32"],      "parameter": ["i32"],                  "immediate": []                         },
    123         "i32.eqz":             { "category": "comparison", "value":  90, "return": ["bool"],     "parameter": ["i32"],                  "immediate": [], "b3op": "Equal(i32(0), @0)" },
    124         "i64.add":             { "category": "arithmetic", "value":  91, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Add"          },
    125         "i64.sub":             { "category": "arithmetic", "value":  92, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Sub"          },
    126         "i64.mul":             { "category": "arithmetic", "value":  93, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Mul"          },
    127         "i64.div_s":           { "category": "arithmetic", "value":  94, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Div"          },
    128         "i64.div_u":           { "category": "arithmetic", "value":  95, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "UDiv"         },
    129         "i64.rem_s":           { "category": "arithmetic", "value":  96, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Mod"          },
    130         "i64.rem_u":           { "category": "arithmetic", "value":  97, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "UDiv"         },
    131         "i64.and":             { "category": "arithmetic", "value":  98, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "BitAnd"       },
    132         "i64.or":              { "category": "arithmetic", "value":  99, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "BitOr"        },
    133         "i64.xor":             { "category": "arithmetic", "value": 100, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "BitXor"       },
    134         "i64.shl":             { "category": "arithmetic", "value": 101, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Shl"          },
    135         "i64.shr_u":           { "category": "arithmetic", "value": 102, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "SShr"         },
    136         "i64.shr_s":           { "category": "arithmetic", "value": 103, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "ZShr"         },
    137         "i64.rotr":            { "category": "arithmetic", "value": 184, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "RotR"         },
    138         "i64.rotl":            { "category": "arithmetic", "value": 185, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "RotL"         },
    139         "i64.eq":              { "category": "comparison", "value": 104, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Equal"        },
    140         "i64.ne":              { "category": "comparison", "value": 105, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "NotEqual"     },
    141         "i64.lt_s":            { "category": "comparison", "value": 106, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "LessThan"     },
    142         "i64.le_s":            { "category": "comparison", "value": 107, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "LessEqual"    },
    143         "i64.lt_u":            { "category": "comparison", "value": 108, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Below"        },
    144         "i64.le_u":            { "category": "comparison", "value": 109, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "BelowEqual"   },
    145         "i64.gt_s":            { "category": "comparison", "value": 110, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "GreaterThan"  },
    146         "i64.ge_s":            { "category": "comparison", "value": 111, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "GreaterEqual" },
    147         "i64.gt_u":            { "category": "comparison", "value": 112, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Above"        },
    148         "i64.ge_u":            { "category": "comparison", "value": 113, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "AboveEqual"   },
    149         "i64.clz":             { "category": "arithmetic", "value": 114, "return": ["i64"],      "parameter": ["i64"],                  "immediate": [], "b3op": "Clz"          },
    150         "i64.ctz":             { "category": "arithmetic", "value": 115, "return": ["i64"],      "parameter": ["i64"],                  "immediate": []                         },
    151         "i64.popcnt":          { "category": "arithmetic", "value": 116, "return": ["i64"],      "parameter": ["i64"],                  "immediate": []                         },
    152         "i64.eqz":             { "category": "comparison", "value": 186, "return": ["bool"],     "parameter": ["i64"],                  "immediate": [], "b3op": "Equal(i32(0), @0)" },
    153         "f32.add":             { "category": "arithmetic", "value": 117, "return": ["f32"],      "parameter": ["f32", "f32"],           "immediate": [], "b3op": "Add"          },
    154         "f32.sub":             { "category": "arithmetic", "value": 118, "return": ["f32"],      "parameter": ["f32", "f32"],           "immediate": [], "b3op": "Sub"          },
    155         "f32.mul":             { "category": "arithmetic", "value": 119, "return": ["f32"],      "parameter": ["f32", "f32"],           "immediate": [], "b3op": "Mul"          },
    156         "f32.div":             { "category": "arithmetic", "value": 120, "return": ["f32"],      "parameter": ["f32", "f32"],           "immediate": [], "b3op": "Div"          },
    157         "f32.min":             { "category": "arithmetic", "value": 121, "return": ["f32"],      "parameter": ["f32", "f32"],           "immediate": [], "b3op": "Select(LessThan(@0, @1), @0, @1)" },
    158         "f32.max":             { "category": "arithmetic", "value": 122, "return": ["f32"],      "parameter": ["f32", "f32"],           "immediate": [], "b3op": "Select(LessThan(@0, @1), @1, @0)" },
    159         "f32.abs":             { "category": "arithmetic", "value": 123, "return": ["f32"],      "parameter": ["f32"],                  "immediate": [], "b3op": "Abs"          },
    160         "f32.neg":             { "category": "arithmetic", "value": 124, "return": ["f32"],      "parameter": ["f32"],                  "immediate": [], "b3op": "Neg"          },
    161         "f32.copysign":        { "category": "arithmetic", "value": 125, "return": ["f32"],      "parameter": ["f32"],                  "immediate": []                         },
    162         "f32.ceil":            { "category": "arithmetic", "value": 126, "return": ["f32"],      "parameter": ["f32"],                  "immediate": [], "b3op": "Ceil"         },
    163         "f32.floor":           { "category": "arithmetic", "value": 127, "return": ["f32"],      "parameter": ["f32"],                  "immediate": [], "b3op": "Floor"        },
    164         "f32.trunc":           { "category": "arithmetic", "value": 128, "return": ["f32"],      "parameter": ["f32"],                  "immediate": []                         },
    165         "f32.nearest":         { "category": "arithmetic", "value": 129, "return": ["f32"],      "parameter": ["f32"],                  "immediate": []                         },
    166         "f32.sqrt":            { "category": "arithmetic", "value": 130, "return": ["f32"],      "parameter": ["f32"],                  "immediate": [], "b3op": "Sqrt"         },
    167         "f32.eq":              { "category": "comparison", "value": 131, "return": ["bool"],     "parameter": ["f32", "f32"],           "immediate": [], "b3op": "Equal"        },
    168         "f32.ne":              { "category": "comparison", "value": 132, "return": ["bool"],     "parameter": ["f32", "f32"],           "immediate": [], "b3op": "NotEqual"     },
    169         "f32.lt":              { "category": "comparison", "value": 133, "return": ["bool"],     "parameter": ["f32", "f32"],           "immediate": [], "b3op": "LessThan"     },
    170         "f32.le":              { "category": "comparison", "value": 134, "return": ["bool"],     "parameter": ["f32", "f32"],           "immediate": [], "b3op": "LessEqual"    },
    171         "f32.gt":              { "category": "comparison", "value": 135, "return": ["bool"],     "parameter": ["f32", "f32"],           "immediate": [], "b3op": "GreaterThan"  },
    172         "f32.ge":              { "category": "comparison", "value": 136, "return": ["bool"],     "parameter": ["f32", "f32"],           "immediate": [], "b3op": "GreaterEqual" },
    173         "f64.add":             { "category": "arithmetic", "value": 137, "return": ["f64"],      "parameter": ["f64", "f64"],           "immediate": [], "b3op": "Add"          },
    174         "f64.sub":             { "category": "arithmetic", "value": 138, "return": ["f64"],      "parameter": ["f64", "f64"],           "immediate": [], "b3op": "Sub"          },
    175         "f64.mul":             { "category": "arithmetic", "value": 139, "return": ["f64"],      "parameter": ["f64", "f64"],           "immediate": [], "b3op": "Mul"          },
    176         "f64.div":             { "category": "arithmetic", "value": 140, "return": ["f64"],      "parameter": ["f64", "f64"],           "immediate": [], "b3op": "Div"          },
    177         "f64.min":             { "category": "arithmetic", "value": 141, "return": ["f64"],      "parameter": ["f64", "f64"],           "immediate": [], "b3op": "Select(LessThan(@0, @1), @0, @1)" },
    178         "f64.max":             { "category": "arithmetic", "value": 142, "return": ["f64"],      "parameter": ["f64", "f64"],           "immediate": [], "b3op": "Select(LessThan(@0, @1), @1, @0)" },
    179         "f64.abs":             { "category": "arithmetic", "value": 143, "return": ["f64"],      "parameter": ["f64"],                  "immediate": [], "b3op": "Abs"          },
    180         "f64.neg":             { "category": "arithmetic", "value": 144, "return": ["f64"],      "parameter": ["f64"],                  "immediate": [], "b3op": "Neg"          },
    181         "f64.copysign":        { "category": "arithmetic", "value": 145, "return": ["f64"],      "parameter": ["f64"],                  "immediate": []                         },
    182         "f64.ceil":            { "category": "arithmetic", "value": 146, "return": ["f64"],      "parameter": ["f64"],                  "immediate": [], "b3op": "Ceil"         },
    183         "f64.floor":           { "category": "arithmetic", "value": 147, "return": ["f64"],      "parameter": ["f64"],                  "immediate": [], "b3op": "Floor"        },
    184         "f64.trunc":           { "category": "arithmetic", "value": 148, "return": ["f64"],      "parameter": ["f64"],                  "immediate": []                         },
    185         "f64.nearest":         { "category": "arithmetic", "value": 149, "return": ["f64"],      "parameter": ["f64"],                  "immediate": []                         },
    186         "f64.sqrt":            { "category": "arithmetic", "value": 150, "return": ["f64"],      "parameter": ["f64"],                  "immediate": [], "b3op": "Sqrt"         },
    187         "f64.eq":              { "category": "comparison", "value": 151, "return": ["bool"],     "parameter": ["f64", "f64"],           "immediate": [], "b3op": "Equal"        },
    188         "f64.ne":              { "category": "comparison", "value": 152, "return": ["bool"],     "parameter": ["f64", "f64"],           "immediate": [], "b3op": "NotEqual"     },
    189         "f64.lt":              { "category": "comparison", "value": 153, "return": ["bool"],     "parameter": ["f64", "f64"],           "immediate": [], "b3op": "LessThan"     },
    190         "f64.le":              { "category": "comparison", "value": 154, "return": ["bool"],     "parameter": ["f64", "f64"],           "immediate": [], "b3op": "LessEqual"    },
    191         "f64.gt":              { "category": "comparison", "value": 155, "return": ["bool"],     "parameter": ["f64", "f64"],           "immediate": [], "b3op": "GreaterThan"  },
    192         "f64.ge":              { "category": "comparison", "value": 156, "return": ["bool"],     "parameter": ["f64", "f64"],           "immediate": [], "b3op": "GreaterEqual" },
    193         "i32.trunc_s/f32":     { "category": "conversion", "value": 157, "return": ["i32"],      "parameter": ["f32"],                  "immediate": []                         },
    194         "i32.trunc_s/f64":     { "category": "conversion", "value": 158, "return": ["i32"],      "parameter": ["f64"],                  "immediate": []                         },
    195         "i32.trunc_u/f32":     { "category": "conversion", "value": 159, "return": ["i32"],      "parameter": ["f32"],                  "immediate": []                         },
    196         "i32.trunc_u/f64":     { "category": "conversion", "value": 160, "return": ["i32"],      "parameter": ["f64"],                  "immediate": []                         },
    197         "i32.wrap/i64":        { "category": "conversion", "value": 161, "return": ["i32"],      "parameter": ["i64"],                  "immediate": []                         },
    198         "i64.trunc_s/f32":     { "category": "conversion", "value": 162, "return": ["i64"],      "parameter": ["f32"],                  "immediate": []                         },
    199         "i64.trunc_s/f64":     { "category": "conversion", "value": 163, "return": ["i64"],      "parameter": ["f64"],                  "immediate": []                         },
    200         "i64.trunc_u/f32":     { "category": "conversion", "value": 164, "return": ["i64"],      "parameter": ["f32"],                  "immediate": []                         },
    201         "i64.trunc_u/f64":     { "category": "conversion", "value": 165, "return": ["i64"],      "parameter": ["f64"],                  "immediate": []                         },
    202         "i64.extend_s/i32":    { "category": "conversion", "value": 166, "return": ["i64"],      "parameter": ["i32"],                  "immediate": [], "b3op": "SExt32"       },
    203         "i64.extend_u/i32":    { "category": "conversion", "value": 167, "return": ["i64"],      "parameter": ["i32"],                  "immediate": [], "b3op": "ZExt32"       },
    204         "f32.convert_s/i32":   { "category": "conversion", "value": 168, "return": ["f32"],      "parameter": ["i32"],                  "immediate": []                         },
    205         "f32.convert_u/i32":   { "category": "conversion", "value": 169, "return": ["f32"],      "parameter": ["i32"],                  "immediate": []                         },
    206         "f32.convert_s/i64":   { "category": "conversion", "value": 170, "return": ["f32"],      "parameter": ["i64"],                  "immediate": []                         },
    207         "f32.convert_u/i64":   { "category": "conversion", "value": 171, "return": ["f32"],      "parameter": ["i64"],                  "immediate": []                         },
    208         "f32.demote/f64":      { "category": "conversion", "value": 172, "return": ["f32"],      "parameter": ["f64"],                  "immediate": [], "b3op": "DoubleToFloat"},
    209         "f32.reinterpret/i32": { "category": "conversion", "value": 173, "return": ["f32"],      "parameter": ["i32"],                  "immediate": [], "b3op": "BitwiseCast"  },
    210         "f64.convert_s/i32":   { "category": "conversion", "value": 174, "return": ["f64"],      "parameter": ["i32"],                  "immediate": []                         },
    211         "f64.convert_u/i32":   { "category": "conversion", "value": 175, "return": ["f64"],      "parameter": ["i32"],                  "immediate": []                         },
    212         "f64.convert_s/i64":   { "category": "conversion", "value": 176, "return": ["f64"],      "parameter": ["i64"],                  "immediate": []                         },
    213         "f64.convert_u/i64":   { "category": "conversion", "value": 177, "return": ["f64"],      "parameter": ["i64"],                  "immediate": []                         },
    214         "f64.promote/f32":     { "category": "conversion", "value": 178, "return": ["f64"],      "parameter": ["f32"],                  "immediate": [], "b3op": "FloatToDouble"},
    215         "f64.reinterpret/i64": { "category": "conversion", "value": 179, "return": ["f64"],      "parameter": ["i64"],                  "immediate": [], "b3op": "BitwiseCast"  },
    216         "i32.reinterpret/f32": { "category": "conversion", "value": 180, "return": ["i32"],      "parameter": ["f32"],                  "immediate": [], "b3op": "BitwiseCast"  },
    217         "i64.reinterpret/f64": { "category": "conversion", "value": 181, "return": ["i64"],      "parameter": ["f64"],                  "immediate": [], "b3op": "BitwiseCast"  }
     53        "return":              { "category": "control",    "value":  15, "return": [],           "parameter": [],                       "immediate": [],                                                                                         "description": "return zero or one value from this function" },
     54        "drop":                { "category": "control",    "value":  26, "return": [],           "parameter": ["any"],                  "immediate": [],                                                                                         "description": "ignore value" },
     55        "nop":                 { "category": "control",    "value":   1, "return": [],           "parameter": [],                       "immediate": [],                                                                                         "description": "no operation" },
     56        "end":                 { "category": "control",    "value":  11, "return": [],           "parameter": [],                       "immediate": [],                                                                                         "description": "end a block, loop, or if" },
     57        "i32.const":           { "category": "special",    "value":  65, "return": ["i32"],      "parameter": [],                       "immediate": [{"name": "value",          "type": "varint32"}],                                           "description": "a constant value interpreted as i32" },
     58        "i64.const":           { "category": "special",    "value":  66, "return": ["i64"],      "parameter": [],                       "immediate": [{"name": "value",          "type": "varint64"}],                                           "description": "a constant value interpreted as i64" },
     59        "f64.const":           { "category": "special",    "value":  68, "return": ["f64"],      "parameter": [],                       "immediate": [{"name": "value",          "type": "uint64"}],                                             "description": "a constant value interpreted as f64" },
     60        "f32.const":           { "category": "special",    "value":  67, "return": ["f32"],      "parameter": [],                       "immediate": [{"name": "value",          "type": "uint32"}],                                             "description": "a constant value interpreted as f32" },
     61        "get_local":           { "category": "special",    "value":  32, "return": ["local"],    "parameter": [],                       "immediate": [{"name": "local_index",    "type": "varuint32"}],                                          "description": "read a local variable or parameter" },
     62        "set_local":           { "category": "special",    "value":  33, "return": [],           "parameter": ["local"],                "immediate": [{"name": "local_index",    "type": "varuint32"}],                                          "description": "write a local variable or parameter" },
     63        "tee_local":           { "category": "special",    "value":  34, "return": ["prev"],     "parameter": ["any"],                  "immediate": [{"name": "local_index",    "type": "varuint32"}],                                          "description": "write a local variable or parameter and return the same value" },
     64        "get_global":          { "category": "special",    "value":  35, "return": ["global"],   "parameter": [],                       "immediate": [{"name": "global_index",   "type": "varuint32"}],                                          "description": "read a global variable" },
     65        "set_global":          { "category": "special",    "value":  36, "return": [""],         "parameter": ["global"],               "immediate": [{"name": "global_index",   "type": "varuint32"}],                                          "description": "write a global variable" },
     66        "call":                { "category": "call",       "value":  16, "return": ["call"],     "parameter": ["call"],                 "immediate": [{"name": "function_index", "type": "varuint32"}],                                          "description": "call a function by its index" },
     67        "call_indirect":       { "category": "call",       "value":  17, "return": ["call"],     "parameter": ["call"],                 "immediate": [{"name": "type_index",     "type": "varuint32"}],                                          "description": "call a function indirect with an expected signature" },
     68        "i32.load8_s":         { "category": "memory",     "value":  44, "return": ["i32"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
     69        "i32.load8_u":         { "category": "memory",     "value":  45, "return": ["i32"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
     70        "i32.load16_s":        { "category": "memory",     "value":  46, "return": ["i32"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
     71        "i32.load16_u":        { "category": "memory",     "value":  47, "return": ["i32"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
     72        "i64.load8_s":         { "category": "memory",     "value":  48, "return": ["i64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
     73        "i64.load8_u":         { "category": "memory",     "value":  49, "return": ["i64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
     74        "i64.load16_s":        { "category": "memory",     "value":  50, "return": ["i64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
     75        "i64.load16_u":        { "category": "memory",     "value":  51, "return": ["i64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
     76        "i64.load32_s":        { "category": "memory",     "value":  52, "return": ["i64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
     77        "i64.load32_u":        { "category": "memory",     "value":  53, "return": ["i64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
     78        "i32.load":            { "category": "memory",     "value":  40, "return": ["i32"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
     79        "i64.load":            { "category": "memory",     "value":  41, "return": ["i64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
     80        "f32.load":            { "category": "memory",     "value":  42, "return": ["f32"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
     81        "f64.load":            { "category": "memory",     "value":  43, "return": ["f64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
     82        "i32.store8":          { "category": "memory",     "value":  58, "return": [],           "parameter": ["addr", "i32"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
     83        "i32.store16":         { "category": "memory",     "value":  59, "return": [],           "parameter": ["addr", "i32"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
     84        "i64.store8":          { "category": "memory",     "value":  60, "return": [],           "parameter": ["addr", "i64"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
     85        "i64.store16":         { "category": "memory",     "value":  61, "return": [],           "parameter": ["addr", "i64"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
     86        "i64.store32":         { "category": "memory",     "value":  62, "return": [],           "parameter": ["addr", "i64"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
     87        "i32.store":           { "category": "memory",     "value":  54, "return": [],           "parameter": ["addr", "i32"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
     88        "i64.store":           { "category": "memory",     "value":  55, "return": [],           "parameter": ["addr", "i64"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
     89        "f32.store":           { "category": "memory",     "value":  56, "return": [],           "parameter": ["addr", "f32"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
     90        "f64.store":           { "category": "memory",     "value":  57, "return": [],           "parameter": ["addr", "f64"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
     91        "current_memory":      { "category": "operation",  "value":  63, "return": ["size"],     "parameter": [],                       "immediate": [],                                                                                         "description": "query the size of memory" },
     92        "grow_memory":         { "category": "operation",  "value":  64, "return": ["size"],     "parameter": ["size"],                 "immediate": [],                                                                                         "description": "grow the size of memory" },
     93        "i32.add":             { "category": "arithmetic", "value": 106, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Add"          },
     94        "i32.sub":             { "category": "arithmetic", "value": 107, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Sub"          },
     95        "i32.mul":             { "category": "arithmetic", "value": 108, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Mul"          },
     96        "i32.div_s":           { "category": "arithmetic", "value": 109, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Div"          },
     97        "i32.div_u":           { "category": "arithmetic", "value": 110, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "UDiv"         },
     98        "i32.rem_s":           { "category": "arithmetic", "value": 111, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Mod"          },
     99        "i32.rem_u":           { "category": "arithmetic", "value": 112, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "UMod"         },
     100        "i32.and":             { "category": "arithmetic", "value": 113, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "BitAnd"       },
     101        "i32.or":              { "category": "arithmetic", "value": 114, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "BitOr"        },
     102        "i32.xor":             { "category": "arithmetic", "value": 115, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "BitXor"       },
     103        "i32.shl":             { "category": "arithmetic", "value": 116, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Shl"          },
     104        "i32.shr_u":           { "category": "arithmetic", "value": 118, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "SShr"         },
     105        "i32.shr_s":           { "category": "arithmetic", "value": 117, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "ZShr"         },
     106        "i32.rotr":            { "category": "arithmetic", "value": 120, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "RotR"         },
     107        "i32.rotl":            { "category": "arithmetic", "value": 119, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "RotL"         },
     108        "i32.eq":              { "category": "comparison", "value":  70, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Equal"        },
     109        "i32.ne":              { "category": "comparison", "value":  71, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "NotEqual"     },
     110        "i32.lt_s":            { "category": "comparison", "value":  72, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "LessThan"     },
     111        "i32.le_s":            { "category": "comparison", "value":  76, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "LessEqual"    },
     112        "i32.lt_u":            { "category": "comparison", "value":  73, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Below"        },
     113        "i32.le_u":            { "category": "comparison", "value":  77, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "BelowEqual"   },
     114        "i32.gt_s":            { "category": "comparison", "value":  74, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "GreaterThan"  },
     115        "i32.ge_s":            { "category": "comparison", "value":  78, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "GreaterEqual" },
     116        "i32.gt_u":            { "category": "comparison", "value":  75, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Above"        },
     117        "i32.ge_u":            { "category": "comparison", "value":  79, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "AboveEqual"   },
     118        "i32.clz":             { "category": "arithmetic", "value": 103, "return": ["i32"],      "parameter": ["i32"],                  "immediate": [], "b3op": "Clz"          },
     119        "i32.ctz":             { "category": "arithmetic", "value": 104, "return": ["i32"],      "parameter": ["i32"],                  "immediate": []                         },
     120        "i32.popcnt":          { "category": "arithmetic", "value": 105, "return": ["i32"],      "parameter": ["i32"],                  "immediate": []                         },
     121        "i32.eqz":             { "category": "comparison", "value":  69, "return": ["bool"],     "parameter": ["i32"],                  "immediate": [], "b3op": "Equal(i32(0), @0)" },
     122        "i64.add":             { "category": "arithmetic", "value": 124, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Add"          },
     123        "i64.sub":             { "category": "arithmetic", "value": 125, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Sub"          },
     124        "i64.mul":             { "category": "arithmetic", "value": 126, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Mul"          },
     125        "i64.div_s":           { "category": "arithmetic", "value": 127, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Div"          },
     126        "i64.div_u":           { "category": "arithmetic", "value": 128, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "UDiv"         },
     127        "i64.rem_s":           { "category": "arithmetic", "value": 129, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Mod"          },
     128        "i64.rem_u":           { "category": "arithmetic", "value": 130, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "UDiv"         },
     129        "i64.and":             { "category": "arithmetic", "value": 131, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "BitAnd"       },
     130        "i64.or":              { "category": "arithmetic", "value": 132, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "BitOr"        },
     131        "i64.xor":             { "category": "arithmetic", "value": 133, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "BitXor"       },
     132        "i64.shl":             { "category": "arithmetic", "value": 134, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Shl"          },
     133        "i64.shr_u":           { "category": "arithmetic", "value": 136, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "SShr"         },
     134        "i64.shr_s":           { "category": "arithmetic", "value": 135, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "ZShr"         },
     135        "i64.rotr":            { "category": "arithmetic", "value": 138, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "RotR"         },
     136        "i64.rotl":            { "category": "arithmetic", "value": 137, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "RotL"         },
     137        "i64.eq":              { "category": "comparison", "value":  81, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Equal"        },
     138        "i64.ne":              { "category": "comparison", "value":  82, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "NotEqual"     },
     139        "i64.lt_s":            { "category": "comparison", "value":  83, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "LessThan"     },
     140        "i64.le_s":            { "category": "comparison", "value":  87, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "LessEqual"    },
     141        "i64.lt_u":            { "category": "comparison", "value":  84, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Below"        },
     142        "i64.le_u":            { "category": "comparison", "value":  88, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "BelowEqual"   },
     143        "i64.gt_s":            { "category": "comparison", "value":  85, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "GreaterThan"  },
     144        "i64.ge_s":            { "category": "comparison", "value":  89, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "GreaterEqual" },
     145        "i64.gt_u":            { "category": "comparison", "value":  86, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Above"        },
     146        "i64.ge_u":            { "category": "comparison", "value":  90, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "AboveEqual"   },
     147        "i64.clz":             { "category": "arithmetic", "value": 121, "return": ["i64"],      "parameter": ["i64"],                  "immediate": [], "b3op": "Clz"          },
     148        "i64.ctz":             { "category": "arithmetic", "value": 122, "return": ["i64"],      "parameter": ["i64"],                  "immediate": []                         },
     149        "i64.popcnt":          { "category": "arithmetic", "value": 123, "return": ["i64"],      "parameter": ["i64"],                  "immediate": []                         },
     150        "i64.eqz":             { "category": "comparison", "value":  80, "return": ["bool"],     "parameter": ["i64"],                  "immediate": [], "b3op": "Equal(i32(0), @0)" },
     151        "f32.add":             { "category": "arithmetic", "value": 146, "return": ["f32"],      "parameter": ["f32", "f32"],           "immediate": [], "b3op": "Add"          },
     152        "f32.sub":             { "category": "arithmetic", "value": 147, "return": ["f32"],      "parameter": ["f32", "f32"],           "immediate": [], "b3op": "Sub"          },
     153        "f32.mul":             { "category": "arithmetic", "value": 148, "return": ["f32"],      "parameter": ["f32", "f32"],           "immediate": [], "b3op": "Mul"          },
     154        "f32.div":             { "category": "arithmetic", "value": 149, "return": ["f32"],      "parameter": ["f32", "f32"],           "immediate": [], "b3op": "Div"          },
     155        "f32.min":             { "category": "arithmetic", "value": 150, "return": ["f32"],      "parameter": ["f32", "f32"],           "immediate": [], "b3op": "Select(LessThan(@0, @1), @0, @1)" },
     156        "f32.max":             { "category": "arithmetic", "value": 151, "return": ["f32"],      "parameter": ["f32", "f32"],           "immediate": [], "b3op": "Select(LessThan(@0, @1), @1, @0)" },
     157        "f32.abs":             { "category": "arithmetic", "value": 139, "return": ["f32"],      "parameter": ["f32"],                  "immediate": [], "b3op": "Abs"          },
     158        "f32.neg":             { "category": "arithmetic", "value": 140, "return": ["f32"],      "parameter": ["f32"],                  "immediate": [], "b3op": "Neg"          },
     159        "f32.copysign":        { "category": "arithmetic", "value": 152, "return": ["f32"],      "parameter": ["f32"],                  "immediate": []                         },
     160        "f32.ceil":            { "category": "arithmetic", "value": 141, "return": ["f32"],      "parameter": ["f32"],                  "immediate": [], "b3op": "Ceil"         },
     161        "f32.floor":           { "category": "arithmetic", "value": 142, "return": ["f32"],      "parameter": ["f32"],                  "immediate": [], "b3op": "Floor"        },
     162        "f32.trunc":           { "category": "arithmetic", "value": 143, "return": ["f32"],      "parameter": ["f32"],                  "immediate": []                         },
     163        "f32.nearest":         { "category": "arithmetic", "value": 144, "return": ["f32"],      "parameter": ["f32"],                  "immediate": []                         },
     164        "f32.sqrt":            { "category": "arithmetic", "value": 145, "return": ["f32"],      "parameter": ["f32"],                  "immediate": [], "b3op": "Sqrt"         },
     165        "f32.eq":              { "category": "comparison", "value":  91, "return": ["bool"],     "parameter": ["f32", "f32"],           "immediate": [], "b3op": "Equal"        },
     166        "f32.ne":              { "category": "comparison", "value":  92, "return": ["bool"],     "parameter": ["f32", "f32"],           "immediate": [], "b3op": "NotEqual"     },
     167        "f32.lt":              { "category": "comparison", "value":  93, "return": ["bool"],     "parameter": ["f32", "f32"],           "immediate": [], "b3op": "LessThan"     },
     168        "f32.le":              { "category": "comparison", "value":  95, "return": ["bool"],     "parameter": ["f32", "f32"],           "immediate": [], "b3op": "LessEqual"    },
     169        "f32.gt":              { "category": "comparison", "value":  94, "return": ["bool"],     "parameter": ["f32", "f32"],           "immediate": [], "b3op": "GreaterThan"  },
     170        "f32.ge":              { "category": "comparison", "value":  96, "return": ["bool"],     "parameter": ["f32", "f32"],           "immediate": [], "b3op": "GreaterEqual" },
     171        "f64.add":             { "category": "arithmetic", "value": 160, "return": ["f64"],      "parameter": ["f64", "f64"],           "immediate": [], "b3op": "Add"          },
     172        "f64.sub":             { "category": "arithmetic", "value": 161, "return": ["f64"],      "parameter": ["f64", "f64"],           "immediate": [], "b3op": "Sub"          },
     173        "f64.mul":             { "category": "arithmetic", "value": 162, "return": ["f64"],      "parameter": ["f64", "f64"],           "immediate": [], "b3op": "Mul"          },
     174        "f64.div":             { "category": "arithmetic", "value": 163, "return": ["f64"],      "parameter": ["f64", "f64"],           "immediate": [], "b3op": "Div"          },
     175        "f64.min":             { "category": "arithmetic", "value": 164, "return": ["f64"],      "parameter": ["f64", "f64"],           "immediate": [], "b3op": "Select(LessThan(@0, @1), @0, @1)" },
     176        "f64.max":             { "category": "arithmetic", "value": 165, "return": ["f64"],      "parameter": ["f64", "f64"],           "immediate": [], "b3op": "Select(LessThan(@0, @1), @1, @0)" },
     177        "f64.abs":             { "category": "arithmetic", "value": 153, "return": ["f64"],      "parameter": ["f64"],                  "immediate": [], "b3op": "Abs"          },
     178        "f64.neg":             { "category": "arithmetic", "value": 154, "return": ["f64"],      "parameter": ["f64"],                  "immediate": [], "b3op": "Neg"          },
     179        "f64.copysign":        { "category": "arithmetic", "value": 166, "return": ["f64"],      "parameter": ["f64"],                  "immediate": []                         },
     180        "f64.ceil":            { "category": "arithmetic", "value": 155, "return": ["f64"],      "parameter": ["f64"],                  "immediate": [], "b3op": "Ceil"         },
     181        "f64.floor":           { "category": "arithmetic", "value": 156, "return": ["f64"],      "parameter": ["f64"],                  "immediate": [], "b3op": "Floor"        },
     182        "f64.trunc":           { "category": "arithmetic", "value": 157, "return": ["f64"],      "parameter": ["f64"],                  "immediate": []                         },
     183        "f64.nearest":         { "category": "arithmetic", "value": 158, "return": ["f64"],      "parameter": ["f64"],                  "immediate": []                         },
     184        "f64.sqrt":            { "category": "arithmetic", "value": 159, "return": ["f64"],      "parameter": ["f64"],                  "immediate": [], "b3op": "Sqrt"         },
     185        "f64.eq":              { "category": "comparison", "value":  97, "return": ["bool"],     "parameter": ["f64", "f64"],           "immediate": [], "b3op": "Equal"        },
     186        "f64.ne":              { "category": "comparison", "value":  98, "return": ["bool"],     "parameter": ["f64", "f64"],           "immediate": [], "b3op": "NotEqual"     },
     187        "f64.lt":              { "category": "comparison", "value":  99, "return": ["bool"],     "parameter": ["f64", "f64"],           "immediate": [], "b3op": "LessThan"     },
     188        "f64.le":              { "category": "comparison", "value": 101, "return": ["bool"],     "parameter": ["f64", "f64"],           "immediate": [], "b3op": "LessEqual"    },
     189        "f64.gt":              { "category": "comparison", "value": 100, "return": ["bool"],     "parameter": ["f64", "f64"],           "immediate": [], "b3op": "GreaterThan"  },
     190        "f64.ge":              { "category": "comparison", "value": 102, "return": ["bool"],     "parameter": ["f64", "f64"],           "immediate": [], "b3op": "GreaterEqual" },
     191        "i32.trunc_s/f32":     { "category": "conversion", "value": 168, "return": ["i32"],      "parameter": ["f32"],                  "immediate": []                         },
     192        "i32.trunc_s/f64":     { "category": "conversion", "value": 170, "return": ["i32"],      "parameter": ["f64"],                  "immediate": []                         },
     193        "i32.trunc_u/f32":     { "category": "conversion", "value": 169, "return": ["i32"],      "parameter": ["f32"],                  "immediate": []                         },
     194        "i32.trunc_u/f64":     { "category": "conversion", "value": 171, "return": ["i32"],      "parameter": ["f64"],                  "immediate": []                         },
     195        "i32.wrap/i64":        { "category": "conversion", "value": 167, "return": ["i32"],      "parameter": ["i64"],                  "immediate": []                         },
     196        "i64.trunc_s/f32":     { "category": "conversion", "value": 174, "return": ["i64"],      "parameter": ["f32"],                  "immediate": []                         },
     197        "i64.trunc_s/f64":     { "category": "conversion", "value": 176, "return": ["i64"],      "parameter": ["f64"],                  "immediate": []                         },
     198        "i64.trunc_u/f32":     { "category": "conversion", "value": 175, "return": ["i64"],      "parameter": ["f32"],                  "immediate": []                         },
     199        "i64.trunc_u/f64":     { "category": "conversion", "value": 177, "return": ["i64"],      "parameter": ["f64"],                  "immediate": []                         },
     200        "i64.extend_s/i32":    { "category": "conversion", "value": 172, "return": ["i64"],      "parameter": ["i32"],                  "immediate": [], "b3op": "SExt32"       },
     201        "i64.extend_u/i32":    { "category": "conversion", "value": 173, "return": ["i64"],      "parameter": ["i32"],                  "immediate": [], "b3op": "ZExt32"       },
     202        "f32.convert_s/i32":   { "category": "conversion", "value": 178, "return": ["f32"],      "parameter": ["i32"],                  "immediate": []                         },
     203        "f32.convert_u/i32":   { "category": "conversion", "value": 179, "return": ["f32"],      "parameter": ["i32"],                  "immediate": []                         },
     204        "f32.convert_s/i64":   { "category": "conversion", "value": 180, "return": ["f32"],      "parameter": ["i64"],                  "immediate": []                         },
     205        "f32.convert_u/i64":   { "category": "conversion", "value": 181, "return": ["f32"],      "parameter": ["i64"],                  "immediate": []                         },
     206        "f32.demote/f64":      { "category": "conversion", "value": 182, "return": ["f32"],      "parameter": ["f64"],                  "immediate": [], "b3op": "DoubleToFloat"},
     207        "f32.reinterpret/i32": { "category": "conversion", "value": 190, "return": ["f32"],      "parameter": ["i32"],                  "immediate": [], "b3op": "BitwiseCast"  },
     208        "f64.convert_s/i32":   { "category": "conversion", "value": 183, "return": ["f64"],      "parameter": ["i32"],                  "immediate": []                         },
     209        "f64.convert_u/i32":   { "category": "conversion", "value": 184, "return": ["f64"],      "parameter": ["i32"],                  "immediate": []                         },
     210        "f64.convert_s/i64":   { "category": "conversion", "value": 185, "return": ["f64"],      "parameter": ["i64"],                  "immediate": []                         },
     211        "f64.convert_u/i64":   { "category": "conversion", "value": 186, "return": ["f64"],      "parameter": ["i64"],                  "immediate": []                         },
     212        "f64.promote/f32":     { "category": "conversion", "value": 187, "return": ["f64"],      "parameter": ["f32"],                  "immediate": [], "b3op": "FloatToDouble"},
     213        "f64.reinterpret/i64": { "category": "conversion", "value": 191, "return": ["f64"],      "parameter": ["i64"],                  "immediate": [], "b3op": "BitwiseCast"  },
     214        "i32.reinterpret/f32": { "category": "conversion", "value": 188, "return": ["i32"],      "parameter": ["f32"],                  "immediate": [], "b3op": "BitwiseCast"  },
     215        "i64.reinterpret/f64": { "category": "conversion", "value": 189, "return": ["i64"],      "parameter": ["f64"],                  "immediate": [], "b3op": "BitwiseCast"  }
    218216    }
    219217}
  • trunk/Source/JavaScriptCore/ChangeLog

    r209173 r209175  
     12016-11-30  JF Bastien  <jfbastien@apple.com>
     2
     3        WebAssembly: update binary format to 0xD version
     4        https://bugs.webkit.org/show_bug.cgi?id=164724
     5
     6        Reviewed by Saam Barati.
     7
     8        As described in the following PR: https://github.com/WebAssembly/design/pull/836
     9
     10        * wasm/WasmB3IRGenerator.cpp:
     11        (JSC::Wasm::B3IRGenerator::B3IRGenerator):
     12        (JSC::Wasm::B3IRGenerator::zeroForType):
     13        (JSC::Wasm::B3IRGenerator::addConstant):
     14        (JSC::Wasm::createJSWrapper):
     15        * wasm/WasmCallingConvention.h:
     16        (JSC::Wasm::CallingConvention::marshallArgument):
     17        * wasm/WasmFormat.cpp:
     18        (JSC::Wasm::toString): Deleted.
     19        * wasm/WasmFormat.h:
     20        (JSC::Wasm::isValueType):
     21        (JSC::Wasm::toB3Type): Deleted.
     22        * wasm/WasmFunctionParser.h:
     23        (JSC::Wasm::FunctionParser<Context>::parseExpression):
     24        * wasm/WasmModuleParser.cpp:
     25        (JSC::Wasm::ModuleParser::parse):
     26        (JSC::Wasm::ModuleParser::parseType):
     27        * wasm/WasmModuleParser.h:
     28        * wasm/WasmParser.h:
     29        (JSC::Wasm::Parser::parseResultType):
     30        * wasm/generateWasm.py:
     31        (Wasm.__init__):
     32        * wasm/generateWasmOpsHeader.py:
     33        (cppMacro):
     34        (typeMacroizer):
     35        (opcodeMacroizer):
     36        * wasm/wasm.json:
     37
    1382016-11-30  Darin Adler  <darin@apple.com>
    239
  • trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp

    r209083 r209175  
    187187    GPRReg m_memoryBaseGPR;
    188188    GPRReg m_memorySizeGPR;
    189     Value* m_zeroValues[Type::LastValueType];
     189    Value* m_zeroValues[numTypes];
    190190};
    191191
     
    197197    m_currentBlock = m_proc.addBlock();
    198198
    199     for (unsigned i = 0; i < Type::LastValueType; ++i)
    200         m_zeroValues[i] = m_currentBlock->appendIntConstant(m_proc, Origin(), toB3Type(static_cast<Type>(i + 1)), 0);
     199    for (unsigned i = 0; i < numTypes; ++i) {
     200        switch (B3::Type b3Type = toB3Type(linearizedToType(i))) {
     201        case B3::Int32:
     202        case B3::Int64:
     203        case B3::Float:
     204        case B3::Double:
     205            m_zeroValues[i] = m_currentBlock->appendIntConstant(m_proc, Origin(), b3Type, 0);
     206            break;
     207        case B3::Void:
     208            m_zeroValues[i] = nullptr;
     209            break;
     210        }
     211    }
    201212
    202213    if (m_memory) {
     
    219230{
    220231    ASSERT(type != Void);
    221     return m_zeroValues[type - 1];
     232    Value* zeroValue = m_zeroValues[linearizeType(type)];
     233    ASSERT(zeroValue);
     234    return zeroValue;
    222235}
    223236
     
    442455{
    443456    switch (type) {
    444     case Int32:
     457    case Wasm::I32:
    445458        return m_currentBlock->appendNew<Const32Value>(m_proc, Origin(), static_cast<int32_t>(value));
    446     case Int64:
     459    case Wasm::I64:
    447460        return m_currentBlock->appendNew<Const64Value>(m_proc, Origin(), value);
    448     case Float:
     461    case Wasm::F32:
    449462        return m_currentBlock->appendNew<ConstFloatValue>(m_proc, Origin(), bitwise_cast<float>(static_cast<int32_t>(value)));
    450     case Double:
     463    case Wasm::F64:
    451464        return m_currentBlock->appendNew<ConstDoubleValue>(m_proc, Origin(), bitwise_cast<double>(value));
    452     default:
    453         RELEASE_ASSERT_NOT_REACHED();
    454         return nullptr;
    455     }
     465    case Wasm::Void:
     466    case Wasm::Func:
     467    case Wasm::Anyfunc:
     468        break;
     469    }
     470    RELEASE_ASSERT_NOT_REACHED();
     471    return nullptr;
    456472}
    457473
     
    702718    // Return the result, if needed.
    703719    switch (signature->returnType) {
    704     case Void:
     720    case Wasm::Void:
    705721        block->appendNewControlValue(proc, B3::Return, Origin());
    706722        break;
    707     case F32:
    708     case F64:
     723    case Wasm::F32:
     724    case Wasm::F64:
    709725        result = block->appendNew<Value>(proc, BitwiseCast, Origin(), result);
    710726        FALLTHROUGH;
    711     case I32:
    712     case I64:
     727    case Wasm::I32:
     728    case Wasm::I64:
    713729        block->appendNewControlValue(proc, B3::Return, Origin(), result);
    714730        break;
     731    case Wasm::Func:
     732    case Wasm::Anyfunc:
     733        RELEASE_ASSERT_NOT_REACHED();
    715734    }
    716735
  • trunk/Source/JavaScriptCore/wasm/WasmCallingConvention.h

    r207781 r209175  
    7777        case B3::Double:
    7878            return marshallArgumentImpl(m_fprArgs, type, fpArgumentCount, stackOffset);
    79         case Void:
     79        case B3::Void:
    8080            break;
    8181        }
  • trunk/Source/JavaScriptCore/wasm/WasmFormat.cpp

    r209171 r209175  
    3232#include "WasmMemory.h"
    3333
    34 #if COMPILER(GCC) && ASSERT_DISABLED
    35 #pragma GCC diagnostic push
    36 #pragma GCC diagnostic ignored "-Wreturn-type"
    37 #endif // COMPILER(GCC) && ASSERT_DISABLED
    38 
    3934namespace JSC { namespace Wasm {
    40 
    41 const char* toString(Type type)
    42 {
    43     switch (type) {
    44     case Void:
    45         return "void";
    46     case I32:
    47         return "i32";
    48     case I64:
    49         return "i64";
    50     case F32:
    51         return "f32";
    52     case F64:
    53         return "f64";
    54     }
    55 }
    5635
    5736ModuleInformation::~ModuleInformation() { }
     
    5938} } // namespace JSC::Wasm
    6039
    61 #if COMPILER(GCC) && ASSERT_DISABLED
    62 #pragma GCC diagnostic pop
    63 #endif // COMPILER(GCC) && ASSERT_DISABLED
    64 
    6540#endif // ENABLE(WEBASSEMBLY)
  • trunk/Source/JavaScriptCore/wasm/WasmFormat.h

    r209123 r209175  
    3232#include "CodeLocation.h"
    3333#include "Identifier.h"
     34#include "WasmOps.h"
    3435#include <wtf/Vector.h>
    3536
     
    3940
    4041namespace Wasm {
    41 
    42 enum Type : uint8_t {
    43     Void,
    44     I32,
    45     I64,
    46     F32,
    47     F64,
    48     LastValueType = F64,
    49 };
    50 
    51 static_assert(I32 == 1, "Wasm needs I32 to have the value 1");
    52 static_assert(I64 == 2, "Wasm needs I64 to have the value 2");
    53 static_assert(F32 == 3, "Wasm needs F32 to have the value 3");
    54 static_assert(F64 == 4, "Wasm needs F64 to have the value 4");
    55 
    56 inline B3::Type toB3Type(Type type)
    57 {
    58     switch (type) {
    59     case I32: return B3::Int32;
    60     case I64: return B3::Int64;
    61     case F32: return B3::Float;
    62     case F64: return B3::Double;
    63     case Void: return B3::Void;
    64     default: break;
    65     }
    66     RELEASE_ASSERT_NOT_REACHED();
    67 }
    6842
    6943inline bool isValueType(Type type)
     
    8054    return false;
    8155}
    82 
    83 const char* toString(Type);
    8456   
    8557struct External {
    8658    enum Kind : uint8_t {
     59        // FIXME auto-generate this. https://bugs.webkit.org/show_bug.cgi?id=165231
    8760        Function = 0,
    8861        Table = 1,
  • trunk/Source/JavaScriptCore/wasm/WasmFunctionParser.h

    r209083 r209175  
    208208{
    209209    switch (op) {
    210 #define CREATE_CASE(name, id, b3op) case OpType::name: return binaryCase<OpType::name>();
     210#define CREATE_CASE(name, id, b3op, inc) case OpType::name: return binaryCase<OpType::name>();
    211211    FOR_EACH_WASM_SIMPLE_BINARY_OP(CREATE_CASE)
    212212#undef CREATE_CASE
    213213
    214 #define CREATE_CASE(name, id, b3op) case OpType::name: return unaryCase<OpType::name>();
     214#define CREATE_CASE(name, id, b3op, inc) case OpType::name: return unaryCase<OpType::name>();
    215215    FOR_EACH_WASM_SIMPLE_UNARY_OP(CREATE_CASE)
    216216#undef CREATE_CASE
     
    237237    }
    238238
    239 #define CREATE_CASE(name, id, b3op) case OpType::name:
     239#define CREATE_CASE(name, id, b3op, inc) case OpType::name:
    240240    FOR_EACH_WASM_MEMORY_LOAD_OP(CREATE_CASE) {
    241241        uint32_t alignment;
  • trunk/Source/JavaScriptCore/wasm/WasmModuleParser.cpp

    r209123 r209175  
    5555    }
    5656
    57     // Skip the version number for now since we don't do anything with it.
    5857    uint32_t versionNumber;
    5958    if (!parseUInt32(versionNumber)) {
     
    6362    }
    6463
    65     if (versionNumber != magicNumber) {
     64    if (versionNumber != expectedVersionNumber) {
    6665        // FIXME improve error message https://bugs.webkit.org/show_bug.cgi?id=163919
    6766        m_errorMessage = "unexpected version number";
     
    170169        if (!parseInt7(type))
    171170            return false;
    172         if (type != -0x20) // Function type constant. FIXME auto-generate from JSON file.
     171        if (type != Func)
    173172            return false;
    174173
  • trunk/Source/JavaScriptCore/wasm/WasmModuleParser.h

    r209123 r209175  
    3838public:
    3939
    40     static const unsigned magicNumber = 0xc;
    41 
    4240    ModuleParser(VM* vm, const uint8_t* sourceBuffer, size_t sourceLength)
    4341        : Parser(sourceBuffer, sourceLength)
  • trunk/Source/JavaScriptCore/wasm/WasmParser.h

    r209083 r209175  
    170170ALWAYS_INLINE bool Parser::parseResultType(Type& result)
    171171{
    172     uint8_t value;
    173     if (!parseUInt7(value))
     172    int8_t value;
     173    if (!parseInt7(value))
    174174        return false;
    175     if (value > static_cast<uint8_t>(Type::LastValueType))
     175    if (!isValidType(value))
    176176        return false;
    177177    result = static_cast<Type>(value);
  • trunk/Source/JavaScriptCore/wasm/generateWasm.py

    r208821 r209175  
    3434        wasm = json.load(open(jsonPath, "r"))
    3535        wasmFile.close()
     36        for pre in wasm["preamble"]:
     37            if pre["name"] == "version":
     38                self.expectedVersionNumber = str(pre["value"])
     39        self.preamble = wasm["preamble"]
     40        self.types = wasm["type"]
    3641        self.opcodes = wasm["opcode"]
    3742        self.header = """/*
  • trunk/Source/JavaScriptCore/wasm/generateWasmOpsHeader.py

    r208821 r209175  
    3636
    3737wasm = Wasm(args[0], args[1])
     38types = wasm.types
    3839opcodes = wasm.opcodes
    3940wasmOpsHFile = open(args[2], "w")
    4041
    4142
    42 def cppMacro(wasmOpcode, value, b3Opcode):
    43     return " \\\n    macro(" + wasm.toCpp(wasmOpcode) + ", " + hex(int(value)) + ", " + b3Opcode + ")"
     43def cppMacro(wasmOpcode, value, b3, inc):
     44    return " \\\n    macro(" + wasm.toCpp(wasmOpcode) + ", " + hex(int(value)) + ", " + b3 + ", " + str(inc) + ")"
     45
     46
     47def typeMacroizer():
     48    inc = 0
     49    for ty in wasm.types:
     50        yield cppMacro(ty, wasm.types[ty]["value"], wasm.types[ty]["b3type"], inc)
     51        inc += 1
     52
     53type_definitions = ["#define FOR_EACH_WASM_TYPE(macro)"]
     54type_definitions.extend([t for t in typeMacroizer()])
     55type_definitions = "".join(type_definitions)
    4456
    4557
    4658def opcodeMacroizer(filter):
     59    inc = 0
    4760    for op in wasm.opcodeIterator(filter):
    4861        b3op = "Oops"
    4962        if isSimple(op["opcode"]):
    5063            b3op = op["opcode"]["b3op"]
    51         yield cppMacro(op["name"], op["opcode"]["value"], b3op)
     64        yield cppMacro(op["name"], op["opcode"]["value"], b3op, inc)
     65        inc += 1
    5266
    5367defines = ["#define FOR_EACH_WASM_SPECIAL_OP(macro)"]
     
    102116namespace JSC { namespace Wasm {
    103117
     118static constexpr unsigned expectedVersionNumber = """ + wasm.expectedVersionNumber + """;
     119
     120static constexpr unsigned numTypes = """ + str(len(types)) + """;
     121
     122""" + type_definitions + """
     123#define CREATE_ENUM_VALUE(name, id, b3type, inc) name = id,
     124enum Type : int8_t {
     125    FOR_EACH_WASM_TYPE(CREATE_ENUM_VALUE)
     126};
     127#undef CREATE_ENUM_VALUE
     128
     129#define CREATE_CASE(name, id, b3type, inc) case id: return true;
     130template <typename Int>
     131inline bool isValidType(Int i)
     132{
     133    switch (i) {
     134    default: return false;
     135    FOR_EACH_WASM_TYPE(CREATE_CASE)
     136    }
     137    RELEASE_ASSERT_NOT_REACHED();
     138    return false;
     139}
     140#undef CREATE_CASE
     141
     142#define CREATE_CASE(name, id, b3type, inc) case name: return b3type;
     143inline B3::Type toB3Type(Type type)
     144{
     145    switch (type) {
     146    FOR_EACH_WASM_TYPE(CREATE_CASE)
     147    }
     148    RELEASE_ASSERT_NOT_REACHED();
     149    return B3::Void;
     150}
     151#undef CREATE_CASE
     152
     153#define CREATE_CASE(name, id, b3type, inc) case name: return "name";
     154inline const char* toString(Type type)
     155{
     156    switch (type) {
     157    FOR_EACH_WASM_TYPE(CREATE_CASE)
     158    }
     159    RELEASE_ASSERT_NOT_REACHED();
     160    return nullptr;
     161}
     162#undef CREATE_CASE
     163
     164#define CREATE_CASE(name, id, b3type, inc) case id: return inc;
     165inline int linearizeType(Type type)
     166{
     167    switch (type) {
     168    FOR_EACH_WASM_TYPE(CREATE_CASE)
     169    }
     170    RELEASE_ASSERT_NOT_REACHED();
     171    return 0;
     172}
     173#undef CREATE_CASE
     174
     175#define CREATE_CASE(name, id, b3type, inc) case inc: return name;
     176inline Type linearizedToType(int i)
     177{
     178    switch (i) {
     179    FOR_EACH_WASM_TYPE(CREATE_CASE)
     180    }
     181    RELEASE_ASSERT_NOT_REACHED();
     182    return Void;
     183}
     184#undef CREATE_CASE
     185
     186
    104187""" + defines + """
    105188#define FOR_EACH_WASM_OP(macro) \\
     
    111194    FOR_EACH_WASM_MEMORY_STORE_OP(macro)
    112195
    113 #define CREATE_ENUM_VALUE(name, id, b3op) name = id,
     196#define CREATE_ENUM_VALUE(name, id, b3op, inc) name = id,
    114197
    115198enum OpType : uint8_t {
     
    146229{
    147230    switch (op) {
    148 #define CREATE_CASE(name, id, b3op) case OpType::name:
     231#define CREATE_CASE(name, id, b3op, inc) case OpType::name:
    149232    FOR_EACH_WASM_CONTROL_FLOW_OP(CREATE_CASE)
    150233        return true;
     
    159242{
    160243    switch (op) {
    161 #define CREATE_CASE(name, id, b3op) case UnaryOpType::name:
     244#define CREATE_CASE(name, id, b3op, inc) case UnaryOpType::name:
    162245    FOR_EACH_WASM_SIMPLE_UNARY_OP(CREATE_CASE)
    163246        return true;
     
    172255{
    173256    switch (op) {
    174 #define CREATE_CASE(name, id, b3op) case BinaryOpType::name:
     257#define CREATE_CASE(name, id, b3op, inc) case BinaryOpType::name:
    175258    FOR_EACH_WASM_SIMPLE_BINARY_OP(CREATE_CASE)
    176259        return true;
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp

    r209171 r209175  
    6464        JSValue arg = state->uncheckedArgument(argIndex);
    6565        switch (signature->arguments[argIndex]) {
    66         case Wasm::Void:
    67         case Wasm::I64:
    68             RELEASE_ASSERT_NOT_REACHED();
    69             break;
    7066        case Wasm::I32:
    7167            arg = JSValue::decode(arg.toInt32(state));
     
    7773            arg = JSValue::decode(bitwise_cast<uint64_t>(arg.toNumber(state)));
    7874            break;
     75        case Wasm::Void:
     76        case Wasm::I64:
     77        case Wasm::Func:
     78        case Wasm::Anyfunc:
     79            RELEASE_ASSERT_NOT_REACHED();
    7980        }
    8081        RETURN_IF_EXCEPTION(scope, encodedJSValue());
     
    100101    case Wasm::Void:
    101102        return JSValue::encode(jsUndefined());
    102     case Wasm::I64:
    103         RELEASE_ASSERT_NOT_REACHED();
    104103    case Wasm::I32:
    105104        return JSValue::encode(JSValue(static_cast<int32_t>(rawResult)));
     
    108107    case Wasm::F64:
    109108        return JSValue::encode(JSValue(bitwise_cast<double>(rawResult)));
     109    case Wasm::I64:
     110    case Wasm::Func:
     111    case Wasm::Anyfunc:
     112        break;
    110113    }
    111114
    112115    RELEASE_ASSERT_NOT_REACHED();
     116    return EncodedJSValue();
    113117}
    114118
  • trunk/Source/JavaScriptCore/wasm/wasm.json

    r209083 r209175  
    11{
    22    "comments": ["This file describes the WebAssembly ISA.",
    3                  "Scripts in this folder auto-generate C++ code for JavaScriptCore as well as the testing DSL which WebKit's WebAssembly tests use.",
    4                  "When you update this file you need to re-generate the C++ code: jsc ./JSTests/stress/wasm/generate-wasmops-header.js > ./Source/JavaScriptCore/wasm/WASMOps.h"
     3                 "Scripts in this folder auto-generate C++ code for JavaScriptCore as well as the testing DSL which WebKit's WebAssembly tests use."
    54                ],
    65    "preamble": [
    76        { "name": "magic number", "type": "uint32", "value": 1836278016, "description": "NULL character followed by 'asm'" },
    8         { "name": "version",      "type": "uint32", "value":         12, "description": "Version number, will be reset to 1 for MVP" }
     7        { "name": "version",      "type": "uint32", "value":         13, "description": "Version number, will be reset to 1 for MVP" }
    98    ],
    10     "value_type" : {
    11         "i32": { "type": "uint8", "value": 1 },
    12         "i64": { "type": "uint8", "value": 2 },
    13         "f32": { "type": "uint8", "value": 3 },
    14         "f64": { "type": "uint8", "value": 4 }
     9    "type" : {
     10        "i32":     { "type": "varint7", "value":  -1, "b3type": "B3::Int32" },
     11        "i64":     { "type": "varint7", "value":  -2, "b3type": "B3::Int64" },
     12        "f32":     { "type": "varint7", "value":  -3, "b3type": "B3::Float" },
     13        "f64":     { "type": "varint7", "value":  -4, "b3type": "B3::Double" },
     14        "anyfunc": { "type": "varint7", "value": -16, "b3type": "B3::Void" },
     15        "func":    { "type": "varint7", "value": -32, "b3type": "B3::Void" },
     16        "void":    { "type": "varint7", "value": -64, "b3type": "B3::Void" }
    1517    },
    16     "inline_signature_type" : {
    17         "void": { "type": "uint8", "value": 0 },
    18         "i32":  { "type": "uint8", "value": 1 },
    19         "i64":  { "type": "uint8", "value": 2 },
    20         "f32":  { "type": "uint8", "value": 3 },
    21         "f64":  { "type": "uint8", "value": 4 }
    22     },
     18    "value_type": ["i32", "i64", "f32", "f64"],
     19    "block_type": ["i32", "i64", "f32", "f64", "void"],
     20    "elem_type": ["anyfunc"],
    2321    "external_kind": {
    2422        "Function": { "type": "uint8", "value": 0 },
     
    4240    "opcode": {
    4341        "unreachable":         { "category": "control",    "value":   0, "return": [],           "parameter": [],                      "immediate": [],                                                                                         "description": "trap immediately" },
    44         "block":               { "category": "control",    "value":   1, "return": ["control"],  "parameter": [],                      "immediate": [{"name": "sig", "type": "inline_signature_type"}],                                         "description": "begin a sequence of expressions, yielding 0 or 1 values" },
    45         "loop":                { "category": "control",    "value":   2, "return": ["control"],  "parameter": [],                      "immediate": [{"name": "sig", "type": "inline_signature_type"}],                                         "description": "begin a block which can also form control flow loops" },
    46         "if":                  { "category": "control",    "value":   3, "return": ["control"],  "parameter": ["bool"],                "immediate": [{"name": "sig", "type": "inline_signature_type"}],                                         "description": "begin if expression" },
    47         "else":                { "category": "control",    "value":   4, "return": ["control"],  "parameter": [],                      "immediate": [],                                                                                         "description": "begin else expression of if" },
    48         "select":              { "category": "control",    "value":   5, "return": ["prev"],     "parameter": ["any", "prev", "bool"], "immediate": [],                                                                                         "description": "select one of two values based on condition" },
    49         "br":                  { "category": "control",    "value":   6, "return": [],           "parameter": [],                      "immediate": [{"name": "relative_depth", "type": "varuint32"}],                                          "description": "break that targets an outer nested block" },
    50         "br_if":               { "category": "control",    "value":   7, "return": [],           "parameter": [],                      "immediate": [{"name": "relative_depth", "type": "varuint32"}],                                          "description": "conditional break that targets an outer nested block" },
    51         "br_table":            { "category": "control",    "value":   8, "return": [],           "parameter": [],                      "immediate": [{"name": "target_count",   "type": "varuint32",                                            "description": "number of entries in the target_table"},
     42        "block":               { "category": "control",    "value":   2, "return": ["control"],  "parameter": [],                      "immediate": [{"name": "sig", "type": "block_type"}],                                                    "description": "begin a sequence of expressions, yielding 0 or 1 values" },
     43        "loop":                { "category": "control",    "value":   3, "return": ["control"],  "parameter": [],                      "immediate": [{"name": "sig", "type": "block_type"}],                                                    "description": "begin a block which can also form control flow loops" },
     44        "if":                  { "category": "control",    "value":   4, "return": ["control"],  "parameter": ["bool"],                "immediate": [{"name": "sig", "type": "block_type"}],                                                    "description": "begin if expression" },
     45        "else":                { "category": "control",    "value":   5, "return": ["control"],  "parameter": [],                      "immediate": [],                                                                                         "description": "begin else expression of if" },
     46        "select":              { "category": "control",    "value":  27, "return": ["prev"],     "parameter": ["any", "prev", "bool"], "immediate": [],                                                                                         "description": "select one of two values based on condition" },
     47        "br":                  { "category": "control",    "value":  12, "return": [],           "parameter": [],                      "immediate": [{"name": "relative_depth", "type": "varuint32"}],                                          "description": "break that targets an outer nested block" },
     48        "br_if":               { "category": "control",    "value":  13, "return": [],           "parameter": [],                      "immediate": [{"name": "relative_depth", "type": "varuint32"}],                                          "description": "conditional break that targets an outer nested block" },
     49        "br_table":            { "category": "control",    "value":  14, "return": [],           "parameter": [],                      "immediate": [{"name": "target_count",   "type": "varuint32",                                            "description": "number of entries in the target_table"},
    5250                                                                                                                                                     {"name": "target_table",   "type": "varuint32*",                                           "description": "target entries that indicate an outer block or loop to which to break"},
    5351                                                                                                                                                     {"name": "default_target", "type": "varuint32",                                            "description": "an outer block or loop to which to break in the default case"}],
    5452                                                                                                                                                                                                                                                "description": "branch table control flow construct" },
    55         "return":              { "category": "control",    "value":   9, "return": [],           "parameter": [],                       "immediate": [],                                                                                         "description": "return zero or one value from this function" },
    56         "drop":                { "category": "control",    "value":  11, "return": [],           "parameter": ["any"],                  "immediate": [],                                                                                         "description": "ignore value" },
    57         "nop":                 { "category": "control",    "value":  10, "return": [],           "parameter": [],                       "immediate": [],                                                                                         "description": "no operation" },
    58         "end":                 { "category": "control",    "value":  15, "return": [],           "parameter": [],                       "immediate": [],                                                                                         "description": "end a block, loop, or if" },
    59         "i32.const":           { "category": "special",    "value":  16, "return": ["i32"],      "parameter": [],                       "immediate": [{"name": "value",          "type": "varint32"}],                                           "description": "a constant value interpreted as i32" },
    60         "i64.const":           { "category": "special",    "value":  17, "return": ["i64"],      "parameter": [],                       "immediate": [{"name": "value",          "type": "varint64"}],                                           "description": "a constant value interpreted as i64" },
    61         "f64.const":           { "category": "special",    "value":  18, "return": ["f64"],      "parameter": [],                       "immediate": [{"name": "value",          "type": "uint64"}],                                             "description": "a constant value interpreted as f64" },
    62         "f32.const":           { "category": "special",    "value":  19, "return": ["f32"],      "parameter": [],                       "immediate": [{"name": "value",          "type": "uint32"}],                                             "description": "a constant value interpreted as f32" },
    63         "get_local":           { "category": "special",    "value":  20, "return": ["local"],    "parameter": [],                       "immediate": [{"name": "local_index",    "type": "varuint32"}],                                          "description": "read a local variable or parameter" },
    64         "set_local":           { "category": "special",    "value":  21, "return": [],           "parameter": ["local"],                "immediate": [{"name": "local_index",    "type": "varuint32"}],                                          "description": "write a local variable or parameter" },
    65         "tee_local":           { "category": "special",    "value":  25, "return": ["prev"],     "parameter": ["any"],                  "immediate": [{"name": "local_index",    "type": "varuint32"}],                                          "description": "write a local variable or parameter and return the same value" },
    66         "get_global":          { "category": "special",    "value": 187, "return": ["global"],   "parameter": [],                       "immediate": [{"name": "global_index",   "type": "varuint32"}],                                          "description": "read a global variable" },
    67         "set_global":          { "category": "special",    "value": 188, "return": [""],         "parameter": ["global"],               "immediate": [{"name": "global_index",   "type": "varuint32"}],                                          "description": "write a global variable" },
    68         "call":                { "category": "call",       "value":  22, "return": ["call"],     "parameter": ["call"],                 "immediate": [{"name": "function_index", "type": "varuint32"}],                                          "description": "call a function by its index" },
    69         "call_indirect":       { "category": "call",       "value":  23, "return": ["call"],     "parameter": ["call"],                 "immediate": [{"name": "type_index",     "type": "varuint32"}],                                          "description": "call a function indirect with an expected signature" },
    70         "i32.load8_s":         { "category": "memory",     "value":  32, "return": ["i32"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
    71         "i32.load8_u":         { "category": "memory",     "value":  33, "return": ["i32"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
    72         "i32.load16_s":        { "category": "memory",     "value":  34, "return": ["i32"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
    73         "i32.load16_u":        { "category": "memory",     "value":  35, "return": ["i32"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
    74         "i64.load8_s":         { "category": "memory",     "value":  36, "return": ["i64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
    75         "i64.load8_u":         { "category": "memory",     "value":  37, "return": ["i64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
    76         "i64.load16_s":        { "category": "memory",     "value":  38, "return": ["i64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
    77         "i64.load16_u":        { "category": "memory",     "value":  39, "return": ["i64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
    78         "i64.load32_s":        { "category": "memory",     "value":  40, "return": ["i64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
    79         "i64.load32_u":        { "category": "memory",     "value":  41, "return": ["i64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
    80         "i32.load":            { "category": "memory",     "value":  42, "return": ["i32"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
    81         "i64.load":            { "category": "memory",     "value":  43, "return": ["i64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
    82         "f32.load":            { "category": "memory",     "value":  44, "return": ["f32"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
    83         "f64.load":            { "category": "memory",     "value":  45, "return": ["f64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
    84         "i32.store8":          { "category": "memory",     "value":  46, "return": [],           "parameter": ["addr", "i32"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
    85         "i32.store16":         { "category": "memory",     "value":  47, "return": [],           "parameter": ["addr", "i32"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
    86         "i64.store8":          { "category": "memory",     "value":  48, "return": [],           "parameter": ["addr", "i64"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
    87         "i64.store16":         { "category": "memory",     "value":  49, "return": [],           "parameter": ["addr", "i64"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
    88         "i64.store32":         { "category": "memory",     "value":  50, "return": [],           "parameter": ["addr", "i64"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
    89         "i32.store":           { "category": "memory",     "value":  51, "return": [],           "parameter": ["addr", "i32"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
    90         "i64.store":           { "category": "memory",     "value":  52, "return": [],           "parameter": ["addr", "i64"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
    91         "f32.store":           { "category": "memory",     "value":  53, "return": [],           "parameter": ["addr", "f32"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
    92         "f64.store":           { "category": "memory",     "value":  54, "return": [],           "parameter": ["addr", "f64"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
    93         "current_memory":      { "category": "operation",  "value":  59, "return": ["size"],     "parameter": [],                       "immediate": [],                                                                                         "description": "query the size of memory" },
    94         "grow_memory":         { "category": "operation",  "value":  57, "return": ["size"],     "parameter": ["size"],                 "immediate": [],                                                                                         "description": "grow the size of memory" },
    95         "i32.add":             { "category": "arithmetic", "value":  64, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Add"          },
    96         "i32.sub":             { "category": "arithmetic", "value":  65, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Sub"          },
    97         "i32.mul":             { "category": "arithmetic", "value":  66, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Mul"          },
    98         "i32.div_s":           { "category": "arithmetic", "value":  67, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Div"          },
    99         "i32.div_u":           { "category": "arithmetic", "value":  68, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "UDiv"         },
    100         "i32.rem_s":           { "category": "arithmetic", "value":  69, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Mod"          },
    101         "i32.rem_u":           { "category": "arithmetic", "value":  70, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "UMod"         },
    102         "i32.and":             { "category": "arithmetic", "value":  71, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "BitAnd"       },
    103         "i32.or":              { "category": "arithmetic", "value":  72, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "BitOr"        },
    104         "i32.xor":             { "category": "arithmetic", "value":  73, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "BitXor"       },
    105         "i32.shl":             { "category": "arithmetic", "value":  74, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Shl"          },
    106         "i32.shr_u":           { "category": "arithmetic", "value":  75, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "SShr"         },
    107         "i32.shr_s":           { "category": "arithmetic", "value":  76, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "ZShr"         },
    108         "i32.rotr":            { "category": "arithmetic", "value": 182, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "RotR"         },
    109         "i32.rotl":            { "category": "arithmetic", "value": 183, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "RotL"         },
    110         "i32.eq":              { "category": "comparison", "value":  77, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Equal"        },
    111         "i32.ne":              { "category": "comparison", "value":  78, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "NotEqual"     },
    112         "i32.lt_s":            { "category": "comparison", "value":  79, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "LessThan"     },
    113         "i32.le_s":            { "category": "comparison", "value":  80, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "LessEqual"    },
    114         "i32.lt_u":            { "category": "comparison", "value":  81, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Below"        },
    115         "i32.le_u":            { "category": "comparison", "value":  82, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "BelowEqual"   },
    116         "i32.gt_s":            { "category": "comparison", "value":  83, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "GreaterThan"  },
    117         "i32.ge_s":            { "category": "comparison", "value":  84, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "GreaterEqual" },
    118         "i32.gt_u":            { "category": "comparison", "value":  85, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Above"        },
    119         "i32.ge_u":            { "category": "comparison", "value":  86, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "AboveEqual"   },
    120         "i32.clz":             { "category": "arithmetic", "value":  87, "return": ["i32"],      "parameter": ["i32"],                  "immediate": [], "b3op": "Clz"          },
    121         "i32.ctz":             { "category": "arithmetic", "value":  88, "return": ["i32"],      "parameter": ["i32"],                  "immediate": []                         },
    122         "i32.popcnt":          { "category": "arithmetic", "value":  89, "return": ["i32"],      "parameter": ["i32"],                  "immediate": []                         },
    123         "i32.eqz":             { "category": "comparison", "value":  90, "return": ["bool"],     "parameter": ["i32"],                  "immediate": [], "b3op": "Equal(i32(0), @0)" },
    124         "i64.add":             { "category": "arithmetic", "value":  91, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Add"          },
    125         "i64.sub":             { "category": "arithmetic", "value":  92, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Sub"          },
    126         "i64.mul":             { "category": "arithmetic", "value":  93, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Mul"          },
    127         "i64.div_s":           { "category": "arithmetic", "value":  94, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Div"          },
    128         "i64.div_u":           { "category": "arithmetic", "value":  95, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "UDiv"         },
    129         "i64.rem_s":           { "category": "arithmetic", "value":  96, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Mod"          },
    130         "i64.rem_u":           { "category": "arithmetic", "value":  97, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "UDiv"         },
    131         "i64.and":             { "category": "arithmetic", "value":  98, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "BitAnd"       },
    132         "i64.or":              { "category": "arithmetic", "value":  99, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "BitOr"        },
    133         "i64.xor":             { "category": "arithmetic", "value": 100, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "BitXor"       },
    134         "i64.shl":             { "category": "arithmetic", "value": 101, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Shl"          },
    135         "i64.shr_u":           { "category": "arithmetic", "value": 102, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "SShr"         },
    136         "i64.shr_s":           { "category": "arithmetic", "value": 103, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "ZShr"         },
    137         "i64.rotr":            { "category": "arithmetic", "value": 184, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "RotR"         },
    138         "i64.rotl":            { "category": "arithmetic", "value": 185, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "RotL"         },
    139         "i64.eq":              { "category": "comparison", "value": 104, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Equal"        },
    140         "i64.ne":              { "category": "comparison", "value": 105, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "NotEqual"     },
    141         "i64.lt_s":            { "category": "comparison", "value": 106, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "LessThan"     },
    142         "i64.le_s":            { "category": "comparison", "value": 107, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "LessEqual"    },
    143         "i64.lt_u":            { "category": "comparison", "value": 108, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Below"        },
    144         "i64.le_u":            { "category": "comparison", "value": 109, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "BelowEqual"   },
    145         "i64.gt_s":            { "category": "comparison", "value": 110, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "GreaterThan"  },
    146         "i64.ge_s":            { "category": "comparison", "value": 111, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "GreaterEqual" },
    147         "i64.gt_u":            { "category": "comparison", "value": 112, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Above"        },
    148         "i64.ge_u":            { "category": "comparison", "value": 113, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "AboveEqual"   },
    149         "i64.clz":             { "category": "arithmetic", "value": 114, "return": ["i64"],      "parameter": ["i64"],                  "immediate": [], "b3op": "Clz"          },
    150         "i64.ctz":             { "category": "arithmetic", "value": 115, "return": ["i64"],      "parameter": ["i64"],                  "immediate": []                         },
    151         "i64.popcnt":          { "category": "arithmetic", "value": 116, "return": ["i64"],      "parameter": ["i64"],                  "immediate": []                         },
    152         "i64.eqz":             { "category": "comparison", "value": 186, "return": ["bool"],     "parameter": ["i64"],                  "immediate": [], "b3op": "Equal(i32(0), @0)" },
    153         "f32.add":             { "category": "arithmetic", "value": 117, "return": ["f32"],      "parameter": ["f32", "f32"],           "immediate": [], "b3op": "Add"          },
    154         "f32.sub":             { "category": "arithmetic", "value": 118, "return": ["f32"],      "parameter": ["f32", "f32"],           "immediate": [], "b3op": "Sub"          },
    155         "f32.mul":             { "category": "arithmetic", "value": 119, "return": ["f32"],      "parameter": ["f32", "f32"],           "immediate": [], "b3op": "Mul"          },
    156         "f32.div":             { "category": "arithmetic", "value": 120, "return": ["f32"],      "parameter": ["f32", "f32"],           "immediate": [], "b3op": "Div"          },
    157         "f32.min":             { "category": "arithmetic", "value": 121, "return": ["f32"],      "parameter": ["f32", "f32"],           "immediate": [], "b3op": "Select(LessThan(@0, @1), @0, @1)" },
    158         "f32.max":             { "category": "arithmetic", "value": 122, "return": ["f32"],      "parameter": ["f32", "f32"],           "immediate": [], "b3op": "Select(LessThan(@0, @1), @1, @0)" },
    159         "f32.abs":             { "category": "arithmetic", "value": 123, "return": ["f32"],      "parameter": ["f32"],                  "immediate": [], "b3op": "Abs"          },
    160         "f32.neg":             { "category": "arithmetic", "value": 124, "return": ["f32"],      "parameter": ["f32"],                  "immediate": [], "b3op": "Neg"          },
    161         "f32.copysign":        { "category": "arithmetic", "value": 125, "return": ["f32"],      "parameter": ["f32"],                  "immediate": []                         },
    162         "f32.ceil":            { "category": "arithmetic", "value": 126, "return": ["f32"],      "parameter": ["f32"],                  "immediate": [], "b3op": "Ceil"         },
    163         "f32.floor":           { "category": "arithmetic", "value": 127, "return": ["f32"],      "parameter": ["f32"],                  "immediate": [], "b3op": "Floor"        },
    164         "f32.trunc":           { "category": "arithmetic", "value": 128, "return": ["f32"],      "parameter": ["f32"],                  "immediate": []                         },
    165         "f32.nearest":         { "category": "arithmetic", "value": 129, "return": ["f32"],      "parameter": ["f32"],                  "immediate": []                         },
    166         "f32.sqrt":            { "category": "arithmetic", "value": 130, "return": ["f32"],      "parameter": ["f32"],                  "immediate": [], "b3op": "Sqrt"         },
    167         "f32.eq":              { "category": "comparison", "value": 131, "return": ["bool"],     "parameter": ["f32", "f32"],           "immediate": [], "b3op": "Equal"        },
    168         "f32.ne":              { "category": "comparison", "value": 132, "return": ["bool"],     "parameter": ["f32", "f32"],           "immediate": [], "b3op": "NotEqual"     },
    169         "f32.lt":              { "category": "comparison", "value": 133, "return": ["bool"],     "parameter": ["f32", "f32"],           "immediate": [], "b3op": "LessThan"     },
    170         "f32.le":              { "category": "comparison", "value": 134, "return": ["bool"],     "parameter": ["f32", "f32"],           "immediate": [], "b3op": "LessEqual"    },
    171         "f32.gt":              { "category": "comparison", "value": 135, "return": ["bool"],     "parameter": ["f32", "f32"],           "immediate": [], "b3op": "GreaterThan"  },
    172         "f32.ge":              { "category": "comparison", "value": 136, "return": ["bool"],     "parameter": ["f32", "f32"],           "immediate": [], "b3op": "GreaterEqual" },
    173         "f64.add":             { "category": "arithmetic", "value": 137, "return": ["f64"],      "parameter": ["f64", "f64"],           "immediate": [], "b3op": "Add"          },
    174         "f64.sub":             { "category": "arithmetic", "value": 138, "return": ["f64"],      "parameter": ["f64", "f64"],           "immediate": [], "b3op": "Sub"          },
    175         "f64.mul":             { "category": "arithmetic", "value": 139, "return": ["f64"],      "parameter": ["f64", "f64"],           "immediate": [], "b3op": "Mul"          },
    176         "f64.div":             { "category": "arithmetic", "value": 140, "return": ["f64"],      "parameter": ["f64", "f64"],           "immediate": [], "b3op": "Div"          },
    177         "f64.min":             { "category": "arithmetic", "value": 141, "return": ["f64"],      "parameter": ["f64", "f64"],           "immediate": [], "b3op": "Select(LessThan(@0, @1), @0, @1)" },
    178         "f64.max":             { "category": "arithmetic", "value": 142, "return": ["f64"],      "parameter": ["f64", "f64"],           "immediate": [], "b3op": "Select(LessThan(@0, @1), @1, @0)" },
    179         "f64.abs":             { "category": "arithmetic", "value": 143, "return": ["f64"],      "parameter": ["f64"],                  "immediate": [], "b3op": "Abs"          },
    180         "f64.neg":             { "category": "arithmetic", "value": 144, "return": ["f64"],      "parameter": ["f64"],                  "immediate": [], "b3op": "Neg"          },
    181         "f64.copysign":        { "category": "arithmetic", "value": 145, "return": ["f64"],      "parameter": ["f64"],                  "immediate": []                         },
    182         "f64.ceil":            { "category": "arithmetic", "value": 146, "return": ["f64"],      "parameter": ["f64"],                  "immediate": [], "b3op": "Ceil"         },
    183         "f64.floor":           { "category": "arithmetic", "value": 147, "return": ["f64"],      "parameter": ["f64"],                  "immediate": [], "b3op": "Floor"        },
    184         "f64.trunc":           { "category": "arithmetic", "value": 148, "return": ["f64"],      "parameter": ["f64"],                  "immediate": []                         },
    185         "f64.nearest":         { "category": "arithmetic", "value": 149, "return": ["f64"],      "parameter": ["f64"],                  "immediate": []                         },
    186         "f64.sqrt":            { "category": "arithmetic", "value": 150, "return": ["f64"],      "parameter": ["f64"],                  "immediate": [], "b3op": "Sqrt"         },
    187         "f64.eq":              { "category": "comparison", "value": 151, "return": ["bool"],     "parameter": ["f64", "f64"],           "immediate": [], "b3op": "Equal"        },
    188         "f64.ne":              { "category": "comparison", "value": 152, "return": ["bool"],     "parameter": ["f64", "f64"],           "immediate": [], "b3op": "NotEqual"     },
    189         "f64.lt":              { "category": "comparison", "value": 153, "return": ["bool"],     "parameter": ["f64", "f64"],           "immediate": [], "b3op": "LessThan"     },
    190         "f64.le":              { "category": "comparison", "value": 154, "return": ["bool"],     "parameter": ["f64", "f64"],           "immediate": [], "b3op": "LessEqual"    },
    191         "f64.gt":              { "category": "comparison", "value": 155, "return": ["bool"],     "parameter": ["f64", "f64"],           "immediate": [], "b3op": "GreaterThan"  },
    192         "f64.ge":              { "category": "comparison", "value": 156, "return": ["bool"],     "parameter": ["f64", "f64"],           "immediate": [], "b3op": "GreaterEqual" },
    193         "i32.trunc_s/f32":     { "category": "conversion", "value": 157, "return": ["i32"],      "parameter": ["f32"],                  "immediate": []                         },
    194         "i32.trunc_s/f64":     { "category": "conversion", "value": 158, "return": ["i32"],      "parameter": ["f64"],                  "immediate": []                         },
    195         "i32.trunc_u/f32":     { "category": "conversion", "value": 159, "return": ["i32"],      "parameter": ["f32"],                  "immediate": []                         },
    196         "i32.trunc_u/f64":     { "category": "conversion", "value": 160, "return": ["i32"],      "parameter": ["f64"],                  "immediate": []                         },
    197         "i32.wrap/i64":        { "category": "conversion", "value": 161, "return": ["i32"],      "parameter": ["i64"],                  "immediate": []                         },
    198         "i64.trunc_s/f32":     { "category": "conversion", "value": 162, "return": ["i64"],      "parameter": ["f32"],                  "immediate": []                         },
    199         "i64.trunc_s/f64":     { "category": "conversion", "value": 163, "return": ["i64"],      "parameter": ["f64"],                  "immediate": []                         },
    200         "i64.trunc_u/f32":     { "category": "conversion", "value": 164, "return": ["i64"],      "parameter": ["f32"],                  "immediate": []                         },
    201         "i64.trunc_u/f64":     { "category": "conversion", "value": 165, "return": ["i64"],      "parameter": ["f64"],                  "immediate": []                         },
    202         "i64.extend_s/i32":    { "category": "conversion", "value": 166, "return": ["i64"],      "parameter": ["i32"],                  "immediate": [], "b3op": "SExt32"       },
    203         "i64.extend_u/i32":    { "category": "conversion", "value": 167, "return": ["i64"],      "parameter": ["i32"],                  "immediate": [], "b3op": "ZExt32"       },
    204         "f32.convert_s/i32":   { "category": "conversion", "value": 168, "return": ["f32"],      "parameter": ["i32"],                  "immediate": []                         },
    205         "f32.convert_u/i32":   { "category": "conversion", "value": 169, "return": ["f32"],      "parameter": ["i32"],                  "immediate": []                         },
    206         "f32.convert_s/i64":   { "category": "conversion", "value": 170, "return": ["f32"],      "parameter": ["i64"],                  "immediate": []                         },
    207         "f32.convert_u/i64":   { "category": "conversion", "value": 171, "return": ["f32"],      "parameter": ["i64"],                  "immediate": []                         },
    208         "f32.demote/f64":      { "category": "conversion", "value": 172, "return": ["f32"],      "parameter": ["f64"],                  "immediate": [], "b3op": "DoubleToFloat"},
    209         "f32.reinterpret/i32": { "category": "conversion", "value": 173, "return": ["f32"],      "parameter": ["i32"],                  "immediate": [], "b3op": "BitwiseCast"  },
    210         "f64.convert_s/i32":   { "category": "conversion", "value": 174, "return": ["f64"],      "parameter": ["i32"],                  "immediate": []                         },
    211         "f64.convert_u/i32":   { "category": "conversion", "value": 175, "return": ["f64"],      "parameter": ["i32"],                  "immediate": []                         },
    212         "f64.convert_s/i64":   { "category": "conversion", "value": 176, "return": ["f64"],      "parameter": ["i64"],                  "immediate": []                         },
    213         "f64.convert_u/i64":   { "category": "conversion", "value": 177, "return": ["f64"],      "parameter": ["i64"],                  "immediate": []                         },
    214         "f64.promote/f32":     { "category": "conversion", "value": 178, "return": ["f64"],      "parameter": ["f32"],                  "immediate": [], "b3op": "FloatToDouble"},
    215         "f64.reinterpret/i64": { "category": "conversion", "value": 179, "return": ["f64"],      "parameter": ["i64"],                  "immediate": [], "b3op": "BitwiseCast"  },
    216         "i32.reinterpret/f32": { "category": "conversion", "value": 180, "return": ["i32"],      "parameter": ["f32"],                  "immediate": [], "b3op": "BitwiseCast"  },
    217         "i64.reinterpret/f64": { "category": "conversion", "value": 181, "return": ["i64"],      "parameter": ["f64"],                  "immediate": [], "b3op": "BitwiseCast"  }
     53        "return":              { "category": "control",    "value":  15, "return": [],           "parameter": [],                       "immediate": [],                                                                                         "description": "return zero or one value from this function" },
     54        "drop":                { "category": "control",    "value":  26, "return": [],           "parameter": ["any"],                  "immediate": [],                                                                                         "description": "ignore value" },
     55        "nop":                 { "category": "control",    "value":   1, "return": [],           "parameter": [],                       "immediate": [],                                                                                         "description": "no operation" },
     56        "end":                 { "category": "control",    "value":  11, "return": [],           "parameter": [],                       "immediate": [],                                                                                         "description": "end a block, loop, or if" },
     57        "i32.const":           { "category": "special",    "value":  65, "return": ["i32"],      "parameter": [],                       "immediate": [{"name": "value",          "type": "varint32"}],                                           "description": "a constant value interpreted as i32" },
     58        "i64.const":           { "category": "special",    "value":  66, "return": ["i64"],      "parameter": [],                       "immediate": [{"name": "value",          "type": "varint64"}],                                           "description": "a constant value interpreted as i64" },
     59        "f64.const":           { "category": "special",    "value":  68, "return": ["f64"],      "parameter": [],                       "immediate": [{"name": "value",          "type": "uint64"}],                                             "description": "a constant value interpreted as f64" },
     60        "f32.const":           { "category": "special",    "value":  67, "return": ["f32"],      "parameter": [],                       "immediate": [{"name": "value",          "type": "uint32"}],                                             "description": "a constant value interpreted as f32" },
     61        "get_local":           { "category": "special",    "value":  32, "return": ["local"],    "parameter": [],                       "immediate": [{"name": "local_index",    "type": "varuint32"}],                                          "description": "read a local variable or parameter" },
     62        "set_local":           { "category": "special",    "value":  33, "return": [],           "parameter": ["local"],                "immediate": [{"name": "local_index",    "type": "varuint32"}],                                          "description": "write a local variable or parameter" },
     63        "tee_local":           { "category": "special",    "value":  34, "return": ["prev"],     "parameter": ["any"],                  "immediate": [{"name": "local_index",    "type": "varuint32"}],                                          "description": "write a local variable or parameter and return the same value" },
     64        "get_global":          { "category": "special",    "value":  35, "return": ["global"],   "parameter": [],                       "immediate": [{"name": "global_index",   "type": "varuint32"}],                                          "description": "read a global variable" },
     65        "set_global":          { "category": "special",    "value":  36, "return": [""],         "parameter": ["global"],               "immediate": [{"name": "global_index",   "type": "varuint32"}],                                          "description": "write a global variable" },
     66        "call":                { "category": "call",       "value":  16, "return": ["call"],     "parameter": ["call"],                 "immediate": [{"name": "function_index", "type": "varuint32"}],                                          "description": "call a function by its index" },
     67        "call_indirect":       { "category": "call",       "value":  17, "return": ["call"],     "parameter": ["call"],                 "immediate": [{"name": "type_index",     "type": "varuint32"}],                                          "description": "call a function indirect with an expected signature" },
     68        "i32.load8_s":         { "category": "memory",     "value":  44, "return": ["i32"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
     69        "i32.load8_u":         { "category": "memory",     "value":  45, "return": ["i32"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
     70        "i32.load16_s":        { "category": "memory",     "value":  46, "return": ["i32"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
     71        "i32.load16_u":        { "category": "memory",     "value":  47, "return": ["i32"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
     72        "i64.load8_s":         { "category": "memory",     "value":  48, "return": ["i64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
     73        "i64.load8_u":         { "category": "memory",     "value":  49, "return": ["i64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
     74        "i64.load16_s":        { "category": "memory",     "value":  50, "return": ["i64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
     75        "i64.load16_u":        { "category": "memory",     "value":  51, "return": ["i64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
     76        "i64.load32_s":        { "category": "memory",     "value":  52, "return": ["i64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
     77        "i64.load32_u":        { "category": "memory",     "value":  53, "return": ["i64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
     78        "i32.load":            { "category": "memory",     "value":  40, "return": ["i32"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
     79        "i64.load":            { "category": "memory",     "value":  41, "return": ["i64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
     80        "f32.load":            { "category": "memory",     "value":  42, "return": ["f32"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
     81        "f64.load":            { "category": "memory",     "value":  43, "return": ["f64"],      "parameter": ["addr"],                 "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "load from memory" },
     82        "i32.store8":          { "category": "memory",     "value":  58, "return": [],           "parameter": ["addr", "i32"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
     83        "i32.store16":         { "category": "memory",     "value":  59, "return": [],           "parameter": ["addr", "i32"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
     84        "i64.store8":          { "category": "memory",     "value":  60, "return": [],           "parameter": ["addr", "i64"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
     85        "i64.store16":         { "category": "memory",     "value":  61, "return": [],           "parameter": ["addr", "i64"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
     86        "i64.store32":         { "category": "memory",     "value":  62, "return": [],           "parameter": ["addr", "i64"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
     87        "i32.store":           { "category": "memory",     "value":  54, "return": [],           "parameter": ["addr", "i32"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
     88        "i64.store":           { "category": "memory",     "value":  55, "return": [],           "parameter": ["addr", "i64"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
     89        "f32.store":           { "category": "memory",     "value":  56, "return": [],           "parameter": ["addr", "f32"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
     90        "f64.store":           { "category": "memory",     "value":  57, "return": [],           "parameter": ["addr", "f64"],          "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset", "type": "varuint32"}], "description": "store to memory" },
     91        "current_memory":      { "category": "operation",  "value":  63, "return": ["size"],     "parameter": [],                       "immediate": [],                                                                                         "description": "query the size of memory" },
     92        "grow_memory":         { "category": "operation",  "value":  64, "return": ["size"],     "parameter": ["size"],                 "immediate": [],                                                                                         "description": "grow the size of memory" },
     93        "i32.add":             { "category": "arithmetic", "value": 106, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Add"          },
     94        "i32.sub":             { "category": "arithmetic", "value": 107, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Sub"          },
     95        "i32.mul":             { "category": "arithmetic", "value": 108, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Mul"          },
     96        "i32.div_s":           { "category": "arithmetic", "value": 109, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Div"          },
     97        "i32.div_u":           { "category": "arithmetic", "value": 110, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "UDiv"         },
     98        "i32.rem_s":           { "category": "arithmetic", "value": 111, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Mod"          },
     99        "i32.rem_u":           { "category": "arithmetic", "value": 112, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "UMod"         },
     100        "i32.and":             { "category": "arithmetic", "value": 113, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "BitAnd"       },
     101        "i32.or":              { "category": "arithmetic", "value": 114, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "BitOr"        },
     102        "i32.xor":             { "category": "arithmetic", "value": 115, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "BitXor"       },
     103        "i32.shl":             { "category": "arithmetic", "value": 116, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Shl"          },
     104        "i32.shr_u":           { "category": "arithmetic", "value": 118, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "SShr"         },
     105        "i32.shr_s":           { "category": "arithmetic", "value": 117, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "ZShr"         },
     106        "i32.rotr":            { "category": "arithmetic", "value": 120, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "RotR"         },
     107        "i32.rotl":            { "category": "arithmetic", "value": 119, "return": ["i32"],      "parameter": ["i32", "i32"],           "immediate": [], "b3op": "RotL"         },
     108        "i32.eq":              { "category": "comparison", "value":  70, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Equal"        },
     109        "i32.ne":              { "category": "comparison", "value":  71, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "NotEqual"     },
     110        "i32.lt_s":            { "category": "comparison", "value":  72, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "LessThan"     },
     111        "i32.le_s":            { "category": "comparison", "value":  76, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "LessEqual"    },
     112        "i32.lt_u":            { "category": "comparison", "value":  73, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Below"        },
     113        "i32.le_u":            { "category": "comparison", "value":  77, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "BelowEqual"   },
     114        "i32.gt_s":            { "category": "comparison", "value":  74, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "GreaterThan"  },
     115        "i32.ge_s":            { "category": "comparison", "value":  78, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "GreaterEqual" },
     116        "i32.gt_u":            { "category": "comparison", "value":  75, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "Above"        },
     117        "i32.ge_u":            { "category": "comparison", "value":  79, "return": ["bool"],     "parameter": ["i32", "i32"],           "immediate": [], "b3op": "AboveEqual"   },
     118        "i32.clz":             { "category": "arithmetic", "value": 103, "return": ["i32"],      "parameter": ["i32"],                  "immediate": [], "b3op": "Clz"          },
     119        "i32.ctz":             { "category": "arithmetic", "value": 104, "return": ["i32"],      "parameter": ["i32"],                  "immediate": []                         },
     120        "i32.popcnt":          { "category": "arithmetic", "value": 105, "return": ["i32"],      "parameter": ["i32"],                  "immediate": []                         },
     121        "i32.eqz":             { "category": "comparison", "value":  69, "return": ["bool"],     "parameter": ["i32"],                  "immediate": [], "b3op": "Equal(i32(0), @0)" },
     122        "i64.add":             { "category": "arithmetic", "value": 124, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Add"          },
     123        "i64.sub":             { "category": "arithmetic", "value": 125, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Sub"          },
     124        "i64.mul":             { "category": "arithmetic", "value": 126, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Mul"          },
     125        "i64.div_s":           { "category": "arithmetic", "value": 127, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Div"          },
     126        "i64.div_u":           { "category": "arithmetic", "value": 128, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "UDiv"         },
     127        "i64.rem_s":           { "category": "arithmetic", "value": 129, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Mod"          },
     128        "i64.rem_u":           { "category": "arithmetic", "value": 130, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "UDiv"         },
     129        "i64.and":             { "category": "arithmetic", "value": 131, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "BitAnd"       },
     130        "i64.or":              { "category": "arithmetic", "value": 132, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "BitOr"        },
     131        "i64.xor":             { "category": "arithmetic", "value": 133, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "BitXor"       },
     132        "i64.shl":             { "category": "arithmetic", "value": 134, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Shl"          },
     133        "i64.shr_u":           { "category": "arithmetic", "value": 136, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "SShr"         },
     134        "i64.shr_s":           { "category": "arithmetic", "value": 135, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "ZShr"         },
     135        "i64.rotr":            { "category": "arithmetic", "value": 138, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "RotR"         },
     136        "i64.rotl":            { "category": "arithmetic", "value": 137, "return": ["i64"],      "parameter": ["i64", "i64"],           "immediate": [], "b3op": "RotL"         },
     137        "i64.eq":              { "category": "comparison", "value":  81, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Equal"        },
     138        "i64.ne":              { "category": "comparison", "value":  82, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "NotEqual"     },
     139        "i64.lt_s":            { "category": "comparison", "value":  83, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "LessThan"     },
     140        "i64.le_s":            { "category": "comparison", "value":  87, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "LessEqual"    },
     141        "i64.lt_u":            { "category": "comparison", "value":  84, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Below"        },
     142        "i64.le_u":            { "category": "comparison", "value":  88, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "BelowEqual"   },
     143        "i64.gt_s":            { "category": "comparison", "value":  85, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "GreaterThan"  },
     144        "i64.ge_s":            { "category": "comparison", "value":  89, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "GreaterEqual" },
     145        "i64.gt_u":            { "category": "comparison", "value":  86, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "Above"        },
     146        "i64.ge_u":            { "category": "comparison", "value":  90, "return": ["bool"],     "parameter": ["i64", "i64"],           "immediate": [], "b3op": "AboveEqual"   },
     147        "i64.clz":             { "category": "arithmetic", "value": 121, "return": ["i64"],      "parameter": ["i64"],                  "immediate": [], "b3op": "Clz"          },
     148        "i64.ctz":             { "category": "arithmetic", "value": 122, "return": ["i64"],      "parameter": ["i64"],                  "immediate": []                         },
     149        "i64.popcnt":          { "category": "arithmetic", "value": 123, "return": ["i64"],      "parameter": ["i64"],                  "immediate": []                         },
     150        "i64.eqz":             { "category": "comparison", "value":  80, "return": ["bool"],     "parameter": ["i64"],                  "immediate": [], "b3op": "Equal(i32(0), @0)" },
     151        "f32.add":             { "category": "arithmetic", "value": 146, "return": ["f32"],      "parameter": ["f32", "f32"],           "immediate": [], "b3op": "Add"          },
     152        "f32.sub":             { "category": "arithmetic", "value": 147, "return": ["f32"],      "parameter": ["f32", "f32"],           "immediate": [], "b3op": "Sub"          },
     153        "f32.mul":             { "category": "arithmetic", "value": 148, "return": ["f32"],      "parameter": ["f32", "f32"],           "immediate": [], "b3op": "Mul"          },
     154        "f32.div":             { "category": "arithmetic", "value": 149, "return": ["f32"],      "parameter": ["f32", "f32"],           "immediate": [], "b3op": "Div"          },
     155        "f32.min":             { "category": "arithmetic", "value": 150, "return": ["f32"],      "parameter": ["f32", "f32"],           "immediate": [], "b3op": "Select(LessThan(@0, @1), @0, @1)" },
     156        "f32.max":             { "category": "arithmetic", "value": 151, "return": ["f32"],      "parameter": ["f32", "f32"],           "immediate": [], "b3op": "Select(LessThan(@0, @1), @1, @0)" },
     157        "f32.abs":             { "category": "arithmetic", "value": 139, "return": ["f32"],      "parameter": ["f32"],                  "immediate": [], "b3op": "Abs"          },
     158        "f32.neg":             { "category": "arithmetic", "value": 140, "return": ["f32"],      "parameter": ["f32"],                  "immediate": [], "b3op": "Neg"          },
     159        "f32.copysign":        { "category": "arithmetic", "value": 152, "return": ["f32"],      "parameter": ["f32"],                  "immediate": []                         },
     160        "f32.ceil":            { "category": "arithmetic", "value": 141, "return": ["f32"],      "parameter": ["f32"],                  "immediate": [], "b3op": "Ceil"         },
     161        "f32.floor":           { "category": "arithmetic", "value": 142, "return": ["f32"],      "parameter": ["f32"],                  "immediate": [], "b3op": "Floor"        },
     162        "f32.trunc":           { "category": "arithmetic", "value": 143, "return": ["f32"],      "parameter": ["f32"],                  "immediate": []                         },
     163        "f32.nearest":         { "category": "arithmetic", "value": 144, "return": ["f32"],      "parameter": ["f32"],                  "immediate": []                         },
     164        "f32.sqrt":            { "category": "arithmetic", "value": 145, "return": ["f32"],      "parameter": ["f32"],                  "immediate": [], "b3op": "Sqrt"         },
     165        "f32.eq":              { "category": "comparison", "value":  91, "return": ["bool"],     "parameter": ["f32", "f32"],           "immediate": [], "b3op": "Equal"        },
     166        "f32.ne":              { "category": "comparison", "value":  92, "return": ["bool"],     "parameter": ["f32", "f32"],           "immediate": [], "b3op": "NotEqual"     },
     167        "f32.lt":              { "category": "comparison", "value":  93, "return": ["bool"],     "parameter": ["f32", "f32"],           "immediate": [], "b3op": "LessThan"     },
     168        "f32.le":              { "category": "comparison", "value":  95, "return": ["bool"],     "parameter": ["f32", "f32"],           "immediate": [], "b3op": "LessEqual"    },
     169        "f32.gt":              { "category": "comparison", "value":  94, "return": ["bool"],     "parameter": ["f32", "f32"],           "immediate": [], "b3op": "GreaterThan"  },
     170        "f32.ge":              { "category": "comparison", "value":  96, "return": ["bool"],     "parameter": ["f32", "f32"],           "immediate": [], "b3op": "GreaterEqual" },
     171        "f64.add":             { "category": "arithmetic", "value": 160, "return": ["f64"],      "parameter": ["f64", "f64"],           "immediate": [], "b3op": "Add"          },
     172        "f64.sub":             { "category": "arithmetic", "value": 161, "return": ["f64"],      "parameter": ["f64", "f64"],           "immediate": [], "b3op": "Sub"          },
     173        "f64.mul":             { "category": "arithmetic", "value": 162, "return": ["f64"],      "parameter": ["f64", "f64"],           "immediate": [], "b3op": "Mul"          },
     174        "f64.div":             { "category": "arithmetic", "value": 163, "return": ["f64"],      "parameter": ["f64", "f64"],           "immediate": [], "b3op": "Div"          },
     175        "f64.min":             { "category": "arithmetic", "value": 164, "return": ["f64"],      "parameter": ["f64", "f64"],           "immediate": [], "b3op": "Select(LessThan(@0, @1), @0, @1)" },
     176        "f64.max":             { "category": "arithmetic", "value": 165, "return": ["f64"],      "parameter": ["f64", "f64"],           "immediate": [], "b3op": "Select(LessThan(@0, @1), @1, @0)" },
     177        "f64.abs":             { "category": "arithmetic", "value": 153, "return": ["f64"],      "parameter": ["f64"],                  "immediate": [], "b3op": "Abs"          },
     178        "f64.neg":             { "category": "arithmetic", "value": 154, "return": ["f64"],      "parameter": ["f64"],                  "immediate": [], "b3op": "Neg"          },
     179        "f64.copysign":        { "category": "arithmetic", "value": 166, "return": ["f64"],      "parameter": ["f64"],                  "immediate": []                         },
     180        "f64.ceil":            { "category": "arithmetic", "value": 155, "return": ["f64"],      "parameter": ["f64"],                  "immediate": [], "b3op": "Ceil"         },
     181        "f64.floor":           { "category": "arithmetic", "value": 156, "return": ["f64"],      "parameter": ["f64"],                  "immediate": [], "b3op": "Floor"        },
     182        "f64.trunc":           { "category": "arithmetic", "value": 157, "return": ["f64"],      "parameter": ["f64"],                  "immediate": []                         },
     183        "f64.nearest":         { "category": "arithmetic", "value": 158, "return": ["f64"],      "parameter": ["f64"],                  "immediate": []                         },
     184        "f64.sqrt":            { "category": "arithmetic", "value": 159, "return": ["f64"],      "parameter": ["f64"],                  "immediate": [], "b3op": "Sqrt"         },
     185        "f64.eq":              { "category": "comparison", "value":  97, "return": ["bool"],     "parameter": ["f64", "f64"],           "immediate": [], "b3op": "Equal"        },
     186        "f64.ne":              { "category": "comparison", "value":  98, "return": ["bool"],     "parameter": ["f64", "f64"],           "immediate": [], "b3op": "NotEqual"     },
     187        "f64.lt":              { "category": "comparison", "value":  99, "return": ["bool"],     "parameter": ["f64", "f64"],           "immediate": [], "b3op": "LessThan"     },
     188        "f64.le":              { "category": "comparison", "value": 101, "return": ["bool"],     "parameter": ["f64", "f64"],           "immediate": [], "b3op": "LessEqual"    },
     189        "f64.gt":              { "category": "comparison", "value": 100, "return": ["bool"],     "parameter": ["f64", "f64"],           "immediate": [], "b3op": "GreaterThan"  },
     190        "f64.ge":              { "category": "comparison", "value": 102, "return": ["bool"],     "parameter": ["f64", "f64"],           "immediate": [], "b3op": "GreaterEqual" },
     191        "i32.trunc_s/f32":     { "category": "conversion", "value": 168, "return": ["i32"],      "parameter": ["f32"],                  "immediate": []                         },
     192        "i32.trunc_s/f64":     { "category": "conversion", "value": 170, "return": ["i32"],      "parameter": ["f64"],                  "immediate": []                         },
     193        "i32.trunc_u/f32":     { "category": "conversion", "value": 169, "return": ["i32"],      "parameter": ["f32"],                  "immediate": []                         },
     194        "i32.trunc_u/f64":     { "category": "conversion", "value": 171, "return": ["i32"],      "parameter": ["f64"],                  "immediate": []                         },
     195        "i32.wrap/i64":        { "category": "conversion", "value": 167, "return": ["i32"],      "parameter": ["i64"],                  "immediate": []                         },
     196        "i64.trunc_s/f32":     { "category": "conversion", "value": 174, "return": ["i64"],      "parameter": ["f32"],                  "immediate": []                         },
     197        "i64.trunc_s/f64":     { "category": "conversion", "value": 176, "return": ["i64"],      "parameter": ["f64"],                  "immediate": []                         },
     198        "i64.trunc_u/f32":     { "category": "conversion", "value": 175, "return": ["i64"],      "parameter": ["f32"],                  "immediate": []                         },
     199        "i64.trunc_u/f64":     { "category": "conversion", "value": 177, "return": ["i64"],      "parameter": ["f64"],                  "immediate": []                         },
     200        "i64.extend_s/i32":    { "category": "conversion", "value": 172, "return": ["i64"],      "parameter": ["i32"],                  "immediate": [], "b3op": "SExt32"       },
     201        "i64.extend_u/i32":    { "category": "conversion", "value": 173, "return": ["i64"],      "parameter": ["i32"],                  "immediate": [], "b3op": "ZExt32"       },
     202        "f32.convert_s/i32":   { "category": "conversion", "value": 178, "return": ["f32"],      "parameter": ["i32"],                  "immediate": []                         },
     203        "f32.convert_u/i32":   { "category": "conversion", "value": 179, "return": ["f32"],      "parameter": ["i32"],                  "immediate": []                         },
     204        "f32.convert_s/i64":   { "category": "conversion", "value": 180, "return": ["f32"],      "parameter": ["i64"],                  "immediate": []                         },
     205        "f32.convert_u/i64":   { "category": "conversion", "value": 181, "return": ["f32"],      "parameter": ["i64"],                  "immediate": []                         },
     206        "f32.demote/f64":      { "category": "conversion", "value": 182, "return": ["f32"],      "parameter": ["f64"],                  "immediate": [], "b3op": "DoubleToFloat"},
     207        "f32.reinterpret/i32": { "category": "conversion", "value": 190, "return": ["f32"],      "parameter": ["i32"],                  "immediate": [], "b3op": "BitwiseCast"  },
     208        "f64.convert_s/i32":   { "category": "conversion", "value": 183, "return": ["f64"],      "parameter": ["i32"],                  "immediate": []                         },
     209        "f64.convert_u/i32":   { "category": "conversion", "value": 184, "return": ["f64"],      "parameter": ["i32"],                  "immediate": []                         },
     210        "f64.convert_s/i64":   { "category": "conversion", "value": 185, "return": ["f64"],      "parameter": ["i64"],                  "immediate": []                         },
     211        "f64.convert_u/i64":   { "category": "conversion", "value": 186, "return": ["f64"],      "parameter": ["i64"],                  "immediate": []                         },
     212        "f64.promote/f32":     { "category": "conversion", "value": 187, "return": ["f64"],      "parameter": ["f32"],                  "immediate": [], "b3op": "FloatToDouble"},
     213        "f64.reinterpret/i64": { "category": "conversion", "value": 191, "return": ["f64"],      "parameter": ["i64"],                  "immediate": [], "b3op": "BitwiseCast"  },
     214        "i32.reinterpret/f32": { "category": "conversion", "value": 188, "return": ["i32"],      "parameter": ["f32"],                  "immediate": [], "b3op": "BitwiseCast"  },
     215        "i64.reinterpret/f64": { "category": "conversion", "value": 189, "return": ["i64"],      "parameter": ["f64"],                  "immediate": [], "b3op": "BitwiseCast"  }
    218216    }
    219217}
Note: See TracChangeset for help on using the changeset viewer.