porffor 0.17.0-55999d22b → 0.17.0-589ace465

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,7 +4,7 @@ import { operatorOpcode } from './expression.js';
4
4
  import { BuiltinFuncs, BuiltinVars, importedFuncs, NULL, UNDEFINED } from './builtins.js';
5
5
  import { PrototypeFuncs } from './prototype.js';
6
6
  import { number } from './embedding.js';
7
- import { TYPES, TYPE_NAMES } from './types.js';
7
+ import { TYPES, TYPE_FLAGS, TYPE_NAMES, typeHasFlag } from './types.js';
8
8
  import * as Rhemyn from '../rhemyn/compile.js';
9
9
  import parse from './parse.js';
10
10
  import { log } from './log.js';
@@ -72,6 +72,9 @@ const generate = (scope, decl, global = false, name = undefined, valueUnused = f
72
72
  case 'ExpressionStatement':
73
73
  return generateExp(scope, decl);
74
74
 
75
+ case 'SequenceExpression':
76
+ return generateSequence(scope, decl);
77
+
75
78
  case 'CallExpression':
76
79
  return generateCall(scope, decl, global, name, valueUnused);
77
80
 
@@ -264,10 +267,12 @@ const internalThrow = (scope, constructor, message, expectsValue = Prefs.alwaysV
264
267
  argument: {
265
268
  type: 'NewExpression',
266
269
  callee: {
270
+ type: 'Identifier',
267
271
  name: constructor
268
272
  },
269
273
  arguments: [
270
274
  {
275
+ type: 'Literal',
271
276
  value: message
272
277
  }
273
278
  ]
@@ -289,12 +294,13 @@ const generateIdent = (scope, decl) => {
289
294
  return wasm.slice();
290
295
  }
291
296
 
292
- if (Object.hasOwn(builtinFuncs, name) || Object.hasOwn(internalConstrs, name)) {
293
- // todo: return an actual something
294
- return number(1);
295
- }
297
+ // todo: enable this by default in future
298
+ // if (!Object.hasOwn(funcIndex, name) && Object.hasOwn(builtinFuncs, name)) {
299
+ // includeBuiltin(scope, name);
300
+ // return number(funcIndex[name] - importedFuncs.length);
301
+ // }
296
302
 
297
- if (isExistingProtoFunc(name)) {
303
+ if (isExistingProtoFunc(name) || Object.hasOwn(internalConstrs, name) || Object.hasOwn(builtinFuncs, name)) {
298
304
  // todo: return an actual something
299
305
  return number(1);
300
306
  }
@@ -973,6 +979,33 @@ const performOp = (scope, op, left, right, leftType, rightType, _global = false,
973
979
  };
974
980
 
975
981
  const generateBinaryExp = (scope, decl, _global, _name) => {
982
+ if (decl.operator === 'instanceof') {
983
+ // very hacky basic instanceof
984
+ // todo: support dynamic right-hand side
985
+
986
+ const out = generate(scope, decl.left);
987
+ disposeLeftover(out);
988
+
989
+ const rightName = decl.right.name;
990
+ if (!rightName) return todo(scope, 'instanceof dynamic right-hand side is not supported yet', true);
991
+
992
+ const checkType = TYPES[rightName.toLowerCase()];
993
+ if (checkType == null || rightName !== TYPE_NAMES[checkType] || checkType === TYPES.undefined) return todo(scope, 'instanceof right-hand side type unsupported', true);
994
+
995
+ if ([TYPES.number, TYPES.boolean, TYPES.string, TYPES.symbol, TYPES.object].includes(checkType)) {
996
+ out.push(...number(0));
997
+ } else {
998
+ out.push(
999
+ ...getNodeType(scope, decl.left),
1000
+ ...number(checkType, Valtype.i32),
1001
+ [ Opcodes.i32_eq ],
1002
+ Opcodes.i32_from_u
1003
+ );
1004
+ }
1005
+
1006
+ return out;
1007
+ }
1008
+
976
1009
  const out = performOp(scope, decl.operator, generate(scope, decl.left), generate(scope, decl.right), getNodeType(scope, decl.left), getNodeType(scope, decl.right), _global, _name);
977
1010
 
978
1011
  if (valtype !== 'i32' && ['==', '===', '!=', '!==', '>', '>=', '<', '<='].includes(decl.operator)) out.push(Opcodes.i32_from_u);
@@ -1279,7 +1312,7 @@ const getNodeType = (scope, node) => {
1279
1312
  }
1280
1313
 
1281
1314
  if (node.type === 'BinaryExpression') {
1282
- if (['==', '===', '!=', '!==', '>', '>=', '<', '<='].includes(node.operator)) return TYPES.boolean;
1315
+ if (['==', '===', '!=', '!==', '>', '>=', '<', '<=', 'instanceof'].includes(node.operator)) return TYPES.boolean;
1283
1316
  if (node.operator !== '+') return TYPES.number;
1284
1317
 
1285
1318
  const knownLeft = knownType(scope, getNodeType(scope, node.left));
@@ -1312,7 +1345,7 @@ const getNodeType = (scope, node) => {
1312
1345
  const objectKnownType = knownType(scope, getNodeType(scope, node.object));
1313
1346
  if (objectKnownType != null) {
1314
1347
  if (name === 'length') {
1315
- if ([ TYPES.string, TYPES.bytestring, TYPES.array ].includes(objectKnownType)) return TYPES.number;
1348
+ if (typeHasFlag(objectKnownType, TYPE_FLAGS.length)) return TYPES.number;
1316
1349
  else return TYPES.undefined;
1317
1350
  }
1318
1351
 
@@ -1424,6 +1457,18 @@ const generateExp = (scope, decl) => {
1424
1457
  return out;
1425
1458
  };
1426
1459
 
1460
+ const generateSequence = (scope, decl) => {
1461
+ let out = [];
1462
+
1463
+ const exprs = decl.expressions;
1464
+ for (let i = 0; i < exprs.length; i++) {
1465
+ if (i > 0) disposeLeftover(out);
1466
+ out.push(...generate(scope, exprs[i]));
1467
+ }
1468
+
1469
+ return out;
1470
+ };
1471
+
1427
1472
  const CTArrayUtil = {
1428
1473
  getLengthI32: pointer => [
1429
1474
  ...number(0, Valtype.i32),
@@ -2012,7 +2057,7 @@ const unhackName = name => {
2012
2057
 
2013
2058
  const knownType = (scope, type) => {
2014
2059
  if (type.length === 1 && type[0][0] === Opcodes.i32_const) {
2015
- return type[0][1];
2060
+ return read_signedLEB128(type[0].slice(1));
2016
2061
  }
2017
2062
 
2018
2063
  if (typedInput && type.length === 1 && type[0][0] === Opcodes.local_get) {
@@ -2299,11 +2344,6 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
2299
2344
  const { type, name } = decl.left;
2300
2345
  const [ local, isGlobal ] = lookupName(scope, name);
2301
2346
 
2302
- if (type === 'ObjectPattern') {
2303
- // hack: ignore object parts of `var a = {} = 2`
2304
- return generate(scope, decl.right);
2305
- }
2306
-
2307
2347
  if (isFuncType(decl.right.type)) {
2308
2348
  // hack for a = function () { ... }
2309
2349
  decl.right.id = { name };
@@ -2376,10 +2416,160 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
2376
2416
  [ Opcodes.i32_load8_u, 0, ValtypeSize.i32 + ValtypeSize[valtype] ]
2377
2417
  ], getNodeType(scope, decl.right), false, name, true)),
2378
2418
  [ Opcodes.local_tee, newValueTmp ],
2379
-
2380
2419
  [ Opcodes.store, 0, ValtypeSize.i32 ]
2381
2420
  ],
2382
2421
 
2422
+ ...wrapBC({
2423
+ [TYPES.uint8array]: [
2424
+ [ Opcodes.i32_add ],
2425
+ ...(op === '=' ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
2426
+
2427
+ ...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
2428
+ [ Opcodes.local_get, pointerTmp ],
2429
+ [ Opcodes.i32_load8_u, 0, 4 ],
2430
+ Opcodes.i32_from_u
2431
+ ], generate(scope, decl.right), number(TYPES.number, Valtype.i32), getNodeType(scope, decl.right), false, name, true)),
2432
+ [ Opcodes.local_tee, newValueTmp ],
2433
+
2434
+ Opcodes.i32_to_u,
2435
+ [ Opcodes.i32_store8, 0, 4 ]
2436
+ ],
2437
+ [TYPES.uint8clampedarray]: [
2438
+ [ Opcodes.i32_add ],
2439
+ ...(op === '=' ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
2440
+
2441
+ ...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
2442
+ [ Opcodes.local_get, pointerTmp ],
2443
+ [ Opcodes.i32_load8_u, 0, 4 ],
2444
+ Opcodes.i32_from_u
2445
+ ], generate(scope, decl.right), number(TYPES.number, Valtype.i32), getNodeType(scope, decl.right), false, name, true)),
2446
+ [ Opcodes.local_tee, newValueTmp ],
2447
+
2448
+ ...number(0),
2449
+ [ Opcodes.f64_max ],
2450
+ ...number(255),
2451
+ [ Opcodes.f64_min ],
2452
+ Opcodes.i32_to_u,
2453
+ [ Opcodes.i32_store8, 0, 4 ]
2454
+ ],
2455
+ [TYPES.int8array]: [
2456
+ [ Opcodes.i32_add ],
2457
+ ...(op === '=' ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
2458
+
2459
+ ...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
2460
+ [ Opcodes.local_get, pointerTmp ],
2461
+ [ Opcodes.i32_load8_s, 0, 4 ],
2462
+ Opcodes.i32_from
2463
+ ], generate(scope, decl.right), number(TYPES.number, Valtype.i32), getNodeType(scope, decl.right), false, name, true)),
2464
+ [ Opcodes.local_tee, newValueTmp ],
2465
+
2466
+ Opcodes.i32_to,
2467
+ [ Opcodes.i32_store8, 0, 4 ]
2468
+ ],
2469
+ [TYPES.uint16array]: [
2470
+ ...number(2, Valtype.i32),
2471
+ [ Opcodes.i32_mul ],
2472
+ [ Opcodes.i32_add ],
2473
+ ...(op === '=' ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
2474
+
2475
+ ...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
2476
+ [ Opcodes.local_get, pointerTmp ],
2477
+ [ Opcodes.i32_load16_u, 0, 4 ],
2478
+ Opcodes.i32_from_u
2479
+ ], generate(scope, decl.right), number(TYPES.number, Valtype.i32), getNodeType(scope, decl.right), false, name, true)),
2480
+ [ Opcodes.local_tee, newValueTmp ],
2481
+
2482
+ Opcodes.i32_to_u,
2483
+ [ Opcodes.i32_store16, 0, 4 ]
2484
+ ],
2485
+ [TYPES.int16array]: [
2486
+ ...number(2, Valtype.i32),
2487
+ [ Opcodes.i32_mul ],
2488
+ [ Opcodes.i32_add ],
2489
+ ...(op === '=' ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
2490
+
2491
+ ...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
2492
+ [ Opcodes.local_get, pointerTmp ],
2493
+ [ Opcodes.i32_load16_s, 0, 4 ],
2494
+ Opcodes.i32_from
2495
+ ], generate(scope, decl.right), number(TYPES.number, Valtype.i32), getNodeType(scope, decl.right), false, name, true)),
2496
+ [ Opcodes.local_tee, newValueTmp ],
2497
+
2498
+ Opcodes.i32_to,
2499
+ [ Opcodes.i32_store16, 0, 4 ]
2500
+ ],
2501
+ [TYPES.uint32array]: [
2502
+ ...number(4, Valtype.i32),
2503
+ [ Opcodes.i32_mul ],
2504
+ [ Opcodes.i32_add ],
2505
+ ...(op === '=' ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
2506
+
2507
+ ...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
2508
+ [ Opcodes.local_get, pointerTmp ],
2509
+ [ Opcodes.i32_load, 0, 4 ],
2510
+ Opcodes.i32_from_u
2511
+ ], generate(scope, decl.right), number(TYPES.number, Valtype.i32), getNodeType(scope, decl.right), false, name, true)),
2512
+ [ Opcodes.local_tee, newValueTmp ],
2513
+
2514
+ Opcodes.i32_to_u,
2515
+ [ Opcodes.i32_store, 0, 4 ]
2516
+ ],
2517
+ [TYPES.int32array]: [
2518
+ ...number(4, Valtype.i32),
2519
+ [ Opcodes.i32_mul ],
2520
+ [ Opcodes.i32_add ],
2521
+ ...(op === '=' ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
2522
+
2523
+ ...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
2524
+ [ Opcodes.local_get, pointerTmp ],
2525
+ [ Opcodes.i32_load, 0, 4 ],
2526
+ Opcodes.i32_from
2527
+ ], generate(scope, decl.right), number(TYPES.number, Valtype.i32), getNodeType(scope, decl.right), false, name, true)),
2528
+ [ Opcodes.local_tee, newValueTmp ],
2529
+
2530
+ Opcodes.i32_to,
2531
+ [ Opcodes.i32_store, 0, 4 ]
2532
+ ],
2533
+ [TYPES.float32array]: [
2534
+ ...number(4, Valtype.i32),
2535
+ [ Opcodes.i32_mul ],
2536
+ [ Opcodes.i32_add ],
2537
+ ...(op === '=' ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
2538
+
2539
+ ...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
2540
+ [ Opcodes.local_get, pointerTmp ],
2541
+ [ Opcodes.f32_load, 0, 4 ],
2542
+ [ Opcodes.f64_promote_f32 ]
2543
+ ], generate(scope, decl.right), number(TYPES.number, Valtype.i32), getNodeType(scope, decl.right), false, name, true)),
2544
+ [ Opcodes.local_tee, newValueTmp ],
2545
+
2546
+ [ Opcodes.f32_demote_f64 ],
2547
+ [ Opcodes.f32_store, 0, 4 ]
2548
+ ],
2549
+ [TYPES.float64array]: [
2550
+ ...number(8, Valtype.i32),
2551
+ [ Opcodes.i32_mul ],
2552
+ [ Opcodes.i32_add ],
2553
+ ...(op === '=' ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
2554
+
2555
+ ...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
2556
+ [ Opcodes.local_get, pointerTmp ],
2557
+ [ Opcodes.f64_load, 0, 4 ]
2558
+ ], generate(scope, decl.right), number(TYPES.number, Valtype.i32), getNodeType(scope, decl.right), false, name, true)),
2559
+ [ Opcodes.local_tee, newValueTmp ],
2560
+
2561
+ [ Opcodes.f64_store, 0, 4 ]
2562
+ ],
2563
+ }, {
2564
+ prelude: [
2565
+ ...generate(scope, decl.left.object),
2566
+ Opcodes.i32_to_u,
2567
+ ...generate(scope, decl.left.property),
2568
+ Opcodes.i32_to_u,
2569
+ ],
2570
+ postlude: setLastType(scope, TYPES.number)
2571
+ }),
2572
+
2383
2573
  default: internalThrow(scope, 'TypeError', `Cannot assign member with non-array`)
