porffor 0.17.0-cab4904b8 → 0.17.0-f43ba190c

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.
package/compiler/2c.js CHANGED
@@ -182,7 +182,15 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
182
182
  }, {});
183
183
  const invGlobals = inv(globals, x => x.idx);
184
184
 
185
- const sanitize = str => str.replace(/[^0-9a-zA-Z_]/g, _ => String.fromCharCode(97 + _.charCodeAt(0) % 32));
185
+ const codeToSanitizedStr = code => {
186
+ let out = '';
187
+ while (code > 0) {
188
+ out += String.fromCharCode(97 + code % 26);
189
+ code -= 26;
190
+ }
191
+ return out;
192
+ };
193
+ const sanitize = str => str.replace(/[^0-9a-zA-Z_]/g, _ => codeToSanitizedStr(_.charCodeAt(0)));
186
194
 
187
195
  for (const x in invGlobals) {
188
196
  invGlobals[x] = sanitize(invGlobals[x]);
@@ -273,10 +281,11 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
273
281
  }
274
282
 
275
283
  const returns = f.returns.length > 0;
284
+ const typedReturns = f.returnType == null;
276
285
 
277
286
  const shouldInline = false; // f.internal;
278
287
  if (f.name === 'main') out += `int main(${prependMain.has('argv') ? 'int argc, char* argv[]' : ''}) {\n`;
279
- else out += `${f.internal ? (returns ? 'f64' : 'void') : 'struct ReturnValue'} ${shouldInline ? 'inline ' : ''}${sanitize(f.name)}(${f.params.map((x, i) => `${CValtype[x]} ${invLocals[i]}`).join(', ')}) {\n`;
288
+ else out += `${!typedReturns ? (returns ? CValtype[f.returns[0]] : 'void') : 'struct ReturnValue'} ${shouldInline ? 'inline ' : ''}${sanitize(f.name)}(${f.params.map((x, i) => `${CValtype[x]} ${invLocals[i]}`).join(', ')}) {\n`;
280
289
 
