tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

wasm-module-builder.js (53833B)


      1 // Copyright 2016 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Used for encoding f32 and double constants to bits.
      6 let byte_view = new Uint8Array(8);
      7 let data_view = new DataView(byte_view.buffer);
      8 
      9 // The bytes function receives one of
     10 //  - several arguments, each of which is either a number or a string of length
     11 //    1; if it's a string, the charcode of the contained character is used.
     12 //  - a single array argument containing the actual arguments
     13 //  - a single string; the returned buffer will contain the char codes of all
     14 //    contained characters.
     15 function bytes(...input) {
     16  if (input.length == 1 && typeof input[0] == 'array') input = input[0];
     17  if (input.length == 1 && typeof input[0] == 'string') {
     18    let len = input[0].length;
     19    let view = new Uint8Array(len);
     20    for (let i = 0; i < len; i++) view[i] = input[0].charCodeAt(i);
     21    return view.buffer;
     22  }
     23  let view = new Uint8Array(input.length);
     24  for (let i = 0; i < input.length; i++) {
     25    let val = input[i];
     26    if (typeof val == 'string') {
     27      assertEquals(1, val.length, 'string inputs must have length 1');
     28      val = val.charCodeAt(0);
     29    }
     30    view[i] = val | 0;
     31  }
     32  return view.buffer;
     33 }
     34 
     35 // Header declaration constants
     36 var kWasmH0 = 0;
     37 var kWasmH1 = 0x61;
     38 var kWasmH2 = 0x73;
     39 var kWasmH3 = 0x6d;
     40 
     41 var kWasmV0 = 0x1;
     42 var kWasmV1 = 0;
     43 var kWasmV2 = 0;
     44 var kWasmV3 = 0;
     45 
     46 var kHeaderSize = 8;
     47 var kPageSize = 65536;
     48 var kSpecMaxPages = 65536;
     49 var kMaxVarInt32Size = 5;
     50 var kMaxVarInt64Size = 10;
     51 
     52 let kDeclNoLocals = 0;
     53 
     54 // Section declaration constants
     55 let kUnknownSectionCode = 0;
     56 let kTypeSectionCode = 1;        // Function signature declarations
     57 let kImportSectionCode = 2;      // Import declarations
     58 let kFunctionSectionCode = 3;    // Function declarations
     59 let kTableSectionCode = 4;       // Indirect function table and other tables
     60 let kMemorySectionCode = 5;      // Memory attributes
     61 let kGlobalSectionCode = 6;      // Global declarations
     62 let kExportSectionCode = 7;      // Exports
     63 let kStartSectionCode = 8;       // Start function declaration
     64 let kElementSectionCode = 9;     // Elements section
     65 let kCodeSectionCode = 10;       // Function code
     66 let kDataSectionCode = 11;       // Data segments
     67 let kDataCountSectionCode = 12;  // Data segment count (between Element & Code)
     68 let kTagSectionCode = 13;        // Tag section (between Memory & Global)
     69 
     70 // Name section types
     71 let kModuleNameCode = 0;
     72 let kFunctionNamesCode = 1;
     73 let kLocalNamesCode = 2;
     74 
     75 let kWasmFunctionTypeForm = 0x60;
     76 let kWasmAnyFunctionTypeForm = 0x70;
     77 let kWasmStructTypeForm = 0x5f;
     78 let kWasmArrayTypeForm = 0x5e;
     79 let kWasmSubtypeForm = 0x50;
     80 let kWasmSubtypeFinalForm = 0x4f;
     81 let kWasmRecursiveTypeGroupForm = 0x4e;
     82 
     83 let kNoSuperType = 0xFFFFFFFF;
     84 globalThis.kNoSuperType = kNoSuperType;
     85 
     86 let kHasMaximumFlag = 1;
     87 let kSharedHasMaximumFlag = 3;
     88 
     89 // Segment flags
     90 let kActiveNoIndex = 0;
     91 let kPassive = 1;
     92 let kActiveWithIndex = 2;
     93 let kPassiveWithElements = 5;
     94 
     95 // Function declaration flags
     96 let kDeclFunctionName   = 0x01;
     97 let kDeclFunctionImport = 0x02;
     98 let kDeclFunctionLocals = 0x04;
     99 let kDeclFunctionExport = 0x08;
    100 
    101 // Local types
    102 let kWasmStmt = 0x40;
    103 let kWasmI32 = 0x7f;
    104 let kWasmI64 = 0x7e;
    105 let kWasmF32 = 0x7d;
    106 let kWasmF64 = 0x7c;
    107 let kWasmS128 = 0x7b;
    108 
    109 // Packed storage types
    110 let kWasmI8 = 0x78;
    111 let kWasmI16 = 0x77;
    112 
    113 // These are defined as negative integers to distinguish them from positive type
    114 // indices.
    115 let kWasmNullFuncRef = -0x0d;
    116 let kWasmNullExternRef = -0x0e;
    117 let kWasmNullRef = -0x0f;
    118 let kWasmFuncRef = -0x10;
    119 let kWasmAnyFunc = kWasmFuncRef;  // Alias named as in the JS API spec
    120 let kWasmExternRef = -0x11;
    121 let kWasmAnyRef = -0x12;
    122 let kWasmEqRef = -0x13;
    123 let kWasmI31Ref = -0x14;
    124 let kWasmStructRef = -0x15;
    125 let kWasmArrayRef = -0x16;
    126 
    127 // Use the positive-byte versions inside function bodies.
    128 let kLeb128Mask = 0x7f;
    129 let kFuncRefCode = kWasmFuncRef & kLeb128Mask;
    130 let kAnyFuncCode = kFuncRefCode;  // Alias named as in the JS API spec
    131 let kExternRefCode = kWasmExternRef & kLeb128Mask;
    132 let kAnyRefCode = kWasmAnyRef & kLeb128Mask;
    133 let kEqRefCode = kWasmEqRef & kLeb128Mask;
    134 let kI31RefCode = kWasmI31Ref & kLeb128Mask;
    135 let kNullExternRefCode = kWasmNullExternRef & kLeb128Mask;
    136 let kNullFuncRefCode = kWasmNullFuncRef & kLeb128Mask;
    137 let kStructRefCode = kWasmStructRef & kLeb128Mask;
    138 let kArrayRefCode = kWasmArrayRef & kLeb128Mask;
    139 let kNullRefCode = kWasmNullRef & kLeb128Mask;
    140 
    141 let kWasmRefNull = 0x63;
    142 let kWasmRef = 0x64;
    143 function wasmRefNullType(heap_type) {
    144  return {opcode: kWasmRefNull, heap_type: heap_type};
    145 }
    146 function wasmRefType(heap_type) {
    147  return {opcode: kWasmRef, heap_type: heap_type};
    148 }
    149 
    150 Object.assign(globalThis, {
    151  kWasmStmt, kWasmI32, kWasmI64, kWasmF32, kWasmF64, kWasmS128, kWasmI8,
    152  kWasmI16, kWasmNullFuncRef, kWasmNullExternRef, kWasmNullRef, kWasmFuncRef,
    153  kWasmAnyFunc, kWasmExternRef, kWasmAnyRef, kWasmEqRef, kWasmI31Ref,
    154  kWasmStructRef, kWasmArrayRef, kFuncRefCode, kAnyFuncCode, kExternRefCode,
    155  kAnyRefCode, kEqRefCode, kI31RefCode, kNullExternRefCode, kNullFuncRefCode,
    156  kStructRefCode, kArrayRefCode, kNullRefCode, kWasmRefNull, kWasmRef,
    157  wasmRefNullType, wasmRefType
    158 });
    159 
    160 let kExternalFunction = 0;
    161 let kExternalTable = 1;
    162 let kExternalMemory = 2;
    163 let kExternalGlobal = 3;
    164 let kExternalTag = 4;
    165 
    166 Object.assign(globalThis, {
    167  kExternalFunction, kExternalTable, kExternalMemory, kExternalGlobal,
    168  kExternalTag
    169 });
    170 
    171 let kTableZero = 0;
    172 let kMemoryZero = 0;
    173 let kSegmentZero = 0;
    174 
    175 let kTagAttribute = 0;
    176 
    177 // Useful signatures
    178 let kSig_i_i = makeSig([kWasmI32], [kWasmI32]);
    179 let kSig_l_l = makeSig([kWasmI64], [kWasmI64]);
    180 let kSig_i_l = makeSig([kWasmI64], [kWasmI32]);
    181 let kSig_i_ii = makeSig([kWasmI32, kWasmI32], [kWasmI32]);
    182 let kSig_i_iii = makeSig([kWasmI32, kWasmI32, kWasmI32], [kWasmI32]);
    183 let kSig_v_iiii = makeSig([kWasmI32, kWasmI32, kWasmI32, kWasmI32], []);
    184 let kSig_f_ff = makeSig([kWasmF32, kWasmF32], [kWasmF32]);
    185 let kSig_d_dd = makeSig([kWasmF64, kWasmF64], [kWasmF64]);
    186 let kSig_l_ll = makeSig([kWasmI64, kWasmI64], [kWasmI64]);
    187 let kSig_i_dd = makeSig([kWasmF64, kWasmF64], [kWasmI32]);
    188 let kSig_v_v = makeSig([], []);
    189 let kSig_i_v = makeSig([], [kWasmI32]);
    190 let kSig_l_v = makeSig([], [kWasmI64]);
    191 let kSig_f_v = makeSig([], [kWasmF32]);
    192 let kSig_d_v = makeSig([], [kWasmF64]);
    193 let kSig_v_i = makeSig([kWasmI32], []);
    194 let kSig_v_ii = makeSig([kWasmI32, kWasmI32], []);
    195 let kSig_v_iii = makeSig([kWasmI32, kWasmI32, kWasmI32], []);
    196 let kSig_v_l = makeSig([kWasmI64], []);
    197 let kSig_v_d = makeSig([kWasmF64], []);
    198 let kSig_v_dd = makeSig([kWasmF64, kWasmF64], []);
    199 let kSig_v_ddi = makeSig([kWasmF64, kWasmF64, kWasmI32], []);
    200 let kSig_ii_v = makeSig([], [kWasmI32, kWasmI32]);
    201 let kSig_iii_v = makeSig([], [kWasmI32, kWasmI32, kWasmI32]);
    202 let kSig_ii_i = makeSig([kWasmI32], [kWasmI32, kWasmI32]);
    203 let kSig_iii_i = makeSig([kWasmI32], [kWasmI32, kWasmI32, kWasmI32]);
    204 let kSig_ii_ii = makeSig([kWasmI32, kWasmI32], [kWasmI32, kWasmI32]);
    205 let kSig_iii_ii = makeSig([kWasmI32, kWasmI32], [kWasmI32, kWasmI32, kWasmI32]);
    206 
    207 let kSig_v_f = makeSig([kWasmF32], []);
    208 let kSig_f_f = makeSig([kWasmF32], [kWasmF32]);
    209 let kSig_f_d = makeSig([kWasmF64], [kWasmF32]);
    210 let kSig_d_d = makeSig([kWasmF64], [kWasmF64]);
    211 let kSig_r_r = makeSig([kWasmExternRef], [kWasmExternRef]);
    212 let kSig_a_a = makeSig([kWasmAnyFunc], [kWasmAnyFunc]);
    213 let kSig_i_r = makeSig([kWasmExternRef], [kWasmI32]);
    214 let kSig_v_r = makeSig([kWasmExternRef], []);
    215 let kSig_v_a = makeSig([kWasmAnyFunc], []);
    216 let kSig_v_rr = makeSig([kWasmExternRef, kWasmExternRef], []);
    217 let kSig_v_aa = makeSig([kWasmAnyFunc, kWasmAnyFunc], []);
    218 let kSig_r_v = makeSig([], [kWasmExternRef]);
    219 let kSig_a_v = makeSig([], [kWasmAnyFunc]);
    220 let kSig_a_i = makeSig([kWasmI32], [kWasmAnyFunc]);
    221 
    222 function makeSig(params, results) {
    223  return {params: params, results: results};
    224 }
    225 
    226 function makeSig_v_x(x) {
    227  return makeSig([x], []);
    228 }
    229 
    230 function makeSig_v_xx(x) {
    231  return makeSig([x, x], []);
    232 }
    233 
    234 function makeSig_r_v(r) {
    235  return makeSig([], [r]);
    236 }
    237 
    238 function makeSig_r_x(r, x) {
    239  return makeSig([x], [r]);
    240 }
    241 
    242 function makeSig_r_xx(r, x) {
    243  return makeSig([x, x], [r]);
    244 }
    245 
    246 Object.assign(globalThis, {
    247  kSig_i_i, kSig_l_l, kSig_i_l, kSig_i_ii, kSig_i_iii, kSig_v_iiii, kSig_f_ff,
    248  kSig_d_dd, kSig_l_ll, kSig_i_dd, kSig_v_v, kSig_i_v, kSig_l_v, kSig_f_v,
    249  kSig_d_v, kSig_v_i, kSig_v_ii, kSig_v_iii, kSig_v_l, kSig_v_d, kSig_v_dd,
    250  kSig_v_ddi, kSig_ii_v, kSig_iii_v, kSig_ii_i, kSig_iii_i, kSig_ii_ii,
    251  kSig_iii_ii, kSig_v_f, kSig_f_f, kSig_f_d, kSig_d_d, kSig_r_r, kSig_a_a,
    252  kSig_i_r, kSig_v_r, kSig_v_a, kSig_v_rr, kSig_v_aa, kSig_r_v, kSig_a_v,
    253  kSig_a_i,
    254  makeSig, makeSig_v_x, makeSig_v_xx, makeSig_r_v, makeSig_r_x, makeSig_r_xx
    255 });
    256 
    257 // Opcodes
    258 let kExprUnreachable = 0x00;
    259 let kExprNop = 0x01;
    260 let kExprBlock = 0x02;
    261 let kExprLoop = 0x03;
    262 let kExprIf = 0x04;
    263 let kExprElse = 0x05;
    264 let kExprTry = 0x06;
    265 let kExprCatch = 0x07;
    266 let kExprCatchAll = 0x19;
    267 let kExprThrow = 0x08;
    268 let kExprRethrow = 0x09;
    269 let kExprBrOnExn = 0x0a;
    270 let kExprEnd = 0x0b;
    271 let kExprBr = 0x0c;
    272 let kExprBrIf = 0x0d;
    273 let kExprBrTable = 0x0e;
    274 let kExprReturn = 0x0f;
    275 let kExprCallFunction = 0x10;
    276 let kExprCallIndirect = 0x11;
    277 let kExprReturnCall = 0x12;
    278 let kExprReturnCallIndirect = 0x13;
    279 let kExprDrop = 0x1a;
    280 let kExprSelect = 0x1b;
    281 let kExprLocalGet = 0x20;
    282 let kExprLocalSet = 0x21;
    283 let kExprLocalTee = 0x22;
    284 let kExprGlobalGet = 0x23;
    285 let kExprGlobalSet = 0x24;
    286 let kExprTableGet = 0x25;
    287 let kExprTableSet = 0x26;
    288 let kExprI32LoadMem = 0x28;
    289 let kExprI64LoadMem = 0x29;
    290 let kExprF32LoadMem = 0x2a;
    291 let kExprF64LoadMem = 0x2b;
    292 let kExprI32LoadMem8S = 0x2c;
    293 let kExprI32LoadMem8U = 0x2d;
    294 let kExprI32LoadMem16S = 0x2e;
    295 let kExprI32LoadMem16U = 0x2f;
    296 let kExprI64LoadMem8S = 0x30;
    297 let kExprI64LoadMem8U = 0x31;
    298 let kExprI64LoadMem16S = 0x32;
    299 let kExprI64LoadMem16U = 0x33;
    300 let kExprI64LoadMem32S = 0x34;
    301 let kExprI64LoadMem32U = 0x35;
    302 let kExprI32StoreMem = 0x36;
    303 let kExprI64StoreMem = 0x37;
    304 let kExprF32StoreMem = 0x38;
    305 let kExprF64StoreMem = 0x39;
    306 let kExprI32StoreMem8 = 0x3a;
    307 let kExprI32StoreMem16 = 0x3b;
    308 let kExprI64StoreMem8 = 0x3c;
    309 let kExprI64StoreMem16 = 0x3d;
    310 let kExprI64StoreMem32 = 0x3e;
    311 let kExprMemorySize = 0x3f;
    312 let kExprMemoryGrow = 0x40;
    313 let kExprI32Const = 0x41;
    314 let kExprI64Const = 0x42;
    315 let kExprF32Const = 0x43;
    316 let kExprF64Const = 0x44;
    317 let kExprI32Eqz = 0x45;
    318 let kExprI32Eq = 0x46;
    319 let kExprI32Ne = 0x47;
    320 let kExprI32LtS = 0x48;
    321 let kExprI32LtU = 0x49;
    322 let kExprI32GtS = 0x4a;
    323 let kExprI32GtU = 0x4b;
    324 let kExprI32LeS = 0x4c;
    325 let kExprI32LeU = 0x4d;
    326 let kExprI32GeS = 0x4e;
    327 let kExprI32GeU = 0x4f;
    328 let kExprI64Eqz = 0x50;
    329 let kExprI64Eq = 0x51;
    330 let kExprI64Ne = 0x52;
    331 let kExprI64LtS = 0x53;
    332 let kExprI64LtU = 0x54;
    333 let kExprI64GtS = 0x55;
    334 let kExprI64GtU = 0x56;
    335 let kExprI64LeS = 0x57;
    336 let kExprI64LeU = 0x58;
    337 let kExprI64GeS = 0x59;
    338 let kExprI64GeU = 0x5a;
    339 let kExprF32Eq = 0x5b;
    340 let kExprF32Ne = 0x5c;
    341 let kExprF32Lt = 0x5d;
    342 let kExprF32Gt = 0x5e;
    343 let kExprF32Le = 0x5f;
    344 let kExprF32Ge = 0x60;
    345 let kExprF64Eq = 0x61;
    346 let kExprF64Ne = 0x62;
    347 let kExprF64Lt = 0x63;
    348 let kExprF64Gt = 0x64;
    349 let kExprF64Le = 0x65;
    350 let kExprF64Ge = 0x66;
    351 let kExprI32Clz = 0x67;
    352 let kExprI32Ctz = 0x68;
    353 let kExprI32Popcnt = 0x69;
    354 let kExprI32Add = 0x6a;
    355 let kExprI32Sub = 0x6b;
    356 let kExprI32Mul = 0x6c;
    357 let kExprI32DivS = 0x6d;
    358 let kExprI32DivU = 0x6e;
    359 let kExprI32RemS = 0x6f;
    360 let kExprI32RemU = 0x70;
    361 let kExprI32And = 0x71;
    362 let kExprI32Ior = 0x72;
    363 let kExprI32Xor = 0x73;
    364 let kExprI32Shl = 0x74;
    365 let kExprI32ShrS = 0x75;
    366 let kExprI32ShrU = 0x76;
    367 let kExprI32Rol = 0x77;
    368 let kExprI32Ror = 0x78;
    369 let kExprI64Clz = 0x79;
    370 let kExprI64Ctz = 0x7a;
    371 let kExprI64Popcnt = 0x7b;
    372 let kExprI64Add = 0x7c;
    373 let kExprI64Sub = 0x7d;
    374 let kExprI64Mul = 0x7e;
    375 let kExprI64DivS = 0x7f;
    376 let kExprI64DivU = 0x80;
    377 let kExprI64RemS = 0x81;
    378 let kExprI64RemU = 0x82;
    379 let kExprI64And = 0x83;
    380 let kExprI64Ior = 0x84;
    381 let kExprI64Xor = 0x85;
    382 let kExprI64Shl = 0x86;
    383 let kExprI64ShrS = 0x87;
    384 let kExprI64ShrU = 0x88;
    385 let kExprI64Rol = 0x89;
    386 let kExprI64Ror = 0x8a;
    387 let kExprF32Abs = 0x8b;
    388 let kExprF32Neg = 0x8c;
    389 let kExprF32Ceil = 0x8d;
    390 let kExprF32Floor = 0x8e;
    391 let kExprF32Trunc = 0x8f;
    392 let kExprF32NearestInt = 0x90;
    393 let kExprF32Sqrt = 0x91;
    394 let kExprF32Add = 0x92;
    395 let kExprF32Sub = 0x93;
    396 let kExprF32Mul = 0x94;
    397 let kExprF32Div = 0x95;
    398 let kExprF32Min = 0x96;
    399 let kExprF32Max = 0x97;
    400 let kExprF32CopySign = 0x98;
    401 let kExprF64Abs = 0x99;
    402 let kExprF64Neg = 0x9a;
    403 let kExprF64Ceil = 0x9b;
    404 let kExprF64Floor = 0x9c;
    405 let kExprF64Trunc = 0x9d;
    406 let kExprF64NearestInt = 0x9e;
    407 let kExprF64Sqrt = 0x9f;
    408 let kExprF64Add = 0xa0;
    409 let kExprF64Sub = 0xa1;
    410 let kExprF64Mul = 0xa2;
    411 let kExprF64Div = 0xa3;
    412 let kExprF64Min = 0xa4;
    413 let kExprF64Max = 0xa5;
    414 let kExprF64CopySign = 0xa6;
    415 let kExprI32ConvertI64 = 0xa7;
    416 let kExprI32SConvertF32 = 0xa8;
    417 let kExprI32UConvertF32 = 0xa9;
    418 let kExprI32SConvertF64 = 0xaa;
    419 let kExprI32UConvertF64 = 0xab;
    420 let kExprI64SConvertI32 = 0xac;
    421 let kExprI64UConvertI32 = 0xad;
    422 let kExprI64SConvertF32 = 0xae;
    423 let kExprI64UConvertF32 = 0xaf;
    424 let kExprI64SConvertF64 = 0xb0;
    425 let kExprI64UConvertF64 = 0xb1;
    426 let kExprF32SConvertI32 = 0xb2;
    427 let kExprF32UConvertI32 = 0xb3;
    428 let kExprF32SConvertI64 = 0xb4;
    429 let kExprF32UConvertI64 = 0xb5;
    430 let kExprF32ConvertF64 = 0xb6;
    431 let kExprF64SConvertI32 = 0xb7;
    432 let kExprF64UConvertI32 = 0xb8;
    433 let kExprF64SConvertI64 = 0xb9;
    434 let kExprF64UConvertI64 = 0xba;
    435 let kExprF64ConvertF32 = 0xbb;
    436 let kExprI32ReinterpretF32 = 0xbc;
    437 let kExprI64ReinterpretF64 = 0xbd;
    438 let kExprF32ReinterpretI32 = 0xbe;
    439 let kExprF64ReinterpretI64 = 0xbf;
    440 let kExprI32SExtendI8 = 0xc0;
    441 let kExprI32SExtendI16 = 0xc1;
    442 let kExprI64SExtendI8 = 0xc2;
    443 let kExprI64SExtendI16 = 0xc3;
    444 let kExprI64SExtendI32 = 0xc4;
    445 let kExprRefNull = 0xd0;
    446 let kExprRefIsNull = 0xd1;
    447 let kExprRefFunc = 0xd2;
    448 
    449 // Prefix opcodes
    450 let kGCPrefix = 0xfb;
    451 let kNumericPrefix = 0xfc;
    452 let kSimdPrefix = 0xfd;
    453 let kAtomicPrefix = 0xfe;
    454 
    455 // Use these for multi-byte instructions (opcode > 0x7F needing two LEB bytes):
    456 function GCInstr(opcode) {
    457  if (opcode <= 0x7F) return [kGCPrefix, opcode];
    458  return [kGCPrefix, 0x80 | (opcode & 0x7F), opcode >> 7];
    459 }
    460 
    461 // GC opcodes
    462 let kExprStructNew = 0x00;
    463 let kExprStructNewDefault = 0x01;
    464 let kExprStructGet = 0x02;
    465 let kExprStructGetS = 0x03;
    466 let kExprStructGetU = 0x04;
    467 let kExprStructSet = 0x05;
    468 let kExprArrayNew = 0x06;
    469 let kExprArrayNewDefault = 0x07;
    470 let kExprArrayNewFixed = 0x08;
    471 let kExprArrayNewData = 0x09;
    472 let kExprArrayNewElem = 0x0a;
    473 let kExprArrayGet = 0x0b;
    474 let kExprArrayGetS = 0x0c;
    475 let kExprArrayGetU = 0x0d;
    476 let kExprArraySet = 0x0e;
    477 let kExprArrayLen = 0x0f;
    478 let kExprArrayFill = 0x10;
    479 let kExprArrayCopy = 0x11;
    480 let kExprArrayInitData = 0x12;
    481 let kExprArrayInitElem = 0x13;
    482 let kExprRefTest = 0x14;
    483 let kExprRefTestNull = 0x15;
    484 let kExprRefCast = 0x16;
    485 let kExprRefCastNull = 0x17;
    486 let kExprBrOnCast = 0x18;
    487 let kExprBrOnCastFail = 0x19;
    488 let kExprExternInternalize = 0x1a;
    489 let kExprExternExternalize = 0x1b;
    490 let kExprI31New = 0x1c;
    491 let kExprI31GetS = 0x1d;
    492 let kExprI31GetU = 0x1e;
    493 
    494 // Numeric opcodes.
    495 let kExprMemoryInit = 0x08;
    496 let kExprDataDrop = 0x09;
    497 let kExprMemoryCopy = 0x0a;
    498 let kExprMemoryFill = 0x0b;
    499 let kExprTableInit = 0x0c;
    500 let kExprElemDrop = 0x0d;
    501 let kExprTableCopy = 0x0e;
    502 let kExprTableGrow = 0x0f;
    503 let kExprTableSize = 0x10;
    504 let kExprTableFill = 0x11;
    505 
    506 // Atomic opcodes.
    507 let kExprAtomicNotify = 0x00;
    508 let kExprI32AtomicWait = 0x01;
    509 let kExprI64AtomicWait = 0x02;
    510 let kExprI32AtomicLoad = 0x10;
    511 let kExprI32AtomicLoad8U = 0x12;
    512 let kExprI32AtomicLoad16U = 0x13;
    513 let kExprI32AtomicStore = 0x17;
    514 let kExprI32AtomicStore8U = 0x19;
    515 let kExprI32AtomicStore16U = 0x1a;
    516 let kExprI32AtomicAdd = 0x1e;
    517 let kExprI32AtomicAdd8U = 0x20;
    518 let kExprI32AtomicAdd16U = 0x21;
    519 let kExprI32AtomicSub = 0x25;
    520 let kExprI32AtomicSub8U = 0x27;
    521 let kExprI32AtomicSub16U = 0x28;
    522 let kExprI32AtomicAnd = 0x2c;
    523 let kExprI32AtomicAnd8U = 0x2e;
    524 let kExprI32AtomicAnd16U = 0x2f;
    525 let kExprI32AtomicOr = 0x33;
    526 let kExprI32AtomicOr8U = 0x35;
    527 let kExprI32AtomicOr16U = 0x36;
    528 let kExprI32AtomicXor = 0x3a;
    529 let kExprI32AtomicXor8U = 0x3c;
    530 let kExprI32AtomicXor16U = 0x3d;
    531 let kExprI32AtomicExchange = 0x41;
    532 let kExprI32AtomicExchange8U = 0x43;
    533 let kExprI32AtomicExchange16U = 0x44;
    534 let kExprI32AtomicCompareExchange = 0x48;
    535 let kExprI32AtomicCompareExchange8U = 0x4a;
    536 let kExprI32AtomicCompareExchange16U = 0x4b;
    537 
    538 let kExprI64AtomicLoad = 0x11;
    539 let kExprI64AtomicLoad8U = 0x14;
    540 let kExprI64AtomicLoad16U = 0x15;
    541 let kExprI64AtomicLoad32U = 0x16;
    542 let kExprI64AtomicStore = 0x18;
    543 let kExprI64AtomicStore8U = 0x1b;
    544 let kExprI64AtomicStore16U = 0x1c;
    545 let kExprI64AtomicStore32U = 0x1d;
    546 let kExprI64AtomicAdd = 0x1f;
    547 let kExprI64AtomicAdd8U = 0x22;
    548 let kExprI64AtomicAdd16U = 0x23;
    549 let kExprI64AtomicAdd32U = 0x24;
    550 let kExprI64AtomicSub = 0x26;
    551 let kExprI64AtomicSub8U = 0x29;
    552 let kExprI64AtomicSub16U = 0x2a;
    553 let kExprI64AtomicSub32U = 0x2b;
    554 let kExprI64AtomicAnd = 0x2d;
    555 let kExprI64AtomicAnd8U = 0x30;
    556 let kExprI64AtomicAnd16U = 0x31;
    557 let kExprI64AtomicAnd32U = 0x32;
    558 let kExprI64AtomicOr = 0x34;
    559 let kExprI64AtomicOr8U = 0x37;
    560 let kExprI64AtomicOr16U = 0x38;
    561 let kExprI64AtomicOr32U = 0x39;
    562 let kExprI64AtomicXor = 0x3b;
    563 let kExprI64AtomicXor8U = 0x3e;
    564 let kExprI64AtomicXor16U = 0x3f;
    565 let kExprI64AtomicXor32U = 0x40;
    566 let kExprI64AtomicExchange = 0x42;
    567 let kExprI64AtomicExchange8U = 0x45;
    568 let kExprI64AtomicExchange16U = 0x46;
    569 let kExprI64AtomicExchange32U = 0x47;
    570 let kExprI64AtomicCompareExchange = 0x49
    571 let kExprI64AtomicCompareExchange8U = 0x4c;
    572 let kExprI64AtomicCompareExchange16U = 0x4d;
    573 let kExprI64AtomicCompareExchange32U = 0x4e;
    574 
    575 // Simd opcodes.
    576 let kExprS128LoadMem = 0x00;
    577 let kExprS128StoreMem = 0x01;
    578 let kExprI32x4Splat = 0x0c;
    579 let kExprI32x4Eq = 0x2c;
    580 let kExprS1x4AllTrue = 0x75;
    581 let kExprF32x4Min = 0x9e;
    582 
    583 Object.assign(globalThis, {
    584  kExprUnreachable, kExprNop, kExprBlock, kExprLoop, kExprIf, kExprElse,
    585  kExprTry, kExprCatch, kExprCatchAll, kExprThrow, kExprRethrow, kExprBrOnExn,
    586  kExprEnd, kExprBr, kExprBrIf, kExprBrTable, kExprReturn, kExprCallFunction,
    587  kExprCallIndirect, kExprReturnCall, kExprReturnCallIndirect, kExprDrop,
    588  kExprSelect, kExprLocalGet, kExprLocalSet, kExprLocalTee, kExprGlobalGet,
    589  kExprGlobalSet, kExprTableGet, kExprTableSet, kExprI32LoadMem,
    590  kExprI64LoadMem, kExprF32LoadMem, kExprF64LoadMem, kExprI32LoadMem8S,
    591  kExprI32LoadMem8U, kExprI32LoadMem16S, kExprI32LoadMem16U, kExprI64LoadMem8S,
    592  kExprI64LoadMem8U, kExprI64LoadMem16S, kExprI64LoadMem16U, kExprI64LoadMem32S,
    593  kExprI64LoadMem32U, kExprI32StoreMem, kExprI64StoreMem, kExprF32StoreMem,
    594  kExprF64StoreMem, kExprI32StoreMem8, kExprI32StoreMem16, kExprI64StoreMem8,
    595  kExprI64StoreMem16, kExprI64StoreMem32, kExprMemorySize, kExprMemoryGrow,
    596  kExprI32Const, kExprI64Const, kExprF32Const, kExprF64Const, kExprI32Eqz,
    597  kExprI32Eq, kExprI32Ne, kExprI32LtS, kExprI32LtU, kExprI32GtS, kExprI32GtU,
    598  kExprI32LeS, kExprI32LeU, kExprI32GeS, kExprI32GeU, kExprI64Eqz, kExprI64Eq,
    599  kExprI64Ne, kExprI64LtS, kExprI64LtU, kExprI64GtS, kExprI64GtU, kExprI64LeS,
    600  kExprI64LeU, kExprI64GeS, kExprI64GeU, kExprF32Eq, kExprF32Ne, kExprF32Lt,
    601  kExprF32Gt, kExprF32Le, kExprF32Ge, kExprF64Eq, kExprF64Ne, kExprF64Lt,
    602  kExprF64Gt, kExprF64Le, kExprF64Ge, kExprI32Clz, kExprI32Ctz, kExprI32Popcnt,
    603  kExprI32Add, kExprI32Sub, kExprI32Mul, kExprI32DivS, kExprI32DivU,
    604  kExprI32RemS, kExprI32RemU, kExprI32And, kExprI32Ior, kExprI32Xor,
    605  kExprI32Shl, kExprI32ShrS, kExprI32ShrU, kExprI32Rol, kExprI32Ror,
    606  kExprI64Clz, kExprI64Ctz, kExprI64Popcnt, kExprI64Add, kExprI64Sub,
    607  kExprI64Mul, kExprI64DivS, kExprI64DivU, kExprI64RemS, kExprI64RemU,
    608  kExprI64And, kExprI64Ior, kExprI64Xor, kExprI64Shl, kExprI64ShrS,
    609  kExprI64ShrU, kExprI64Rol, kExprI64Ror, kExprF32Abs, kExprF32Neg,
    610  kExprF32Ceil, kExprF32Floor, kExprF32Trunc, kExprF32NearestInt, kExprF32Sqrt,
    611  kExprF32Add, kExprF32Sub, kExprF32Mul, kExprF32Div, kExprF32Min, kExprF32Max,
    612  kExprF32CopySign, kExprF64Abs, kExprF64Neg, kExprF64Ceil, kExprF64Floor,
    613  kExprF64Trunc, kExprF64NearestInt, kExprF64Sqrt, kExprF64Add, kExprF64Sub,
    614  kExprF64Mul, kExprF64Div, kExprF64Min, kExprF64Max, kExprF64CopySign,
    615  kExprI32ConvertI64, kExprI32SConvertF32, kExprI32UConvertF32,
    616  kExprI32SConvertF64, kExprI32UConvertF64, kExprI64SConvertI32,
    617  kExprI64UConvertI32, kExprI64SConvertF32, kExprI64UConvertF32,
    618  kExprI64SConvertF64, kExprI64UConvertF64, kExprF32SConvertI32,
    619  kExprF32UConvertI32, kExprF32SConvertI64, kExprF32UConvertI64,
    620  kExprF32ConvertF64, kExprF64SConvertI32, kExprF64UConvertI32,
    621  kExprF64SConvertI64, kExprF64UConvertI64, kExprF64ConvertF32,
    622  kExprI32ReinterpretF32, kExprI64ReinterpretF64, kExprF32ReinterpretI32,
    623  kExprF64ReinterpretI64, kExprI32SExtendI8, kExprI32SExtendI16,
    624  kExprI64SExtendI8, kExprI64SExtendI16, kExprI64SExtendI32, kExprRefNull,
    625  kExprRefIsNull, kExprRefFunc,
    626  GCInstr,
    627  kExprStructNew, kExprStructNewDefault, kExprStructGet, kExprStructGetS,
    628  kExprStructGetU, kExprStructSet, kExprArrayNew, kExprArrayNewDefault,
    629  kExprArrayNewFixed, kExprArrayNewData, kExprArrayNewElem, kExprArrayGet,
    630  kExprArrayGetS, kExprArrayGetU, kExprArraySet, kExprArrayLen, kExprArrayFill,
    631  kExprArrayCopy, kExprArrayInitData, kExprArrayInitElem, kExprRefTest,
    632  kExprRefTestNull, kExprRefCast, kExprRefCastNull, kExprBrOnCast,
    633  kExprBrOnCastFail, kExprExternInternalize, kExprExternExternalize,
    634  kExprI31New, kExprI31GetS, kExprI31GetU,
    635  kExprMemoryInit, kExprDataDrop, kExprMemoryCopy, kExprMemoryFill,
    636  kExprTableInit, kExprElemDrop, kExprTableCopy, kExprTableGrow, kExprTableSize,
    637  kExprTableFill,
    638  kExprAtomicNotify, kExprI32AtomicWait, kExprI64AtomicWait, kExprI32AtomicLoad,
    639  kExprI32AtomicLoad8U, kExprI32AtomicLoad16U, kExprI32AtomicStore,
    640  kExprI32AtomicStore8U, kExprI32AtomicStore16U, kExprI32AtomicAdd,
    641  kExprI32AtomicAdd8U, kExprI32AtomicAdd16U, kExprI32AtomicSub,
    642  kExprI32AtomicSub8U, kExprI32AtomicSub16U, kExprI32AtomicAnd,
    643  kExprI32AtomicAnd8U, kExprI32AtomicAnd16U, kExprI32AtomicOr,
    644  kExprI32AtomicOr8U, kExprI32AtomicOr16U, kExprI32AtomicXor,
    645  kExprI32AtomicXor8U, kExprI32AtomicXor16U, kExprI32AtomicExchange,
    646  kExprI32AtomicExchange8U, kExprI32AtomicExchange16U,
    647  kExprI32AtomicCompareExchange, kExprI32AtomicCompareExchange8U,
    648  kExprI32AtomicCompareExchange16U, kExprI64AtomicLoad, kExprI64AtomicLoad8U,
    649  kExprI64AtomicLoad16U, kExprI64AtomicLoad32U, kExprI64AtomicStore,
    650  kExprI64AtomicStore8U, kExprI64AtomicStore16U, kExprI64AtomicStore32U,
    651  kExprI64AtomicAdd, kExprI64AtomicAdd8U, kExprI64AtomicAdd16U,
    652  kExprI64AtomicAdd32U, kExprI64AtomicSub, kExprI64AtomicSub8U,
    653  kExprI64AtomicSub16U, kExprI64AtomicSub32U, kExprI64AtomicAnd,
    654  kExprI64AtomicAnd8U, kExprI64AtomicAnd16U, kExprI64AtomicAnd32U,
    655  kExprI64AtomicOr, kExprI64AtomicOr8U, kExprI64AtomicOr16U,
    656  kExprI64AtomicOr32U, kExprI64AtomicXor, kExprI64AtomicXor8U,
    657  kExprI64AtomicXor16U, kExprI64AtomicXor32U, kExprI64AtomicExchange,
    658  kExprI64AtomicExchange8U, kExprI64AtomicExchange16U,
    659  kExprI64AtomicExchange32U, kExprI64AtomicCompareExchange,
    660  kExprI64AtomicCompareExchange8U, kExprI64AtomicCompareExchange16U,
    661  kExprI64AtomicCompareExchange32U,
    662  kExprS128LoadMem, kExprS128StoreMem, kExprI32x4Splat, kExprI32x4Eq,
    663  kExprS1x4AllTrue, kExprF32x4Min
    664 });
    665 
    666 class Binary {
    667  constructor() {
    668    this.length = 0;
    669    this.buffer = new Uint8Array(8192);
    670  }
    671 
    672  ensure_space(needed) {
    673    if (this.buffer.length - this.length >= needed) return;
    674    let new_capacity = this.buffer.length * 2;
    675    while (new_capacity - this.length < needed) new_capacity *= 2;
    676    let new_buffer = new Uint8Array(new_capacity);
    677    new_buffer.set(this.buffer);
    678    this.buffer = new_buffer;
    679  }
    680 
    681  trunc_buffer() {
    682    return new Uint8Array(this.buffer.buffer, 0, this.length);
    683  }
    684 
    685  reset() {
    686    this.length = 0;
    687  }
    688 
    689  emit_u8(val) {
    690    this.ensure_space(1);
    691    this.buffer[this.length++] = val;
    692  }
    693 
    694  emit_u16(val) {
    695    this.ensure_space(2);
    696    this.buffer[this.length++] = val;
    697    this.buffer[this.length++] = val >> 8;
    698  }
    699 
    700  emit_u32(val) {
    701    this.ensure_space(4);
    702    this.buffer[this.length++] = val;
    703    this.buffer[this.length++] = val >> 8;
    704    this.buffer[this.length++] = val >> 16;
    705    this.buffer[this.length++] = val >> 24;
    706  }
    707 
    708  emit_leb_u(val, max_len) {
    709    this.ensure_space(max_len);
    710    for (let i = 0; i < max_len; ++i) {
    711      let v = val & 0xff;
    712      val = val >>> 7;
    713      if (val == 0) {
    714        this.buffer[this.length++] = v;
    715        return;
    716      }
    717      this.buffer[this.length++] = v | 0x80;
    718    }
    719    throw new Error("Leb value exceeds maximum length of " + max_len);
    720  }
    721 
    722  emit_u32v(val) {
    723    this.emit_leb_u(val, kMaxVarInt32Size);
    724  }
    725 
    726  emit_u64v(val) {
    727    this.emit_leb_u(val, kMaxVarInt64Size);
    728  }
    729 
    730  emit_bytes(data) {
    731    this.ensure_space(data.length);
    732    this.buffer.set(data, this.length);
    733    this.length += data.length;
    734  }
    735 
    736  emit_string(string) {
    737    // When testing illegal names, we pass a byte array directly.
    738    if (string instanceof Array) {
    739      this.emit_u32v(string.length);
    740      this.emit_bytes(string);
    741      return;
    742    }
    743 
    744    // This is the hacky way to convert a JavaScript string to a UTF8 encoded
    745    // string only containing single-byte characters.
    746    let string_utf8 = unescape(encodeURIComponent(string));
    747    this.emit_u32v(string_utf8.length);
    748    for (let i = 0; i < string_utf8.length; i++) {
    749      this.emit_u8(string_utf8.charCodeAt(i));
    750    }
    751  }
    752 
    753  emit_heap_type(heap_type) {
    754    this.emit_bytes(wasmSignedLeb(heap_type, kMaxVarInt32Size));
    755  }
    756 
    757  emit_type(type) {
    758    if ((typeof type) == 'number') {
    759      this.emit_u8(type >= 0 ? type : type & kLeb128Mask);
    760    } else {
    761      this.emit_u8(type.opcode);
    762      if ('depth' in type) this.emit_u8(type.depth);
    763      this.emit_heap_type(type.heap_type);
    764    }
    765  }
    766 
    767  emit_init_expr(expr) {
    768    this.emit_bytes(expr);
    769    this.emit_u8(kExprEnd);
    770  }
    771 
    772  emit_header() {
    773    this.emit_bytes([
    774      kWasmH0, kWasmH1, kWasmH2, kWasmH3, kWasmV0, kWasmV1, kWasmV2, kWasmV3
    775    ]);
    776  }
    777 
    778  emit_section(section_code, content_generator) {
    779    // Emit section name.
    780    this.emit_u8(section_code);
    781    // Emit the section to a temporary buffer: its full length isn't know yet.
    782    const section = new Binary;
    783    content_generator(section);
    784    // Emit section length.
    785    this.emit_u32v(section.length);
    786    // Copy the temporary buffer.
    787    // Avoid spread because {section} can be huge.
    788    this.emit_bytes(section.trunc_buffer());
    789  }
    790 }
    791 
    792 class WasmFunctionBuilder {
    793  constructor(module, name, type_index) {
    794    this.module = module;
    795    this.name = name;
    796    this.type_index = type_index;
    797    this.body = [];
    798    this.locals = [];
    799    this.local_names = [];
    800  }
    801 
    802  numLocalNames() {
    803    let num_local_names = 0;
    804    for (let loc_name of this.local_names) {
    805      if (loc_name !== undefined) ++num_local_names;
    806    }
    807    return num_local_names;
    808  }
    809 
    810  exportAs(name) {
    811    this.module.addExport(name, this.index);
    812    return this;
    813  }
    814 
    815  exportFunc() {
    816    this.exportAs(this.name);
    817    return this;
    818  }
    819 
    820  addBody(body) {
    821    for (let b of body) {
    822      if (typeof b !== 'number' || (b & (~0xFF)) !== 0 )
    823        throw new Error('invalid body (entries must be 8 bit numbers): ' + body);
    824    }
    825    this.body = body.slice();
    826    // Automatically add the end for the function block to the body.
    827    this.body.push(kExprEnd);
    828    return this;
    829  }
    830 
    831  addBodyWithEnd(body) {
    832    this.body = body;
    833    return this;
    834  }
    835 
    836  getNumLocals() {
    837    let total_locals = 0;
    838    for (let l of this.locals) {
    839      for (let type of ["i32", "i64", "f32", "f64", "s128"]) {
    840        total_locals += l[type + "_count"] || 0;
    841      }
    842    }
    843    return total_locals;
    844  }
    845 
    846  addLocals(locals, names) {
    847    const old_num_locals = this.getNumLocals();
    848    this.locals.push(locals);
    849    if (names) {
    850      const missing_names = old_num_locals - this.local_names.length;
    851      this.local_names.push(...new Array(missing_names), ...names);
    852    }
    853    return this;
    854  }
    855 
    856  end() {
    857    return this.module;
    858  }
    859 }
    860 
    861 class WasmGlobalBuilder {
    862  constructor(module, type, mutable, init) {
    863    this.module = module;
    864    this.type = type;
    865    this.mutable = mutable;
    866    this.init = init;
    867  }
    868 
    869  exportAs(name) {
    870    this.module.exports.push({name: name, kind: kExternalGlobal,
    871                              index: this.index});
    872    return this;
    873  }
    874 }
    875 
    876 function checkExpr(expr) {
    877  for (let b of expr) {
    878    if (typeof b !== 'number' || (b & (~0xFF)) !== 0) {
    879      throw new Error(
    880          'invalid body (entries must be 8 bit numbers): ' + expr);
    881    }
    882  }
    883 }
    884 
    885 class WasmTableBuilder {
    886  constructor(module, type, initial_size, max_size, init_expr) {
    887    this.module = module;
    888    this.type = type;
    889    this.initial_size = initial_size;
    890    this.has_max = max_size != undefined;
    891    this.max_size = max_size;
    892    this.init_expr = init_expr;
    893    this.has_init = init_expr !== undefined;
    894  }
    895 
    896  exportAs(name) {
    897    this.module.exports.push({name: name, kind: kExternalTable,
    898                              index: this.index});
    899    return this;
    900  }
    901 }
    902 
    903 function makeField(type, mutability) {
    904  if ((typeof mutability) != 'boolean') {
    905    throw new Error('field mutability must be boolean');
    906  }
    907  return {type: type, mutability: mutability};
    908 }
    909 
    910 class WasmStruct {
    911  constructor(fields, is_final, supertype_idx) {
    912    if (!Array.isArray(fields)) {
    913      throw new Error('struct fields must be an array');
    914    }
    915    this.fields = fields;
    916    this.type_form = kWasmStructTypeForm;
    917    this.is_final = is_final;
    918    this.supertype = supertype_idx;
    919  }
    920 }
    921 
    922 class WasmArray {
    923  constructor(type, mutability, is_final, supertype_idx) {
    924    this.type = type;
    925    this.mutability = mutability;
    926    this.type_form = kWasmArrayTypeForm;
    927    this.is_final = is_final;
    928    this.supertype = supertype_idx;
    929  }
    930 }
    931 
    932 class WasmModuleBuilder {
    933  constructor() {
    934    this.types = [];
    935    this.imports = [];
    936    this.exports = [];
    937    this.globals = [];
    938    this.tables = [];
    939    this.tags = [];
    940    this.functions = [];
    941    this.element_segments = [];
    942    this.data_segments = [];
    943    this.explicit = [];
    944    this.rec_groups = [];
    945    this.num_imported_funcs = 0;
    946    this.num_imported_globals = 0;
    947    this.num_imported_tables = 0;
    948    this.num_imported_tags = 0;
    949    return this;
    950  }
    951 
    952  addStart(start_index) {
    953    this.start_index = start_index;
    954    return this;
    955  }
    956 
    957  addMemory(min, max, exp, shared) {
    958    this.memory = {min: min, max: max, exp: exp, shared: shared};
    959    return this;
    960  }
    961 
    962  addExplicitSection(bytes) {
    963    this.explicit.push(bytes);
    964    return this;
    965  }
    966 
    967  stringToBytes(name) {
    968    var result = new Binary();
    969    result.emit_string(name);
    970    return result.trunc_buffer()
    971  }
    972 
    973  createCustomSection(name, bytes) {
    974    name = this.stringToBytes(name);
    975    var section = new Binary();
    976    section.emit_u8(kUnknownSectionCode);
    977    section.emit_u32v(name.length + bytes.length);
    978    section.emit_bytes(name);
    979    section.emit_bytes(bytes);
    980    return section.trunc_buffer();
    981  }
    982 
    983  addCustomSection(name, bytes) {
    984    this.explicit.push(this.createCustomSection(name, bytes));
    985  }
    986 
    987  // We use {is_final = true} so that the MVP syntax is generated for
    988  // signatures.
    989  addType(type, supertype_idx = kNoSuperType, is_final = true) {
    990    var pl = type.params.length;   // should have params
    991    var rl = type.results.length;  // should have results
    992    var type_copy = {params: type.params, results: type.results,
    993                     is_final: is_final, supertype: supertype_idx};
    994    this.types.push(type_copy);
    995    return this.types.length - 1;
    996  }
    997 
    998  addStruct(fields, supertype_idx = kNoSuperType, is_final = false) {
    999    this.types.push(new WasmStruct(fields, is_final, supertype_idx));
   1000    return this.types.length - 1;
   1001  }
   1002 
   1003  addArray(type, mutability, supertype_idx = kNoSuperType, is_final = false) {
   1004    this.types.push(new WasmArray(type, mutability, is_final, supertype_idx));
   1005    return this.types.length - 1;
   1006  }
   1007 
   1008  static defaultFor(type) {
   1009    switch (type) {
   1010      case kWasmI32:
   1011        return wasmI32Const(0);
   1012      case kWasmI64:
   1013        return wasmI64Const(0);
   1014      case kWasmF32:
   1015        return wasmF32Const(0.0);
   1016      case kWasmF64:
   1017        return wasmF64Const(0.0);
   1018      case kWasmS128:
   1019        return [kSimdPrefix, kExprS128Const, ...(new Array(16).fill(0))];
   1020      default:
   1021        if ((typeof type) != 'number' && type.opcode != kWasmRefNull) {
   1022          throw new Error("Non-defaultable type");
   1023        }
   1024        let heap_type = (typeof type) == 'number' ? type : type.heap_type;
   1025        return [kExprRefNull, ...wasmSignedLeb(heap_type, kMaxVarInt32Size)];
   1026    }
   1027  }
   1028 
   1029  addGlobal(type, mutable, init) {
   1030    if (init === undefined) init = WasmModuleBuilder.defaultFor(type);
   1031    checkExpr(init);
   1032    let glob = new WasmGlobalBuilder(this, type, mutable, init);
   1033    glob.index = this.globals.length + this.num_imported_globals;
   1034    this.globals.push(glob);
   1035    return glob;
   1036  }
   1037 
   1038  addTable(type, initial_size, max_size = undefined, init_expr = undefined) {
   1039    if (type == kWasmI32 || type == kWasmI64 || type == kWasmF32 ||
   1040        type == kWasmF64 || type == kWasmS128 || type == kWasmStmt) {
   1041      throw new Error('Tables must be of a reference type');
   1042    }
   1043    if (init_expr != undefined) checkExpr(init_expr);
   1044    let table = new WasmTableBuilder(
   1045        this, type, initial_size, max_size, init_expr);
   1046    table.index = this.tables.length + this.num_imported_tables;
   1047    this.tables.push(table);
   1048    return table;
   1049  }
   1050 
   1051  addTag(type) {
   1052    let type_index = (typeof type) == "number" ? type : this.addType(type);
   1053    let tag_index = this.tags.length + this.num_imported_tags;
   1054    this.tags.push(type_index);
   1055    return tag_index;
   1056  }
   1057 
   1058  addFunction(name, type) {
   1059    let type_index = (typeof type) == "number" ? type : this.addType(type);
   1060    let func = new WasmFunctionBuilder(this, name, type_index);
   1061    func.index = this.functions.length + this.num_imported_funcs;
   1062    this.functions.push(func);
   1063    return func;
   1064  }
   1065 
   1066  addImport(module, name, type) {
   1067    if (this.functions.length != 0) {
   1068      throw new Error('Imported functions must be declared before local ones');
   1069    }
   1070    let type_index = (typeof type) == "number" ? type : this.addType(type);
   1071    this.imports.push({module: module, name: name, kind: kExternalFunction,
   1072                       type: type_index});
   1073    return this.num_imported_funcs++;
   1074  }
   1075 
   1076  addImportedGlobal(module, name, type, mutable = false) {
   1077    if (this.globals.length != 0) {
   1078      throw new Error('Imported globals must be declared before local ones');
   1079    }
   1080    let o = {module: module, name: name, kind: kExternalGlobal, type: type,
   1081             mutable: mutable};
   1082    this.imports.push(o);
   1083    return this.num_imported_globals++;
   1084  }
   1085 
   1086  addImportedMemory(module, name, initial = 0, maximum, shared) {
   1087    let o = {module: module, name: name, kind: kExternalMemory,
   1088             initial: initial, maximum: maximum, shared: shared};
   1089    this.imports.push(o);
   1090    return this;
   1091  }
   1092 
   1093  addImportedTable(module, name, initial, maximum, type) {
   1094    if (this.tables.length != 0) {
   1095      throw new Error('Imported tables must be declared before local ones');
   1096    }
   1097    let o = {module: module, name: name, kind: kExternalTable, initial: initial,
   1098             maximum: maximum, type: type || kWasmAnyFunctionTypeForm};
   1099    this.imports.push(o);
   1100    return this.num_imported_tables++;
   1101  }
   1102 
   1103  addImportedTag(module, name, type) {
   1104    if (this.tags.length != 0) {
   1105      throw new Error('Imported tags must be declared before local ones');
   1106    }
   1107    let type_index = (typeof type) == "number" ? type : this.addType(type);
   1108    let o = {module: module, name: name, kind: kExternalTag, type: type_index};
   1109    this.imports.push(o);
   1110    return this.num_imported_tags++;
   1111  }
   1112 
   1113  addExport(name, index) {
   1114    this.exports.push({name: name, kind: kExternalFunction, index: index});
   1115    return this;
   1116  }
   1117 
   1118  addExportOfKind(name, kind, index) {
   1119    this.exports.push({name: name, kind: kind, index: index});
   1120    return this;
   1121  }
   1122 
   1123  addDataSegment(addr, data, is_global = false) {
   1124    this.data_segments.push(
   1125        {addr: addr, data: data, is_global: is_global, is_active: true});
   1126    return this.data_segments.length - 1;
   1127  }
   1128 
   1129  addPassiveDataSegment(data) {
   1130    this.data_segments.push({data: data, is_active: false});
   1131    return this.data_segments.length - 1;
   1132  }
   1133 
   1134  exportMemoryAs(name) {
   1135    this.exports.push({name: name, kind: kExternalMemory, index: 0});
   1136  }
   1137 
   1138  addElementSegment(table, base, is_global, array) {
   1139    this.element_segments.push({table: table, base: base, is_global: is_global,
   1140                                    array: array, is_active: true});
   1141    return this;
   1142  }
   1143 
   1144  addPassiveElementSegment(array, is_import = false) {
   1145    this.element_segments.push({array: array, is_active: false});
   1146    return this;
   1147  }
   1148 
   1149  appendToTable(array) {
   1150    for (let n of array) {
   1151      if (typeof n != 'number')
   1152        throw new Error('invalid table (entries have to be numbers): ' + array);
   1153    }
   1154    if (this.tables.length == 0) {
   1155      this.addTable(kWasmAnyFunc, 0);
   1156    }
   1157    // Adjust the table to the correct size.
   1158    let table = this.tables[0];
   1159    const base = table.initial_size;
   1160    const table_size = base + array.length;
   1161    table.initial_size = table_size;
   1162    if (table.has_max && table_size > table.max_size) {
   1163      table.max_size = table_size;
   1164    }
   1165    return this.addElementSegment(0, base, false, array);
   1166  }
   1167 
   1168  setTableBounds(min, max = undefined) {
   1169    if (this.tables.length != 0) {
   1170      throw new Error("The table bounds of table '0' have already been set.");
   1171    }
   1172    this.addTable(kWasmAnyFunc, min, max);
   1173    return this;
   1174  }
   1175 
   1176  startRecGroup() {
   1177    this.rec_groups.push({start: this.types.length, size: 0});
   1178  }
   1179 
   1180  endRecGroup() {
   1181    if (this.rec_groups.length == 0) {
   1182      throw new Error("Did not start a recursive group before ending one")
   1183    }
   1184    let last_element = this.rec_groups[this.rec_groups.length - 1]
   1185    if (last_element.size != 0) {
   1186      throw new Error("Did not start a recursive group before ending one")
   1187    }
   1188    last_element.size = this.types.length - last_element.start;
   1189  }
   1190 
   1191  setName(name) {
   1192    this.name = name;
   1193    return this;
   1194  }
   1195 
   1196  toBuffer(debug = false) {
   1197    let binary = new Binary;
   1198    let wasm = this;
   1199 
   1200    // Add header
   1201    binary.emit_header();
   1202 
   1203    // Add type section
   1204    if (wasm.types.length > 0) {
   1205      if (debug) print('emitting types @ ' + binary.length);
   1206      binary.emit_section(kTypeSectionCode, section => {
   1207        let length_with_groups = wasm.types.length;
   1208        for (let group of wasm.rec_groups) {
   1209          length_with_groups -= group.size - 1;
   1210        }
   1211        section.emit_u32v(length_with_groups);
   1212 
   1213        let rec_group_index = 0;
   1214 
   1215        for (let i = 0; i < wasm.types.length; i++) {
   1216          if (rec_group_index < wasm.rec_groups.length &&
   1217              wasm.rec_groups[rec_group_index].start == i) {
   1218            section.emit_u8(kWasmRecursiveTypeGroupForm);
   1219            section.emit_u32v(wasm.rec_groups[rec_group_index].size);
   1220            rec_group_index++;
   1221          }
   1222 
   1223          let type = wasm.types[i];
   1224          if (type.supertype != kNoSuperType) {
   1225            section.emit_u8(type.is_final ? kWasmSubtypeFinalForm
   1226                                          : kWasmSubtypeForm);
   1227            section.emit_u8(1);  // supertype count
   1228            section.emit_u32v(type.supertype);
   1229          } else if (!type.is_final) {
   1230            section.emit_u8(kWasmSubtypeForm);
   1231            section.emit_u8(0);  // no supertypes
   1232          }
   1233          if (type instanceof WasmStruct) {
   1234            section.emit_u8(kWasmStructTypeForm);
   1235            section.emit_u32v(type.fields.length);
   1236            for (let field of type.fields) {
   1237              section.emit_type(field.type);
   1238              section.emit_u8(field.mutability ? 1 : 0);
   1239            }
   1240          } else if (type instanceof WasmArray) {
   1241            section.emit_u8(kWasmArrayTypeForm);
   1242            section.emit_type(type.type);
   1243            section.emit_u8(type.mutability ? 1 : 0);
   1244          } else {
   1245            section.emit_u8(kWasmFunctionTypeForm);
   1246            section.emit_u32v(type.params.length);
   1247            for (let param of type.params) {
   1248              section.emit_type(param);
   1249            }
   1250            section.emit_u32v(type.results.length);
   1251            for (let result of type.results) {
   1252              section.emit_type(result);
   1253            }
   1254          }
   1255        }
   1256      });
   1257    }
   1258 
   1259    // Add imports section
   1260    if (wasm.imports.length > 0) {
   1261      if (debug) print("emitting imports @ " + binary.length);
   1262      binary.emit_section(kImportSectionCode, section => {
   1263        section.emit_u32v(wasm.imports.length);
   1264        for (let imp of wasm.imports) {
   1265          section.emit_string(imp.module);
   1266          section.emit_string(imp.name || '');
   1267          section.emit_u8(imp.kind);
   1268          if (imp.kind == kExternalFunction) {
   1269            section.emit_u32v(imp.type);
   1270          } else if (imp.kind == kExternalGlobal) {
   1271            section.emit_type(imp.type);
   1272            section.emit_u8(imp.mutable);
   1273          } else if (imp.kind == kExternalMemory) {
   1274            var has_max = (typeof imp.maximum) != "undefined";
   1275            var is_shared = (typeof imp.shared) != "undefined";
   1276            if (is_shared) {
   1277              section.emit_u8(has_max ? 3 : 2); // flags
   1278            } else {
   1279              section.emit_u8(has_max ? 1 : 0); // flags
   1280            }
   1281            section.emit_u32v(imp.initial); // initial
   1282            if (has_max) section.emit_u32v(imp.maximum); // maximum
   1283          } else if (imp.kind == kExternalTable) {
   1284            section.emit_type(imp.type);
   1285            var has_max = (typeof imp.maximum) != "undefined";
   1286            section.emit_u8(has_max ? 1 : 0); // flags
   1287            section.emit_u32v(imp.initial); // initial
   1288            if (has_max) section.emit_u32v(imp.maximum); // maximum
   1289          } else if (imp.kind == kExternalTag) {
   1290            section.emit_u32v(kTagAttribute);
   1291            section.emit_u32v(imp.type);
   1292          } else {
   1293            throw new Error("unknown/unsupported import kind " + imp.kind);
   1294          }
   1295        }
   1296      });
   1297    }
   1298 
   1299    // Add functions declarations
   1300    if (wasm.functions.length > 0) {
   1301      if (debug) print("emitting function decls @ " + binary.length);
   1302      binary.emit_section(kFunctionSectionCode, section => {
   1303        section.emit_u32v(wasm.functions.length);
   1304        for (let func of wasm.functions) {
   1305          section.emit_u32v(func.type_index);
   1306        }
   1307      });
   1308    }
   1309 
   1310    // Add table section
   1311    if (wasm.tables.length > 0) {
   1312      if (debug) print ("emitting tables @ " + binary.length);
   1313      binary.emit_section(kTableSectionCode, section => {
   1314        section.emit_u32v(wasm.tables.length);
   1315        for (let table of wasm.tables) {
   1316          section.emit_type(table.type);
   1317          section.emit_u8(table.has_max);
   1318          section.emit_u32v(table.initial_size);
   1319          if (table.has_max) section.emit_u32v(table.max_size);
   1320          if (table.has_init) section.emit_init_expr(table.init_expr);
   1321        }
   1322      });
   1323    }
   1324 
   1325    // Add memory section
   1326    if (wasm.memory !== undefined) {
   1327      if (debug) print("emitting memory @ " + binary.length);
   1328      binary.emit_section(kMemorySectionCode, section => {
   1329        section.emit_u8(1);  // one memory entry
   1330        const has_max = wasm.memory.max !== undefined;
   1331        const is_shared = wasm.memory.shared !== undefined;
   1332        // Emit flags (bit 0: reszeable max, bit 1: shared memory)
   1333        if (is_shared) {
   1334          section.emit_u8(has_max ? kSharedHasMaximumFlag : 2);
   1335        } else {
   1336          section.emit_u8(has_max ? kHasMaximumFlag : 0);
   1337        }
   1338        section.emit_u32v(wasm.memory.min);
   1339        if (has_max) section.emit_u32v(wasm.memory.max);
   1340      });
   1341    }
   1342 
   1343    // Add global section.
   1344    if (wasm.globals.length > 0) {
   1345      if (debug) print ("emitting globals @ " + binary.length);
   1346      binary.emit_section(kGlobalSectionCode, section => {
   1347        section.emit_u32v(wasm.globals.length);
   1348        for (let global of wasm.globals) {
   1349          section.emit_type(global.type);
   1350          section.emit_u8(global.mutable);
   1351          section.emit_init_expr(global.init);
   1352        }
   1353      });
   1354    }
   1355 
   1356    // Add tags.
   1357    if (wasm.tags.length > 0) {
   1358      if (debug) print("emitting tags @ " + binary.length);
   1359      binary.emit_section(kTagSectionCode, section => {
   1360        section.emit_u32v(wasm.tags.length);
   1361        for (let type of wasm.tags) {
   1362          section.emit_u32v(kTagAttribute);
   1363          section.emit_u32v(type);
   1364        }
   1365      });
   1366    }
   1367 
   1368    // Add export table.
   1369    var mem_export = (wasm.memory !== undefined && wasm.memory.exp);
   1370    var exports_count = wasm.exports.length + (mem_export ? 1 : 0);
   1371    if (exports_count > 0) {
   1372      if (debug) print("emitting exports @ " + binary.length);
   1373      binary.emit_section(kExportSectionCode, section => {
   1374        section.emit_u32v(exports_count);
   1375        for (let exp of wasm.exports) {
   1376          section.emit_string(exp.name);
   1377          section.emit_u8(exp.kind);
   1378          section.emit_u32v(exp.index);
   1379        }
   1380        if (mem_export) {
   1381          section.emit_string("memory");
   1382          section.emit_u8(kExternalMemory);
   1383          section.emit_u8(0);
   1384        }
   1385      });
   1386    }
   1387 
   1388    // Add start function section.
   1389    if (wasm.start_index !== undefined) {
   1390      if (debug) print("emitting start function @ " + binary.length);
   1391      binary.emit_section(kStartSectionCode, section => {
   1392        section.emit_u32v(wasm.start_index);
   1393      });
   1394    }
   1395 
   1396    // Add element segments
   1397    if (wasm.element_segments.length > 0) {
   1398      if (debug) print("emitting element segments @ " + binary.length);
   1399      binary.emit_section(kElementSectionCode, section => {
   1400        var inits = wasm.element_segments;
   1401        section.emit_u32v(inits.length);
   1402 
   1403        for (let init of inits) {
   1404          if (init.is_active) {
   1405            // Active segment.
   1406            if (init.table == 0) {
   1407              section.emit_u32v(kActiveNoIndex);
   1408            } else {
   1409              section.emit_u32v(kActiveWithIndex);
   1410              section.emit_u32v(init.table);
   1411            }
   1412            if (init.is_global) {
   1413              section.emit_u8(kExprGlobalGet);
   1414            } else {
   1415              section.emit_u8(kExprI32Const);
   1416            }
   1417            section.emit_u32v(init.base);
   1418            section.emit_u8(kExprEnd);
   1419            if (init.table != 0) {
   1420              section.emit_u8(kExternalFunction);
   1421            }
   1422            section.emit_u32v(init.array.length);
   1423            for (let index of init.array) {
   1424              section.emit_u32v(index);
   1425            }
   1426          } else {
   1427            // Passive segment.
   1428            section.emit_u8(kPassiveWithElements);  // flags
   1429            section.emit_u8(kWasmAnyFunc);
   1430            section.emit_u32v(init.array.length);
   1431            for (let index of init.array) {
   1432              if (index === null) {
   1433                section.emit_u8(kExprRefNull);
   1434                section.emit_u8(kExprEnd);
   1435              } else {
   1436                section.emit_u8(kExprRefFunc);
   1437                section.emit_u32v(index);
   1438                section.emit_u8(kExprEnd);
   1439              }
   1440            }
   1441          }
   1442        }
   1443      });
   1444    }
   1445 
   1446    // If there are any passive data segments, add the DataCount section.
   1447    if (wasm.data_segments.some(seg => !seg.is_active)) {
   1448      binary.emit_section(kDataCountSectionCode, section => {
   1449        section.emit_u32v(wasm.data_segments.length);
   1450      });
   1451    }
   1452 
   1453    // Add function bodies.
   1454    if (wasm.functions.length > 0) {
   1455      // emit function bodies
   1456      if (debug) print("emitting code @ " + binary.length);
   1457      binary.emit_section(kCodeSectionCode, section => {
   1458        section.emit_u32v(wasm.functions.length);
   1459        let header = new Binary;
   1460        for (let func of wasm.functions) {
   1461          header.reset();
   1462          // Function body length will be patched later.
   1463          let local_decls = [];
   1464          for (let l of func.locals || []) {
   1465            if (l.i32_count > 0) {
   1466              local_decls.push({count: l.i32_count, type: kWasmI32});
   1467            }
   1468            if (l.i64_count > 0) {
   1469              local_decls.push({count: l.i64_count, type: kWasmI64});
   1470            }
   1471            if (l.f32_count > 0) {
   1472              local_decls.push({count: l.f32_count, type: kWasmF32});
   1473            }
   1474            if (l.f64_count > 0) {
   1475              local_decls.push({count: l.f64_count, type: kWasmF64});
   1476            }
   1477            if (l.s128_count > 0) {
   1478              local_decls.push({count: l.s128_count, type: kWasmS128});
   1479            }
   1480            if (l.anyref_count > 0) {
   1481              local_decls.push({count: l.anyref_count, type: kWasmExternRef});
   1482            }
   1483            if (l.anyfunc_count > 0) {
   1484              local_decls.push({count: l.anyfunc_count, type: kWasmAnyFunc});
   1485            }
   1486          }
   1487 
   1488          header.emit_u32v(local_decls.length);
   1489          for (let decl of local_decls) {
   1490            header.emit_u32v(decl.count);
   1491            header.emit_type(decl.type);
   1492          }
   1493 
   1494          section.emit_u32v(header.length + func.body.length);
   1495          section.emit_bytes(header.trunc_buffer());
   1496          section.emit_bytes(func.body);
   1497        }
   1498      });
   1499    }
   1500 
   1501    // Add data segments.
   1502    if (wasm.data_segments.length > 0) {
   1503      if (debug) print("emitting data segments @ " + binary.length);
   1504      binary.emit_section(kDataSectionCode, section => {
   1505        section.emit_u32v(wasm.data_segments.length);
   1506        for (let seg of wasm.data_segments) {
   1507          if (seg.is_active) {
   1508            section.emit_u8(0);  // linear memory index 0 / flags
   1509            if (seg.is_global) {
   1510              // initializer is a global variable
   1511              section.emit_u8(kExprGlobalGet);
   1512              section.emit_u32v(seg.addr);
   1513            } else {
   1514              // initializer is a constant
   1515              section.emit_u8(kExprI32Const);
   1516              section.emit_u32v(seg.addr);
   1517            }
   1518            section.emit_u8(kExprEnd);
   1519          } else {
   1520            section.emit_u8(kPassive);  // flags
   1521          }
   1522          section.emit_u32v(seg.data.length);
   1523          section.emit_bytes(seg.data);
   1524        }
   1525      });
   1526    }
   1527 
   1528    // Add any explicitly added sections
   1529    for (let exp of wasm.explicit) {
   1530      if (debug) print("emitting explicit @ " + binary.length);
   1531      binary.emit_bytes(exp);
   1532    }
   1533 
   1534    // Add names.
   1535    let num_function_names = 0;
   1536    let num_functions_with_local_names = 0;
   1537    for (let func of wasm.functions) {
   1538      if (func.name !== undefined) ++num_function_names;
   1539      if (func.numLocalNames() > 0) ++num_functions_with_local_names;
   1540    }
   1541    if (num_function_names > 0 || num_functions_with_local_names > 0 ||
   1542        wasm.name !== undefined) {
   1543      if (debug) print('emitting names @ ' + binary.length);
   1544      binary.emit_section(kUnknownSectionCode, section => {
   1545        section.emit_string('name');
   1546        // Emit module name.
   1547        if (wasm.name !== undefined) {
   1548          section.emit_section(kModuleNameCode, name_section => {
   1549            name_section.emit_string(wasm.name);
   1550          });
   1551        }
   1552        // Emit function names.
   1553        if (num_function_names > 0) {
   1554          section.emit_section(kFunctionNamesCode, name_section => {
   1555            name_section.emit_u32v(num_function_names);
   1556            for (let func of wasm.functions) {
   1557              if (func.name === undefined) continue;
   1558              name_section.emit_u32v(func.index);
   1559              name_section.emit_string(func.name);
   1560            }
   1561          });
   1562        }
   1563        // Emit local names.
   1564        if (num_functions_with_local_names > 0) {
   1565          section.emit_section(kLocalNamesCode, name_section => {
   1566            name_section.emit_u32v(num_functions_with_local_names);
   1567            for (let func of wasm.functions) {
   1568              if (func.numLocalNames() == 0) continue;
   1569              name_section.emit_u32v(func.index);
   1570              name_section.emit_u32v(func.numLocalNames());
   1571              for (let i = 0; i < func.local_names.length; ++i) {
   1572                if (func.local_names[i] === undefined) continue;
   1573                name_section.emit_u32v(i);
   1574                name_section.emit_string(func.local_names[i]);
   1575              }
   1576            }
   1577          });
   1578        }
   1579      });
   1580    }
   1581 
   1582    return binary.trunc_buffer();
   1583  }
   1584 
   1585  toArray(debug = false) {
   1586    return Array.from(this.toBuffer(debug));
   1587  }
   1588 
   1589  instantiate(ffi) {
   1590    let module = this.toModule();
   1591    let instance = new WebAssembly.Instance(module, ffi);
   1592    return instance;
   1593  }
   1594 
   1595  asyncInstantiate(ffi) {
   1596    return WebAssembly.instantiate(this.toBuffer(), ffi)
   1597        .then(({module, instance}) => instance);
   1598  }
   1599 
   1600  toModule(debug = false) {
   1601    return new WebAssembly.Module(this.toBuffer(debug));
   1602  }
   1603 }
   1604 globalThis.WasmModuleBuilder = WasmModuleBuilder;
   1605 
   1606 function wasmSignedLeb(val, max_len = 5) {
   1607  let res = [];
   1608  for (let i = 0; i < max_len; ++i) {
   1609    let v = val & 0x7f;
   1610    // If {v} sign-extended from 7 to 32 bits is equal to val, we are done.
   1611    if (((v << 25) >> 25) == val) {
   1612      res.push(v);
   1613      return res;
   1614    }
   1615    res.push(v | 0x80);
   1616    val = val >> 7;
   1617  }
   1618  throw new Error(
   1619      'Leb value <' + val + '> exceeds maximum length of ' + max_len);
   1620 }
   1621 globalThis.wasmSignedLeb = wasmSignedLeb;
   1622 
   1623 function wasmI32Const(val) {
   1624  return [kExprI32Const, ...wasmSignedLeb(val, 5)];
   1625 }
   1626 globalThis.wasmI32Const = wasmI32Const;
   1627 
   1628 function wasmF32Const(f) {
   1629  // Write in little-endian order at offset 0.
   1630  data_view.setFloat32(0, f, true);
   1631  return [
   1632    kExprF32Const, byte_view[0], byte_view[1], byte_view[2], byte_view[3]
   1633  ];
   1634 }
   1635 globalThis.wasmI32Const = wasmI32Const;
   1636 
   1637 function wasmF64Const(f) {
   1638  // Write in little-endian order at offset 0.
   1639  data_view.setFloat64(0, f, true);
   1640  return [
   1641    kExprF64Const, byte_view[0], byte_view[1], byte_view[2],
   1642    byte_view[3], byte_view[4], byte_view[5], byte_view[6], byte_view[7]
   1643  ];
   1644 }
   1645 globalThis.wasmF64Const = wasmF64Const;