porffor 0.19.12 → 0.19.14

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.
@@ -127,4 +127,11 @@ export const __Map_prototype_values = (_this: Map) => {
127
127
  }
128
128
 
129
129
  return out;
130
- };
130
+ };
131
+
132
+ export const __Map_prototype_toString = (_this: Map) => {
133
+ const str: bytestring = '[object Map]';
134
+ return str;
135
+ }
136
+
137
+ export const __Map_prototype_toLocaleString = (_this: Map) => __Map_prototype_toString(_this);
@@ -261,170 +261,6 @@ export const BuiltinFuncs = function() {
261
261
  constr: true
262
262
  };
263
263
 
264
-
265
- this.__Porffor_print = {
266
- params: [ globalThis.precompile ? Valtype.f64 : valtypeBinary, Valtype.i32 ],
267
- typedParams: true,
268
- locals: [ Valtype.i32, Valtype.i32 ],
269
- returns: [],
270
- wasm: (scope, { typeSwitch, builtin }) => [
271
- ...typeSwitch(scope, [ [ Opcodes.local_get, 1 ] ], {
272
- [TYPES.number]: [
273
- [ Opcodes.local_get, 0 ],
274
- [ Opcodes.call, importedFuncs.print ],
275
- ],
276
- [TYPES.boolean]: [
277
- [ Opcodes.local_get, 0 ],
278
- Opcodes.i32_to_u,
279
- [ Opcodes.if, Blocktype.void ],
280
- ...printStaticStr('true'),
281
- [ Opcodes.else ],
282
- ...printStaticStr('false'),
283
- [ Opcodes.end ]
284
- ],
285
- [TYPES.string]: [
286
- // simply print a string :))
287
- // cache input pointer as i32
288
- [ Opcodes.local_get, 0 ],
289
- Opcodes.i32_to_u,
290
- [ Opcodes.local_tee, 2 ],
291
-
292
- // make end pointer
293
- [ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
294
- ...number(ValtypeSize.i16, Valtype.i32),
295
- [ Opcodes.i32_mul ],
296
-
297
- [ Opcodes.local_get, 2 ],
298
- [ Opcodes.i32_add ],
299
- [ Opcodes.local_set, 3 ],
300
-
301
- [ Opcodes.loop, Blocktype.void ],
302
-
303
- // print current char
304
- [ Opcodes.local_get, 2 ],
305
- [ Opcodes.i32_load16_u, Math.log2(ValtypeSize.i16) - 1, ValtypeSize.i32 ],
306
- Opcodes.i32_from_u,
307
- [ Opcodes.call, importedFuncs.printChar ],
308
-
309
- // increment pointer by sizeof i16
310
- [ Opcodes.local_get, 2 ],
311
- ...number(ValtypeSize.i16, Valtype.i32),
312
- [ Opcodes.i32_add ],
313
- [ Opcodes.local_tee, 2 ],
314
-
315
- // if pointer != end pointer, loop
316
- [ Opcodes.local_get, 3 ],
317
- [ Opcodes.i32_ne ],
318
- [ Opcodes.br_if, 0 ],
319
-
320
- [ Opcodes.end ]
321
- ],
322
- [TYPES.bytestring]: [
323
- // simply print a (byte)string :))
324
- // cache input pointer as i32
325
- [ Opcodes.local_get, 0 ],
326
- Opcodes.i32_to_u,
327
- [ Opcodes.local_tee, 2 ],
328
-
329
- // make end pointer
330
- [ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
331
- [ Opcodes.local_get, 2 ],
332
- [ Opcodes.i32_add ],
333
- [ Opcodes.local_set, 3 ],
334
-
335
- [ Opcodes.loop, Blocktype.void ],
336
-
337
- // print current char
338
- [ Opcodes.local_get, 2 ],
339
- [ Opcodes.i32_load8_u, Math.log2(ValtypeSize.i16) - 1, ValtypeSize.i32 ],
340
- Opcodes.i32_from_u,
341
- [ Opcodes.call, importedFuncs.printChar ],
342
-
343
- // increment pointer
344
- [ Opcodes.local_get, 2 ],
345
- [ Opcodes.i32_const, 1 ],
346
- [ Opcodes.i32_add ],
347
- [ Opcodes.local_tee, 2 ],
348
-
349
- // if pointer != end pointer, loop
350
- [ Opcodes.local_get, 3 ],
351
- [ Opcodes.i32_ne ],
352
- [ Opcodes.br_if, 0 ],
353
-
354
- [ Opcodes.end ]
355
- ],
356
- [TYPES.array]: [
357
- ...printStaticStr('[ '),
358
-
359
- // cache input pointer as i32
360
- [ Opcodes.local_get, 0 ],
361
- Opcodes.i32_to_u,
362
- [ Opcodes.local_tee, 2 ],
363
-
364
- // make end pointer
365
- [ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
366
- ...number(ValtypeSize[valtype] + 1, Valtype.i32),
367
- [ Opcodes.i32_mul ],
368
-
369
- [ Opcodes.local_get, 2 ],
370
- [ Opcodes.i32_add ],
371
- [ Opcodes.local_set, 3 ],
372
-
373
- [ Opcodes.loop, Blocktype.void ],
374
-
375
- // print current array element
376
- [ Opcodes.local_get, 2 ],
377
- [ Opcodes.load, 0, ValtypeSize.i32 ],
378
-
379
- [ Opcodes.local_get, 2 ],
380
- [ Opcodes.i32_load8_u, 0, ValtypeSize.i32 + ValtypeSize[valtype] ],
381
-
382
- [ Opcodes.call, builtin('__Porffor_print') ],
383
-
384
- // increment pointer by sizeof valtype
385
- [ Opcodes.local_get, 2 ],
386
- ...number(ValtypeSize[valtype] + 1, Valtype.i32),
387
- [ Opcodes.i32_add ],
388
- [ Opcodes.local_tee, 2 ],
389
-
390
- // if pointer != end pointer, print separator and loop
391
- [ Opcodes.local_get, 3 ],
392
- [ Opcodes.i32_ne ],
393
- [ Opcodes.if, Blocktype.void ],
394
- ...printStaticStr(', '),
395
- [ Opcodes.br, 1 ],
396
- [ Opcodes.end ],
397
-
398
- [ Opcodes.end ],
399
-
400
- ...printStaticStr(' ]'),
401
- ],
402
- [TYPES.undefined]: [
403
- ...printStaticStr('undefined')
404
- ],
405
- [TYPES.function]: [
406
- ...printStaticStr('function () {}')
407
- ],
408
- [TYPES.object]: [
409
- [ Opcodes.local_get, 0 ],
410
- Opcodes.i32_to_u,
411
- [ Opcodes.if, Blocktype.void ],
412
- ...printStaticStr('{}'),
413
- [ Opcodes.else ],
414
- ...printStaticStr('null'),
415
- [ Opcodes.end ]
416
- ],
417
- default: [
418
- [ Opcodes.local_get, 0 ],
419
- [ Opcodes.call, importedFuncs.print ],
420
- ]
421
- }, Blocktype.void)
422
- ]
423
- };
424
-
425
- // todo: add more console funcs
426
-
427
-
428
264
  this.isNaN = {
429
265
  floatOnly: true,
430
266
  params: [ valtypeBinary ],
@@ -442,7 +442,6 @@ const concatStrings = (scope, left, right, leftType, rightType, allBytestrings =
442
442
  const out = localTmp(scope, 'concat_out_pointer', Valtype.i32);
443
443
 
444
444
  if (!skipTypeCheck && !allBytestrings) includeBuiltin(scope, '__Porffor_bytestringToString');
445
- includeBuiltin(scope, '__Porffor_print');
446
445
  return [
447
446
  // setup pointers
448
447
  ...(left.length === 0 ? [
@@ -489,7 +488,7 @@ const concatStrings = (scope, left, right, leftType, rightType, allBytestrings =
489
488
  [ Opcodes.if, Blocktype.void ],
490
489
  [ Opcodes.local_get, leftPointer ],
491
490
  [ Opcodes.local_get, leftLength ],
492
- [ Opcodes.call, funcIndex.__Porffor_bytestringToString ],
491
+ [ Opcodes.call, ...unsignedLEB128(funcIndex.__Porffor_bytestringToString) ],
493
492
  [ Opcodes.local_set, leftPointer ],
494
493
  [ Opcodes.end ],
495
494
 
@@ -499,7 +498,7 @@ const concatStrings = (scope, left, right, leftType, rightType, allBytestrings =
499
498
  [ Opcodes.if, Blocktype.void ],
500
499
  [ Opcodes.local_get, rightPointer ],
501
500
  [ Opcodes.local_get, rightLength ],
502
- [ Opcodes.call, funcIndex.__Porffor_bytestringToString ],
501
+ [ Opcodes.call, ...unsignedLEB128(funcIndex.__Porffor_bytestringToString) ],
503
502
  [ Opcodes.local_set, rightPointer ],
504
503
  [ Opcodes.end ]
505
504
  ]),
@@ -564,7 +563,6 @@ const compareStrings = (scope, left, right, leftType, rightType, allBytestrings
564
563
  const indexEnd = localTmp(scope, 'compare_index_end', Valtype.i32);
565
564
 
566
565
  if (!skipTypeCheck && !allBytestrings) includeBuiltin(scope, '__Porffor_bytestringToString');
567
- includeBuiltin(scope, '__Porffor_print');
568
566
  return [
569
567
  // setup pointers
570
568
  ...(left.length === 0 ? [
@@ -606,7 +604,7 @@ const compareStrings = (scope, left, right, leftType, rightType, allBytestrings
606
604
  [ Opcodes.if, Blocktype.void ],
607
605
  [ Opcodes.local_get, leftPointer ],
608
606
  [ Opcodes.local_get, leftLength ],
609
- [ Opcodes.call, funcIndex.__Porffor_bytestringToString ],
607
+ [ Opcodes.call, ...unsignedLEB128(funcIndex.__Porffor_bytestringToString) ],
610
608
  [ Opcodes.local_set, leftPointer ],
611
609
  [ Opcodes.end ],
612
610
 
@@ -617,7 +615,7 @@ const compareStrings = (scope, left, right, leftType, rightType, allBytestrings
617
615
  [ Opcodes.local_get, rightPointer ],
618
616
  [ Opcodes.local_get, rightPointer ],
619
617
  [ Opcodes.i32_load, 0, 0 ],
620
- [ Opcodes.call, funcIndex.__Porffor_bytestringToString ],
618
+ [ Opcodes.call, ...unsignedLEB128(funcIndex.__Porffor_bytestringToString) ],
621
619
  [ Opcodes.local_set, rightPointer ],
622
620
  [ Opcodes.end ]
623
621
  ]),
@@ -953,7 +951,7 @@ const performOp = (scope, op, left, right, leftType, rightType, _global = false,
953
951
  return finalize([
954
952
  ...left,
955
953
  ...right,
956
- [ Opcodes.call, idx ]
954
+ [ Opcodes.call, ...unsignedLEB128(idx) ]
957
955
  ]);
958
956
  }
959
957
 
@@ -1130,32 +1128,37 @@ const asmFuncToAsm = (scope, func) => {
1130
1128
  }
1131
1129
 
1132
1130
  if (idx == null) throw new Error(`builtin('${n}') failed to find a func (inside ${scope.name})`);
1133
- return idx;
1131
+ return unsignedLEB128(idx);
1134
1132
  },
1135
1133
  glbl: (opcode, name, type) => {
1136
- if (!globals[name]) {
1134
+ const globalName = '#porf#' + name; // avoid potential name clashing with user js
1135
+ if (!globals[globalName]) {
1137
1136
  const idx = globals['#ind']++;
1138
- globals[name] = { idx, type };
1137
+ globals[globalName] = { idx, type };
1139
1138
 
1140
1139
  const tmpIdx = globals['#ind']++;
1141
- globals[name + '#glbl_inited'] = { idx: tmpIdx, type: Valtype.i32 };
1140
+ globals[globalName + '#glbl_inited'] = { idx: tmpIdx, type: Valtype.i32 };
1141
+ }
1142
1142
 
1143
- if (scope.globalInits[name]) return [
1144
- [ Opcodes.global_get, tmpIdx ],
1143
+ const out = [
1144
+ [ opcode, globals[globalName].idx ]
1145
+ ];
1146
+
1147
+ scope.initedGlobals ??= new Set();
1148
+ if (!scope.initedGlobals.has(name)) {
1149
+ scope.initedGlobals.add(name);
1150
+ if (scope.globalInits[name]) out.unshift(
1151
+ [ Opcodes.global_get, globals[globalName + '#glbl_inited'].idx ],
1145
1152
  [ Opcodes.i32_eqz ],
1146
1153
  [ Opcodes.if, Blocktype.void ],
1147
1154
  ...asmFuncToAsm(scope, scope.globalInits[name]),
1148
1155
  ...number(1, Valtype.i32),
1149
- [ Opcodes.global_set, tmpIdx ],
1150
- [ Opcodes.end ],
1151
-
1152
- [ opcode, globals[name].idx ]
1153
- ];
1156
+ [ Opcodes.global_set, globals[globalName + '#glbl_inited'].idx ],
1157
+ [ Opcodes.end ]
1158
+ );
1154
1159
  }
1155
1160
 
1156
- return [
1157
- [ opcode, globals[name].idx ]
1158
- ];
1161
+ return out;
1159
1162
  },
1160
1163
  loc: (name, type) => {
1161
1164
  if (!scope.locals[name]) {
@@ -1496,6 +1499,10 @@ const getNodeType = (scope, node) => {
1496
1499
  return TYPES.number;
1497
1500
  }
1498
1501
 
1502
+ if (node.type === 'UpdateExpression') {
1503
+ return TYPES.number;
1504
+ }
1505
+
1499
1506
  if (node.type === 'MemberExpression') {
1500
1507
  const name = node.property.name;
1501
1508
 
@@ -1609,8 +1616,7 @@ const countLeftover = wasm => {
1609
1616
  };
1610
1617
 
1611
1618
  const disposeLeftover = wasm => {
1612
- let leftover = countLeftover(wasm);
1613
-
1619
+ const leftover = countLeftover(wasm);
1614
1620
  for (let i = 0; i < leftover; i++) wasm.push([ Opcodes.drop ]);
1615
1621
  };
1616
1622
 
@@ -1777,7 +1783,7 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
1777
1783
  ...getNodeType(scope, decl.arguments[0]),
1778
1784
 
1779
1785
  // call regex func
1780
- [ Opcodes.call, idx ],
1786
+ [ Opcodes.call, ...unsignedLEB128(idx) ],
1781
1787
  Opcodes.i32_from_u,
1782
1788
 
1783
1789
  ...setLastType(scope, Rhemyn.types[funcName])
@@ -1820,7 +1826,7 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
1820
1826
  ...getNodeType(scope, target),
1821
1827
 
1822
1828
  // call regex func
1823
- [ Opcodes.call, idx ],
1829
+ [ Opcodes.call, ...unsignedLEB128(idx) ],
1824
1830
  Opcodes.i32_from,
1825
1831
 
1826
1832
  ...setLastType(scope, Rhemyn.types[protoName])
@@ -2248,12 +2254,13 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
2248
2254
  if (args.length < paramCount) {
2249
2255
  args = args.concat(new Array(paramCount - 1 - args.length).fill(DEFAULT_VALUE));
2250
2256
  }
2257
+
2251
2258
  const restArgs = args.slice(paramCount - 1);
2252
2259
  args = args.slice(0, paramCount - 1);
2253
2260
  args.push({
2254
2261
  type: 'ArrayExpression',
2255
2262
  elements: restArgs
2256
- })
2263
+ });
2257
2264
  }
2258
2265
 
2259
2266
  if (func && args.length > paramCount) {
@@ -2289,7 +2296,7 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
2289
2296
  if (typedParams) out = out.concat(getNodeType(scope, arg));
2290
2297
  }
2291
2298
 
2292
- out.push([ Opcodes.call, idx ]);
2299
+ out.push([ Opcodes.call, ...unsignedLEB128(idx) ]);
2293
2300
 
2294
2301
  if (!typedReturns) {
2295
2302
  // let type;
@@ -2563,6 +2570,36 @@ const extractTypeAnnotation = decl => {
2563
2570
  return { type, typeName, elementType };
2564
2571
  };
2565
2572
 
2573
+ const setLocalWithType = (scope, name, isGlobal, decl, tee = false, overrideType = undefined) => {
2574
+ const local = isGlobal ? globals[name] : scope.locals[name];
2575
+ const out = Array.isArray(decl) ? decl : generate(scope, decl, isGlobal, name);
2576
+
2577
+ // optimize away last type usage
2578
+ // todo: detect last type then i32 conversion op
2579
+ const lastOp = out.at(-1);
2580
+ if (lastOp[0] === Opcodes.local_set && lastOp[1] === scope.locals['#last_type']?.idx) {
2581
+ out.pop();
2582
+
2583
+ const setOut = setType(scope, name, []);
2584
+ out.push(
2585
+ // drop if setType is empty
2586
+ ...(setOut.length === 0 ? [ [ Opcodes.drop ] ] : setOut),
2587
+
2588
+ [ isGlobal ? Opcodes.global_set : Opcodes.local_set, local.idx ],
2589
+ ...(tee ? [ [ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ] ] : [])
2590
+ );
2591
+ } else {
2592
+ out.push(
2593
+ [ isGlobal ? Opcodes.global_set : Opcodes.local_set, local.idx ],
2594
+ ...(tee ? [ [ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ] ] : []),
2595
+
2596
+ ...setType(scope, name, overrideType ?? getNodeType(scope, decl))
2597
+ );
2598
+ }
2599
+
2600
+ return out;
2601
+ };
2602
+
2566
2603
  const generateVar = (scope, decl) => {
2567
2604
  let out = [];
2568
2605
 
@@ -2715,17 +2752,19 @@ const generateVar = (scope, decl) => {
2715
2752
  if (x.init) {
2716
2753
  const alreadyArray = scope.arrays?.get(name) != null;
2717
2754
 
2718
- const newOut = generate(scope, x.init, global, name);
2755
+ let newOut = generate(scope, x.init, global, name);
2719
2756
  if (!alreadyArray && scope.arrays?.get(name) != null) {
2720
2757
  // hack to set local as pointer before
2721
2758
  newOut.unshift(...number(scope.arrays.get(name)), [ global ? Opcodes.global_set : Opcodes.local_set, idx ]);
2722
2759
  if (newOut.at(-1) == Opcodes.i32_from_u) newOut.pop();
2723
- newOut.push([ Opcodes.drop ]);
2760
+ newOut.push(
2761
+ [ Opcodes.drop ],
2762
+ ...setType(scope, name, getNodeType(scope, x.init))
2763
+ );
2724
2764
  } else {
2725
- newOut.push([ global ? Opcodes.global_set : Opcodes.local_set, idx ]);
2765
+ newOut = setLocalWithType(scope, name, global, newOut, false, getNodeType(scope, x.init));
2726
2766
  }
2727
2767
 
2728
- newOut.push(...setType(scope, name, getNodeType(scope, x.init)));
2729
2768
  out = out.concat(newOut);
2730
2769
 
2731
2770
  if (globalThis.precompile && global) {
@@ -2850,13 +2889,13 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
2850
2889
  [ Opcodes.local_get, localTmp(scope, '#objset_property') ],
2851
2890
  ...getNodeType(scope, property),
2852
2891
 
2853
- [ Opcodes.call, funcIndex.__Map_prototype_get ],
2892
+ [ Opcodes.call, ...unsignedLEB128(funcIndex.__Map_prototype_get) ],
2854
2893
  ...setLastType(scope)
2855
2894
  ], generate(scope, decl.right), getLastType(scope), getNodeType(scope, decl.right), false, name, true)),
2856
2895
  [ Opcodes.local_tee, newValueTmp ],
2857
2896
  ...getNodeType(scope, decl),
2858
2897
 
2859
- [ Opcodes.call, funcIndex.__Map_prototype_set ],
2898
+ [ Opcodes.call, ...unsignedLEB128(funcIndex.__Map_prototype_set) ],
2860
2899
  [ Opcodes.drop ],
2861
2900
 
2862
2901
  ...setLastType(scope, getNodeType(scope, decl)),
@@ -3043,13 +3082,7 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
3043
3082
  }
3044
3083
 
3045
3084
  if (op === '=') {
3046
- return [
3047
- ...generate(scope, decl.right, isGlobal, name),
3048
- [ isGlobal ? Opcodes.global_set : Opcodes.local_set, local.idx ],
3049
- [ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ],
3050
-
3051
- ...setType(scope, name, getNodeType(scope, decl.right))
3052
- ];
3085
+ return setLocalWithType(scope, name, isGlobal, decl.right, true);
3053
3086
  }
3054
3087
 
3055
3088
  if (op === '||' || op === '&&' || op === '??') {
@@ -3062,7 +3095,7 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
3062
3095
  ...performOp(scope, op, [
3063
3096
  [ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ]
3064
3097
  ], [
3065
- ...generate(scope, decl.right),
3098
+ ...generate(scope, decl.right, isGlobal, name),
3066
3099
  [ isGlobal ? Opcodes.global_set : Opcodes.local_set, local.idx ],
3067
3100
  [ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ]
3068
3101
  ], getType(scope, name), getNodeType(scope, decl.right), isGlobal, name, true),
@@ -3072,13 +3105,12 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
3072
3105
  ];
3073
3106
  }
3074
3107
 
3075
- return [
3076
- ...performOp(scope, op, [ [ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ] ], generate(scope, decl.right), getType(scope, name), getNodeType(scope, decl.right), isGlobal, name, true),
3077
- [ isGlobal ? Opcodes.global_set : Opcodes.local_set, local.idx ],
3078
- [ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ],
3079
-
3080
- ...setType(scope, name, getNodeType(scope, decl))
3081
- ];
3108
+ return setLocalWithType(
3109
+ scope, name, isGlobal,
3110
+ performOp(scope, op, [ [ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ] ], generate(scope, decl.right), getType(scope, name), getNodeType(scope, decl.right), isGlobal, name, true),
3111
+ true,
3112
+ getNodeType(scope, decl)
3113
+ );
3082
3114
  };
3083
3115
 
3084
3116
  const ifIdentifierErrors = (scope, decl) => {
@@ -4134,16 +4166,19 @@ const makeArray = (scope, decl, global = false, name = '$undeclared', initEmpty
4134
4166
  const firstAssign = !scope.arrays.has(uniqueName);
4135
4167
  if (firstAssign) scope.arrays.set(uniqueName, rawPtr);
4136
4168
 
4137
- if (Prefs.data && firstAssign && useRawElements) {
4169
+ const local = global ? globals[name] : scope.locals[name];
4170
+ if (
4171
+ Prefs.data && firstAssign && useRawElements &&
4172
+ (!globalThis.precompile || !global)
4173
+ ) {
4138
4174
  makeData(scope, elements, rawPtr, itemType, initEmpty);
4139
4175
 
4140
4176
  // local value as pointer
4141
4177
  return [ number(rawPtr, intOut ? Valtype.i32 : valtypeBinary), pointer ];
4142
4178
  }
4143
4179
 
4144
- const local = global ? globals[name] : scope.locals[name];
4145
- const pointerTmp = local != null ? localTmp(scope, '#makearray_pointer_tmp', Valtype.i32) : null;
4146
- if (pointerTmp != null) {
4180
+ if (local != null) {
4181
+ const pointerTmp = localTmp(scope, '#makearray_pointer_tmp', Valtype.i32);
4147
4182
  out.push(
4148
4183
  [ global ? Opcodes.global_get : Opcodes.local_get, local.idx ],
4149
4184
  Opcodes.i32_to_u,
@@ -4312,7 +4347,7 @@ const generateObject = (scope, decl, global = false, name = '$undeclared') => {
4312
4347
  ...generate(scope, value),
4313
4348
  ...getNodeType(scope, value),
4314
4349
 
4315
- [ Opcodes.call, funcIndex.__Map_prototype_set ],
4350
+ [ Opcodes.call, ...unsignedLEB128(funcIndex.__Map_prototype_set) ],
4316
4351
 
4317
4352
  [ Opcodes.drop ],
4318
4353
  [ Opcodes.drop ]
@@ -4546,7 +4581,7 @@ const generateMember = (scope, decl, _global, _name) => {
4546
4581
  ...propertyWasm,
4547
4582
  ...getNodeType(scope, property),
4548
4583
 
4549
- [ Opcodes.call, funcIndex.__Map_prototype_get ],
4584
+ [ Opcodes.call, ...unsignedLEB128(funcIndex.__Map_prototype_get) ],
4550
4585
  ...setLastType(scope)
4551
4586
  ],
4552
4587
 
@@ -4674,6 +4709,9 @@ const objectHack = node => {
4674
4709
  const out = (() => {
4675
4710
  if (node.computed || node.optional) return;
4676
4711
 
4712
+ // hack: block these properties as they can be accessed on functions
4713
+ if (node.property.name == "length" || node.property.name == "name") return;
4714
+
4677
4715
  let objectName = node.object.name;
4678
4716
 
4679
4717
  // if object is not identifier or another member exp, give up
@@ -4829,10 +4867,9 @@ const internalConstrs = {
4829
4867
  }, global, name);
4830
4868
 
4831
4869
  // new Array(n)
4832
-
4833
4870
  const [ out, pointer ] = makeArray(scope, {
4834
4871
  rawElements: new Array(0)
4835
- }, global, name, true, undefined, true);
4872
+ }, global, name, true, undefined, true, true);
4836
4873
 
4837
4874
  const arg = decl.arguments[0] ?? DEFAULT_VALUE;
4838
4875
 
@@ -4957,41 +4994,14 @@ const internalConstrs = {
4957
4994
  length: 2
4958
4995
  },
4959
4996
 
4960
- __console_log: {
4997
+ printStatic: {
4961
4998
  generate: (scope, decl) => {
4962
- const out = [];
4963
-
4964
- for (let i = 0; i < decl.arguments.length; i++) {
4965
- out.push(
4966
- ...generateCall(scope, {
4967
- callee: {
4968
- type: 'Identifier',
4969
- name: '__Porffor_print'
4970
- },
4971
- arguments: [ decl.arguments[i] ]
4972
- }),
4973
-
4974
- // print space
4975
- ...(i !== decl.arguments.length - 1 ? [
4976
- ...number(32, globalThis.precompile ? Valtype.f64 : valtypeBinary),
4977
- [ Opcodes.call, importedFuncs.printChar ]
4978
- ] : [])
4979
- );
4980
- }
4981
-
4982
- // print newline
4983
- out.push(
4984
- ...number(10, globalThis.precompile ? Valtype.f64 : valtypeBinary),
4985
- [ Opcodes.call, importedFuncs.printChar ]
4986
- );
4987
-
4988
- out.push(...number(UNDEFINED));
4989
-
4990
- return out;
4999
+ const str = decl.arguments[0].value;
5000
+ return printStaticStr(str);
4991
5001
  },
4992
5002
  type: TYPES.undefined,
4993
5003
  notConstr: true,
4994
- length: 0
5004
+ length: 1
4995
5005
  }
4996
5006
  };
4997
5007
 
@@ -89,10 +89,11 @@ export default (wasm, name = '', ind = 0, locals = {}, params = [], returns = []
89
89
  }
90
90
 
91
91
  if (inst[0] === Opcodes.call || inst[0] === Opcodes.return_call) {
92
- const callFunc = funcs.find(x => x.index === inst[1]);
92
+ const idx = read_unsignedLEB128(inst.slice(1));
93
+ const callFunc = funcs.find(x => x.index === idx);
93
94
  if (callFunc) out += ` ;; $${callFunc.name} ${makeSignature(callFunc.params, callFunc.returns)}`;
94
- if (globalThis.importFuncs && inst[1] < importFuncs.length) {
95
- const importFunc = importFuncs[inst[1]];
95
+ if (globalThis.importFuncs && idx < importFuncs.length) {
96
+ const importFunc = importFuncs[idx];
96
97
  out += ` ;; import ${importFunc.name} ${makeSignature(typeof importFunc.params === 'object' ? importFunc.params : new Array(importFunc.params).fill(valtypeBinary), new Array(importFunc.returns).fill(valtypeBinary),)}`;
97
98
  }
98
99
  }