281
290
  if (f.name === 'main') {
282
291
  out += ' ' + [...prependMain.values()].join('\n ');
@@ -418,11 +427,14 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
418
427
  continue;
419
428
 
420
429
  case Opcodes.return:
421
- // line(`return${returns ? ` ${removeBrackets(vals.pop())}` : ''}`);
422
- const b = vals.pop();
423
- const a = vals.pop();
430
+ if (!typedReturns) {
431
+ line(`return${returns ? ` ${removeBrackets(vals.pop())}` : ''}`);
432
+ break;
433
+ }
434
+
435
+ const b = returns ? vals.pop() : -1;
436
+ const a = returns ? vals.pop() : -1;
424
437
  line(`return${returns ? ` (struct ReturnValue){ ${removeBrackets(a)}, ${removeBrackets(b)} }` : ''}`);
425
- // line(`return${returns ? ` (struct ReturnValue){ ${removeBrackets(vals.pop())}, ${removeBrackets(vals.pop())} }` : ''}`);
426
438
  break;
427
439
 
428
440
  case Opcodes.if: {
@@ -549,10 +561,15 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
549
561
 
550
562
  prepend.set('__Porffor_readFile',
551
563
  `i32 __Porffor_readFile(u32 pathPtr, u32 outPtr) {
552
- char* path = _memory + pathPtr + 4;
553
- FILE* fp = fopen(path, "r");
554
- if (fp == NULL) {
555
- return -1;
564
+ FILE* fp;
565
+ if (pathPtr == 0) {
566
+ fp = stdin;
567
+ } else {
568
+ char* path = _memory + pathPtr + 4;
569
+ fp = fopen(path, "r");
570
+ if (fp == NULL) {
571
+ return -1;
572
+ }
556
573
  }
557
574
 
558
575
  u32 read = 0;
@@ -585,7 +602,7 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
585
602
  for (let j = 0; j < func.params.length; j++) args.unshift(removeBrackets(vals.pop()));
586
603
 
587
604
  if (func.returns.length > 0) {
588
- if (func.internal) {
605
+ if (func.returnType != null) {
589
606
  vals.push(`${sanitize(func.name)}(${args.join(', ')})`);
590
607
  } else {
591
608
  const id = retTmpId++;
@@ -225,6 +225,16 @@ export const __Array_prototype_every = (_this: any[], callbackFn: any) => {
225
225
  return true;
226
226
  };
227
227
 
228
+ export const __Array_prototype_some = (_this: any[], callbackFn: any) => {
229
+ const len: i32 = _this.length;
230
+ let i: i32 = 0;
231
+ while (i < len) {
232
+ if (Boolean(callbackFn(_this[i], i++, _this))) return true;
233
+ }
234
+
235
+ return false;
236
+ };
237
+
228
238
  export const __Array_prototype_reduce = (_this: any[], callbackFn: any, initialValue: any) => {
229
239
  let acc: any = initialValue ?? _this[0];
230
240
 
@@ -237,6 +247,18 @@ export const __Array_prototype_reduce = (_this: any[], callbackFn: any, initialV
237
247
  return acc;
238
248
  };
239
249
 
250
+ export const __Array_prototype_reduceRight = (_this: any[], callbackFn: any, initialValue: any) => {
251
+ const len: i32 = _this.length;
252
+ let acc: any = initialValue ?? _this[len - 1];
253
+
254
+ let i: i32 = len;
255
+ while (i > 0) {
256
+ acc = callbackFn(acc, _this[--i], i, _this);
257
+ }
258
+
259
+ return acc;
260
+ };
261
+
240
262
  export const __Array_prototype_toString = (_this: any[]) => {
241
263
  // todo: this is bytestring only!
242
264
 
@@ -170,15 +170,8 @@ export const Set = () => {
170
170
  export const Set$constructor = (iterable: any): Set => {
171
171
  const out: Set = __Porffor_allocate();
172
172
 
173
- const type: number = Porffor.rawType(iterable);
174
- if (Porffor.fastOr(
175
- type == Porffor.TYPES.array,
176
- type == Porffor.TYPES.string, type == Porffor.TYPES.bytestring,
177
- type == Porffor.TYPES.set
178
- )) {
179
- for (const x of iterable) {
180
- __Set_prototype_add(out, x);
181
- }
173
+ if (Porffor.rawType(iterable) != Porffor.TYPES.undefined) for (const x of iterable) {
174
+ __Set_prototype_add(out, x);
182
175
  }
183
176
 
184
177
  return out;
@@ -0,0 +1,42 @@
1
+ export default () => {
2
+ let out = '';
3
+
4
+ const constr = name => out += `export const ${name} = () => {
5
+ throw new TypeError("Constructor ${name} requires 'new'");
6
+ };
7
+
8
+ export const ${name}$constructor = (arg: any): ${name} => {
9
+ const out: ${name} = Porffor.allocate();
10
+ let len: i32 = 0;
11
+
12
+ const type: i32 = Porffor.rawType(arg);
13
+ if (Porffor.fastOr(
14
+ type == Porffor.TYPES.array,
15
+ type == Porffor.TYPES.string, type == Porffor.TYPES.bytestring,
16
+ type == Porffor.TYPES.set
17
+ )) {
18
+ let i: i32 = 0;
19
+ for (const x of arg) {
20
+ out[i++] = x;
21
+ }
22
+ len = i;
23
+ } else if (type == Porffor.TYPES.number) {
24
+ len = arg;
25
+ }
26
+
27
+ out.length = len;
28
+ return out;
29
+ };`;
30
+
31
+ constr('Uint8Array');
32
+ constr('Int8Array');
33
+ constr('Uint8ClampedArray');
34
+ constr('Uint16Array');
35
+ constr('Int16Array');
36
+ constr('Uint32Array');
37
+ constr('Int32Array');
38
+ constr('Float32Array');
39
+ constr('Float64Array');
40
+
41
+ return out;
42
+ };
@@ -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';
@@ -619,11 +619,14 @@ const compareStrings = (scope, left, right, bytestrings = false) => {
619
619
  };
620
620
 
621
621
  const truthy = (scope, wasm, type, intIn = false, intOut = false, forceTruthyMode = undefined) => {
622
- // if (isIntToFloatOp(wasm[wasm.length - 1])) return [
623
- // ...wasm,
624
- // ...(!intIn && intOut ? [ Opcodes.i32_to_u ] : [])
625
- // ];
626
- // if (isIntOp(wasm[wasm.length - 1])) return [ ...wasm ];
622
+ if (isIntToFloatOp(wasm[wasm.length - 1])) return [
623
+ ...wasm,
624
+ ...(!intIn && intOut ? [ Opcodes.i32_to_u ] : [])
625
+ ];
626
+ if (isIntOp(wasm[wasm.length - 1])) return [
627
+ ...wasm,
628
+ ...(intOut ? [] : [ Opcodes.i32_from ]),
629
+ ];
627
630
 
628
631
  // todo/perf: use knownType and custom bytecode here instead of typeSwitch
629
632
 
@@ -1345,7 +1348,7 @@ const getNodeType = (scope, node) => {
1345
1348
  const objectKnownType = knownType(scope, getNodeType(scope, node.object));
1346
1349
  if (objectKnownType != null) {
1347
1350
  if (name === 'length') {
1348
- if ([ TYPES.string, TYPES.bytestring, TYPES.array ].includes(objectKnownType)) return TYPES.number;
1351
+ if (typeHasFlag(objectKnownType, TYPE_FLAGS.length)) return TYPES.number;
1349
1352
  else return TYPES.undefined;
1350
1353
  }
1351
1354
 
@@ -2057,7 +2060,7 @@ const unhackName = name => {
2057
2060
 
2058
2061
  const knownType = (scope, type) => {
2059
2062
  if (type.length === 1 && type[0][0] === Opcodes.i32_const) {
2060
- return type[0][1];
2063
+ return read_signedLEB128(type[0].slice(1));
2061
2064
  }
2062
2065
 
2063
2066
  if (typedInput && type.length === 1 && type[0][0] === Opcodes.local_get) {
@@ -2416,10 +2419,160 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
2416
2419
  [ Opcodes.i32_load8_u, 0, ValtypeSize.i32 + ValtypeSize[valtype] ]
2417
2420
  ], getNodeType(scope, decl.right), false, name, true)),
2418
2421
  [ Opcodes.local_tee, newValueTmp ],
2419
-
2420
2422
  [ Opcodes.store, 0, ValtypeSize.i32 ]
2421
2423
  ],
2422
2424
 
2425
+ ...wrapBC({
2426
+ [TYPES.uint8array]: [
2427
+ [ Opcodes.i32_add ],
2428
+ ...(op === '=' ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
2429
+
2430
+ ...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
2431
+ [ Opcodes.local_get, pointerTmp ],
2432
+ [ Opcodes.i32_load8_u, 0, 4 ],
2433
+ Opcodes.i32_from_u
2434
+ ], generate(scope, decl.right), number(TYPES.number, Valtype.i32), getNodeType(scope, decl.right), false, name, true)),
2435
+ [ Opcodes.local_tee, newValueTmp ],
2436
+
2437
+ Opcodes.i32_to_u,
2438
+ [ Opcodes.i32_store8, 0, 4 ]
2439
+ ],
2440
+ [TYPES.uint8clampedarray]: [
2441
+ [ Opcodes.i32_add ],
2442
+ ...(op === '=' ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
2443
+
2444
+ ...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
2445
+ [ Opcodes.local_get, pointerTmp ],
2446
+ [ Opcodes.i32_load8_u, 0, 4 ],
2447
+ Opcodes.i32_from_u
2448
+ ], generate(scope, decl.right), number(TYPES.number, Valtype.i32), getNodeType(scope, decl.right), false, name, true)),
2449
+ [ Opcodes.local_tee, newValueTmp ],
2450
+
2451
+ ...number(0),
2452
+ [ Opcodes.f64_max ],
2453
+ ...number(255),
2454
+ [ Opcodes.f64_min ],
2455
+ Opcodes.i32_to_u,
2456
+ [ Opcodes.i32_store8, 0, 4 ]
2457
+ ],
2458
+ [TYPES.int8array]: [
2459
+ [ Opcodes.i32_add ],
2460
+ ...(op === '=' ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
2461
+
2462
+ ...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
2463
+ [ Opcodes.local_get, pointerTmp ],
2464
+ [ Opcodes.i32_load8_s, 0, 4 ],
2465
+ Opcodes.i32_from
2466
+ ], generate(scope, decl.right), number(TYPES.number, Valtype.i32), getNodeType(scope, decl.right), false, name, true)),
2467
+ [ Opcodes.local_tee, newValueTmp ],
2468
+
2469
+ Opcodes.i32_to,
2470
+ [ Opcodes.i32_store8, 0, 4 ]
2471
+ ],
2472
+ [TYPES.uint16array]: [
2473
+ ...number(2, Valtype.i32),
2474
+ [ Opcodes.i32_mul ],
2475
+ [ Opcodes.i32_add ],
2476
+ ...(op === '=' ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
2477
+
2478
+ ...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
2479
+ [ Opcodes.local_get, pointerTmp ],
2480
+ [ Opcodes.i32_load16_u, 0, 4 ],
2481
+ Opcodes.i32_from_u
2482
+ ], generate(scope, decl.right), number(TYPES.number, Valtype.i32), getNodeType(scope, decl.right), false, name, true)),
2483
+ [ Opcodes.local_tee, newValueTmp ],
2484
+
2485
+ Opcodes.i32_to_u,
2486
+ [ Opcodes.i32_store16, 0, 4 ]
2487
+ ],
2488
+ [TYPES.int16array]: [
2489
+ ...number(2, Valtype.i32),
2490
+ [ Opcodes.i32_mul ],
2491
+ [ Opcodes.i32_add ],
2492
+ ...(op === '=' ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
2493
+
2494
+ ...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
2495
+ [ Opcodes.local_get, pointerTmp ],
2496
+ [ Opcodes.i32_load16_s, 0, 4 ],
2497
+ Opcodes.i32_from
2498
+ ], generate(scope, decl.right), number(TYPES.number, Valtype.i32), getNodeType(scope, decl.right), false, name, true)),
2499
+ [ Opcodes.local_tee, newValueTmp ],
2500
+
2501
+ Opcodes.i32_to,
2502
+ [ Opcodes.i32_store16, 0, 4 ]
2503
+ ],
2504
+ [TYPES.uint32array]: [
2505
+ ...number(4, Valtype.i32),
2506
+ [ Opcodes.i32_mul ],
2507
+ [ Opcodes.i32_add ],
2508
+ ...(op === '=' ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
2509
+
2510
+ ...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
2511
+ [ Opcodes.local_get, pointerTmp ],
2512
+ [ Opcodes.i32_load, 0, 4 ],
2513
+ Opcodes.i32_from_u
2514
+ ], generate(scope, decl.right), number(TYPES.number, Valtype.i32), getNodeType(scope, decl.right), false, name, true)),
2515
+ [ Opcodes.local_tee, newValueTmp ],
2516
+
2517
+ Opcodes.i32_to_u,
2518
+ [ Opcodes.i32_store, 0, 4 ]
2519
+ ],
2520
+ [TYPES.int32array]: [
2521
+ ...number(4, Valtype.i32),
2522
+ [ Opcodes.i32_mul ],
2523
+ [ Opcodes.i32_add ],
2524
+ ...(op === '=' ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
2525
+
2526
+ ...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
2527
+ [ Opcodes.local_get, pointerTmp ],
2528
+ [ Opcodes.i32_load, 0, 4 ],
2529
+ Opcodes.i32_from
2530
+ ], generate(scope, decl.right), number(TYPES.number, Valtype.i32), getNodeType(scope, decl.right), false, name, true)),
2531
+ [ Opcodes.local_tee, newValueTmp ],
2532
+
2533
+ Opcodes.i32_to,
2534
+ [ Opcodes.i32_store, 0, 4 ]
2535
+ ],
2536
+ [TYPES.float32array]: [
2537
+ ...number(4, Valtype.i32),
2538
+ [ Opcodes.i32_mul ],
2539
+ [ Opcodes.i32_add ],
2540
+ ...(op === '=' ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
2541
+
2542
+ ...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
2543
+ [ Opcodes.local_get, pointerTmp ],
2544
+ [ Opcodes.f32_load, 0, 4 ],
2545
+ [ Opcodes.f64_promote_f32 ]
2546
+ ], generate(scope, decl.right), number(TYPES.number, Valtype.i32), getNodeType(scope, decl.right), false, name, true)),
2547
+ [ Opcodes.local_tee, newValueTmp ],
2548
+
2549
+ [ Opcodes.f32_demote_f64 ],
2550
+ [ Opcodes.f32_store, 0, 4 ]
2551
+ ],
2552
+ [TYPES.float64array]: [
2553
+ ...number(8, Valtype.i32),
2554
+ [ Opcodes.i32_mul ],
2555
+ [ Opcodes.i32_add ],
2556
+ ...(op === '=' ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
2557
+
2558
+ ...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
2559
+ [ Opcodes.local_get, pointerTmp ],
2560
+ [ Opcodes.f64_load, 0, 4 ]
2561
+ ], generate(scope, decl.right), number(TYPES.number, Valtype.i32), getNodeType(scope, decl.right), false, name, true)),
2562
+ [ Opcodes.local_tee, newValueTmp ],
2563
+
2564
+ [ Opcodes.f64_store, 0, 4 ]
2565
+ ],
2566
+ }, {
2567
+ prelude: [
2568
+ ...generate(scope, decl.left.object),
2569
+ Opcodes.i32_to_u,
2570
+ ...generate(scope, decl.left.property),
2571
+ Opcodes.i32_to_u,
2572
+ ],
2573
+ postlude: setLastType(scope, TYPES.number)
2574
+ }),
2575
+
2423
2576
  default: internalThrow(scope, 'TypeError', `Cannot assign member with non-array`)
2424
2577
  }, Blocktype.void),
2425
2578
 
@@ -2997,6 +3150,7 @@ const generateForOf = (scope, decl) => {
2997
3150
  [ Opcodes.end ],
2998
3151
  [ Opcodes.end ]
2999
3152
  ],
3153
+ // todo: typed arrays
3000
3154
  default: internalThrow(scope, 'TypeError', `Tried for..of on non-iterable type`)
3001
3155
  }, Blocktype.void));
3002
3156
 
@@ -3085,13 +3239,14 @@ const generateThrow = (scope, decl) => {
3085
3239
  idx: tags.length
3086
3240
  });
3087
3241
 
3088
- let exceptId = exceptions.push({ constructor, message }) - 1;
3242
+ let exceptId = exceptions.findIndex(x => x.constructor === constructor && x.message === message);
3243
+ if (exceptId === -1) exceptId = exceptions.push({ constructor, message }) - 1;
3089
3244
 
3090
3245
  scope.exceptions ??= [];
3091
3246
  scope.exceptions.push(exceptId);
3092
3247
 
3093
3248
  return [
3094
- [ Opcodes.i32_const, signedLEB128(exceptId) ],
3249
+ ...number(exceptId, Valtype.i32),
3095
3250
  [ Opcodes.throw, tags[0].idx ]
3096
3251
  ];
3097
3252
  }
@@ -3158,7 +3313,7 @@ const generateThrow = (scope, decl) => {
3158
3313
  scope.exceptions.push(exceptId);
3159
3314
 
3160
3315
  return [
3161
- [ Opcodes.i32_const, signedLEB128(exceptId) ],
3316
+ ...number(exceptId, Valtype.i32),
3162
3317
  ...generate(scope, message),
3163
3318
  ...getNodeType(scope, message),
3164
3319
  [ Opcodes.throw, tags[0].idx ]
@@ -3516,6 +3671,19 @@ const withType = (scope, wasm, type) => [
3516
3671
  ...setLastType(scope, type)
3517
3672
  ];
3518
3673
 
3674
+ const wrapBC = (bc, { prelude = [], postlude = [] } = {}) => {
3675
+ const out = {};
3676
+ for (const x in bc) {
3677
+ out[x] = [
3678
+ ...prelude,
3679
+ ...bc[x],
3680
+ ...postlude
3681
+ ];
3682
+ }
3683
+
3684
+ return out;
3685
+ };
3686
+
3519
3687
  const generateMember = (scope, decl, _global, _name) => {
3520
3688
  const name = decl.object.name;
3521
3689
 
@@ -3569,7 +3737,7 @@ const generateMember = (scope, decl, _global, _name) => {
3569
3737
  const type = getNodeType(scope, decl.object);
3570
3738
  const known = knownType(scope, type);
3571
3739
  if (known != null) {
3572
- if ([ TYPES.string, TYPES.bytestring, TYPES.array ].includes(known)) return [
3740
+ if (typeHasFlag(known, TYPE_FLAGS.length)) return [
3573
3741
  ...generate(scope, decl.object),
3574
3742
  Opcodes.i32_to_u,
3575
3743
 
@@ -3581,7 +3749,9 @@ const generateMember = (scope, decl, _global, _name) => {
3581
3749
  }
3582
3750
 
3583
3751
  return [
3584
- ...typeIsOneOf(getNodeType(scope, decl.object), [ TYPES.string, TYPES.bytestring, TYPES.array ]),
3752
+ ...getNodeType(scope, decl.object),
3753
+ ...number(TYPE_FLAGS.length, Valtype.i32),
3754
+ [ Opcodes.i32_and ],
3585
3755
  [ Opcodes.if, valtypeBinary ],
3586
3756
  ...generate(scope, decl.object),
3587
3757
  Opcodes.i32_to_u,
@@ -3630,7 +3800,9 @@ const generateMember = (scope, decl, _global, _name) => {
3630
3800
  // // todo: we should only do this for strings but we don't know at compile-time :(
3631
3801
  // hack: this is naughty and will break things!
3632
3802
  let newOut = number(0, Valtype.i32), newPointer = number(0, Valtype.i32);
3633
- if (pages.hasAnyString && knownType(scope, getNodeType(scope, decl.object)) !== TYPES.array) {
3803
+
3804
+ const known = knownType(scope, getNodeType(scope, decl.object));
3805
+ if ((known === TYPES.string || known === TYPES.bytestring) || (pages.hasAnyString && known == null)) {
3634
3806
  // todo: we use i16 even for bytestrings which should not make a bad thing happen, just be confusing for debugging?
3635
3807
  0, [ newOut, newPointer ] = makeArray(scope, {
3636
3808
  rawElements: new Array(0)
@@ -3704,6 +3876,82 @@ const generateMember = (scope, decl, _global, _name) => {
3704
3876
  ...setLastType(scope, TYPES.bytestring)
3705
3877
  ],
3706
3878
 
3879
+ ...wrapBC({
3880
+ [TYPES.uint8array]: [
3881
+ [ Opcodes.i32_add ],
3882
+
3883
+ [ Opcodes.i32_load8_u, 0, 4 ],
3884
+ Opcodes.i32_from_u
3885
+ ],
3886
+ [TYPES.uint8clampedarray]: [
3887
+ [ Opcodes.i32_add ],
3888
+
3889
+ [ Opcodes.i32_load8_u, 0, 4 ],
3890
+ Opcodes.i32_from_u
3891
+ ],
3892
+ [TYPES.int8array]: [
3893
+ [ Opcodes.i32_add ],
3894
+
3895
+ [ Opcodes.i32_load8_s, 0, 4 ],
3896
+ Opcodes.i32_from
3897
+ ],
3898
+ [TYPES.uint16array]: [
3899
+ ...number(2, Valtype.i32),
3900
+ [ Opcodes.i32_mul ],
3901
+ [ Opcodes.i32_add ],
3902
+
3903
+ [ Opcodes.i32_load16_u, 0, 4 ],
3904
+ Opcodes.i32_from_u
3905
+ ],
3906
+ [TYPES.int16array]: [
3907
+ ...number(2, Valtype.i32),
3908
+ [ Opcodes.i32_mul ],
3909
+ [ Opcodes.i32_add ],
3910
+
3911
+ [ Opcodes.i32_load16_s, 0, 4 ],
3912
+ Opcodes.i32_from
3913
+ ],
3914
+ [TYPES.uint32array]: [
3915
+ ...number(4, Valtype.i32),
3916
+ [ Opcodes.i32_mul ],
3917
+ [ Opcodes.i32_add ],
3918
+
3919
+ [ Opcodes.i32_load, 0, 4 ],
3920
+ Opcodes.i32_from_u
3921
+ ],
3922
+ [TYPES.int32array]: [
3923
+ ...number(4, Valtype.i32),
3924
+ [ Opcodes.i32_mul ],
3925
+ [ Opcodes.i32_add ],
3926
+
3927
+ [ Opcodes.i32_load, 0, 4 ],
3928
+ Opcodes.i32_from
3929
+ ],
3930
+ [TYPES.float32array]: [
3931
+ ...number(4, Valtype.i32),
3932
+ [ Opcodes.i32_mul ],
3933
+ [ Opcodes.i32_add ],
3934
+
3935
+ [ Opcodes.f32_load, 0, 4 ],
3936
+ [ Opcodes.f64_promote_f32 ]
3937
+ ],
3938
+ [TYPES.float64array]: [
3939
+ ...number(8, Valtype.i32),
3940
+ [ Opcodes.i32_mul ],
3941
+ [ Opcodes.i32_add ],
3942
+
3943
+ [ Opcodes.f64_load, 0, 4 ]
3944
+ ],
3945
+ }, {
3946
+ prelude: [
3947
+ ...object,
3948
+ Opcodes.i32_to_u,
3949
+ ...property,
3950
+ Opcodes.i32_to_u
3951
+ ],
3952
+ postlude: setLastType(scope, TYPES.number)
3953
+ }),
3954
+
3707
3955
  default: internalThrow(scope, 'TypeError', 'Member expression is not supported for non-string non-array yet', true)
3708
3956
  });
3709
3957
  };