2384
2574
  }, Blocktype.void),
2385
2575
 
@@ -2957,6 +3147,7 @@ const generateForOf = (scope, decl) => {
2957
3147
  [ Opcodes.end ],
2958
3148
  [ Opcodes.end ]
2959
3149
  ],
3150
+ // todo: typed arrays
2960
3151
  default: internalThrow(scope, 'TypeError', `Tried for..of on non-iterable type`)
2961
3152
  }, Blocktype.void));
2962
3153
 
@@ -3029,32 +3220,102 @@ const generateLabel = (scope, decl) => {
3029
3220
  const generateThrow = (scope, decl) => {
3030
3221
  scope.throws = true;
3031
3222
 
3032
- let message = decl.argument.value, constructor = null;
3223
+ const exceptionMode = Prefs.exceptionMode ?? 'lut';
3224
+ if (exceptionMode === 'lut') {
3225
+ let message = decl.argument.value, constructor = null;
3226
+
3227
+ // support `throw (new)? Error(...)`
3228
+ if (!message && (decl.argument.type === 'NewExpression' || decl.argument.type === 'CallExpression')) {
3229
+ constructor = decl.argument.callee.name;
3230
+ message = decl.argument.arguments[0]?.value ?? '';
3231
+ }
3232
+
3233
+ if (tags.length === 0) tags.push({
3234
+ params: [ Valtype.i32 ],
3235
+ results: [],
3236
+ idx: tags.length
3237
+ });
3238
+
3239
+ let exceptId = exceptions.findIndex(x => x.constructor === constructor && x.message === message);
3240
+ if (exceptId === -1) exceptId = exceptions.push({ constructor, message }) - 1;
3241
+
3242
+ scope.exceptions ??= [];
3243
+ scope.exceptions.push(exceptId);
3033
3244
 
3034
- // hack: throw new X("...") -> throw "..."
3035
- if (!message && (decl.argument.type === 'NewExpression' || decl.argument.type === 'CallExpression')) {
3036
- constructor = decl.argument.callee.name;
3037
- message = decl.argument.arguments[0]?.value ?? '';
3245
+ return [
3246
+ ...number(exceptId, Valtype.i32),
3247
+ [ Opcodes.throw, tags[0].idx ]
3248
+ ];
3038
3249
  }
3039
3250
 
3040
- if (tags.length === 0) tags.push({
3041
- params: [ Valtype.i32 ],
3042
- results: [],
3043
- idx: tags.length
3044
- });
3251
+ if (exceptionMode === 'stack') {
3252
+ if (tags.length === 0) tags.push({
3253
+ params: [ valtypeBinary, Valtype.i32 ],
3254
+ results: [],
3255
+ idx: tags.length
3256
+ });
3045
3257
 
3046
- let exceptId = exceptions.push({ constructor, message }) - 1;
3047
- let tagIdx = tags[0].idx;
3258
+ return [
3259
+ ...generate(scope, decl.argument),
3260
+ ...getNodeType(scope, decl.argument),
3261
+ [ Opcodes.throw, tags[0].idx ]
3262
+ ];
3263
+ }
3048
3264
 
3049
- scope.exceptions ??= [];
3050
- scope.exceptions.push(exceptId);
3265
+ if (exceptionMode === 'stackest') {
3266
+ let message = decl.argument, constructor = null;
3051
3267
 
3052
- // todo: write a description of how this works lol
3268
+ // support `throw (new)? Error(...)`
3269
+ if (message.type === 'NewExpression' || message.type === 'CallExpression') {
3270
+ constructor = decl.argument.callee;
3271
+ message = decl.argument.arguments[0];
3272
+ }
3053
3273
 
3054
- return [
3055
- [ Opcodes.i32_const, signedLEB128(exceptId) ],
3056
- [ Opcodes.throw, tagIdx ]
3057
- ];
3274
+ message ??= DEFAULT_VALUE;
3275
+
3276
+ if (tags.length === 0) tags.push({
3277
+ params: [ valtypeBinary, valtypeBinary, Valtype.i32 ],
3278
+ results: [],
3279
+ idx: tags.length
3280
+ });
3281
+
3282
+ return [
3283
+ ...(constructor == null ? number(-1) : generate(scope, constructor)),
3284
+ ...generate(scope, message),
3285
+ ...getNodeType(scope, message),
3286
+ [ Opcodes.throw, tags[0].idx ]
3287
+ ];
3288
+ }
3289
+
3290
+ if (exceptionMode === 'partial') {
3291
+ let message = decl.argument, constructor = null;
3292
+
3293
+ // support `throw (new)? Error(...)`
3294
+ if (message.type === 'NewExpression' || message.type === 'CallExpression') {
3295
+ constructor = decl.argument.callee.name;
3296
+ message = decl.argument.arguments[0];
3297
+ }
3298
+
3299
+ message ??= DEFAULT_VALUE;
3300
+
3301
+ if (tags.length === 0) tags.push({
3302
+ params: [ Valtype.i32, valtypeBinary, Valtype.i32 ],
3303
+ results: [],
3304
+ idx: tags.length
3305
+ });
3306
+
3307
+ let exceptId = exceptions.push({ constructor }) - 1;
3308
+
3309
+ scope.exceptions ??= [];
3310
+ scope.exceptions.push(exceptId);
3311
+
3312
+ return [
3313
+ ...number(exceptId, Valtype.i32),
3314
+ ...generate(scope, message),
3315
+ ...getNodeType(scope, message),
3316
+ [ Opcodes.throw, tags[0].idx ]
3317
+ ];
3318
+ }
3058
3319
  };
3059
3320
 
3060
3321
  const generateTry = (scope, decl) => {
@@ -3407,6 +3668,19 @@ const withType = (scope, wasm, type) => [
3407
3668
  ...setLastType(scope, type)
3408
3669
  ];
3409
3670
 
3671
+ const wrapBC = (bc, { prelude = [], postlude = [] } = {}) => {
3672
+ const out = {};
3673
+ for (const x in bc) {
3674
+ out[x] = [
3675
+ ...prelude,
3676
+ ...bc[x],
3677
+ ...postlude
3678
+ ];
3679
+ }
3680
+
3681
+ return out;
3682
+ };
3683
+
3410
3684
  const generateMember = (scope, decl, _global, _name) => {
3411
3685
  const name = decl.object.name;
3412
3686
 
@@ -3460,7 +3734,7 @@ const generateMember = (scope, decl, _global, _name) => {
3460
3734
  const type = getNodeType(scope, decl.object);
3461
3735
  const known = knownType(scope, type);
3462
3736
  if (known != null) {
3463
- if ([ TYPES.string, TYPES.bytestring, TYPES.array ].includes(known)) return [
3737
+ if (typeHasFlag(known, TYPE_FLAGS.length)) return [
3464
3738
  ...generate(scope, decl.object),
3465
3739
  Opcodes.i32_to_u,
3466
3740
 
@@ -3472,7 +3746,9 @@ const generateMember = (scope, decl, _global, _name) => {
3472
3746
  }
3473
3747
 
3474
3748
  return [
3475
- ...typeIsOneOf(getNodeType(scope, decl.object), [ TYPES.string, TYPES.bytestring, TYPES.array ]),
3749
+ ...getNodeType(scope, decl.object),
3750
+ ...number(TYPE_FLAGS.length, Valtype.i32),
3751
+ [ Opcodes.i32_and ],
3476
3752
  [ Opcodes.if, valtypeBinary ],
3477
3753
  ...generate(scope, decl.object),
3478
3754
  Opcodes.i32_to_u,
@@ -3521,7 +3797,9 @@ const generateMember = (scope, decl, _global, _name) => {
3521
3797
  // // todo: we should only do this for strings but we don't know at compile-time :(
3522
3798
  // hack: this is naughty and will break things!
3523
3799
  let newOut = number(0, Valtype.i32), newPointer = number(0, Valtype.i32);
3524
- if (pages.hasAnyString && knownType(scope, getNodeType(scope, decl.object)) !== TYPES.array) {
3800
+
3801
+ const known = knownType(scope, getNodeType(scope, decl.object));
3802
+ if ((known === TYPES.string || known === TYPES.bytestring) || (pages.hasAnyString && known == null)) {
3525
3803
  // todo: we use i16 even for bytestrings which should not make a bad thing happen, just be confusing for debugging?
3526
3804
  0, [ newOut, newPointer ] = makeArray(scope, {
3527
3805
  rawElements: new Array(0)
@@ -3595,6 +3873,82 @@ const generateMember = (scope, decl, _global, _name) => {
3595
3873
  ...setLastType(scope, TYPES.bytestring)
3596
3874
  ],
3597
3875
 
3876
+ ...wrapBC({
3877
+ [TYPES.uint8array]: [
3878
+ [ Opcodes.i32_add ],
3879
+
3880
+ [ Opcodes.i32_load8_u, 0, 4 ],
3881
+ Opcodes.i32_from_u
3882
+ ],
3883
+ [TYPES.uint8clampedarray]: [
3884
+ [ Opcodes.i32_add ],
3885
+
3886
+ [ Opcodes.i32_load8_u, 0, 4 ],
3887
+ Opcodes.i32_from_u
3888
+ ],
3889
+ [TYPES.int8array]: [
3890
+ [ Opcodes.i32_add ],
3891
+
3892
+ [ Opcodes.i32_load8_s, 0, 4 ],
3893
+ Opcodes.i32_from
3894
+ ],
3895
+ [TYPES.uint16array]: [
3896
+ ...number(2, Valtype.i32),
3897
+ [ Opcodes.i32_mul ],
3898
+ [ Opcodes.i32_add ],
3899
+
3900
+ [ Opcodes.i32_load16_u, 0, 4 ],
3901
+ Opcodes.i32_from_u
3902
+ ],
3903
+ [TYPES.int16array]: [
3904
+ ...number(2, Valtype.i32),
3905
+ [ Opcodes.i32_mul ],
3906
+ [ Opcodes.i32_add ],
3907
+
3908
+ [ Opcodes.i32_load16_s, 0, 4 ],
3909
+ Opcodes.i32_from
3910
+ ],
3911
+ [TYPES.uint32array]: [
3912
+ ...number(4, Valtype.i32),
3913
+ [ Opcodes.i32_mul ],
3914
+ [ Opcodes.i32_add ],
3915
+
3916
+ [ Opcodes.i32_load, 0, 4 ],
3917
+ Opcodes.i32_from_u
3918
+ ],
3919
+ [TYPES.int32array]: [
3920
+ ...number(4, Valtype.i32),
3921
+ [ Opcodes.i32_mul ],
3922
+ [ Opcodes.i32_add ],
3923
+
3924
+ [ Opcodes.i32_load, 0, 4 ],
3925
+ Opcodes.i32_from
3926
+ ],
3927
+ [TYPES.float32array]: [
3928
+ ...number(4, Valtype.i32),
3929
+ [ Opcodes.i32_mul ],
3930
+ [ Opcodes.i32_add ],
3931
+
3932
+ [ Opcodes.f32_load, 0, 4 ],
3933
+ [ Opcodes.f64_promote_f32 ]
3934
+ ],
3935
+ [TYPES.float64array]: [
3936
+ ...number(8, Valtype.i32),
3937
+ [ Opcodes.i32_mul ],
3938
+ [ Opcodes.i32_add ],
3939
+
3940
+ [ Opcodes.f64_load, 0, 4 ]
3941
+ ],
3942
+ }, {
3943
+ prelude: [
3944
+ ...object,
3945
+ Opcodes.i32_to_u,
3946
+ ...property,
3947
+ Opcodes.i32_to_u
3948
+ ],
3949
+ postlude: setLastType(scope, TYPES.number)
3950
+ }),
3951
+
3598
3952
  default: internalThrow(scope, 'TypeError', 'Member expression is not supported for non-string non-array yet', true)
3599
3953
  });
3600
3954
  };
@@ -3772,7 +4126,7 @@ const internalConstrs = {
3772
4126
 
3773
4127
  // todo: check in wasm instead of here
3774
4128
  const literalValue = arg.value ?? 0;
3775
- if (literalValue < 0 || !Number.isFinite(literalValue) || literalValue > 4294967295) return internalThrow(scope, 'RangeThrow', 'Invalid array length', true);
4129
+ if (literalValue < 0 || !Number.isFinite(literalValue) || literalValue > 4294967295) return internalThrow(scope, 'RangeError', 'Invalid array length', true);
3776
4130
 
3777
4131
  return [
3778
4132
  ...out,