Changeset 269729 in webkit


Ignore:
Timestamp:
Nov 12, 2020 3:59:44 AM (3 years ago)
Author:
commit-queue@webkit.org
Message:

[WASM-References] Support imm for ref.null
https://bugs.webkit.org/show_bug.cgi?id=218744

Patch by Dmitry Bezhetskov <dbezhetskov> on 2020-11-12
Reviewed by Yusuke Suzuki.

JSTests:

Updated the Builder DSL and spec tests for ref.null extern/funcref.
Spec is here - https://webassembly.github.io/reference-types/core/.

  • wasm/Builder.js:

(export.default.Builder.prototype._registerSectionBuilders.const.section.in.WASM.description.section.switch.section.case.string_appeared_here.this.section):

  • wasm/Builder_WebAssemblyBinary.js:

(const.putInitExpr):

  • wasm/LowLevelBinary.js:

(export.default.LowLevelBinary.prototype.ref_type):

  • wasm/WASM.js:
  • wasm/references-spec-tests/ref_is_null.js:
  • wasm/references-spec-tests/ref_null.js:
  • wasm/references/externref_globals.js:
  • wasm/references/externref_modules.js:
  • wasm/references/externref_table.js:
  • wasm/references/externref_table_import.js:

(makeImport):
(string_appeared_here.fullGC.assert.eq.1.exports.get_tbl.makeImport):
(string_appeared_here.fullGC.assert.eq.1.exports.get_tbl):

  • wasm/references/func_ref.js:

(assert.eq.instance.exports.fix):

  • wasm/references/is_null.js:

(checkRefNullWithI32ImmType):

  • wasm/references/multitable.js:
  • wasm/wasm.json:

Source/JavaScriptCore:

Updated ref.null according to the ref-types spec:
https://github.com/WebAssembly/reference-types/.

  • wasm/WasmFormat.h:

(JSC::Wasm::isRefType):

  • wasm/WasmFunctionParser.h:

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

  • wasm/WasmParser.h:

(JSC::Wasm::Parser<SuccessType>::parseRefType):

  • wasm/WasmSectionParser.cpp:

(JSC::Wasm::SectionParser::parseInitExpr):

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

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r269722 r269729  
     12020-11-12  Dmitry Bezhetskov  <dbezhetskov@igalia.com>
     2
     3        [WASM-References] Support imm for ref.null
     4        https://bugs.webkit.org/show_bug.cgi?id=218744
     5
     6        Reviewed by Yusuke Suzuki.
     7       
     8        Updated the Builder DSL and spec tests for ref.null extern/funcref.
     9        Spec is here - https://webassembly.github.io/reference-types/core/.
     10
     11        * wasm/Builder.js:
     12        (export.default.Builder.prototype._registerSectionBuilders.const.section.in.WASM.description.section.switch.section.case.string_appeared_here.this.section):
     13        * wasm/Builder_WebAssemblyBinary.js:
     14        (const.putInitExpr):
     15        * wasm/LowLevelBinary.js:
     16        (export.default.LowLevelBinary.prototype.ref_type):
     17        * wasm/WASM.js:
     18        * wasm/references-spec-tests/ref_is_null.js:
     19        * wasm/references-spec-tests/ref_null.js:
     20        * wasm/references/externref_globals.js:
     21        * wasm/references/externref_modules.js:
     22        * wasm/references/externref_table.js:
     23        * wasm/references/externref_table_import.js:
     24        (makeImport):
     25        (string_appeared_here.fullGC.assert.eq.1.exports.get_tbl.makeImport):
     26        (string_appeared_here.fullGC.assert.eq.1.exports.get_tbl):
     27        * wasm/references/func_ref.js:
     28        (assert.eq.instance.exports.fix):
     29        * wasm/references/is_null.js:
     30        (checkRefNullWithI32ImmType):
     31        * wasm/references/multitable.js:
     32        * wasm/wasm.json:
     33
    1342020-11-12  Angelos Oikonomopoulos  <angelos@igalia.com>
    235
  • trunk/JSTests/wasm/Builder.js

    r269552 r269729  
    308308        case "reserved": break; // improve checking https://bugs.webkit.org/show_bug.cgi?id=163421
    309309        case "table_index": break; // improve checking https://bugs.webkit.org/show_bug.cgi?id=163421
     310        case "reftype":
     311            assert.truthy(WASM.isValidRefType(imms[idx]), `Invalid ref type on ${op}: "${imms[idx]}"`);
     312            break;
    310313        default: throw new Error(`Implementation problem: unhandled immediate "${expect.name}" on "${op}"`);
    311314        }
     
    543546                        },
    544547                        RefNull: (type, mutability) => {
    545                             s.data.push({ type, op: "ref.null", mutability: _normalizeMutability(mutability) });
     548                            s.data.push({ type, op: "ref.null", mutability: _normalizeMutability(mutability), reftype: type});
    546549                            return _errorHandlingProxyFor(globalBuilder);
    547550                        }
  • trunk/JSTests/wasm/Builder_WebAssemblyBinary.js

    r264304 r269729  
    9494const putInitExpr = (bin, expr) => {
    9595    if (expr.op == "ref.null")
    96         putOp(bin, { value: WASM.description.opcode[expr.op].value, name: expr.op, immediates: [], arguments: [] });
     96        putOp(bin, { value: WASM.description.opcode[expr.op].value, name: expr.op, immediates: [expr.reftype], arguments: [] });
    9797    else
    9898        putOp(bin, { value: WASM.description.opcode[expr.op].value, name: expr.op, immediates: [expr.initValue], arguments: [] });
  • trunk/JSTests/wasm/LowLevelBinary.js

    r264304 r269729  
    201201        if (!WASM.isValidBlockType(v))
    202202            throw new Error(`Invalid block type ${v}`);
     203        this.varint7(WASM.typeValue[v]);
     204    }
     205    ref_type(v) {
     206        if (!WASM.isValidRefType(v))
     207            throw new Error(`Invalid elem type ${v}`);
    203208        this.varint7(WASM.typeValue[v]);
    204209    }
  • trunk/JSTests/wasm/WASM.js

    r264304 r269729  
    4242const _blockTypeSet = new Set(description.block_type);
    4343export const isValidBlockType = v => _blockTypeSet.has(v);
     44const _refTypeSet = new Set(description.ref_type);
     45export const isValidRefType = v => _refTypeSet.has(v);
    4446export const externalKindValue = _mapValues(description.external_kind);
    4547export const sections = Object.keys(description.section);
  • trunk/JSTests/wasm/references-spec-tests/ref_is_null.js

    r247036 r269729  
    173173
    174174// ref_is_null.wast:1
    175 let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x97\x80\x80\x80\x00\x05\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x00\x00\x60\x01\x6f\x00\x60\x01\x7f\x01\x7f\x03\x88\x80\x80\x80\x00\x07\x00\x01\x02\x03\x02\x04\x04\x04\x87\x80\x80\x80\x00\x02\x6f\x00\x02\x70\x00\x02\x07\xc1\x80\x80\x80\x00\x06\x06\x61\x6e\x79\x72\x65\x66\x00\x00\x07\x66\x75\x6e\x63\x72\x65\x66\x00\x01\x04\x69\x6e\x69\x74\x00\x03\x06\x64\x65\x69\x6e\x69\x74\x00\x04\x0b\x61\x6e\x79\x72\x65\x66\x2d\x65\x6c\x65\x6d\x00\x05\x0c\x66\x75\x6e\x63\x72\x65\x66\x2d\x65\x6c\x65\x6d\x00\x06\x09\x88\x80\x80\x80\x00\x01\x02\x01\x41\x01\x0b\x01\x02\x0a\xd4\x80\x80\x80\x00\x07\x85\x80\x80\x80\x00\x00\x20\x00\xd1\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xd1\x0b\x82\x80\x80\x80\x00\x00\x0b\x88\x80\x80\x80\x00\x00\x41\x01\x20\x00\x26\x00\x0b\x8c\x80\x80\x80\x00\x00\x41\x01\xd0\x26\x00\x41\x01\xd0\x26\x01\x0b\x88\x80\x80\x80\x00\x00\x20\x00\x25\x00\x10\x00\x0b\x88\x80\x80\x80\x00\x00\x20\x00\x25\x01\x10\x01\x0b");
    176 
    177 // ref_is_null.wast:29
    178 assert_return(() => call($1, "anyref", [null]), 1);
     175let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x97\x80\x80\x80\x00\x05\x60\x01\x70\x01\x7f\x60\x01\x6f\x01\x7f\x60\x00\x00\x60\x01\x6f\x00\x60\x01\x7f\x01\x7f\x03\x88\x80\x80\x80\x00\x07\x00\x01\x02\x03\x02\x04\x04\x04\x87\x80\x80\x80\x00\x02\x70\x00\x02\x6f\x00\x02\x07\xc7\x80\x80\x80\x00\x06\x07\x66\x75\x6e\x63\x72\x65\x66\x00\x00\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x04\x69\x6e\x69\x74\x00\x03\x06\x64\x65\x69\x6e\x69\x74\x00\x04\x0c\x66\x75\x6e\x63\x72\x65\x66\x2d\x65\x6c\x65\x6d\x00\x05\x0e\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x2d\x65\x6c\x65\x6d\x00\x06\x09\x87\x80\x80\x80\x00\x01\x00\x41\x01\x0b\x01\x02\x0a\xd6\x80\x80\x80\x00\x07\x85\x80\x80\x80\x00\x00\x20\x00\xd1\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xd1\x0b\x82\x80\x80\x80\x00\x00\x0b\x88\x80\x80\x80\x00\x00\x41\x01\x20\x00\x26\x01\x0b\x8e\x80\x80\x80\x00\x00\x41\x01\xd0\x70\x26\x00\x41\x01\xd0\x6f\x26\x01\x0b\x88\x80\x80\x80\x00\x00\x20\x00\x25\x00\x10\x00\x0b\x88\x80\x80\x80\x00\x00\x20\x00\x25\x01\x10\x01\x0b");
    179176
    180177// ref_is_null.wast:30
    181178assert_return(() => call($1, "funcref", [null]), 1);
    182179
    183 // ref_is_null.wast:32
    184 assert_return(() => call($1, "anyref", [hostref(1)]), 0);
    185 
    186 // ref_is_null.wast:34
     180// ref_is_null.wast:31
     181assert_return(() => call($1, "externref", [null]), 1);
     182
     183// ref_is_null.wast:33
     184assert_return(() => call($1, "externref", [hostref(1)]), 0);
     185
     186// ref_is_null.wast:35
    187187run(() => call($1, "init", [hostref(0)]));
    188 
    189 // ref_is_null.wast:36
    190 assert_return(() => call($1, "anyref-elem", [0]), 1);
    191188
    192189// ref_is_null.wast:37
    193190assert_return(() => call($1, "funcref-elem", [0]), 1);
    194191
    195 // ref_is_null.wast:39
    196 assert_return(() => call($1, "anyref-elem", [1]), 0);
     192// ref_is_null.wast:38
     193assert_return(() => call($1, "externref-elem", [0]), 1);
    197194
    198195// ref_is_null.wast:40
    199196assert_return(() => call($1, "funcref-elem", [1]), 0);
    200197
    201 // ref_is_null.wast:42
     198// ref_is_null.wast:41
     199assert_return(() => call($1, "externref-elem", [1]), 0);
     200
     201// ref_is_null.wast:43
    202202run(() => call($1, "deinit", []));
    203 
    204 // ref_is_null.wast:44
    205 assert_return(() => call($1, "anyref-elem", [0]), 1);
    206203
    207204// ref_is_null.wast:45
    208205assert_return(() => call($1, "funcref-elem", [0]), 1);
    209206
    210 // ref_is_null.wast:47
    211 assert_return(() => call($1, "anyref-elem", [1]), 1);
     207// ref_is_null.wast:46
     208assert_return(() => call($1, "externref-elem", [0]), 1);
    212209
    213210// ref_is_null.wast:48
    214211assert_return(() => call($1, "funcref-elem", [1]), 1);
     212
     213// ref_is_null.wast:49
     214assert_return(() => call($1, "externref-elem", [1]), 1);
     215
     216// ref_is_null.wast:51
     217assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x01\x7f\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x20\x00\xd1\x0b");
     218
     219// ref_is_null.wast:55
     220assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x89\x80\x80\x80\x00\x01\x83\x80\x80\x80\x00\x00\xd1\x0b");
  • trunk/JSTests/wasm/references-spec-tests/ref_null.js

    r247036 r269729  
    176176
    177177// ref_null.wast:1
    178 let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x01\x6f\x60\x00\x01\x70\x03\x83\x80\x80\x80\x00\x02\x00\x01\x06\x89\x80\x80\x80\x00\x02\x6f\x00\xd0\x0b\x70\x00\xd0\x0b\x07\x94\x80\x80\x80\x00\x02\x06\x61\x6e\x79\x72\x65\x66\x00\x00\x07\x66\x75\x6e\x63\x72\x65\x66\x00\x01\x0a\x91\x80\x80\x80\x00\x02\x83\x80\x80\x80\x00\x00\xd0\x0b\x83\x80\x80\x80\x00\x00\xd0\x0b");
     178let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x01\x6f\x60\x00\x01\x70\x03\x83\x80\x80\x80\x00\x02\x00\x01\x06\x8b\x80\x80\x80\x00\x02\x6f\x00\xd0\x6f\x0b\x70\x00\xd0\x70\x0b\x07\x97\x80\x80\x80\x00\x02\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x00\x07\x66\x75\x6e\x63\x72\x65\x66\x00\x01\x0a\x93\x80\x80\x80\x00\x02\x84\x80\x80\x80\x00\x00\xd0\x6f\x0b\x84\x80\x80\x80\x00\x00\xd0\x70\x0b");
    179179
    180180// ref_null.wast:9
    181 assert_return(() => call($1, "anyref", []), null);
     181assert_return(() => call($1, "externref", []), null);
    182182
    183183// ref_null.wast:10
  • trunk/JSTests/wasm/references/externref_globals.js

    r269552 r269729  
    4242
    4343        .Function("set_glob_null", { params: [], ret: "void" })
    44             .RefNull()
     44            .RefNull("externref")
    4545            .Call(0)
    4646        .End()
  • trunk/JSTests/wasm/references/externref_modules.js

    r269552 r269729  
    1818
    1919        .Function("i", { params: [], ret: "externref" })
    20             .RefNull()
     20            .RefNull("externref")
    2121            .Call(0)
    2222        .End()
     
    2828
    2929        .Function("k", { params: [], ret: "i32" })
    30             .RefNull()
     30            .RefNull("externref")
    3131            .RefIsNull()
    3232        .End()
     
    6363
    6464        .Function("call_h_null", { params: [], ret: "externref" })
    65           .RefNull()
     65          .RefNull("externref")
    6666          .Call(0)
    6767        .End()
    6868
    6969        .Function("call_j_null", { params: [], ret: "i32" })
    70           .RefNull()
     70          .RefNull("externref")
    7171          .Call(1)
    7272        .End()
     
    8787
    8888        .Function("call_ident_null", { params: [], ret: "externref" })
    89           .RefNull()
     89          .RefNull("externref")
    9090          .Call(2)
    9191        .End()
  • trunk/JSTests/wasm/references/externref_table.js

    r269552 r269729  
    3434
    3535        .Function("set_tbl_null", { params: [], ret: "void" })
    36             .RefNull()
     36            .RefNull("externref")
    3737            .Call(0)
    3838        .End()
  • trunk/JSTests/wasm/references/externref_table_import.js

    r269552 r269729  
    3838
    3939            .Function("set_tbl_null", { params: [], ret: "void" })
    40                 .RefNull()
     40                .RefNull("externref")
    4141                .Call(0)
    4242            .End()
     
    104104
    105105            .Function("set_tbl_null", { params: [], ret: "void" })
    106                 .RefNull()
     106                .RefNull("externref")
    107107                .Call(0)
    108108            .End()
     
    143143
    144144            .Function("set_tbl_null", { params: [], ret: "void" })
    145                 .RefNull()
     145                .RefNull("externref")
    146146                .Call(0)
    147147            .End()
  • trunk/JSTests/wasm/references/func_ref.js

    r269552 r269729  
    204204
    205205        .Function("set_glob_null", { params: [], ret: "void" })
    206             .RefNull()
     206            .RefNull("funcref")
    207207            .Call(0)
    208208        .End()
  • trunk/JSTests/wasm/references/is_null.js

    r269552 r269729  
    22import * as assert from '../assert.js';
    33import Builder from '../Builder.js';
     4
     5function checkRefNullWithI32ImmType() {
     6  /*
     7  (module
     8    (func (export "r") (result i32)
     9      ref.null i32
     10      ref.is_null
     11    )
     12  )
     13  */
     14  let bytes = Uint8Array.from([0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x05, 0x01, 0x60, 0x00, 0x01, 0x7f, 0x03, 0x02, 0x01, 0x00, 0x07, 0x05, 0x01, 0x01, 0x72, 0x00, 0x00, 0x0a, 0x07, 0x01, 0x05, 0x00, 0xd0, 0x7f, 0xd1, 0x0b]);
     15  assert.throws(() => new WebAssembly.Module(bytes), Error, "WebAssembly.Module doesn't parse at byte 3: ref.null type must be a reference type, in function at index 0 (evaluating 'new WebAssembly.Module(bytes)')");
     16}
     17
     18checkRefNullWithI32ImmType();
    419
    520const builder = (new Builder())
     
    2136
    2237        .Function("i", { params: [], ret: "externref" })
    23             .RefNull()
     38            .RefNull("externref")
    2439            .Call(0)
    2540        .End()
     
    3146
    3247        .Function("k", { params: [], ret: "i32" })
    33             .RefNull()
     48            .RefNull("externref")
    3449            .RefIsNull()
    3550        .End()
  • trunk/JSTests/wasm/references/multitable.js

    r269552 r269729  
    331331            .Function("fun", { params: [], ret: "void" })
    332332              .I32Const(0)
    333               .RefNull()
     333              .RefNull("externref")
    334334              .TableSet(2)
    335335            .End()
     
    371371          .Code()
    372372            .Function("fun", { params: [], ret: "void" })
    373               .RefNull()
     373              .RefNull("funcref")
    374374              .TableGet(0)
    375375            .End()
     
    386386          .Code()
    387387            .Function("fun", { params: [], ret: "void" })
    388               .RefNull()
    389               .RefNull()
     388              .RefNull("funcref")
     389              .RefNull("funcref")
    390390              .TableSet(0)
    391391            .End()
  • trunk/JSTests/wasm/wasm.json

    r269552 r269729  
    1919    "value_type": ["i32", "i64", "f32", "f64", "externref", "funcref"],
    2020    "block_type": ["i32", "i64", "f32", "f64", "void", "externref", "funcref"],
    21     "elem_type": ["funcref","externref"],
     21    "ref_type": ["funcref","externref"],
    2222    "external_kind": {
    2323        "Function": { "type": "uint8", "value": 0 },
     
    4040    },
    4141    "opcode": {
    42         "unreachable":         { "category": "control",    "value":   0, "return": [],              "parameter": [],                             "immediate": [],                                                                                            "description": "trap immediately" },
    43         "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" },
    44         "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" },
    45         "if":                  { "category": "control",    "value":   4, "return": ["control"],     "parameter": ["bool"],                       "immediate": [{"name": "sig", "type": "block_type"}],                                                       "description": "begin if expression" },
    46         "else":                { "category": "control",    "value":   5, "return": ["control"],     "parameter": [],                             "immediate": [],                                                                                            "description": "begin else expression of if" },
    47         "select":              { "category": "control",    "value":  27, "return": ["prev"],        "parameter": ["any", "prev", "bool"],        "immediate": [],                                                                                            "description": "select one of two values based on condition" },
    48         "br":                  { "category": "control",    "value":  12, "return": [],              "parameter": [],                             "immediate": [{"name": "relative_depth", "type": "varuint32"}],                                             "description": "break that targets an outer nested block" },
    49         "br_if":               { "category": "control",    "value":  13, "return": [],              "parameter": [],                             "immediate": [{"name": "relative_depth", "type": "varuint32"}],                                             "description": "conditional break that targets an outer nested block" },
    50         "br_table":            { "category": "control",    "value":  14, "return": [],              "parameter": [],                             "immediate": [{"name": "target_count",   "type": "varuint32",                                               "description": "number of entries in the target_table"},
    51                                                                                                                                                                {"name": "target_table",   "type": "varuint32*",                                              "description": "target entries that indicate an outer block or loop to which to break"},
    52                                                                                                                                                                {"name": "default_target", "type": "varuint32",                                               "description": "an outer block or loop to which to break in the default case"}],
    53                                                                                                                                                                                                                                                              "description": "branch table control flow construct" },
    54         "return":              { "category": "control",    "value":  15, "return": [],              "parameter": [],                             "immediate": [],                                                                                            "description": "return zero or one value from this function" },
    55         "drop":                { "category": "control",    "value":  26, "return": [],              "parameter": ["any"],                        "immediate": [],                                                                                            "description": "ignore value" },
    56         "nop":                 { "category": "control",    "value":   1, "return": [],              "parameter": [],                             "immediate": [],                                                                                            "description": "no operation" },
    57         "end":                 { "category": "control",    "value":  11, "return": [],              "parameter": [],                             "immediate": [],                                                                                            "description": "end a block, loop, or if" },
    58         "i32.const":           { "category": "special",    "value":  65, "return": ["i32"],         "parameter": [],                             "immediate": [{"name": "value",          "type": "varint32"}],                                              "description": "a constant value interpreted as i32" },
    59         "i64.const":           { "category": "special",    "value":  66, "return": ["i64"],         "parameter": [],                             "immediate": [{"name": "value",          "type": "varint64"}],                                              "description": "a constant value interpreted as i64" },
    60         "f64.const":           { "category": "special",    "value":  68, "return": ["f64"],         "parameter": [],                             "immediate": [{"name": "value",          "type": "double"}],                                                "description": "a constant value interpreted as f64" },
    61         "f32.const":           { "category": "special",    "value":  67, "return": ["f32"],         "parameter": [],                             "immediate": [{"name": "value",          "type": "float"}],                                                 "description": "a constant value interpreted as f32" },
    62         "ref.null":            { "category": "special",    "value": 208, "return": ["funcref"],     "parameter": [],                             "immediate": [],                                                                                            "description": "a constant null reference" },
    63         "ref.is_null":         { "category": "special",    "value": 209, "return": ["i32"],         "parameter": ["externref"],                  "immediate": [],                                                                                            "description": "determine if a reference is null" },
    64         "ref.func":            { "category": "special",    "value": 210, "return": ["funcref"],     "parameter": [],                             "immediate": [{"name": "function_index", "type": "varuint32"}],                                             "description": "return a reference to the function at the given index" },
    65         "get_local":           { "category": "special",    "value":  32, "return": ["any"],         "parameter": [],                             "immediate": [{"name": "local_index",    "type": "varuint32"}],                                             "description": "read a local variable or parameter" },
    66         "set_local":           { "category": "special",    "value":  33, "return": [],              "parameter": ["any"],                        "immediate": [{"name": "local_index",    "type": "varuint32"}],                                             "description": "write a local variable or parameter" },
    67         "tee_local":           { "category": "special",    "value":  34, "return": ["any"],         "parameter": ["any"],                        "immediate": [{"name": "local_index",    "type": "varuint32"}],                                             "description": "write a local variable or parameter and return the same value" },
    68         "get_global":          { "category": "special",    "value":  35, "return": ["any"],         "parameter": [],                             "immediate": [{"name": "global_index",   "type": "varuint32"}],                                             "description": "read a global variable" },
    69         "set_global":          { "category": "special",    "value":  36, "return": [],              "parameter": ["any"],                        "immediate": [{"name": "global_index",   "type": "varuint32"}],                                             "description": "write a global variable" },
    70         "table.get":           { "category": "special",    "value":  37, "return": ["externref"],   "parameter": ["i32"],                        "immediate": [{"name": "table_index",    "type": "varuint32"}],                                             "description": "get a table value" },
    71         "table.set":           { "category": "special",    "value":  38, "return": [],              "parameter": ["i32", "externref"],           "immediate": [{"name": "table_index",    "type": "varuint32"}],                                             "description": "set a table value" },
    72         "table.size":          { "category": "exttable",   "value":  252, "return": ["i32"],        "parameter": [],                             "immediate": [{"name": "table_index",    "type": "varuint32"}],                                             "description": "get the size of a table", "extendedOp": 15 },
    73         "table.grow":          { "category": "exttable",   "value":  252, "return": ["i32"],        "parameter": ["externref", "i32"],           "immediate": [{"name": "table_index",    "type": "varuint32"}],                                             "description": "grow a table by the given delta and return the previous size, or -1 if enough space cannot be allocated", "extendedOp": 16 },
    74         "table.fill":          { "category": "exttable",   "value":  252, "return": ["i32"],        "parameter": ["i32", "externref", "i32"],    "immediate": [{"name": "table_index",    "type": "varuint32"}],                                             "description": "fill entries [i,i+n) with the given value", "extendedOp": 17 },
    75         "call":                { "category": "call",       "value":  16, "return": ["call"],        "parameter": ["call"],                       "immediate": [{"name": "function_index", "type": "varuint32"}],                                             "description": "call a function by its index" },
    76         "call_indirect":       { "category": "call",       "value":  17, "return": ["call"],        "parameter": ["call"],                       "immediate": [{"name": "type_index",     "type": "varuint32"}, {"name": "table_index","type": "varuint32"}],"description": "call a function indirect with an expected signature" },
    77         "i32.load8_s":         { "category": "memory",     "value":  44, "return": ["i32"],         "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
    78         "i32.load8_u":         { "category": "memory",     "value":  45, "return": ["i32"],         "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
    79         "i32.load16_s":        { "category": "memory",     "value":  46, "return": ["i32"],         "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
    80         "i32.load16_u":        { "category": "memory",     "value":  47, "return": ["i32"],         "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
    81         "i64.load8_s":         { "category": "memory",     "value":  48, "return": ["i64"],         "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
    82         "i64.load8_u":         { "category": "memory",     "value":  49, "return": ["i64"],         "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
    83         "i64.load16_s":        { "category": "memory",     "value":  50, "return": ["i64"],         "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
    84         "i64.load16_u":        { "category": "memory",     "value":  51, "return": ["i64"],         "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
    85         "i64.load32_s":        { "category": "memory",     "value":  52, "return": ["i64"],         "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
    86         "i64.load32_u":        { "category": "memory",     "value":  53, "return": ["i64"],         "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
    87         "i32.load":            { "category": "memory",     "value":  40, "return": ["i32"],         "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
    88         "i64.load":            { "category": "memory",     "value":  41, "return": ["i64"],         "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
    89         "f32.load":            { "category": "memory",     "value":  42, "return": ["f32"],         "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
    90         "f64.load":            { "category": "memory",     "value":  43, "return": ["f64"],         "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
    91         "i32.store8":          { "category": "memory",     "value":  58, "return": [],              "parameter": ["addr", "i32"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
    92         "i32.store16":         { "category": "memory",     "value":  59, "return": [],              "parameter": ["addr", "i32"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
    93         "i64.store8":          { "category": "memory",     "value":  60, "return": [],              "parameter": ["addr", "i64"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
    94         "i64.store16":         { "category": "memory",     "value":  61, "return": [],              "parameter": ["addr", "i64"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
    95         "i64.store32":         { "category": "memory",     "value":  62, "return": [],              "parameter": ["addr", "i64"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
    96         "i32.store":           { "category": "memory",     "value":  54, "return": [],              "parameter": ["addr", "i32"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
    97         "i64.store":           { "category": "memory",     "value":  55, "return": [],              "parameter": ["addr", "i64"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
    98         "f32.store":           { "category": "memory",     "value":  56, "return": [],              "parameter": ["addr", "f32"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
    99         "f64.store":           { "category": "memory",     "value":  57, "return": [],              "parameter": ["addr", "f64"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
    100         "current_memory":      { "category": "operation",  "value":  63, "return": ["size"],        "parameter": [],                             "immediate": [{"name": "flags",          "type": "varuint32"}],                                            "description": "query the size of memory" },
    101         "grow_memory":         { "category": "operation",  "value":  64, "return": ["size"],        "parameter": ["size"],                       "immediate": [{"name": "flags",          "type": "varuint32"}],                                            "description": "grow the size of memory" },
    102         "i32.add":             { "category": "arithmetic", "value": 106, "return": ["i32"],         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "Add"          },
    103         "i32.sub":             { "category": "arithmetic", "value": 107, "return": ["i32"],         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "Sub"          },
    104         "i32.mul":             { "category": "arithmetic", "value": 108, "return": ["i32"],         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "Mul"          },
    105         "i32.div_s":           { "category": "arithmetic", "value": 109, "return": ["i32"],         "parameter": ["i32", "i32"],                 "immediate": []                         },
    106         "i32.div_u":           { "category": "arithmetic", "value": 110, "return": ["i32"],         "parameter": ["i32", "i32"],                 "immediate": []                         },
    107         "i32.rem_s":           { "category": "arithmetic", "value": 111, "return": ["i32"],         "parameter": ["i32", "i32"],                 "immediate": []                         },
    108         "i32.rem_u":           { "category": "arithmetic", "value": 112, "return": ["i32"],         "parameter": ["i32", "i32"],                 "immediate": []                         },
    109         "i32.and":             { "category": "arithmetic", "value": 113, "return": ["i32"],         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "BitAnd"       },
    110         "i32.or":              { "category": "arithmetic", "value": 114, "return": ["i32"],         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "BitOr"        },
    111         "i32.xor":             { "category": "arithmetic", "value": 115, "return": ["i32"],         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "BitXor"       },
    112         "i32.shl":             { "category": "arithmetic", "value": 116, "return": ["i32"],         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "Shl"          },
    113         "i32.shr_u":           { "category": "arithmetic", "value": 118, "return": ["i32"],         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "ZShr"         },
    114         "i32.shr_s":           { "category": "arithmetic", "value": 117, "return": ["i32"],         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "SShr"         },
    115         "i32.rotr":            { "category": "arithmetic", "value": 120, "return": ["i32"],         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "RotR"         },
    116         "i32.rotl":            { "category": "arithmetic", "value": 119, "return": ["i32"],         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "RotL"         },
    117         "i32.eq":              { "category": "comparison", "value":  70, "return": ["bool"],        "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "Equal"        },
    118         "i32.ne":              { "category": "comparison", "value":  71, "return": ["bool"],        "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "NotEqual"     },
    119         "i32.lt_s":            { "category": "comparison", "value":  72, "return": ["bool"],        "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "LessThan"     },
    120         "i32.le_s":            { "category": "comparison", "value":  76, "return": ["bool"],        "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "LessEqual"    },
    121         "i32.lt_u":            { "category": "comparison", "value":  73, "return": ["bool"],        "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "Below"        },
    122         "i32.le_u":            { "category": "comparison", "value":  77, "return": ["bool"],        "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "BelowEqual"   },
    123         "i32.gt_s":            { "category": "comparison", "value":  74, "return": ["bool"],        "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "GreaterThan"  },
    124         "i32.ge_s":            { "category": "comparison", "value":  78, "return": ["bool"],        "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "GreaterEqual" },
    125         "i32.gt_u":            { "category": "comparison", "value":  75, "return": ["bool"],        "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "Above"        },
    126         "i32.ge_u":            { "category": "comparison", "value":  79, "return": ["bool"],        "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "AboveEqual"   },
    127         "i32.clz":             { "category": "arithmetic", "value": 103, "return": ["i32"],         "parameter": ["i32"],                        "immediate": [], "b3op": "Clz"          },
    128         "i32.ctz":             { "category": "arithmetic", "value": 104, "return": ["i32"],         "parameter": ["i32"],                        "immediate": []                         },
    129         "i32.popcnt":          { "category": "arithmetic", "value": 105, "return": ["i32"],         "parameter": ["i32"],                        "immediate": []                         },
    130         "i32.eqz":             { "category": "comparison", "value":  69, "return": ["bool"],        "parameter": ["i32"],                        "immediate": [], "b3op": "Equal(i32(0), @0)" },
    131         "i64.add":             { "category": "arithmetic", "value": 124, "return": ["i64"],         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "Add"          },
    132         "i64.sub":             { "category": "arithmetic", "value": 125, "return": ["i64"],         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "Sub"          },
    133         "i64.mul":             { "category": "arithmetic", "value": 126, "return": ["i64"],         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "Mul"          },
    134         "i64.div_s":           { "category": "arithmetic", "value": 127, "return": ["i64"],         "parameter": ["i64", "i64"],                 "immediate": []                         },
    135         "i64.div_u":           { "category": "arithmetic", "value": 128, "return": ["i64"],         "parameter": ["i64", "i64"],                 "immediate": []                         },
    136         "i64.rem_s":           { "category": "arithmetic", "value": 129, "return": ["i64"],         "parameter": ["i64", "i64"],                 "immediate": []                         },
    137         "i64.rem_u":           { "category": "arithmetic", "value": 130, "return": ["i64"],         "parameter": ["i64", "i64"],                 "immediate": []                         },
    138         "i64.and":             { "category": "arithmetic", "value": 131, "return": ["i64"],         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "BitAnd"       },
    139         "i64.or":              { "category": "arithmetic", "value": 132, "return": ["i64"],         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "BitOr"        },
    140         "i64.xor":             { "category": "arithmetic", "value": 133, "return": ["i64"],         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "BitXor"       },
    141         "i64.shl":             { "category": "arithmetic", "value": 134, "return": ["i64"],         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "Shl(@0, Trunc(@1))" },
    142         "i64.shr_u":           { "category": "arithmetic", "value": 136, "return": ["i64"],         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "ZShr(@0, Trunc(@1))" },
    143         "i64.shr_s":           { "category": "arithmetic", "value": 135, "return": ["i64"],         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "SShr(@0, Trunc(@1))" },
    144         "i64.rotr":            { "category": "arithmetic", "value": 138, "return": ["i64"],         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "RotR(@0, Trunc(@1))" },
    145         "i64.rotl":            { "category": "arithmetic", "value": 137, "return": ["i64"],         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "RotL(@0, Trunc(@1))" },
    146         "i64.eq":              { "category": "comparison", "value":  81, "return": ["bool"],        "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "Equal"        },
    147         "i64.ne":              { "category": "comparison", "value":  82, "return": ["bool"],        "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "NotEqual"     },
    148         "i64.lt_s":            { "category": "comparison", "value":  83, "return": ["bool"],        "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "LessThan"     },
    149         "i64.le_s":            { "category": "comparison", "value":  87, "return": ["bool"],        "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "LessEqual"    },
    150         "i64.lt_u":            { "category": "comparison", "value":  84, "return": ["bool"],        "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "Below"        },
    151         "i64.le_u":            { "category": "comparison", "value":  88, "return": ["bool"],        "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "BelowEqual"   },
    152         "i64.gt_s":            { "category": "comparison", "value":  85, "return": ["bool"],        "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "GreaterThan"  },
    153         "i64.ge_s":            { "category": "comparison", "value":  89, "return": ["bool"],        "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "GreaterEqual" },
    154         "i64.gt_u":            { "category": "comparison", "value":  86, "return": ["bool"],        "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "Above"        },
    155         "i64.ge_u":            { "category": "comparison", "value":  90, "return": ["bool"],        "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "AboveEqual"   },
    156         "i64.clz":             { "category": "arithmetic", "value": 121, "return": ["i64"],         "parameter": ["i64"],                        "immediate": [], "b3op": "Clz"          },
    157         "i64.ctz":             { "category": "arithmetic", "value": 122, "return": ["i64"],         "parameter": ["i64"],                        "immediate": []                         },
    158         "i64.popcnt":          { "category": "arithmetic", "value": 123, "return": ["i64"],         "parameter": ["i64"],                        "immediate": []                         },
    159         "i64.eqz":             { "category": "comparison", "value":  80, "return": ["bool"],        "parameter": ["i64"],                        "immediate": [], "b3op": "Equal(i64(0), @0)" },
    160         "f32.add":             { "category": "arithmetic", "value": 146, "return": ["f32"],         "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "Add"          },
    161         "f32.sub":             { "category": "arithmetic", "value": 147, "return": ["f32"],         "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "Sub"          },
    162         "f32.mul":             { "category": "arithmetic", "value": 148, "return": ["f32"],         "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "Mul"          },
    163         "f32.div":             { "category": "arithmetic", "value": 149, "return": ["f32"],         "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "Div"          },
    164         "f32.min":             { "category": "arithmetic", "value": 150, "return": ["f32"],         "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "Select(Equal(@0, @1), BitOr(@0, @1), Select(LessThan(@0, @1), @0, Select(GreaterThan(@0, @1), @1, Add(@0, @1))))" },
    165         "f32.max":             { "category": "arithmetic", "value": 151, "return": ["f32"],         "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "Select(Equal(@0, @1), BitAnd(@0, @1), Select(LessThan(@0, @1), @1, Select(GreaterThan(@0, @1), @0, Add(@0, @1))))" },
    166         "f32.abs":             { "category": "arithmetic", "value": 139, "return": ["f32"],         "parameter": ["f32"],                        "immediate": [], "b3op": "Abs"          },
    167         "f32.neg":             { "category": "arithmetic", "value": 140, "return": ["f32"],         "parameter": ["f32"],                        "immediate": [], "b3op": "Neg"          },
    168         "f32.copysign":        { "category": "arithmetic", "value": 152, "return": ["f32"],         "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "BitwiseCast(BitOr(BitAnd(BitwiseCast(@1), i32(0x80000000)), BitAnd(BitwiseCast(@0), i32(0x7fffffff))))" },
    169         "f32.ceil":            { "category": "arithmetic", "value": 141, "return": ["f32"],         "parameter": ["f32"],                        "immediate": [], "b3op": "Ceil"         },
    170         "f32.floor":           { "category": "arithmetic", "value": 142, "return": ["f32"],         "parameter": ["f32"],                        "immediate": [], "b3op": "Floor"        },
    171         "f32.trunc":           { "category": "arithmetic", "value": 143, "return": ["f32"],         "parameter": ["f32"],                        "immediate": []                         },
    172         "f32.nearest":         { "category": "arithmetic", "value": 144, "return": ["f32"],         "parameter": ["f32"],                        "immediate": []                         },
    173         "f32.sqrt":            { "category": "arithmetic", "value": 145, "return": ["f32"],         "parameter": ["f32"],                        "immediate": [], "b3op": "Sqrt"         },
    174         "f32.eq":              { "category": "comparison", "value":  91, "return": ["bool"],        "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "Equal"        },
    175         "f32.ne":              { "category": "comparison", "value":  92, "return": ["bool"],        "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "NotEqual"     },
    176         "f32.lt":              { "category": "comparison", "value":  93, "return": ["bool"],        "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "LessThan"     },
    177         "f32.le":              { "category": "comparison", "value":  95, "return": ["bool"],        "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "LessEqual"    },
    178         "f32.gt":              { "category": "comparison", "value":  94, "return": ["bool"],        "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "GreaterThan"  },
    179         "f32.ge":              { "category": "comparison", "value":  96, "return": ["bool"],        "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "GreaterEqual" },
    180         "f64.add":             { "category": "arithmetic", "value": 160, "return": ["f64"],         "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "Add"          },
    181         "f64.sub":             { "category": "arithmetic", "value": 161, "return": ["f64"],         "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "Sub"          },
    182         "f64.mul":             { "category": "arithmetic", "value": 162, "return": ["f64"],         "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "Mul"          },
    183         "f64.div":             { "category": "arithmetic", "value": 163, "return": ["f64"],         "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "Div"          },
    184         "f64.min":             { "category": "arithmetic", "value": 164, "return": ["f64"],         "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "Select(Equal(@0, @1), BitOr(@0, @1), Select(LessThan(@0, @1), @0, Select(GreaterThan(@0, @1), @1, Add(@0, @1))))" },
    185         "f64.max":             { "category": "arithmetic", "value": 165, "return": ["f64"],         "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "Select(Equal(@0, @1), BitAnd(@0, @1), Select(LessThan(@0, @1), @1, Select(GreaterThan(@0, @1), @0, Add(@0, @1))))" },
    186         "f64.abs":             { "category": "arithmetic", "value": 153, "return": ["f64"],         "parameter": ["f64"],                        "immediate": [], "b3op": "Abs"          },
    187         "f64.neg":             { "category": "arithmetic", "value": 154, "return": ["f64"],         "parameter": ["f64"],                        "immediate": [], "b3op": "Neg"          },
    188         "f64.copysign":        { "category": "arithmetic", "value": 166, "return": ["f64"],         "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "BitwiseCast(BitOr(BitAnd(BitwiseCast(@1), i64(0x8000000000000000)), BitAnd(BitwiseCast(@0), i64(0x7fffffffffffffff))))" },
    189         "f64.ceil":            { "category": "arithmetic", "value": 155, "return": ["f64"],         "parameter": ["f64"],                        "immediate": [], "b3op": "Ceil"         },
    190         "f64.floor":           { "category": "arithmetic", "value": 156, "return": ["f64"],         "parameter": ["f64"],                        "immediate": [], "b3op": "Floor"        },
    191         "f64.trunc":           { "category": "arithmetic", "value": 157, "return": ["f64"],         "parameter": ["f64"],                        "immediate": []                         },
    192         "f64.nearest":         { "category": "arithmetic", "value": 158, "return": ["f64"],         "parameter": ["f64"],                        "immediate": []                         },
    193         "f64.sqrt":            { "category": "arithmetic", "value": 159, "return": ["f64"],         "parameter": ["f64"],                        "immediate": [], "b3op": "Sqrt"         },
    194         "f64.eq":              { "category": "comparison", "value":  97, "return": ["bool"],        "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "Equal"        },
    195         "f64.ne":              { "category": "comparison", "value":  98, "return": ["bool"],        "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "NotEqual"     },
    196         "f64.lt":              { "category": "comparison", "value":  99, "return": ["bool"],        "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "LessThan"     },
    197         "f64.le":              { "category": "comparison", "value": 101, "return": ["bool"],        "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "LessEqual"    },
    198         "f64.gt":              { "category": "comparison", "value": 100, "return": ["bool"],        "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "GreaterThan"  },
    199         "f64.ge":              { "category": "comparison", "value": 102, "return": ["bool"],        "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "GreaterEqual" },
    200         "i32.trunc_s/f32":     { "category": "conversion", "value": 168, "return": ["i32"],         "parameter": ["f32"],                        "immediate": []                         },
    201         "i32.trunc_s/f64":     { "category": "conversion", "value": 170, "return": ["i32"],         "parameter": ["f64"],                        "immediate": []                         },
    202         "i32.trunc_u/f32":     { "category": "conversion", "value": 169, "return": ["i32"],         "parameter": ["f32"],                        "immediate": []                         },
    203         "i32.trunc_u/f64":     { "category": "conversion", "value": 171, "return": ["i32"],         "parameter": ["f64"],                        "immediate": []                         },
    204         "i32.wrap/i64":        { "category": "conversion", "value": 167, "return": ["i32"],         "parameter": ["i64"],                        "immediate": [], "b3op": "Trunc"        },
    205         "i64.trunc_s/f32":     { "category": "conversion", "value": 174, "return": ["i64"],         "parameter": ["f32"],                        "immediate": []                         },
    206         "i64.trunc_s/f64":     { "category": "conversion", "value": 176, "return": ["i64"],         "parameter": ["f64"],                        "immediate": []                         },
    207         "i64.trunc_u/f32":     { "category": "conversion", "value": 175, "return": ["i64"],         "parameter": ["f32"],                        "immediate": []                         },
    208         "i64.trunc_u/f64":     { "category": "conversion", "value": 177, "return": ["i64"],         "parameter": ["f64"],                        "immediate": []                         },
    209         "i64.extend_s/i32":    { "category": "conversion", "value": 172, "return": ["i64"],         "parameter": ["i32"],                        "immediate": [], "b3op": "SExt32"       },
    210         "i64.extend_u/i32":    { "category": "conversion", "value": 173, "return": ["i64"],         "parameter": ["i32"],                        "immediate": [], "b3op": "ZExt32"       },
    211         "f32.convert_s/i32":   { "category": "conversion", "value": 178, "return": ["f32"],         "parameter": ["i32"],                        "immediate": [], "b3op": "IToF"         },
    212         "f32.convert_u/i32":   { "category": "conversion", "value": 179, "return": ["f32"],         "parameter": ["i32"],                        "immediate": [], "b3op": "IToF(ZExt32(@0))" },
    213         "f32.convert_s/i64":   { "category": "conversion", "value": 180, "return": ["f32"],         "parameter": ["i64"],                        "immediate": [], "b3op": "IToF"         },
    214         "f32.convert_u/i64":   { "category": "conversion", "value": 181, "return": ["f32"],         "parameter": ["i64"],                        "immediate": []                         },
    215         "f32.demote/f64":      { "category": "conversion", "value": 182, "return": ["f32"],         "parameter": ["f64"],                        "immediate": [], "b3op": "DoubleToFloat"},
    216         "f32.reinterpret/i32": { "category": "conversion", "value": 190, "return": ["f32"],         "parameter": ["i32"],                        "immediate": [], "b3op": "BitwiseCast"  },
    217         "f64.convert_s/i32":   { "category": "conversion", "value": 183, "return": ["f64"],         "parameter": ["i32"],                        "immediate": [], "b3op": "IToD"         },
    218         "f64.convert_u/i32":   { "category": "conversion", "value": 184, "return": ["f64"],         "parameter": ["i32"],                        "immediate": [], "b3op": "IToD(ZExt32(@0))" },
    219         "f64.convert_s/i64":   { "category": "conversion", "value": 185, "return": ["f64"],         "parameter": ["i64"],                        "immediate": [], "b3op": "IToD"         },
    220         "f64.convert_u/i64":   { "category": "conversion", "value": 186, "return": ["f64"],         "parameter": ["i64"],                        "immediate": []                         },
    221         "f64.promote/f32":     { "category": "conversion", "value": 187, "return": ["f64"],         "parameter": ["f32"],                        "immediate": [], "b3op": "FloatToDouble"},
    222         "f64.reinterpret/i64": { "category": "conversion", "value": 191, "return": ["f64"],         "parameter": ["i64"],                        "immediate": [], "b3op": "BitwiseCast"  },
    223         "i32.reinterpret/f32": { "category": "conversion", "value": 188, "return": ["i32"],         "parameter": ["f32"],                        "immediate": [], "b3op": "BitwiseCast"  },
    224         "i64.reinterpret/f64": { "category": "conversion", "value": 189, "return": ["i64"],         "parameter": ["f64"],                        "immediate": [], "b3op": "BitwiseCast"  }
     42        "unreachable":         { "category": "control",    "value":   0, "return": [],                               "parameter": [],                             "immediate": [],                                                                                            "description": "trap immediately" },
     43        "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" },
     44        "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" },
     45        "if":                  { "category": "control",    "value":   4, "return": ["control"],                      "parameter": ["bool"],                       "immediate": [{"name": "sig", "type": "block_type"}],                                                       "description": "begin if expression" },
     46        "else":                { "category": "control",    "value":   5, "return": ["control"],                      "parameter": [],                             "immediate": [],                                                                                            "description": "begin else expression of if" },
     47        "select":              { "category": "control",    "value":  27, "return": ["prev"],                         "parameter": ["any", "prev", "bool"],        "immediate": [],                                                                                            "description": "select one of two values based on condition" },
     48        "br":                  { "category": "control",    "value":  12, "return": [],                               "parameter": [],                             "immediate": [{"name": "relative_depth", "type": "varuint32"}],                                             "description": "break that targets an outer nested block" },
     49        "br_if":               { "category": "control",    "value":  13, "return": [],                               "parameter": [],                             "immediate": [{"name": "relative_depth", "type": "varuint32"}],                                             "description": "conditional break that targets an outer nested block" },
     50        "br_table":            { "category": "control",    "value":  14, "return": [],                               "parameter": [],                             "immediate": [{"name": "target_count",   "type": "varuint32",                                               "description": "number of entries in the target_table"},
     51                                                                                                                                                                                {"name": "target_table",   "type": "varuint32*",                                              "description": "target entries that indicate an outer block or loop to which to break"},
     52                                                                                                                                                                                {"name": "default_target", "type": "varuint32",                                               "description": "an outer block or loop to which to break in the default case"}],
     53                                                                                                                                                                                                                                                                              "description": "branch table control flow construct" },
     54        "return":              { "category": "control",    "value":  15, "return": [],                               "parameter": [],                             "immediate": [],                                                                                            "description": "return zero or one value from this function" },
     55        "drop":                { "category": "control",    "value":  26, "return": [],                               "parameter": ["any"],                        "immediate": [],                                                                                            "description": "ignore value" },
     56        "nop":                 { "category": "control",    "value":   1, "return": [],                               "parameter": [],                             "immediate": [],                                                                                            "description": "no operation" },
     57        "end":                 { "category": "control",    "value":  11, "return": [],                               "parameter": [],                             "immediate": [],                                                                                            "description": "end a block, loop, or if" },
     58        "i32.const":           { "category": "special",    "value":  65, "return": ["i32"],                          "parameter": [],                             "immediate": [{"name": "value",          "type": "varint32"}],                                              "description": "a constant value interpreted as i32" },
     59        "i64.const":           { "category": "special",    "value":  66, "return": ["i64"],                          "parameter": [],                             "immediate": [{"name": "value",          "type": "varint64"}],                                              "description": "a constant value interpreted as i64" },
     60        "f64.const":           { "category": "special",    "value":  68, "return": ["f64"],                          "parameter": [],                             "immediate": [{"name": "value",          "type": "double"}],                                                "description": "a constant value interpreted as f64" },
     61        "f32.const":           { "category": "special",    "value":  67, "return": ["f32"],                          "parameter": [],                             "immediate": [{"name": "value",          "type": "float"}],                                                 "description": "a constant value interpreted as f32" },
     62        "ref.null":            { "category": "special",    "value": 208, "return": ["externref", "funcref"],         "parameter": [],                             "immediate": [{"name": "reftype",        "type": "ref_type"}],                                              "description": "a constant null reference" },
     63        "ref.is_null":         { "category": "special",    "value": 209, "return": ["i32"],                          "parameter": ["externref"],                  "immediate": [],                                                                                            "description": "determine if a reference is null" },
     64        "ref.func":            { "category": "special",    "value": 210, "return": ["funcref"],                      "parameter": [],                             "immediate": [{"name": "function_index", "type": "varuint32"}],                                             "description": "return a reference to the function at the given index" },
     65        "get_local":           { "category": "special",    "value":  32, "return": ["any"],                          "parameter": [],                             "immediate": [{"name": "local_index",    "type": "varuint32"}],                                             "description": "read a local variable or parameter" },
     66        "set_local":           { "category": "special",    "value":  33, "return": [],                               "parameter": ["any"],                        "immediate": [{"name": "local_index",    "type": "varuint32"}],                                             "description": "write a local variable or parameter" },
     67        "tee_local":           { "category": "special",    "value":  34, "return": ["any"],                          "parameter": ["any"],                        "immediate": [{"name": "local_index",    "type": "varuint32"}],                                             "description": "write a local variable or parameter and return the same value" },
     68        "get_global":          { "category": "special",    "value":  35, "return": ["any"],                          "parameter": [],                             "immediate": [{"name": "global_index",   "type": "varuint32"}],                                             "description": "read a global variable" },
     69        "set_global":          { "category": "special",    "value":  36, "return": [],                               "parameter": ["any"],                        "immediate": [{"name": "global_index",   "type": "varuint32"}],                                             "description": "write a global variable" },
     70        "table.get":           { "category": "special",    "value":  37, "return": ["externref"],                    "parameter": ["i32"],                        "immediate": [{"name": "table_index",    "type": "varuint32"}],                                             "description": "get a table value" },
     71        "table.set":           { "category": "special",    "value":  38, "return": [],                               "parameter": ["i32", "externref"],           "immediate": [{"name": "table_index",    "type": "varuint32"}],                                             "description": "set a table value" },
     72        "table.size":          { "category": "exttable",   "value":  252, "return": ["i32"],                         "parameter": [],                             "immediate": [{"name": "table_index",    "type": "varuint32"}],                                             "description": "get the size of a table", "extendedOp": 15 },
     73        "table.grow":          { "category": "exttable",   "value":  252, "return": ["i32"],                         "parameter": ["externref", "i32"],           "immediate": [{"name": "table_index",    "type": "varuint32"}],                                             "description": "grow a table by the given delta and return the previous size, or -1 if enough space cannot be allocated", "extendedOp": 16 },
     74        "table.fill":          { "category": "exttable",   "value":  252, "return": ["i32"],                         "parameter": ["i32", "externref", "i32"],    "immediate": [{"name": "table_index",    "type": "varuint32"}],                                             "description": "fill entries [i,i+n) with the given value", "extendedOp": 17 },
     75        "call":                { "category": "call",       "value":  16, "return": ["call"],                         "parameter": ["call"],                       "immediate": [{"name": "function_index", "type": "varuint32"}],                                             "description": "call a function by its index" },
     76        "call_indirect":       { "category": "call",       "value":  17, "return": ["call"],                         "parameter": ["call"],                       "immediate": [{"name": "type_index",     "type": "varuint32"}, {"name": "table_index","type": "varuint32"}],"description": "call a function indirect with an expected signature" },
     77        "i32.load8_s":         { "category": "memory",     "value":  44, "return": ["i32"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
     78        "i32.load8_u":         { "category": "memory",     "value":  45, "return": ["i32"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
     79        "i32.load16_s":        { "category": "memory",     "value":  46, "return": ["i32"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
     80        "i32.load16_u":        { "category": "memory",     "value":  47, "return": ["i32"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
     81        "i64.load8_s":         { "category": "memory",     "value":  48, "return": ["i64"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
     82        "i64.load8_u":         { "category": "memory",     "value":  49, "return": ["i64"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
     83        "i64.load16_s":        { "category": "memory",     "value":  50, "return": ["i64"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
     84        "i64.load16_u":        { "category": "memory",     "value":  51, "return": ["i64"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
     85        "i64.load32_s":        { "category": "memory",     "value":  52, "return": ["i64"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
     86        "i64.load32_u":        { "category": "memory",     "value":  53, "return": ["i64"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
     87        "i32.load":            { "category": "memory",     "value":  40, "return": ["i32"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
     88        "i64.load":            { "category": "memory",     "value":  41, "return": ["i64"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
     89        "f32.load":            { "category": "memory",     "value":  42, "return": ["f32"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
     90        "f64.load":            { "category": "memory",     "value":  43, "return": ["f64"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
     91        "i32.store8":          { "category": "memory",     "value":  58, "return": [],                               "parameter": ["addr", "i32"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
     92        "i32.store16":         { "category": "memory",     "value":  59, "return": [],                               "parameter": ["addr", "i32"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
     93        "i64.store8":          { "category": "memory",     "value":  60, "return": [],                               "parameter": ["addr", "i64"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
     94        "i64.store16":         { "category": "memory",     "value":  61, "return": [],                               "parameter": ["addr", "i64"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
     95        "i64.store32":         { "category": "memory",     "value":  62, "return": [],                               "parameter": ["addr", "i64"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
     96        "i32.store":           { "category": "memory",     "value":  54, "return": [],                               "parameter": ["addr", "i32"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
     97        "i64.store":           { "category": "memory",     "value":  55, "return": [],                               "parameter": ["addr", "i64"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
     98        "f32.store":           { "category": "memory",     "value":  56, "return": [],                               "parameter": ["addr", "f32"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
     99        "f64.store":           { "category": "memory",     "value":  57, "return": [],                               "parameter": ["addr", "f64"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
     100        "current_memory":      { "category": "operation",  "value":  63, "return": ["size"],                         "parameter": [],                             "immediate": [{"name": "flags",          "type": "varuint32"}],                                            "description": "query the size of memory" },
     101        "grow_memory":         { "category": "operation",  "value":  64, "return": ["size"],                         "parameter": ["size"],                       "immediate": [{"name": "flags",          "type": "varuint32"}],                                            "description": "grow the size of memory" },
     102        "i32.add":             { "category": "arithmetic", "value": 106, "return": ["i32"],                          "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "Add"          },
     103        "i32.sub":             { "category": "arithmetic", "value": 107, "return": ["i32"],                          "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "Sub"          },
     104        "i32.mul":             { "category": "arithmetic", "value": 108, "return": ["i32"],                          "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "Mul"          },
     105        "i32.div_s":           { "category": "arithmetic", "value": 109, "return": ["i32"],                          "parameter": ["i32", "i32"],                 "immediate": []                         },
     106        "i32.div_u":           { "category": "arithmetic", "value": 110, "return": ["i32"],                          "parameter": ["i32", "i32"],                 "immediate": []                         },
     107        "i32.rem_s":           { "category": "arithmetic", "value": 111, "return": ["i32"],                          "parameter": ["i32", "i32"],                 "immediate": []                         },
     108        "i32.rem_u":           { "category": "arithmetic", "value": 112, "return": ["i32"],                          "parameter": ["i32", "i32"],                 "immediate": []                         },
     109        "i32.and":             { "category": "arithmetic", "value": 113, "return": ["i32"],                          "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "BitAnd"       },
     110        "i32.or":              { "category": "arithmetic", "value": 114, "return": ["i32"],                          "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "BitOr"        },
     111        "i32.xor":             { "category": "arithmetic", "value": 115, "return": ["i32"],                          "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "BitXor"       },
     112        "i32.shl":             { "category": "arithmetic", "value": 116, "return": ["i32"],                          "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "Shl"          },
     113        "i32.shr_u":           { "category": "arithmetic", "value": 118, "return": ["i32"],                          "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "ZShr"         },
     114        "i32.shr_s":           { "category": "arithmetic", "value": 117, "return": ["i32"],                          "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "SShr"         },
     115        "i32.rotr":            { "category": "arithmetic", "value": 120, "return": ["i32"],                          "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "RotR"         },
     116        "i32.rotl":            { "category": "arithmetic", "value": 119, "return": ["i32"],                          "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "RotL"         },
     117        "i32.eq":              { "category": "comparison", "value":  70, "return": ["bool"],                         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "Equal"        },
     118        "i32.ne":              { "category": "comparison", "value":  71, "return": ["bool"],                         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "NotEqual"     },
     119        "i32.lt_s":            { "category": "comparison", "value":  72, "return": ["bool"],                         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "LessThan"     },
     120        "i32.le_s":            { "category": "comparison", "value":  76, "return": ["bool"],                         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "LessEqual"    },
     121        "i32.lt_u":            { "category": "comparison", "value":  73, "return": ["bool"],                         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "Below"        },
     122        "i32.le_u":            { "category": "comparison", "value":  77, "return": ["bool"],                         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "BelowEqual"   },
     123        "i32.gt_s":            { "category": "comparison", "value":  74, "return": ["bool"],                         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "GreaterThan"  },
     124        "i32.ge_s":            { "category": "comparison", "value":  78, "return": ["bool"],                         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "GreaterEqual" },
     125        "i32.gt_u":            { "category": "comparison", "value":  75, "return": ["bool"],                         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "Above"        },
     126        "i32.ge_u":            { "category": "comparison", "value":  79, "return": ["bool"],                         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "AboveEqual"   },
     127        "i32.clz":             { "category": "arithmetic", "value": 103, "return": ["i32"],                          "parameter": ["i32"],                        "immediate": [], "b3op": "Clz"          },
     128        "i32.ctz":             { "category": "arithmetic", "value": 104, "return": ["i32"],                          "parameter": ["i32"],                        "immediate": []                         },
     129        "i32.popcnt":          { "category": "arithmetic", "value": 105, "return": ["i32"],                          "parameter": ["i32"],                        "immediate": []                         },
     130        "i32.eqz":             { "category": "comparison", "value":  69, "return": ["bool"],                         "parameter": ["i32"],                        "immediate": [], "b3op": "Equal(i32(0), @0)" },
     131        "i64.add":             { "category": "arithmetic", "value": 124, "return": ["i64"],                          "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "Add"          },
     132        "i64.sub":             { "category": "arithmetic", "value": 125, "return": ["i64"],                          "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "Sub"          },
     133        "i64.mul":             { "category": "arithmetic", "value": 126, "return": ["i64"],                          "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "Mul"          },
     134        "i64.div_s":           { "category": "arithmetic", "value": 127, "return": ["i64"],                          "parameter": ["i64", "i64"],                 "immediate": []                         },
     135        "i64.div_u":           { "category": "arithmetic", "value": 128, "return": ["i64"],                          "parameter": ["i64", "i64"],                 "immediate": []                         },
     136        "i64.rem_s":           { "category": "arithmetic", "value": 129, "return": ["i64"],                          "parameter": ["i64", "i64"],                 "immediate": []                         },
     137        "i64.rem_u":           { "category": "arithmetic", "value": 130, "return": ["i64"],                          "parameter": ["i64", "i64"],                 "immediate": []                         },
     138        "i64.and":             { "category": "arithmetic", "value": 131, "return": ["i64"],                          "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "BitAnd"       },
     139        "i64.or":              { "category": "arithmetic", "value": 132, "return": ["i64"],                          "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "BitOr"        },
     140        "i64.xor":             { "category": "arithmetic", "value": 133, "return": ["i64"],                          "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "BitXor"       },
     141        "i64.shl":             { "category": "arithmetic", "value": 134, "return": ["i64"],                          "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "Shl(@0, Trunc(@1))" },
     142        "i64.shr_u":           { "category": "arithmetic", "value": 136, "return": ["i64"],                          "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "ZShr(@0, Trunc(@1))" },
     143        "i64.shr_s":           { "category": "arithmetic", "value": 135, "return": ["i64"],                          "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "SShr(@0, Trunc(@1))" },
     144        "i64.rotr":            { "category": "arithmetic", "value": 138, "return": ["i64"],                          "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "RotR(@0, Trunc(@1))" },
     145        "i64.rotl":            { "category": "arithmetic", "value": 137, "return": ["i64"],                          "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "RotL(@0, Trunc(@1))" },
     146        "i64.eq":              { "category": "comparison", "value":  81, "return": ["bool"],                         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "Equal"        },
     147        "i64.ne":              { "category": "comparison", "value":  82, "return": ["bool"],                         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "NotEqual"     },
     148        "i64.lt_s":            { "category": "comparison", "value":  83, "return": ["bool"],                         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "LessThan"     },
     149        "i64.le_s":            { "category": "comparison", "value":  87, "return": ["bool"],                         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "LessEqual"    },
     150        "i64.lt_u":            { "category": "comparison", "value":  84, "return": ["bool"],                         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "Below"        },
     151        "i64.le_u":            { "category": "comparison", "value":  88, "return": ["bool"],                         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "BelowEqual"   },
     152        "i64.gt_s":            { "category": "comparison", "value":  85, "return": ["bool"],                         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "GreaterThan"  },
     153        "i64.ge_s":            { "category": "comparison", "value":  89, "return": ["bool"],                         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "GreaterEqual" },
     154        "i64.gt_u":            { "category": "comparison", "value":  86, "return": ["bool"],                         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "Above"        },
     155        "i64.ge_u":            { "category": "comparison", "value":  90, "return": ["bool"],                         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "AboveEqual"   },
     156        "i64.clz":             { "category": "arithmetic", "value": 121, "return": ["i64"],                          "parameter": ["i64"],                        "immediate": [], "b3op": "Clz"          },
     157        "i64.ctz":             { "category": "arithmetic", "value": 122, "return": ["i64"],                          "parameter": ["i64"],                        "immediate": []                         },
     158        "i64.popcnt":          { "category": "arithmetic", "value": 123, "return": ["i64"],                          "parameter": ["i64"],                        "immediate": []                         },
     159        "i64.eqz":             { "category": "comparison", "value":  80, "return": ["bool"],                         "parameter": ["i64"],                        "immediate": [], "b3op": "Equal(i64(0), @0)" },
     160        "f32.add":             { "category": "arithmetic", "value": 146, "return": ["f32"],                          "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "Add"          },
     161        "f32.sub":             { "category": "arithmetic", "value": 147, "return": ["f32"],                          "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "Sub"          },
     162        "f32.mul":             { "category": "arithmetic", "value": 148, "return": ["f32"],                          "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "Mul"          },
     163        "f32.div":             { "category": "arithmetic", "value": 149, "return": ["f32"],                          "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "Div"          },
     164        "f32.min":             { "category": "arithmetic", "value": 150, "return": ["f32"],                          "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "Select(Equal(@0, @1), BitOr(@0, @1), Select(LessThan(@0, @1), @0, Select(GreaterThan(@0, @1), @1, Add(@0, @1))))" },
     165        "f32.max":             { "category": "arithmetic", "value": 151, "return": ["f32"],                          "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "Select(Equal(@0, @1), BitAnd(@0, @1), Select(LessThan(@0, @1), @1, Select(GreaterThan(@0, @1), @0, Add(@0, @1))))" },
     166        "f32.abs":             { "category": "arithmetic", "value": 139, "return": ["f32"],                          "parameter": ["f32"],                        "immediate": [], "b3op": "Abs"          },
     167        "f32.neg":             { "category": "arithmetic", "value": 140, "return": ["f32"],                          "parameter": ["f32"],                        "immediate": [], "b3op": "Neg"          },
     168        "f32.copysign":        { "category": "arithmetic", "value": 152, "return": ["f32"],                          "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "BitwiseCast(BitOr(BitAnd(BitwiseCast(@1), i32(0x80000000)), BitAnd(BitwiseCast(@0), i32(0x7fffffff))))" },
     169        "f32.ceil":            { "category": "arithmetic", "value": 141, "return": ["f32"],                          "parameter": ["f32"],                        "immediate": [], "b3op": "Ceil"         },
     170        "f32.floor":           { "category": "arithmetic", "value": 142, "return": ["f32"],                          "parameter": ["f32"],                        "immediate": [], "b3op": "Floor"        },
     171        "f32.trunc":           { "category": "arithmetic", "value": 143, "return": ["f32"],                          "parameter": ["f32"],                        "immediate": []                         },
     172        "f32.nearest":         { "category": "arithmetic", "value": 144, "return": ["f32"],                          "parameter": ["f32"],                        "immediate": []                         },
     173        "f32.sqrt":            { "category": "arithmetic", "value": 145, "return": ["f32"],                          "parameter": ["f32"],                        "immediate": [], "b3op": "Sqrt"         },
     174        "f32.eq":              { "category": "comparison", "value":  91, "return": ["bool"],                         "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "Equal"        },
     175        "f32.ne":              { "category": "comparison", "value":  92, "return": ["bool"],                         "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "NotEqual"     },
     176        "f32.lt":              { "category": "comparison", "value":  93, "return": ["bool"],                         "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "LessThan"     },
     177        "f32.le":              { "category": "comparison", "value":  95, "return": ["bool"],                         "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "LessEqual"    },
     178        "f32.gt":              { "category": "comparison", "value":  94, "return": ["bool"],                         "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "GreaterThan"  },
     179        "f32.ge":              { "category": "comparison", "value":  96, "return": ["bool"],                         "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "GreaterEqual" },
     180        "f64.add":             { "category": "arithmetic", "value": 160, "return": ["f64"],                          "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "Add"          },
     181        "f64.sub":             { "category": "arithmetic", "value": 161, "return": ["f64"],                          "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "Sub"          },
     182        "f64.mul":             { "category": "arithmetic", "value": 162, "return": ["f64"],                          "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "Mul"          },
     183        "f64.div":             { "category": "arithmetic", "value": 163, "return": ["f64"],                          "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "Div"          },
     184        "f64.min":             { "category": "arithmetic", "value": 164, "return": ["f64"],                          "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "Select(Equal(@0, @1), BitOr(@0, @1), Select(LessThan(@0, @1), @0, Select(GreaterThan(@0, @1), @1, Add(@0, @1))))" },
     185        "f64.max":             { "category": "arithmetic", "value": 165, "return": ["f64"],                          "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "Select(Equal(@0, @1), BitAnd(@0, @1), Select(LessThan(@0, @1), @1, Select(GreaterThan(@0, @1), @0, Add(@0, @1))))" },
     186        "f64.abs":             { "category": "arithmetic", "value": 153, "return": ["f64"],                          "parameter": ["f64"],                        "immediate": [], "b3op": "Abs"          },
     187        "f64.neg":             { "category": "arithmetic", "value": 154, "return": ["f64"],                          "parameter": ["f64"],                        "immediate": [], "b3op": "Neg"          },
     188        "f64.copysign":        { "category": "arithmetic", "value": 166, "return": ["f64"],                          "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "BitwiseCast(BitOr(BitAnd(BitwiseCast(@1), i64(0x8000000000000000)), BitAnd(BitwiseCast(@0), i64(0x7fffffffffffffff))))" },
     189        "f64.ceil":            { "category": "arithmetic", "value": 155, "return": ["f64"],                          "parameter": ["f64"],                        "immediate": [], "b3op": "Ceil"         },
     190        "f64.floor":           { "category": "arithmetic", "value": 156, "return": ["f64"],                          "parameter": ["f64"],                        "immediate": [], "b3op": "Floor"        },
     191        "f64.trunc":           { "category": "arithmetic", "value": 157, "return": ["f64"],                          "parameter": ["f64"],                        "immediate": []                         },
     192        "f64.nearest":         { "category": "arithmetic", "value": 158, "return": ["f64"],                          "parameter": ["f64"],                        "immediate": []                         },
     193        "f64.sqrt":            { "category": "arithmetic", "value": 159, "return": ["f64"],                          "parameter": ["f64"],                        "immediate": [], "b3op": "Sqrt"         },
     194        "f64.eq":              { "category": "comparison", "value":  97, "return": ["bool"],                         "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "Equal"        },
     195        "f64.ne":              { "category": "comparison", "value":  98, "return": ["bool"],                         "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "NotEqual"     },
     196        "f64.lt":              { "category": "comparison", "value":  99, "return": ["bool"],                         "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "LessThan"     },
     197        "f64.le":              { "category": "comparison", "value": 101, "return": ["bool"],                         "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "LessEqual"    },
     198        "f64.gt":              { "category": "comparison", "value": 100, "return": ["bool"],                         "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "GreaterThan"  },
     199        "f64.ge":              { "category": "comparison", "value": 102, "return": ["bool"],                         "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "GreaterEqual" },
     200        "i32.trunc_s/f32":     { "category": "conversion", "value": 168, "return": ["i32"],                          "parameter": ["f32"],                        "immediate": []                         },
     201        "i32.trunc_s/f64":     { "category": "conversion", "value": 170, "return": ["i32"],                          "parameter": ["f64"],                        "immediate": []                         },
     202        "i32.trunc_u/f32":     { "category": "conversion", "value": 169, "return": ["i32"],                          "parameter": ["f32"],                        "immediate": []                         },
     203        "i32.trunc_u/f64":     { "category": "conversion", "value": 171, "return": ["i32"],                          "parameter": ["f64"],                        "immediate": []                         },
     204        "i32.wrap/i64":        { "category": "conversion", "value": 167, "return": ["i32"],                          "parameter": ["i64"],                        "immediate": [], "b3op": "Trunc"        },
     205        "i64.trunc_s/f32":     { "category": "conversion", "value": 174, "return": ["i64"],                          "parameter": ["f32"],                        "immediate": []                         },
     206        "i64.trunc_s/f64":     { "category": "conversion", "value": 176, "return": ["i64"],                          "parameter": ["f64"],                        "immediate": []                         },
     207        "i64.trunc_u/f32":     { "category": "conversion", "value": 175, "return": ["i64"],                          "parameter": ["f32"],                        "immediate": []                         },
     208        "i64.trunc_u/f64":     { "category": "conversion", "value": 177, "return": ["i64"],                          "parameter": ["f64"],                        "immediate": []                         },
     209        "i64.extend_s/i32":    { "category": "conversion", "value": 172, "return": ["i64"],                          "parameter": ["i32"],                        "immediate": [], "b3op": "SExt32"       },
     210        "i64.extend_u/i32":    { "category": "conversion", "value": 173, "return": ["i64"],                          "parameter": ["i32"],                        "immediate": [], "b3op": "ZExt32"       },
     211        "f32.convert_s/i32":   { "category": "conversion", "value": 178, "return": ["f32"],                          "parameter": ["i32"],                        "immediate": [], "b3op": "IToF"         },
     212        "f32.convert_u/i32":   { "category": "conversion", "value": 179, "return": ["f32"],                          "parameter": ["i32"],                        "immediate": [], "b3op": "IToF(ZExt32(@0))" },
     213        "f32.convert_s/i64":   { "category": "conversion", "value": 180, "return": ["f32"],                          "parameter": ["i64"],                        "immediate": [], "b3op": "IToF"         },
     214        "f32.convert_u/i64":   { "category": "conversion", "value": 181, "return": ["f32"],                          "parameter": ["i64"],                        "immediate": []                         },
     215        "f32.demote/f64":      { "category": "conversion", "value": 182, "return": ["f32"],                          "parameter": ["f64"],                        "immediate": [], "b3op": "DoubleToFloat"},
     216        "f32.reinterpret/i32": { "category": "conversion", "value": 190, "return": ["f32"],                          "parameter": ["i32"],                        "immediate": [], "b3op": "BitwiseCast"  },
     217        "f64.convert_s/i32":   { "category": "conversion", "value": 183, "return": ["f64"],                          "parameter": ["i32"],                        "immediate": [], "b3op": "IToD"         },
     218        "f64.convert_u/i32":   { "category": "conversion", "value": 184, "return": ["f64"],                          "parameter": ["i32"],                        "immediate": [], "b3op": "IToD(ZExt32(@0))" },
     219        "f64.convert_s/i64":   { "category": "conversion", "value": 185, "return": ["f64"],                          "parameter": ["i64"],                        "immediate": [], "b3op": "IToD"         },
     220        "f64.convert_u/i64":   { "category": "conversion", "value": 186, "return": ["f64"],                          "parameter": ["i64"],                        "immediate": []                         },
     221        "f64.promote/f32":     { "category": "conversion", "value": 187, "return": ["f64"],                          "parameter": ["f32"],                        "immediate": [], "b3op": "FloatToDouble"},
     222        "f64.reinterpret/i64": { "category": "conversion", "value": 191, "return": ["f64"],                          "parameter": ["i64"],                        "immediate": [], "b3op": "BitwiseCast"  },
     223        "i32.reinterpret/f32": { "category": "conversion", "value": 188, "return": ["i32"],                          "parameter": ["f32"],                        "immediate": [], "b3op": "BitwiseCast"  },
     224        "i64.reinterpret/f64": { "category": "conversion", "value": 189, "return": ["i64"],                          "parameter": ["f64"],                        "immediate": [], "b3op": "BitwiseCast"  }
    225225    }
    226226}
  • trunk/Source/JavaScriptCore/ChangeLog

    r269712 r269729  
     12020-11-12  Dmitry Bezhetskov  <dbezhetskov@igalia.com>
     2
     3        [WASM-References] Support imm for ref.null
     4        https://bugs.webkit.org/show_bug.cgi?id=218744
     5
     6        Reviewed by Yusuke Suzuki.
     7       
     8        Updated ref.null according to the ref-types spec:
     9        https://github.com/WebAssembly/reference-types/.
     10
     11        * wasm/WasmFormat.h:
     12        (JSC::Wasm::isRefType):
     13        * wasm/WasmFunctionParser.h:
     14        (JSC::Wasm::FunctionParser<Context>::parseExpression):
     15        * wasm/WasmParser.h:
     16        (JSC::Wasm::Parser<SuccessType>::parseRefType):
     17        * wasm/WasmSectionParser.cpp:
     18        (JSC::Wasm::SectionParser::parseInitExpr):
     19        * wasm/wasm.json:
     20
    1212020-11-11  John Wilander  <wilander@apple.com>
    222
  • trunk/Source/JavaScriptCore/wasm/WasmFormat.h

    r269552 r269729  
    8585    return sub == Funcref && parent == Externref;
    8686}
     87
     88inline bool isRefType(Type type)
     89{
     90    return type == Externref || type == Funcref;
     91}
    8792   
    8893enum class ExternalKind : uint8_t {
  • trunk/Source/JavaScriptCore/wasm/WasmFunctionParser.h

    r269552 r269729  
    494494    case RefNull: {
    495495        WASM_PARSER_FAIL_IF(!Options::useWebAssemblyReferences(), "references are not enabled");
    496         m_expressionStack.constructAndAppend(Funcref, m_context.addConstant(Funcref, JSValue::encode(jsNull())));
     496        Type typeOfNull;
     497        WASM_PARSER_FAIL_IF(!parseRefType(typeOfNull), "ref.null type must be a reference type");
     498        m_expressionStack.constructAndAppend(typeOfNull, m_context.addConstant(typeOfNull, JSValue::encode(jsNull())));
    497499        return { };
    498500    }
  • trunk/Source/JavaScriptCore/wasm/WasmParser.h

    r255394 r269729  
    8686    PartialResult WARN_UNUSED_RETURN parseBlockSignature(const ModuleInformation&, BlockSignature&);
    8787    bool WARN_UNUSED_RETURN parseValueType(Type&);
     88    bool WARN_UNUSED_RETURN parseRefType(Type&);
    8889    bool WARN_UNUSED_RETURN parseExternalKind(ExternalKind&);
    8990
     
    308309
    309310template<typename SuccessType>
     311ALWAYS_INLINE bool Parser<SuccessType>::parseRefType(Type& result)
     312{
     313    const bool parsed = parseValueType(result);
     314    return parsed && isRefType(result);
     315}
     316
     317template<typename SuccessType>
    310318ALWAYS_INLINE bool Parser<SuccessType>::parseExternalKind(ExternalKind& result)
    311319{
  • trunk/Source/JavaScriptCore/wasm/WasmSectionParser.cpp

    r269552 r269729  
    475475
    476476    case RefNull: {
    477         resultType = Funcref;
     477        Type typeOfNull;
     478        WASM_PARSER_FAIL_IF(!parseRefType(typeOfNull), "ref.null type must be a reference type");
     479        resultType = typeOfNull;
    478480        bitsOrImportNumber = JSValue::encode(jsNull());
    479481        break;
  • trunk/Source/JavaScriptCore/wasm/wasm.json

    r269552 r269729  
    1919    "value_type": ["i32", "i64", "f32", "f64", "externref", "funcref"],
    2020    "block_type": ["i32", "i64", "f32", "f64", "void", "externref", "funcref"],
    21     "elem_type": ["funcref","externref"],
     21    "ref_type": ["funcref","externref"],
    2222    "external_kind": {
    2323        "Function": { "type": "uint8", "value": 0 },
     
    4040    },
    4141    "opcode": {
    42         "unreachable":         { "category": "control",    "value":   0, "return": [],              "parameter": [],                             "immediate": [],                                                                                            "description": "trap immediately" },
    43         "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" },
    44         "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" },
    45         "if":                  { "category": "control",    "value":   4, "return": ["control"],     "parameter": ["bool"],                       "immediate": [{"name": "sig", "type": "block_type"}],                                                       "description": "begin if expression" },
    46         "else":                { "category": "control",    "value":   5, "return": ["control"],     "parameter": [],                             "immediate": [],                                                                                            "description": "begin else expression of if" },
    47         "select":              { "category": "control",    "value":  27, "return": ["prev"],        "parameter": ["any", "prev", "bool"],        "immediate": [],                                                                                            "description": "select one of two values based on condition" },
    48         "br":                  { "category": "control",    "value":  12, "return": [],              "parameter": [],                             "immediate": [{"name": "relative_depth", "type": "varuint32"}],                                             "description": "break that targets an outer nested block" },
    49         "br_if":               { "category": "control",    "value":  13, "return": [],              "parameter": [],                             "immediate": [{"name": "relative_depth", "type": "varuint32"}],                                             "description": "conditional break that targets an outer nested block" },
    50         "br_table":            { "category": "control",    "value":  14, "return": [],              "parameter": [],                             "immediate": [{"name": "target_count",   "type": "varuint32",                                               "description": "number of entries in the target_table"},
    51                                                                                                                                                                {"name": "target_table",   "type": "varuint32*",                                              "description": "target entries that indicate an outer block or loop to which to break"},
    52                                                                                                                                                                {"name": "default_target", "type": "varuint32",                                               "description": "an outer block or loop to which to break in the default case"}],
    53                                                                                                                                                                                                                                                              "description": "branch table control flow construct" },
    54         "return":              { "category": "control",    "value":  15, "return": [],              "parameter": [],                             "immediate": [],                                                                                            "description": "return zero or one value from this function" },
    55         "drop":                { "category": "control",    "value":  26, "return": [],              "parameter": ["any"],                        "immediate": [],                                                                                            "description": "ignore value" },
    56         "nop":                 { "category": "control",    "value":   1, "return": [],              "parameter": [],                             "immediate": [],                                                                                            "description": "no operation" },
    57         "end":                 { "category": "control",    "value":  11, "return": [],              "parameter": [],                             "immediate": [],                                                                                            "description": "end a block, loop, or if" },
    58         "i32.const":           { "category": "special",    "value":  65, "return": ["i32"],         "parameter": [],                             "immediate": [{"name": "value",          "type": "varint32"}],                                              "description": "a constant value interpreted as i32" },
    59         "i64.const":           { "category": "special",    "value":  66, "return": ["i64"],         "parameter": [],                             "immediate": [{"name": "value",          "type": "varint64"}],                                              "description": "a constant value interpreted as i64" },
    60         "f64.const":           { "category": "special",    "value":  68, "return": ["f64"],         "parameter": [],                             "immediate": [{"name": "value",          "type": "double"}],                                                "description": "a constant value interpreted as f64" },
    61         "f32.const":           { "category": "special",    "value":  67, "return": ["f32"],         "parameter": [],                             "immediate": [{"name": "value",          "type": "float"}],                                                 "description": "a constant value interpreted as f32" },
    62         "ref.null":            { "category": "special",    "value": 208, "return": ["funcref"],     "parameter": [],                             "immediate": [],                                                                                            "description": "a constant null reference" },
    63         "ref.is_null":         { "category": "special",    "value": 209, "return": ["i32"],         "parameter": ["externref"],                  "immediate": [],                                                                                            "description": "determine if a reference is null" },
    64         "ref.func":            { "category": "special",    "value": 210, "return": ["funcref"],     "parameter": [],                             "immediate": [{"name": "function_index", "type": "varuint32"}],                                             "description": "return a reference to the function at the given index" },
    65         "get_local":           { "category": "special",    "value":  32, "return": ["any"],         "parameter": [],                             "immediate": [{"name": "local_index",    "type": "varuint32"}],                                             "description": "read a local variable or parameter" },
    66         "set_local":           { "category": "special",    "value":  33, "return": [],              "parameter": ["any"],                        "immediate": [{"name": "local_index",    "type": "varuint32"}],                                             "description": "write a local variable or parameter" },
    67         "tee_local":           { "category": "special",    "value":  34, "return": ["any"],         "parameter": ["any"],                        "immediate": [{"name": "local_index",    "type": "varuint32"}],                                             "description": "write a local variable or parameter and return the same value" },
    68         "get_global":          { "category": "special",    "value":  35, "return": ["any"],         "parameter": [],                             "immediate": [{"name": "global_index",   "type": "varuint32"}],                                             "description": "read a global variable" },
    69         "set_global":          { "category": "special",    "value":  36, "return": [],              "parameter": ["any"],                        "immediate": [{"name": "global_index",   "type": "varuint32"}],                                             "description": "write a global variable" },
    70         "table.get":           { "category": "special",    "value":  37, "return": ["externref"],   "parameter": ["i32"],                        "immediate": [{"name": "table_index",    "type": "varuint32"}],                                             "description": "get a table value" },
    71         "table.set":           { "category": "special",    "value":  38, "return": [],              "parameter": ["i32", "externref"],           "immediate": [{"name": "table_index",    "type": "varuint32"}],                                             "description": "set a table value" },
    72         "table.size":          { "category": "exttable",   "value":  252, "return": ["i32"],        "parameter": [],                             "immediate": [{"name": "table_index",    "type": "varuint32"}],                                             "description": "get the size of a table", "extendedOp": 15 },
    73         "table.grow":          { "category": "exttable",   "value":  252, "return": ["i32"],        "parameter": ["externref", "i32"],           "immediate": [{"name": "table_index",    "type": "varuint32"}],                                             "description": "grow a table by the given delta and return the previous size, or -1 if enough space cannot be allocated", "extendedOp": 16 },
    74         "table.fill":          { "category": "exttable",   "value":  252, "return": ["i32"],        "parameter": ["i32", "externref", "i32"],    "immediate": [{"name": "table_index",    "type": "varuint32"}],                                             "description": "fill entries [i,i+n) with the given value", "extendedOp": 17 },
    75         "call":                { "category": "call",       "value":  16, "return": ["call"],        "parameter": ["call"],                       "immediate": [{"name": "function_index", "type": "varuint32"}],                                             "description": "call a function by its index" },
    76         "call_indirect":       { "category": "call",       "value":  17, "return": ["call"],        "parameter": ["call"],                       "immediate": [{"name": "type_index",     "type": "varuint32"}, {"name": "table_index","type": "varuint32"}],"description": "call a function indirect with an expected signature" },
    77         "i32.load8_s":         { "category": "memory",     "value":  44, "return": ["i32"],         "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
    78         "i32.load8_u":         { "category": "memory",     "value":  45, "return": ["i32"],         "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
    79         "i32.load16_s":        { "category": "memory",     "value":  46, "return": ["i32"],         "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
    80         "i32.load16_u":        { "category": "memory",     "value":  47, "return": ["i32"],         "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
    81         "i64.load8_s":         { "category": "memory",     "value":  48, "return": ["i64"],         "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
    82         "i64.load8_u":         { "category": "memory",     "value":  49, "return": ["i64"],         "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
    83         "i64.load16_s":        { "category": "memory",     "value":  50, "return": ["i64"],         "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
    84         "i64.load16_u":        { "category": "memory",     "value":  51, "return": ["i64"],         "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
    85         "i64.load32_s":        { "category": "memory",     "value":  52, "return": ["i64"],         "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
    86         "i64.load32_u":        { "category": "memory",     "value":  53, "return": ["i64"],         "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
    87         "i32.load":            { "category": "memory",     "value":  40, "return": ["i32"],         "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
    88         "i64.load":            { "category": "memory",     "value":  41, "return": ["i64"],         "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
    89         "f32.load":            { "category": "memory",     "value":  42, "return": ["f32"],         "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
    90         "f64.load":            { "category": "memory",     "value":  43, "return": ["f64"],         "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
    91         "i32.store8":          { "category": "memory",     "value":  58, "return": [],              "parameter": ["addr", "i32"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
    92         "i32.store16":         { "category": "memory",     "value":  59, "return": [],              "parameter": ["addr", "i32"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
    93         "i64.store8":          { "category": "memory",     "value":  60, "return": [],              "parameter": ["addr", "i64"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
    94         "i64.store16":         { "category": "memory",     "value":  61, "return": [],              "parameter": ["addr", "i64"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
    95         "i64.store32":         { "category": "memory",     "value":  62, "return": [],              "parameter": ["addr", "i64"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
    96         "i32.store":           { "category": "memory",     "value":  54, "return": [],              "parameter": ["addr", "i32"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
    97         "i64.store":           { "category": "memory",     "value":  55, "return": [],              "parameter": ["addr", "i64"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
    98         "f32.store":           { "category": "memory",     "value":  56, "return": [],              "parameter": ["addr", "f32"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
    99         "f64.store":           { "category": "memory",     "value":  57, "return": [],              "parameter": ["addr", "f64"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
    100         "current_memory":      { "category": "operation",  "value":  63, "return": ["size"],        "parameter": [],                             "immediate": [{"name": "flags",          "type": "varuint32"}],                                            "description": "query the size of memory" },
    101         "grow_memory":         { "category": "operation",  "value":  64, "return": ["size"],        "parameter": ["size"],                       "immediate": [{"name": "flags",          "type": "varuint32"}],                                            "description": "grow the size of memory" },
    102         "i32.add":             { "category": "arithmetic", "value": 106, "return": ["i32"],         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "Add"          },
    103         "i32.sub":             { "category": "arithmetic", "value": 107, "return": ["i32"],         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "Sub"          },
    104         "i32.mul":             { "category": "arithmetic", "value": 108, "return": ["i32"],         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "Mul"          },
    105         "i32.div_s":           { "category": "arithmetic", "value": 109, "return": ["i32"],         "parameter": ["i32", "i32"],                 "immediate": []                         },
    106         "i32.div_u":           { "category": "arithmetic", "value": 110, "return": ["i32"],         "parameter": ["i32", "i32"],                 "immediate": []                         },
    107         "i32.rem_s":           { "category": "arithmetic", "value": 111, "return": ["i32"],         "parameter": ["i32", "i32"],                 "immediate": []                         },
    108         "i32.rem_u":           { "category": "arithmetic", "value": 112, "return": ["i32"],         "parameter": ["i32", "i32"],                 "immediate": []                         },
    109         "i32.and":             { "category": "arithmetic", "value": 113, "return": ["i32"],         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "BitAnd"       },
    110         "i32.or":              { "category": "arithmetic", "value": 114, "return": ["i32"],         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "BitOr"        },
    111         "i32.xor":             { "category": "arithmetic", "value": 115, "return": ["i32"],         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "BitXor"       },
    112         "i32.shl":             { "category": "arithmetic", "value": 116, "return": ["i32"],         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "Shl"          },
    113         "i32.shr_u":           { "category": "arithmetic", "value": 118, "return": ["i32"],         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "ZShr"         },
    114         "i32.shr_s":           { "category": "arithmetic", "value": 117, "return": ["i32"],         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "SShr"         },
    115         "i32.rotr":            { "category": "arithmetic", "value": 120, "return": ["i32"],         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "RotR"         },
    116         "i32.rotl":            { "category": "arithmetic", "value": 119, "return": ["i32"],         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "RotL"         },
    117         "i32.eq":              { "category": "comparison", "value":  70, "return": ["bool"],        "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "Equal"        },
    118         "i32.ne":              { "category": "comparison", "value":  71, "return": ["bool"],        "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "NotEqual"     },
    119         "i32.lt_s":            { "category": "comparison", "value":  72, "return": ["bool"],        "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "LessThan"     },
    120         "i32.le_s":            { "category": "comparison", "value":  76, "return": ["bool"],        "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "LessEqual"    },
    121         "i32.lt_u":            { "category": "comparison", "value":  73, "return": ["bool"],        "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "Below"        },
    122         "i32.le_u":            { "category": "comparison", "value":  77, "return": ["bool"],        "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "BelowEqual"   },
    123         "i32.gt_s":            { "category": "comparison", "value":  74, "return": ["bool"],        "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "GreaterThan"  },
    124         "i32.ge_s":            { "category": "comparison", "value":  78, "return": ["bool"],        "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "GreaterEqual" },
    125         "i32.gt_u":            { "category": "comparison", "value":  75, "return": ["bool"],        "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "Above"        },
    126         "i32.ge_u":            { "category": "comparison", "value":  79, "return": ["bool"],        "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "AboveEqual"   },
    127         "i32.clz":             { "category": "arithmetic", "value": 103, "return": ["i32"],         "parameter": ["i32"],                        "immediate": [], "b3op": "Clz"          },
    128         "i32.ctz":             { "category": "arithmetic", "value": 104, "return": ["i32"],         "parameter": ["i32"],                        "immediate": []                         },
    129         "i32.popcnt":          { "category": "arithmetic", "value": 105, "return": ["i32"],         "parameter": ["i32"],                        "immediate": []                         },
    130         "i32.eqz":             { "category": "comparison", "value":  69, "return": ["bool"],        "parameter": ["i32"],                        "immediate": [], "b3op": "Equal(i32(0), @0)" },
    131         "i64.add":             { "category": "arithmetic", "value": 124, "return": ["i64"],         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "Add"          },
    132         "i64.sub":             { "category": "arithmetic", "value": 125, "return": ["i64"],         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "Sub"          },
    133         "i64.mul":             { "category": "arithmetic", "value": 126, "return": ["i64"],         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "Mul"          },
    134         "i64.div_s":           { "category": "arithmetic", "value": 127, "return": ["i64"],         "parameter": ["i64", "i64"],                 "immediate": []                         },
    135         "i64.div_u":           { "category": "arithmetic", "value": 128, "return": ["i64"],         "parameter": ["i64", "i64"],                 "immediate": []                         },
    136         "i64.rem_s":           { "category": "arithmetic", "value": 129, "return": ["i64"],         "parameter": ["i64", "i64"],                 "immediate": []                         },
    137         "i64.rem_u":           { "category": "arithmetic", "value": 130, "return": ["i64"],         "parameter": ["i64", "i64"],                 "immediate": []                         },
    138         "i64.and":             { "category": "arithmetic", "value": 131, "return": ["i64"],         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "BitAnd"       },
    139         "i64.or":              { "category": "arithmetic", "value": 132, "return": ["i64"],         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "BitOr"        },
    140         "i64.xor":             { "category": "arithmetic", "value": 133, "return": ["i64"],         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "BitXor"       },
    141         "i64.shl":             { "category": "arithmetic", "value": 134, "return": ["i64"],         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "Shl(@0, Trunc(@1))" },
    142         "i64.shr_u":           { "category": "arithmetic", "value": 136, "return": ["i64"],         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "ZShr(@0, Trunc(@1))" },
    143         "i64.shr_s":           { "category": "arithmetic", "value": 135, "return": ["i64"],         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "SShr(@0, Trunc(@1))" },
    144         "i64.rotr":            { "category": "arithmetic", "value": 138, "return": ["i64"],         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "RotR(@0, Trunc(@1))" },
    145         "i64.rotl":            { "category": "arithmetic", "value": 137, "return": ["i64"],         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "RotL(@0, Trunc(@1))" },
    146         "i64.eq":              { "category": "comparison", "value":  81, "return": ["bool"],        "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "Equal"        },
    147         "i64.ne":              { "category": "comparison", "value":  82, "return": ["bool"],        "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "NotEqual"     },
    148         "i64.lt_s":            { "category": "comparison", "value":  83, "return": ["bool"],        "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "LessThan"     },
    149         "i64.le_s":            { "category": "comparison", "value":  87, "return": ["bool"],        "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "LessEqual"    },
    150         "i64.lt_u":            { "category": "comparison", "value":  84, "return": ["bool"],        "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "Below"        },
    151         "i64.le_u":            { "category": "comparison", "value":  88, "return": ["bool"],        "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "BelowEqual"   },
    152         "i64.gt_s":            { "category": "comparison", "value":  85, "return": ["bool"],        "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "GreaterThan"  },
    153         "i64.ge_s":            { "category": "comparison", "value":  89, "return": ["bool"],        "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "GreaterEqual" },
    154         "i64.gt_u":            { "category": "comparison", "value":  86, "return": ["bool"],        "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "Above"        },
    155         "i64.ge_u":            { "category": "comparison", "value":  90, "return": ["bool"],        "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "AboveEqual"   },
    156         "i64.clz":             { "category": "arithmetic", "value": 121, "return": ["i64"],         "parameter": ["i64"],                        "immediate": [], "b3op": "Clz"          },
    157         "i64.ctz":             { "category": "arithmetic", "value": 122, "return": ["i64"],         "parameter": ["i64"],                        "immediate": []                         },
    158         "i64.popcnt":          { "category": "arithmetic", "value": 123, "return": ["i64"],         "parameter": ["i64"],                        "immediate": []                         },
    159         "i64.eqz":             { "category": "comparison", "value":  80, "return": ["bool"],        "parameter": ["i64"],                        "immediate": [], "b3op": "Equal(i64(0), @0)" },
    160         "f32.add":             { "category": "arithmetic", "value": 146, "return": ["f32"],         "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "Add"          },
    161         "f32.sub":             { "category": "arithmetic", "value": 147, "return": ["f32"],         "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "Sub"          },
    162         "f32.mul":             { "category": "arithmetic", "value": 148, "return": ["f32"],         "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "Mul"          },
    163         "f32.div":             { "category": "arithmetic", "value": 149, "return": ["f32"],         "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "Div"          },
    164         "f32.min":             { "category": "arithmetic", "value": 150, "return": ["f32"],         "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "Select(Equal(@0, @1), BitOr(@0, @1), Select(LessThan(@0, @1), @0, Select(GreaterThan(@0, @1), @1, Add(@0, @1))))" },
    165         "f32.max":             { "category": "arithmetic", "value": 151, "return": ["f32"],         "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "Select(Equal(@0, @1), BitAnd(@0, @1), Select(LessThan(@0, @1), @1, Select(GreaterThan(@0, @1), @0, Add(@0, @1))))" },
    166         "f32.abs":             { "category": "arithmetic", "value": 139, "return": ["f32"],         "parameter": ["f32"],                        "immediate": [], "b3op": "Abs"          },
    167         "f32.neg":             { "category": "arithmetic", "value": 140, "return": ["f32"],         "parameter": ["f32"],                        "immediate": [], "b3op": "Neg"          },
    168         "f32.copysign":        { "category": "arithmetic", "value": 152, "return": ["f32"],         "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "BitwiseCast(BitOr(BitAnd(BitwiseCast(@1), i32(0x80000000)), BitAnd(BitwiseCast(@0), i32(0x7fffffff))))" },
    169         "f32.ceil":            { "category": "arithmetic", "value": 141, "return": ["f32"],         "parameter": ["f32"],                        "immediate": [], "b3op": "Ceil"         },
    170         "f32.floor":           { "category": "arithmetic", "value": 142, "return": ["f32"],         "parameter": ["f32"],                        "immediate": [], "b3op": "Floor"        },
    171         "f32.trunc":           { "category": "arithmetic", "value": 143, "return": ["f32"],         "parameter": ["f32"],                        "immediate": []                         },
    172         "f32.nearest":         { "category": "arithmetic", "value": 144, "return": ["f32"],         "parameter": ["f32"],                        "immediate": []                         },
    173         "f32.sqrt":            { "category": "arithmetic", "value": 145, "return": ["f32"],         "parameter": ["f32"],                        "immediate": [], "b3op": "Sqrt"         },
    174         "f32.eq":              { "category": "comparison", "value":  91, "return": ["bool"],        "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "Equal"        },
    175         "f32.ne":              { "category": "comparison", "value":  92, "return": ["bool"],        "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "NotEqual"     },
    176         "f32.lt":              { "category": "comparison", "value":  93, "return": ["bool"],        "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "LessThan"     },
    177         "f32.le":              { "category": "comparison", "value":  95, "return": ["bool"],        "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "LessEqual"    },
    178         "f32.gt":              { "category": "comparison", "value":  94, "return": ["bool"],        "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "GreaterThan"  },
    179         "f32.ge":              { "category": "comparison", "value":  96, "return": ["bool"],        "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "GreaterEqual" },
    180         "f64.add":             { "category": "arithmetic", "value": 160, "return": ["f64"],         "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "Add"          },
    181         "f64.sub":             { "category": "arithmetic", "value": 161, "return": ["f64"],         "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "Sub"          },
    182         "f64.mul":             { "category": "arithmetic", "value": 162, "return": ["f64"],         "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "Mul"          },
    183         "f64.div":             { "category": "arithmetic", "value": 163, "return": ["f64"],         "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "Div"          },
    184         "f64.min":             { "category": "arithmetic", "value": 164, "return": ["f64"],         "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "Select(Equal(@0, @1), BitOr(@0, @1), Select(LessThan(@0, @1), @0, Select(GreaterThan(@0, @1), @1, Add(@0, @1))))" },
    185         "f64.max":             { "category": "arithmetic", "value": 165, "return": ["f64"],         "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "Select(Equal(@0, @1), BitAnd(@0, @1), Select(LessThan(@0, @1), @1, Select(GreaterThan(@0, @1), @0, Add(@0, @1))))" },
    186         "f64.abs":             { "category": "arithmetic", "value": 153, "return": ["f64"],         "parameter": ["f64"],                        "immediate": [], "b3op": "Abs"          },
    187         "f64.neg":             { "category": "arithmetic", "value": 154, "return": ["f64"],         "parameter": ["f64"],                        "immediate": [], "b3op": "Neg"          },
    188         "f64.copysign":        { "category": "arithmetic", "value": 166, "return": ["f64"],         "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "BitwiseCast(BitOr(BitAnd(BitwiseCast(@1), i64(0x8000000000000000)), BitAnd(BitwiseCast(@0), i64(0x7fffffffffffffff))))" },
    189         "f64.ceil":            { "category": "arithmetic", "value": 155, "return": ["f64"],         "parameter": ["f64"],                        "immediate": [], "b3op": "Ceil"         },
    190         "f64.floor":           { "category": "arithmetic", "value": 156, "return": ["f64"],         "parameter": ["f64"],                        "immediate": [], "b3op": "Floor"        },
    191         "f64.trunc":           { "category": "arithmetic", "value": 157, "return": ["f64"],         "parameter": ["f64"],                        "immediate": []                         },
    192         "f64.nearest":         { "category": "arithmetic", "value": 158, "return": ["f64"],         "parameter": ["f64"],                        "immediate": []                         },
    193         "f64.sqrt":            { "category": "arithmetic", "value": 159, "return": ["f64"],         "parameter": ["f64"],                        "immediate": [], "b3op": "Sqrt"         },
    194         "f64.eq":              { "category": "comparison", "value":  97, "return": ["bool"],        "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "Equal"        },
    195         "f64.ne":              { "category": "comparison", "value":  98, "return": ["bool"],        "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "NotEqual"     },
    196         "f64.lt":              { "category": "comparison", "value":  99, "return": ["bool"],        "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "LessThan"     },
    197         "f64.le":              { "category": "comparison", "value": 101, "return": ["bool"],        "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "LessEqual"    },
    198         "f64.gt":              { "category": "comparison", "value": 100, "return": ["bool"],        "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "GreaterThan"  },
    199         "f64.ge":              { "category": "comparison", "value": 102, "return": ["bool"],        "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "GreaterEqual" },
    200         "i32.trunc_s/f32":     { "category": "conversion", "value": 168, "return": ["i32"],         "parameter": ["f32"],                        "immediate": []                         },
    201         "i32.trunc_s/f64":     { "category": "conversion", "value": 170, "return": ["i32"],         "parameter": ["f64"],                        "immediate": []                         },
    202         "i32.trunc_u/f32":     { "category": "conversion", "value": 169, "return": ["i32"],         "parameter": ["f32"],                        "immediate": []                         },
    203         "i32.trunc_u/f64":     { "category": "conversion", "value": 171, "return": ["i32"],         "parameter": ["f64"],                        "immediate": []                         },
    204         "i32.wrap/i64":        { "category": "conversion", "value": 167, "return": ["i32"],         "parameter": ["i64"],                        "immediate": [], "b3op": "Trunc"        },
    205         "i64.trunc_s/f32":     { "category": "conversion", "value": 174, "return": ["i64"],         "parameter": ["f32"],                        "immediate": []                         },
    206         "i64.trunc_s/f64":     { "category": "conversion", "value": 176, "return": ["i64"],         "parameter": ["f64"],                        "immediate": []                         },
    207         "i64.trunc_u/f32":     { "category": "conversion", "value": 175, "return": ["i64"],         "parameter": ["f32"],                        "immediate": []                         },
    208         "i64.trunc_u/f64":     { "category": "conversion", "value": 177, "return": ["i64"],         "parameter": ["f64"],                        "immediate": []                         },
    209         "i64.extend_s/i32":    { "category": "conversion", "value": 172, "return": ["i64"],         "parameter": ["i32"],                        "immediate": [], "b3op": "SExt32"       },
    210         "i64.extend_u/i32":    { "category": "conversion", "value": 173, "return": ["i64"],         "parameter": ["i32"],                        "immediate": [], "b3op": "ZExt32"       },
    211         "f32.convert_s/i32":   { "category": "conversion", "value": 178, "return": ["f32"],         "parameter": ["i32"],                        "immediate": [], "b3op": "IToF"         },
    212         "f32.convert_u/i32":   { "category": "conversion", "value": 179, "return": ["f32"],         "parameter": ["i32"],                        "immediate": [], "b3op": "IToF(ZExt32(@0))" },
    213         "f32.convert_s/i64":   { "category": "conversion", "value": 180, "return": ["f32"],         "parameter": ["i64"],                        "immediate": [], "b3op": "IToF"         },
    214         "f32.convert_u/i64":   { "category": "conversion", "value": 181, "return": ["f32"],         "parameter": ["i64"],                        "immediate": []                         },
    215         "f32.demote/f64":      { "category": "conversion", "value": 182, "return": ["f32"],         "parameter": ["f64"],                        "immediate": [], "b3op": "DoubleToFloat"},
    216         "f32.reinterpret/i32": { "category": "conversion", "value": 190, "return": ["f32"],         "parameter": ["i32"],                        "immediate": [], "b3op": "BitwiseCast"  },
    217         "f64.convert_s/i32":   { "category": "conversion", "value": 183, "return": ["f64"],         "parameter": ["i32"],                        "immediate": [], "b3op": "IToD"         },
    218         "f64.convert_u/i32":   { "category": "conversion", "value": 184, "return": ["f64"],         "parameter": ["i32"],                        "immediate": [], "b3op": "IToD(ZExt32(@0))" },
    219         "f64.convert_s/i64":   { "category": "conversion", "value": 185, "return": ["f64"],         "parameter": ["i64"],                        "immediate": [], "b3op": "IToD"         },
    220         "f64.convert_u/i64":   { "category": "conversion", "value": 186, "return": ["f64"],         "parameter": ["i64"],                        "immediate": []                         },
    221         "f64.promote/f32":     { "category": "conversion", "value": 187, "return": ["f64"],         "parameter": ["f32"],                        "immediate": [], "b3op": "FloatToDouble"},
    222         "f64.reinterpret/i64": { "category": "conversion", "value": 191, "return": ["f64"],         "parameter": ["i64"],                        "immediate": [], "b3op": "BitwiseCast"  },
    223         "i32.reinterpret/f32": { "category": "conversion", "value": 188, "return": ["i32"],         "parameter": ["f32"],                        "immediate": [], "b3op": "BitwiseCast"  },
    224         "i64.reinterpret/f64": { "category": "conversion", "value": 189, "return": ["i64"],         "parameter": ["f64"],                        "immediate": [], "b3op": "BitwiseCast"  }
     42        "unreachable":         { "category": "control",    "value":   0, "return": [],                               "parameter": [],                             "immediate": [],                                                                                            "description": "trap immediately" },
     43        "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" },
     44        "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" },
     45        "if":                  { "category": "control",    "value":   4, "return": ["control"],                      "parameter": ["bool"],                       "immediate": [{"name": "sig", "type": "block_type"}],                                                       "description": "begin if expression" },
     46        "else":                { "category": "control",    "value":   5, "return": ["control"],                      "parameter": [],                             "immediate": [],                                                                                            "description": "begin else expression of if" },
     47        "select":              { "category": "control",    "value":  27, "return": ["prev"],                         "parameter": ["any", "prev", "bool"],        "immediate": [],                                                                                            "description": "select one of two values based on condition" },
     48        "br":                  { "category": "control",    "value":  12, "return": [],                               "parameter": [],                             "immediate": [{"name": "relative_depth", "type": "varuint32"}],                                             "description": "break that targets an outer nested block" },
     49        "br_if":               { "category": "control",    "value":  13, "return": [],                               "parameter": [],                             "immediate": [{"name": "relative_depth", "type": "varuint32"}],                                             "description": "conditional break that targets an outer nested block" },
     50        "br_table":            { "category": "control",    "value":  14, "return": [],                               "parameter": [],                             "immediate": [{"name": "target_count",   "type": "varuint32",                                               "description": "number of entries in the target_table"},
     51                                                                                                                                                                                {"name": "target_table",   "type": "varuint32*",                                              "description": "target entries that indicate an outer block or loop to which to break"},
     52                                                                                                                                                                                {"name": "default_target", "type": "varuint32",                                               "description": "an outer block or loop to which to break in the default case"}],
     53                                                                                                                                                                                                                                                                              "description": "branch table control flow construct" },
     54        "return":              { "category": "control",    "value":  15, "return": [],                               "parameter": [],                             "immediate": [],                                                                                            "description": "return zero or one value from this function" },
     55        "drop":                { "category": "control",    "value":  26, "return": [],                               "parameter": ["any"],                        "immediate": [],                                                                                            "description": "ignore value" },
     56        "nop":                 { "category": "control",    "value":   1, "return": [],                               "parameter": [],                             "immediate": [],                                                                                            "description": "no operation" },
     57        "end":                 { "category": "control",    "value":  11, "return": [],                               "parameter": [],                             "immediate": [],                                                                                            "description": "end a block, loop, or if" },
     58        "i32.const":           { "category": "special",    "value":  65, "return": ["i32"],                          "parameter": [],                             "immediate": [{"name": "value",          "type": "varint32"}],                                              "description": "a constant value interpreted as i32" },
     59        "i64.const":           { "category": "special",    "value":  66, "return": ["i64"],                          "parameter": [],                             "immediate": [{"name": "value",          "type": "varint64"}],                                              "description": "a constant value interpreted as i64" },
     60        "f64.const":           { "category": "special",    "value":  68, "return": ["f64"],                          "parameter": [],                             "immediate": [{"name": "value",          "type": "double"}],                                                "description": "a constant value interpreted as f64" },
     61        "f32.const":           { "category": "special",    "value":  67, "return": ["f32"],                          "parameter": [],                             "immediate": [{"name": "value",          "type": "float"}],                                                 "description": "a constant value interpreted as f32" },
     62        "ref.null":            { "category": "special",    "value": 208, "return": ["externref", "funcref"],         "parameter": [],                             "immediate": [{"name": "reftype",        "type": "ref_type"}],                                              "description": "a constant null reference" },
     63        "ref.is_null":         { "category": "special",    "value": 209, "return": ["i32"],                          "parameter": ["externref"],                  "immediate": [],                                                                                            "description": "determine if a reference is null" },
     64        "ref.func":            { "category": "special",    "value": 210, "return": ["funcref"],                      "parameter": [],                             "immediate": [{"name": "function_index", "type": "varuint32"}],                                             "description": "return a reference to the function at the given index" },
     65        "get_local":           { "category": "special",    "value":  32, "return": ["any"],                          "parameter": [],                             "immediate": [{"name": "local_index",    "type": "varuint32"}],                                             "description": "read a local variable or parameter" },
     66        "set_local":           { "category": "special",    "value":  33, "return": [],                               "parameter": ["any"],                        "immediate": [{"name": "local_index",    "type": "varuint32"}],                                             "description": "write a local variable or parameter" },
     67        "tee_local":           { "category": "special",    "value":  34, "return": ["any"],                          "parameter": ["any"],                        "immediate": [{"name": "local_index",    "type": "varuint32"}],                                             "description": "write a local variable or parameter and return the same value" },
     68        "get_global":          { "category": "special",    "value":  35, "return": ["any"],                          "parameter": [],                             "immediate": [{"name": "global_index",   "type": "varuint32"}],                                             "description": "read a global variable" },
     69        "set_global":          { "category": "special",    "value":  36, "return": [],                               "parameter": ["any"],                        "immediate": [{"name": "global_index",   "type": "varuint32"}],                                             "description": "write a global variable" },
     70        "table.get":           { "category": "special",    "value":  37, "return": ["externref"],                    "parameter": ["i32"],                        "immediate": [{"name": "table_index",    "type": "varuint32"}],                                             "description": "get a table value" },
     71        "table.set":           { "category": "special",    "value":  38, "return": [],                               "parameter": ["i32", "externref"],           "immediate": [{"name": "table_index",    "type": "varuint32"}],                                             "description": "set a table value" },
     72        "table.size":          { "category": "exttable",   "value":  252, "return": ["i32"],                         "parameter": [],                             "immediate": [{"name": "table_index",    "type": "varuint32"}],                                             "description": "get the size of a table", "extendedOp": 15 },
     73        "table.grow":          { "category": "exttable",   "value":  252, "return": ["i32"],                         "parameter": ["externref", "i32"],           "immediate": [{"name": "table_index",    "type": "varuint32"}],                                             "description": "grow a table by the given delta and return the previous size, or -1 if enough space cannot be allocated", "extendedOp": 16 },
     74        "table.fill":          { "category": "exttable",   "value":  252, "return": ["i32"],                         "parameter": ["i32", "externref", "i32"],    "immediate": [{"name": "table_index",    "type": "varuint32"}],                                             "description": "fill entries [i,i+n) with the given value", "extendedOp": 17 },
     75        "call":                { "category": "call",       "value":  16, "return": ["call"],                         "parameter": ["call"],                       "immediate": [{"name": "function_index", "type": "varuint32"}],                                             "description": "call a function by its index" },
     76        "call_indirect":       { "category": "call",       "value":  17, "return": ["call"],                         "parameter": ["call"],                       "immediate": [{"name": "type_index",     "type": "varuint32"}, {"name": "table_index","type": "varuint32"}],"description": "call a function indirect with an expected signature" },
     77        "i32.load8_s":         { "category": "memory",     "value":  44, "return": ["i32"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
     78        "i32.load8_u":         { "category": "memory",     "value":  45, "return": ["i32"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
     79        "i32.load16_s":        { "category": "memory",     "value":  46, "return": ["i32"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
     80        "i32.load16_u":        { "category": "memory",     "value":  47, "return": ["i32"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
     81        "i64.load8_s":         { "category": "memory",     "value":  48, "return": ["i64"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
     82        "i64.load8_u":         { "category": "memory",     "value":  49, "return": ["i64"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
     83        "i64.load16_s":        { "category": "memory",     "value":  50, "return": ["i64"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
     84        "i64.load16_u":        { "category": "memory",     "value":  51, "return": ["i64"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
     85        "i64.load32_s":        { "category": "memory",     "value":  52, "return": ["i64"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
     86        "i64.load32_u":        { "category": "memory",     "value":  53, "return": ["i64"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
     87        "i32.load":            { "category": "memory",     "value":  40, "return": ["i32"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
     88        "i64.load":            { "category": "memory",     "value":  41, "return": ["i64"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
     89        "f32.load":            { "category": "memory",     "value":  42, "return": ["f32"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
     90        "f64.load":            { "category": "memory",     "value":  43, "return": ["f64"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
     91        "i32.store8":          { "category": "memory",     "value":  58, "return": [],                               "parameter": ["addr", "i32"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
     92        "i32.store16":         { "category": "memory",     "value":  59, "return": [],                               "parameter": ["addr", "i32"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
     93        "i64.store8":          { "category": "memory",     "value":  60, "return": [],                               "parameter": ["addr", "i64"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
     94        "i64.store16":         { "category": "memory",     "value":  61, "return": [],                               "parameter": ["addr", "i64"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
     95        "i64.store32":         { "category": "memory",     "value":  62, "return": [],                               "parameter": ["addr", "i64"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
     96        "i32.store":           { "category": "memory",     "value":  54, "return": [],                               "parameter": ["addr", "i32"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
     97        "i64.store":           { "category": "memory",     "value":  55, "return": [],                               "parameter": ["addr", "i64"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
     98        "f32.store":           { "category": "memory",     "value":  56, "return": [],                               "parameter": ["addr", "f32"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
     99        "f64.store":           { "category": "memory",     "value":  57, "return": [],                               "parameter": ["addr", "f64"],                "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "store to memory" },
     100        "current_memory":      { "category": "operation",  "value":  63, "return": ["size"],                         "parameter": [],                             "immediate": [{"name": "flags",          "type": "varuint32"}],                                            "description": "query the size of memory" },
     101        "grow_memory":         { "category": "operation",  "value":  64, "return": ["size"],                         "parameter": ["size"],                       "immediate": [{"name": "flags",          "type": "varuint32"}],                                            "description": "grow the size of memory" },
     102        "i32.add":             { "category": "arithmetic", "value": 106, "return": ["i32"],                          "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "Add"          },
     103        "i32.sub":             { "category": "arithmetic", "value": 107, "return": ["i32"],                          "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "Sub"          },
     104        "i32.mul":             { "category": "arithmetic", "value": 108, "return": ["i32"],                          "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "Mul"          },
     105        "i32.div_s":           { "category": "arithmetic", "value": 109, "return": ["i32"],                          "parameter": ["i32", "i32"],                 "immediate": []                         },
     106        "i32.div_u":           { "category": "arithmetic", "value": 110, "return": ["i32"],                          "parameter": ["i32", "i32"],                 "immediate": []                         },
     107        "i32.rem_s":           { "category": "arithmetic", "value": 111, "return": ["i32"],                          "parameter": ["i32", "i32"],                 "immediate": []                         },
     108        "i32.rem_u":           { "category": "arithmetic", "value": 112, "return": ["i32"],                          "parameter": ["i32", "i32"],                 "immediate": []                         },
     109        "i32.and":             { "category": "arithmetic", "value": 113, "return": ["i32"],                          "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "BitAnd"       },
     110        "i32.or":              { "category": "arithmetic", "value": 114, "return": ["i32"],                          "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "BitOr"        },
     111        "i32.xor":             { "category": "arithmetic", "value": 115, "return": ["i32"],                          "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "BitXor"       },
     112        "i32.shl":             { "category": "arithmetic", "value": 116, "return": ["i32"],                          "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "Shl"          },
     113        "i32.shr_u":           { "category": "arithmetic", "value": 118, "return": ["i32"],                          "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "ZShr"         },
     114        "i32.shr_s":           { "category": "arithmetic", "value": 117, "return": ["i32"],                          "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "SShr"         },
     115        "i32.rotr":            { "category": "arithmetic", "value": 120, "return": ["i32"],                          "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "RotR"         },
     116        "i32.rotl":            { "category": "arithmetic", "value": 119, "return": ["i32"],                          "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "RotL"         },
     117        "i32.eq":              { "category": "comparison", "value":  70, "return": ["bool"],                         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "Equal"        },
     118        "i32.ne":              { "category": "comparison", "value":  71, "return": ["bool"],                         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "NotEqual"     },
     119        "i32.lt_s":            { "category": "comparison", "value":  72, "return": ["bool"],                         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "LessThan"     },
     120        "i32.le_s":            { "category": "comparison", "value":  76, "return": ["bool"],                         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "LessEqual"    },
     121        "i32.lt_u":            { "category": "comparison", "value":  73, "return": ["bool"],                         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "Below"        },
     122        "i32.le_u":            { "category": "comparison", "value":  77, "return": ["bool"],                         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "BelowEqual"   },
     123        "i32.gt_s":            { "category": "comparison", "value":  74, "return": ["bool"],                         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "GreaterThan"  },
     124        "i32.ge_s":            { "category": "comparison", "value":  78, "return": ["bool"],                         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "GreaterEqual" },
     125        "i32.gt_u":            { "category": "comparison", "value":  75, "return": ["bool"],                         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "Above"        },
     126        "i32.ge_u":            { "category": "comparison", "value":  79, "return": ["bool"],                         "parameter": ["i32", "i32"],                 "immediate": [], "b3op": "AboveEqual"   },
     127        "i32.clz":             { "category": "arithmetic", "value": 103, "return": ["i32"],                          "parameter": ["i32"],                        "immediate": [], "b3op": "Clz"          },
     128        "i32.ctz":             { "category": "arithmetic", "value": 104, "return": ["i32"],                          "parameter": ["i32"],                        "immediate": []                         },
     129        "i32.popcnt":          { "category": "arithmetic", "value": 105, "return": ["i32"],                          "parameter": ["i32"],                        "immediate": []                         },
     130        "i32.eqz":             { "category": "comparison", "value":  69, "return": ["bool"],                         "parameter": ["i32"],                        "immediate": [], "b3op": "Equal(i32(0), @0)" },
     131        "i64.add":             { "category": "arithmetic", "value": 124, "return": ["i64"],                          "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "Add"          },
     132        "i64.sub":             { "category": "arithmetic", "value": 125, "return": ["i64"],                          "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "Sub"          },
     133        "i64.mul":             { "category": "arithmetic", "value": 126, "return": ["i64"],                          "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "Mul"          },
     134        "i64.div_s":           { "category": "arithmetic", "value": 127, "return": ["i64"],                          "parameter": ["i64", "i64"],                 "immediate": []                         },
     135        "i64.div_u":           { "category": "arithmetic", "value": 128, "return": ["i64"],                          "parameter": ["i64", "i64"],                 "immediate": []                         },
     136        "i64.rem_s":           { "category": "arithmetic", "value": 129, "return": ["i64"],                          "parameter": ["i64", "i64"],                 "immediate": []                         },
     137        "i64.rem_u":           { "category": "arithmetic", "value": 130, "return": ["i64"],                          "parameter": ["i64", "i64"],                 "immediate": []                         },
     138        "i64.and":             { "category": "arithmetic", "value": 131, "return": ["i64"],                          "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "BitAnd"       },
     139        "i64.or":              { "category": "arithmetic", "value": 132, "return": ["i64"],                          "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "BitOr"        },
     140        "i64.xor":             { "category": "arithmetic", "value": 133, "return": ["i64"],                          "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "BitXor"       },
     141        "i64.shl":             { "category": "arithmetic", "value": 134, "return": ["i64"],                          "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "Shl(@0, Trunc(@1))" },
     142        "i64.shr_u":           { "category": "arithmetic", "value": 136, "return": ["i64"],                          "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "ZShr(@0, Trunc(@1))" },
     143        "i64.shr_s":           { "category": "arithmetic", "value": 135, "return": ["i64"],                          "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "SShr(@0, Trunc(@1))" },
     144        "i64.rotr":            { "category": "arithmetic", "value": 138, "return": ["i64"],                          "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "RotR(@0, Trunc(@1))" },
     145        "i64.rotl":            { "category": "arithmetic", "value": 137, "return": ["i64"],                          "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "RotL(@0, Trunc(@1))" },
     146        "i64.eq":              { "category": "comparison", "value":  81, "return": ["bool"],                         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "Equal"        },
     147        "i64.ne":              { "category": "comparison", "value":  82, "return": ["bool"],                         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "NotEqual"     },
     148        "i64.lt_s":            { "category": "comparison", "value":  83, "return": ["bool"],                         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "LessThan"     },
     149        "i64.le_s":            { "category": "comparison", "value":  87, "return": ["bool"],                         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "LessEqual"    },
     150        "i64.lt_u":            { "category": "comparison", "value":  84, "return": ["bool"],                         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "Below"        },
     151        "i64.le_u":            { "category": "comparison", "value":  88, "return": ["bool"],                         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "BelowEqual"   },
     152        "i64.gt_s":            { "category": "comparison", "value":  85, "return": ["bool"],                         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "GreaterThan"  },
     153        "i64.ge_s":            { "category": "comparison", "value":  89, "return": ["bool"],                         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "GreaterEqual" },
     154        "i64.gt_u":            { "category": "comparison", "value":  86, "return": ["bool"],                         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "Above"        },
     155        "i64.ge_u":            { "category": "comparison", "value":  90, "return": ["bool"],                         "parameter": ["i64", "i64"],                 "immediate": [], "b3op": "AboveEqual"   },
     156        "i64.clz":             { "category": "arithmetic", "value": 121, "return": ["i64"],                          "parameter": ["i64"],                        "immediate": [], "b3op": "Clz"          },
     157        "i64.ctz":             { "category": "arithmetic", "value": 122, "return": ["i64"],                          "parameter": ["i64"],                        "immediate": []                         },
     158        "i64.popcnt":          { "category": "arithmetic", "value": 123, "return": ["i64"],                          "parameter": ["i64"],                        "immediate": []                         },
     159        "i64.eqz":             { "category": "comparison", "value":  80, "return": ["bool"],                         "parameter": ["i64"],                        "immediate": [], "b3op": "Equal(i64(0), @0)" },
     160        "f32.add":             { "category": "arithmetic", "value": 146, "return": ["f32"],                          "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "Add"          },
     161        "f32.sub":             { "category": "arithmetic", "value": 147, "return": ["f32"],                          "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "Sub"          },
     162        "f32.mul":             { "category": "arithmetic", "value": 148, "return": ["f32"],                          "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "Mul"          },
     163        "f32.div":             { "category": "arithmetic", "value": 149, "return": ["f32"],                          "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "Div"          },
     164        "f32.min":             { "category": "arithmetic", "value": 150, "return": ["f32"],                          "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "Select(Equal(@0, @1), BitOr(@0, @1), Select(LessThan(@0, @1), @0, Select(GreaterThan(@0, @1), @1, Add(@0, @1))))" },
     165        "f32.max":             { "category": "arithmetic", "value": 151, "return": ["f32"],                          "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "Select(Equal(@0, @1), BitAnd(@0, @1), Select(LessThan(@0, @1), @1, Select(GreaterThan(@0, @1), @0, Add(@0, @1))))" },
     166        "f32.abs":             { "category": "arithmetic", "value": 139, "return": ["f32"],                          "parameter": ["f32"],                        "immediate": [], "b3op": "Abs"          },
     167        "f32.neg":             { "category": "arithmetic", "value": 140, "return": ["f32"],                          "parameter": ["f32"],                        "immediate": [], "b3op": "Neg"          },
     168        "f32.copysign":        { "category": "arithmetic", "value": 152, "return": ["f32"],                          "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "BitwiseCast(BitOr(BitAnd(BitwiseCast(@1), i32(0x80000000)), BitAnd(BitwiseCast(@0), i32(0x7fffffff))))" },
     169        "f32.ceil":            { "category": "arithmetic", "value": 141, "return": ["f32"],                          "parameter": ["f32"],                        "immediate": [], "b3op": "Ceil"         },
     170        "f32.floor":           { "category": "arithmetic", "value": 142, "return": ["f32"],                          "parameter": ["f32"],                        "immediate": [], "b3op": "Floor"        },
     171        "f32.trunc":           { "category": "arithmetic", "value": 143, "return": ["f32"],                          "parameter": ["f32"],                        "immediate": []                         },
     172        "f32.nearest":         { "category": "arithmetic", "value": 144, "return": ["f32"],                          "parameter": ["f32"],                        "immediate": []                         },
     173        "f32.sqrt":            { "category": "arithmetic", "value": 145, "return": ["f32"],                          "parameter": ["f32"],                        "immediate": [], "b3op": "Sqrt"         },
     174        "f32.eq":              { "category": "comparison", "value":  91, "return": ["bool"],                         "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "Equal"        },
     175        "f32.ne":              { "category": "comparison", "value":  92, "return": ["bool"],                         "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "NotEqual"     },
     176        "f32.lt":              { "category": "comparison", "value":  93, "return": ["bool"],                         "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "LessThan"     },
     177        "f32.le":              { "category": "comparison", "value":  95, "return": ["bool"],                         "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "LessEqual"    },
     178        "f32.gt":              { "category": "comparison", "value":  94, "return": ["bool"],                         "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "GreaterThan"  },
     179        "f32.ge":              { "category": "comparison", "value":  96, "return": ["bool"],                         "parameter": ["f32", "f32"],                 "immediate": [], "b3op": "GreaterEqual" },
     180        "f64.add":             { "category": "arithmetic", "value": 160, "return": ["f64"],                          "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "Add"          },
     181        "f64.sub":             { "category": "arithmetic", "value": 161, "return": ["f64"],                          "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "Sub"          },
     182        "f64.mul":             { "category": "arithmetic", "value": 162, "return": ["f64"],                          "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "Mul"          },
     183        "f64.div":             { "category": "arithmetic", "value": 163, "return": ["f64"],                          "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "Div"          },
     184        "f64.min":             { "category": "arithmetic", "value": 164, "return": ["f64"],                          "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "Select(Equal(@0, @1), BitOr(@0, @1), Select(LessThan(@0, @1), @0, Select(GreaterThan(@0, @1), @1, Add(@0, @1))))" },
     185        "f64.max":             { "category": "arithmetic", "value": 165, "return": ["f64"],                          "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "Select(Equal(@0, @1), BitAnd(@0, @1), Select(LessThan(@0, @1), @1, Select(GreaterThan(@0, @1), @0, Add(@0, @1))))" },
     186        "f64.abs":             { "category": "arithmetic", "value": 153, "return": ["f64"],                          "parameter": ["f64"],                        "immediate": [], "b3op": "Abs"          },
     187        "f64.neg":             { "category": "arithmetic", "value": 154, "return": ["f64"],                          "parameter": ["f64"],                        "immediate": [], "b3op": "Neg"          },
     188        "f64.copysign":        { "category": "arithmetic", "value": 166, "return": ["f64"],                          "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "BitwiseCast(BitOr(BitAnd(BitwiseCast(@1), i64(0x8000000000000000)), BitAnd(BitwiseCast(@0), i64(0x7fffffffffffffff))))" },
     189        "f64.ceil":            { "category": "arithmetic", "value": 155, "return": ["f64"],                          "parameter": ["f64"],                        "immediate": [], "b3op": "Ceil"         },
     190        "f64.floor":           { "category": "arithmetic", "value": 156, "return": ["f64"],                          "parameter": ["f64"],                        "immediate": [], "b3op": "Floor"        },
     191        "f64.trunc":           { "category": "arithmetic", "value": 157, "return": ["f64"],                          "parameter": ["f64"],                        "immediate": []                         },
     192        "f64.nearest":         { "category": "arithmetic", "value": 158, "return": ["f64"],                          "parameter": ["f64"],                        "immediate": []                         },
     193        "f64.sqrt":            { "category": "arithmetic", "value": 159, "return": ["f64"],                          "parameter": ["f64"],                        "immediate": [], "b3op": "Sqrt"         },
     194        "f64.eq":              { "category": "comparison", "value":  97, "return": ["bool"],                         "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "Equal"        },
     195        "f64.ne":              { "category": "comparison", "value":  98, "return": ["bool"],                         "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "NotEqual"     },
     196        "f64.lt":              { "category": "comparison", "value":  99, "return": ["bool"],                         "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "LessThan"     },
     197        "f64.le":              { "category": "comparison", "value": 101, "return": ["bool"],                         "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "LessEqual"    },
     198        "f64.gt":              { "category": "comparison", "value": 100, "return": ["bool"],                         "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "GreaterThan"  },
     199        "f64.ge":              { "category": "comparison", "value": 102, "return": ["bool"],                         "parameter": ["f64", "f64"],                 "immediate": [], "b3op": "GreaterEqual" },
     200        "i32.trunc_s/f32":     { "category": "conversion", "value": 168, "return": ["i32"],                          "parameter": ["f32"],                        "immediate": []                         },
     201        "i32.trunc_s/f64":     { "category": "conversion", "value": 170, "return": ["i32"],                          "parameter": ["f64"],                        "immediate": []                         },
     202        "i32.trunc_u/f32":     { "category": "conversion", "value": 169, "return": ["i32"],                          "parameter": ["f32"],                        "immediate": []                         },
     203        "i32.trunc_u/f64":     { "category": "conversion", "value": 171, "return": ["i32"],                          "parameter": ["f64"],                        "immediate": []                         },
     204        "i32.wrap/i64":        { "category": "conversion", "value": 167, "return": ["i32"],                          "parameter": ["i64"],                        "immediate": [], "b3op": "Trunc"        },
     205        "i64.trunc_s/f32":     { "category": "conversion", "value": 174, "return": ["i64"],                          "parameter": ["f32"],                        "immediate": []                         },
     206        "i64.trunc_s/f64":     { "category": "conversion", "value": 176, "return": ["i64"],                          "parameter": ["f64"],                        "immediate": []                         },
     207        "i64.trunc_u/f32":     { "category": "conversion", "value": 175, "return": ["i64"],                          "parameter": ["f32"],                        "immediate": []                         },
     208        "i64.trunc_u/f64":     { "category": "conversion", "value": 177, "return": ["i64"],                          "parameter": ["f64"],                        "immediate": []                         },
     209        "i64.extend_s/i32":    { "category": "conversion", "value": 172, "return": ["i64"],                          "parameter": ["i32"],                        "immediate": [], "b3op": "SExt32"       },
     210        "i64.extend_u/i32":    { "category": "conversion", "value": 173, "return": ["i64"],                          "parameter": ["i32"],                        "immediate": [], "b3op": "ZExt32"       },
     211        "f32.convert_s/i32":   { "category": "conversion", "value": 178, "return": ["f32"],                          "parameter": ["i32"],                        "immediate": [], "b3op": "IToF"         },
     212        "f32.convert_u/i32":   { "category": "conversion", "value": 179, "return": ["f32"],                          "parameter": ["i32"],                        "immediate": [], "b3op": "IToF(ZExt32(@0))" },
     213        "f32.convert_s/i64":   { "category": "conversion", "value": 180, "return": ["f32"],                          "parameter": ["i64"],                        "immediate": [], "b3op": "IToF"         },
     214        "f32.convert_u/i64":   { "category": "conversion", "value": 181, "return": ["f32"],                          "parameter": ["i64"],                        "immediate": []                         },
     215        "f32.demote/f64":      { "category": "conversion", "value": 182, "return": ["f32"],                          "parameter": ["f64"],                        "immediate": [], "b3op": "DoubleToFloat"},
     216        "f32.reinterpret/i32": { "category": "conversion", "value": 190, "return": ["f32"],                          "parameter": ["i32"],                        "immediate": [], "b3op": "BitwiseCast"  },
     217        "f64.convert_s/i32":   { "category": "conversion", "value": 183, "return": ["f64"],                          "parameter": ["i32"],                        "immediate": [], "b3op": "IToD"         },
     218        "f64.convert_u/i32":   { "category": "conversion", "value": 184, "return": ["f64"],                          "parameter": ["i32"],                        "immediate": [], "b3op": "IToD(ZExt32(@0))" },
     219        "f64.convert_s/i64":   { "category": "conversion", "value": 185, "return": ["f64"],                          "parameter": ["i64"],                        "immediate": [], "b3op": "IToD"         },
     220        "f64.convert_u/i64":   { "category": "conversion", "value": 186, "return": ["f64"],                          "parameter": ["i64"],                        "immediate": []                         },
     221        "f64.promote/f32":     { "category": "conversion", "value": 187, "return": ["f64"],                          "parameter": ["f32"],                        "immediate": [], "b3op": "FloatToDouble"},
     222        "f64.reinterpret/i64": { "category": "conversion", "value": 191, "return": ["f64"],                          "parameter": ["i64"],                        "immediate": [], "b3op": "BitwiseCast"  },
     223        "i32.reinterpret/f32": { "category": "conversion", "value": 188, "return": ["i32"],                          "parameter": ["f32"],                        "immediate": [], "b3op": "BitwiseCast"  },
     224        "i64.reinterpret/f64": { "category": "conversion", "value": 189, "return": ["i64"],                          "parameter": ["f64"],                        "immediate": [], "b3op": "BitwiseCast"  }
    225225    }
    226226}
Note: See TracChangeset for help on using the changeset viewer.