porffor 0.2.0-e04e26f → 0.2.0-e62542f

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.
@@ -201,7 +201,7 @@ const generate = (scope, decl, global = false, name = undefined, valueUnused = f
201
201
  }
202
202
 
203
203
  let inst = Opcodes[asm[0].replace('.', '_')];
204
- if (!inst) throw new Error(`inline asm: inst ${asm[0]} not found`);
204
+ if (inst == null) throw new Error(`inline asm: inst ${asm[0]} not found`);
205
205
 
206
206
  if (!Array.isArray(inst)) inst = [ inst ];
207
207
  const immediates = asm.slice(1).map(x => {
@@ -219,8 +219,8 @@ const generate = (scope, decl, global = false, name = undefined, valueUnused = f
219
219
  __Porffor_bs: str => [
220
220
  ...makeString(scope, str, global, name, true),
221
221
 
222
- ...(name ? setType(scope, name, TYPES._bytestring) : [
223
- ...number(TYPES._bytestring, Valtype.i32),
222
+ ...(name ? setType(scope, name, TYPES.bytestring) : [
223
+ ...number(TYPES.bytestring, Valtype.i32),
224
224
  ...setLastType(scope)
225
225
  ])
226
226
  ],
@@ -460,7 +460,7 @@ const concatStrings = (scope, left, right, global, name, assign = false, bytestr
460
460
  const rightLength = localTmp(scope, 'concat_right_length', Valtype.i32);
461
461
  const leftLength = localTmp(scope, 'concat_left_length', Valtype.i32);
462
462
 
463
- if (assign) {
463
+ if (assign && Prefs.aotPointerOpt) {
464
464
  const pointer = scope.arrays?.get(name ?? '$undeclared');
465
465
 
466
466
  return [
@@ -723,7 +723,7 @@ const truthy = (scope, wasm, type, intIn = false, intOut = false) => {
723
723
 
724
724
  ...typeSwitch(scope, type, {
725
725
  // [TYPES.number]: def,
726
- [TYPES._array]: [
726
+ [TYPES.array]: [
727
727
  // arrays are always truthy
728
728
  ...number(1, intOut ? Valtype.i32 : valtypeBinary)
729
729
  ],
@@ -739,7 +739,7 @@ const truthy = (scope, wasm, type, intIn = false, intOut = false) => {
739
739
  [ Opcodes.i32_eqz ], */
740
740
  ...(intOut ? [] : [ Opcodes.i32_from_u ])
741
741
  ],
742
- [TYPES._bytestring]: [ // duplicate of string
742
+ [TYPES.bytestring]: [ // duplicate of string
743
743
  ...(!useTmp ? [] : [ [ Opcodes.local_get, tmp ] ]),
744
744
  ...(intIn ? [] : [ Opcodes.i32_to_u ]),
745
745
 
@@ -762,7 +762,7 @@ const falsy = (scope, wasm, type, intIn = false, intOut = false) => {
762
762
  ...(!useTmp ? [] : [ [ Opcodes.local_set, tmp ] ]),
763
763
 
764
764
  ...typeSwitch(scope, type, {
765
- [TYPES._array]: [
765
+ [TYPES.array]: [
766
766
  // arrays are always truthy
767
767
  ...number(0, intOut ? Valtype.i32 : valtypeBinary)
768
768
  ],
@@ -777,7 +777,7 @@ const falsy = (scope, wasm, type, intIn = false, intOut = false) => {
777
777
  [ Opcodes.i32_eqz ],
778
778
  ...(intOut ? [] : [ Opcodes.i32_from_u ])
779
779
  ],
780
- [TYPES._bytestring]: [ // duplicate of string
780
+ [TYPES.bytestring]: [ // duplicate of string
781
781
  ...(!useTmp ? [] : [ [ Opcodes.local_get, tmp ] ]),
782
782
  ...(intIn ? [] : [ Opcodes.i32_to_u ]),
783
783
 
@@ -922,7 +922,7 @@ const performOp = (scope, op, left, right, leftType, rightType, _global = false,
922
922
  }
923
923
  }
924
924
 
925
- if (knownLeft === TYPES._bytestring || knownRight === TYPES._bytestring) {
925
+ if (knownLeft === TYPES.bytestring || knownRight === TYPES.bytestring) {
926
926
  if (op === '+') {
927
927
  // todo: this should be dynamic too but for now only static
928
928
  // string concat (a + b)
@@ -1041,12 +1041,12 @@ const performOp = (scope, op, left, right, leftType, rightType, _global = false,
1041
1041
 
1042
1042
  // if left is bytestring
1043
1043
  ...leftType,
1044
- ...number(TYPES._bytestring, Valtype.i32),
1044
+ ...number(TYPES.bytestring, Valtype.i32),
1045
1045
  [ Opcodes.i32_eq ],
1046
1046
 
1047
1047
  // if right is bytestring
1048
1048
  ...rightType,
1049
- ...number(TYPES._bytestring, Valtype.i32),
1049
+ ...number(TYPES.bytestring, Valtype.i32),
1050
1050
  [ Opcodes.i32_eq ],
1051
1051
 
1052
1052
  // if both are true
@@ -1188,7 +1188,7 @@ const generateLogicExp = (scope, decl) => {
1188
1188
  // 5: pointer
1189
1189
 
1190
1190
  const isExistingProtoFunc = name => {
1191
- if (name.startsWith('__Array_prototype')) return !!prototypeFuncs[TYPES._array][name.slice(18)];
1191
+ if (name.startsWith('__Array_prototype')) return !!prototypeFuncs[TYPES.array][name.slice(18)];
1192
1192
  if (name.startsWith('__String_prototype_')) return !!prototypeFuncs[TYPES.string][name.slice(19)];
1193
1193
 
1194
1194
  return false;
@@ -1247,9 +1247,9 @@ const setLastType = scope => {
1247
1247
  const getNodeType = (scope, node) => {
1248
1248
  const inner = () => {
1249
1249
  if (node.type === 'Literal') {
1250
- if (node.regex) return TYPES._regexp;
1250
+ if (node.regex) return TYPES.regexp;
1251
1251
 
1252
- if (typeof node.value === 'string' && byteStringable(node.value)) return TYPES._bytestring;
1252
+ if (typeof node.value === 'string' && byteStringable(node.value)) return TYPES.bytestring;
1253
1253
 
1254
1254
  return TYPES[typeof node.value];
1255
1255
  }
@@ -1303,7 +1303,7 @@ const getNodeType = (scope, node) => {
1303
1303
  const spl = name.slice(2).split('_');
1304
1304
 
1305
1305
  const func = spl[spl.length - 1];
1306
- const protoFuncs = Object.keys(prototypeFuncs).filter(x => x != TYPES._bytestring && prototypeFuncs[x][func] != null);
1306
+ const protoFuncs = Object.keys(prototypeFuncs).filter(x => x != TYPES.bytestring && prototypeFuncs[x][func] != null);
1307
1307
  if (protoFuncs.length === 1) return protoFuncs[0].returnType ?? TYPES.number;
1308
1308
  }
1309
1309
 
@@ -1355,7 +1355,7 @@ const getNodeType = (scope, node) => {
1355
1355
  }
1356
1356
 
1357
1357
  if (node.type === 'ArrayExpression') {
1358
- return TYPES._array;
1358
+ return TYPES.array;
1359
1359
  }
1360
1360
 
1361
1361
  if (node.type === 'BinaryExpression') {
@@ -1367,7 +1367,7 @@ const getNodeType = (scope, node) => {
1367
1367
 
1368
1368
  // todo: this should be dynamic but for now only static
1369
1369
  if (knownLeft === TYPES.string || knownRight === TYPES.string) return TYPES.string;
1370
- if (knownLeft === TYPES._bytestring || knownRight === TYPES._bytestring) return TYPES._bytestring;
1370
+ if (knownLeft === TYPES.bytestring || knownRight === TYPES.bytestring) return TYPES.bytestring;
1371
1371
 
1372
1372
  return TYPES.number;
1373
1373
 
@@ -1393,7 +1393,7 @@ const getNodeType = (scope, node) => {
1393
1393
  if (node.operator === '!') return TYPES.boolean;
1394
1394
  if (node.operator === 'void') return TYPES.undefined;
1395
1395
  if (node.operator === 'delete') return TYPES.boolean;
1396
- if (node.operator === 'typeof') return Prefs.bytestring ? TYPES._bytestring : TYPES.string;
1396
+ if (node.operator === 'typeof') return Prefs.bytestring ? TYPES.bytestring : TYPES.string;
1397
1397
 
1398
1398
  return TYPES.number;
1399
1399
  }
@@ -1404,8 +1404,8 @@ const getNodeType = (scope, node) => {
1404
1404
 
1405
1405
  // ts hack
1406
1406
  if (scope.locals[node.object.name]?.metadata?.type === TYPES.string) return TYPES.string;
1407
- if (scope.locals[node.object.name]?.metadata?.type === TYPES._bytestring) return TYPES._bytestring;
1408
- if (scope.locals[node.object.name]?.metadata?.type === TYPES._array) return TYPES.number;
1407
+ if (scope.locals[node.object.name]?.metadata?.type === TYPES.bytestring) return TYPES.bytestring;
1408
+ if (scope.locals[node.object.name]?.metadata?.type === TYPES.array) return TYPES.number;
1409
1409
 
1410
1410
  if (scope.locals['#last_type']) return getLastType(scope);
1411
1411
 
@@ -1646,18 +1646,25 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
1646
1646
  // megahack for /regex/.func()
1647
1647
  const funcName = decl.callee.property.name;
1648
1648
  if (decl.callee.object.regex && Object.hasOwn(Rhemyn, funcName)) {
1649
- const func = Rhemyn[funcName](decl.callee.object.regex.pattern, currentFuncIndex++);
1649
+ const regex = decl.callee.object.regex.pattern;
1650
+ const rhemynName = `regex_${funcName}_${regex}`;
1650
1651
 
1651
- funcIndex[func.name] = func.index;
1652
- funcs.push(func);
1652
+ if (!funcIndex[rhemynName]) {
1653
+ const func = Rhemyn[funcName](regex, currentFuncIndex++, rhemynName);
1653
1654
 
1655
+ funcIndex[func.name] = func.index;
1656
+ funcs.push(func);
1657
+ }
1658
+
1659
+ const idx = funcIndex[rhemynName];
1654
1660
  return [
1655
1661
  // make string arg
1656
1662
  ...generate(scope, decl.arguments[0]),
1663
+ Opcodes.i32_to_u,
1664
+ ...getNodeType(scope, decl.arguments[0]),
1657
1665
 
1658
1666
  // call regex func
1659
- Opcodes.i32_to_u,
1660
- [ Opcodes.call, func.index ],
1667
+ [ Opcodes.call, idx ],
1661
1668
  Opcodes.i32_from_u,
1662
1669
 
1663
1670
  ...number(TYPES.boolean, Valtype.i32),
@@ -1697,6 +1704,7 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
1697
1704
 
1698
1705
  protoBC[type] = generateCall(scope, {
1699
1706
  callee: {
1707
+ type: 'Identifier',
1700
1708
  name: x
1701
1709
  },
1702
1710
  arguments: [ target, ...decl.arguments ],
@@ -1819,20 +1827,20 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
1819
1827
  idx = funcIndex[name];
1820
1828
 
1821
1829
  // infer arguments types from builtins params
1822
- const func = funcs.find(x => x.name === name);
1823
- for (let i = 0; i < decl.arguments.length; i++) {
1824
- const arg = decl.arguments[i];
1825
- if (!arg.name) continue;
1826
-
1827
- const local = scope.locals[arg.name];
1828
- if (!local) continue;
1829
-
1830
- local.type = func.params[i];
1831
- if (local.type === Valtype.v128) {
1832
- // specify vec subtype inferred from last vec type in function name
1833
- local.vecType = name.split('_').reverse().find(x => x.includes('x'));
1834
- }
1835
- }
1830
+ // const func = funcs.find(x => x.name === name);
1831
+ // for (let i = 0; i < decl.arguments.length; i++) {
1832
+ // const arg = decl.arguments[i];
1833
+ // if (!arg.name) continue;
1834
+
1835
+ // const local = scope.locals[arg.name];
1836
+ // if (!local) continue;
1837
+
1838
+ // local.type = func.params[i];
1839
+ // if (local.type === Valtype.v128) {
1840
+ // // specify vec subtype inferred from last vec type in function name
1841
+ // local.vecType = name.split('_').reverse().find(x => x.includes('x'));
1842
+ // }
1843
+ // }
1836
1844
  }
1837
1845
 
1838
1846
  if (idx === undefined && internalConstrs[name]) return internalConstrs[name].generate(scope, decl, _global, _name);
@@ -1864,9 +1872,6 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
1864
1872
 
1865
1873
  // value
1866
1874
  i32_const: { imms: 1, args: [], returns: 1 },
1867
-
1868
- // a, b
1869
- i32_or: { imms: 0, args: [ true, true ], returns: 1 },
1870
1875
  };
1871
1876
 
1872
1877
  const opName = name.slice('__Porffor_wasm_'.length);
@@ -2087,7 +2092,7 @@ const brTable = (input, bc, returns) => {
2087
2092
  };
2088
2093
 
2089
2094
  const typeSwitch = (scope, type, bc, returns = valtypeBinary) => {
2090
- if (!Prefs.bytestring) delete bc[TYPES._bytestring];
2095
+ if (!Prefs.bytestring) delete bc[TYPES.bytestring];
2091
2096
 
2092
2097
  const known = knownType(scope, type);
2093
2098
  if (known != null) {
@@ -2190,7 +2195,7 @@ const extractTypeAnnotation = decl => {
2190
2195
  const typeName = type;
2191
2196
  type = typeAnnoToPorfType(type);
2192
2197
 
2193
- if (type === TYPES._bytestring && !Prefs.bytestring) type = TYPES.string;
2198
+ if (type === TYPES.bytestring && !Prefs.bytestring) type = TYPES.string;
2194
2199
 
2195
2200
  // if (decl.name) console.log(decl.name, { type, elementType });
2196
2201
 
@@ -2204,6 +2209,7 @@ const generateVar = (scope, decl) => {
2204
2209
 
2205
2210
  // global variable if in top scope (main) and var ..., or if wanted
2206
2211
  const global = topLevel || decl._bare; // decl.kind === 'var';
2212
+ const target = global ? globals : scope.locals;
2207
2213
 
2208
2214
  for (const x of decl.declarations) {
2209
2215
  const name = mapName(x.id.name);
@@ -2225,6 +2231,10 @@ const generateVar = (scope, decl) => {
2225
2231
  continue; // always ignore
2226
2232
  }
2227
2233
 
2234
+ // // generate init before allocating var
2235
+ // let generated;
2236
+ // if (x.init) generated = generate(scope, x.init, global, name);
2237
+
2228
2238
  const typed = typedInput && x.id.typeAnnotation;
2229
2239
  let idx = allocVar(scope, name, global, !(typed && extractTypeAnnotation(x.id).type != null));
2230
2240
 
@@ -2233,9 +2243,17 @@ const generateVar = (scope, decl) => {
2233
2243
  }
2234
2244
 
2235
2245
  if (x.init) {
2236
- out = out.concat(generate(scope, x.init, global, name));
2237
-
2238
- out.push([ global ? Opcodes.global_set : Opcodes.local_set, idx ]);
2246
+ const generated = generate(scope, x.init, global, name);
2247
+ if (scope.arrays?.get(name) != null) {
2248
+ // hack to set local as pointer before
2249
+ out.push(...number(scope.arrays.get(name)), [ global ? Opcodes.global_set : Opcodes.local_set, idx ]);
2250
+ if (generated.at(-1) == Opcodes.i32_from_u) generated.pop();
2251
+ generated.pop();
2252
+ out = out.concat(generated);
2253
+ } else {
2254
+ out = out.concat(generated);
2255
+ out.push([ global ? Opcodes.global_set : Opcodes.local_set, idx ]);
2256
+ }
2239
2257
  out.push(...setType(scope, name, getNodeType(scope, x.init)));
2240
2258
  }
2241
2259
 
@@ -2262,6 +2280,8 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
2262
2280
  return [];
2263
2281
  }
2264
2282
 
2283
+ const op = decl.operator.slice(0, -1) || '=';
2284
+
2265
2285
  // hack: .length setter
2266
2286
  if (decl.left.type === 'MemberExpression' && decl.left.property.name === 'length') {
2267
2287
  const name = decl.left.object.name;
@@ -2270,14 +2290,20 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
2270
2290
  const aotPointer = Prefs.aotPointerOpt && pointer != null;
2271
2291
 
2272
2292
  const newValueTmp = localTmp(scope, '__length_setter_tmp');
2293
+ const pointerTmp = op === '=' ? null : localTmp(scope, '__member_setter_ptr_tmp', Valtype.i32);
2273
2294
 
2274
2295
  return [
2275
2296
  ...(aotPointer ? number(0, Valtype.i32) : [
2276
2297
  ...generate(scope, decl.left.object),
2277
2298
  Opcodes.i32_to_u
2278
2299
  ]),
2300
+ ...(!pointerTmp ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
2279
2301
 
2280
- ...generate(scope, decl.right),
2302
+ ...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
2303
+ [ Opcodes.local_get, pointerTmp ],
2304
+ [ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
2305
+ Opcodes.i32_from_u
2306
+ ], generate(scope, decl.right), number(TYPES.number, Valtype.i32), getNodeType(scope, decl.right))),
2281
2307
  [ Opcodes.local_tee, newValueTmp ],
2282
2308
 
2283
2309
  Opcodes.i32_to_u,
@@ -2287,8 +2313,6 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
2287
2313
  ];
2288
2314
  }
2289
2315
 
2290
- const op = decl.operator.slice(0, -1) || '=';
2291
-
2292
2316
  // arr[i]
2293
2317
  if (decl.left.type === 'MemberExpression' && decl.left.computed) {
2294
2318
  const name = decl.left.object.name;
@@ -2301,7 +2325,7 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
2301
2325
 
2302
2326
  return [
2303
2327
  ...typeSwitch(scope, getNodeType(scope, decl.left.object), {
2304
- [TYPES._array]: [
2328
+ [TYPES.array]: [
2305
2329
  ...(aotPointer ? [] : [
2306
2330
  ...generate(scope, decl.left.object),
2307
2331
  Opcodes.i32_to_u
@@ -2503,7 +2527,7 @@ const generateUnary = (scope, decl) => {
2503
2527
  [TYPES.undefined]: makeString(scope, 'undefined', false, '#typeof_result'),
2504
2528
  [TYPES.function]: makeString(scope, 'function', false, '#typeof_result'),
2505
2529
 
2506
- [TYPES._bytestring]: makeString(scope, 'string', false, '#typeof_result'),
2530
+ [TYPES.bytestring]: makeString(scope, 'string', false, '#typeof_result'),
2507
2531
 
2508
2532
  // object and internal types
2509
2533
  default: makeString(scope, 'object', false, '#typeof_result'),
@@ -2739,7 +2763,7 @@ const generateForOf = (scope, decl) => {
2739
2763
  // set type for local
2740
2764
  // todo: optimize away counter and use end pointer
2741
2765
  out.push(...typeSwitch(scope, getNodeType(scope, decl.right), {
2742
- [TYPES._array]: [
2766
+ [TYPES.array]: [
2743
2767
  ...setType(scope, leftName, TYPES.number),
2744
2768
 
2745
2769
  [ Opcodes.loop, Blocktype.void ],
@@ -2822,8 +2846,8 @@ const generateForOf = (scope, decl) => {
2822
2846
  [ Opcodes.end ],
2823
2847
  [ Opcodes.end ]
2824
2848
  ],
2825
- [TYPES._bytestring]: [
2826
- ...setType(scope, leftName, TYPES._bytestring),
2849
+ [TYPES.bytestring]: [
2850
+ ...setType(scope, leftName, TYPES.bytestring),
2827
2851
 
2828
2852
  [ Opcodes.loop, Blocktype.void ],
2829
2853
 
@@ -3092,12 +3116,14 @@ const makeArray = (scope, decl, global = false, name = '$undeclared', initEmpty
3092
3116
  // todo: can we just have 1 undeclared array? probably not? but this is not really memory efficient
3093
3117
  const uniqueName = name === '$undeclared' ? name + Math.random().toString().slice(2) : name;
3094
3118
 
3095
- if (Prefs.scopedPageNames) scope.arrays.set(name, allocPage(scope, `${scope.name} | ${getAllocType(itemType)}: ${uniqueName}`, itemType) * pageSize);
3119
+ if (Prefs.scopedPageNames) scope.arrays.set(name, allocPage(scope, `${getAllocType(itemType)}: ${scope.name}/${uniqueName}`, itemType) * pageSize);
3096
3120
  else scope.arrays.set(name, allocPage(scope, `${getAllocType(itemType)}: ${uniqueName}`, itemType) * pageSize);
3097
3121
  }
3098
3122
 
3099
3123
  const pointer = scope.arrays.get(name);
3100
3124
 
3125
+ const local = global ? globals[name] : scope.locals[name];
3126
+
3101
3127
  const useRawElements = !!decl.rawElements;
3102
3128
  const elements = useRawElements ? decl.rawElements : decl.elements;
3103
3129
 
@@ -3130,11 +3156,22 @@ const makeArray = (scope, decl, global = false, name = '$undeclared', initEmpty
3130
3156
  return [ out, pointer ];
3131
3157
  }
3132
3158
 
3159
+ const pointerTmp = local != null ? localTmp(scope, '#makearray_pointer_tmp', Valtype.i32) : null;
3160
+ if (pointerTmp != null) {
3161
+ out.push(
3162
+ [ global ? Opcodes.global_get : Opcodes.local_get, local.idx ],
3163
+ Opcodes.i32_to_u,
3164
+ [ Opcodes.local_set, pointerTmp ]
3165
+ );
3166
+ }
3167
+
3168
+ const pointerWasm = pointerTmp != null ? [ [ Opcodes.local_get, pointerTmp ] ] : number(pointer, Valtype.i32);
3169
+
3133
3170
  // store length as 0th array
3134
3171
  out.push(
3135
- ...number(0, Valtype.i32),
3172
+ ...pointerWasm,
3136
3173
  ...number(length, Valtype.i32),
3137
- [ Opcodes.i32_store, Math.log2(ValtypeSize.i32) - 1, ...unsignedLEB128(pointer) ]
3174
+ [ Opcodes.i32_store, Math.log2(ValtypeSize.i32) - 1, 0 ]
3138
3175
  );
3139
3176
 
3140
3177
  const storeOp = StoreOps[itemType];
@@ -3143,14 +3180,14 @@ const makeArray = (scope, decl, global = false, name = '$undeclared', initEmpty
3143
3180
  if (elements[i] == null) continue;
3144
3181
 
3145
3182
  out.push(
3146
- ...number(0, Valtype.i32),
3183
+ ...pointerWasm,
3147
3184
  ...(useRawElements ? number(elements[i], Valtype[valtype]) : generate(scope, elements[i])),
3148
- [ storeOp, (Math.log2(ValtypeSize[itemType]) || 1) - 1, ...unsignedLEB128(pointer + ValtypeSize.i32 + i * ValtypeSize[itemType]) ]
3185
+ [ storeOp, (Math.log2(ValtypeSize[itemType]) || 1) - 1, ...unsignedLEB128(ValtypeSize.i32 + i * ValtypeSize[itemType]) ]
3149
3186
  );
3150
3187
  }
3151
3188
 
3152
3189
  // local value as pointer
3153
- out.push(...number(pointer));
3190
+ out.push(...pointerWasm, Opcodes.i32_from_u);
3154
3191
 
3155
3192
  return [ out, pointer ];
3156
3193
  };
@@ -3229,7 +3266,7 @@ export const generateMember = (scope, decl, _global, _name) => {
3229
3266
  }
3230
3267
 
3231
3268
  return typeSwitch(scope, getNodeType(scope, decl.object), {
3232
- [TYPES._array]: [
3269
+ [TYPES.array]: [
3233
3270
  // get index as valtype
3234
3271
  ...property,
3235
3272
 
@@ -3282,7 +3319,7 @@ export const generateMember = (scope, decl, _global, _name) => {
3282
3319
  ...number(TYPES.string, Valtype.i32),
3283
3320
  ...setLastType(scope)
3284
3321
  ],
3285
- [TYPES._bytestring]: [
3322
+ [TYPES.bytestring]: [
3286
3323
  // setup new/out array
3287
3324
  ...newOut,
3288
3325
  [ Opcodes.drop ],
@@ -3307,7 +3344,7 @@ export const generateMember = (scope, decl, _global, _name) => {
3307
3344
  // return new string (page)
3308
3345
  ...number(newPointer),
3309
3346
 
3310
- ...number(TYPES._bytestring, Valtype.i32),
3347
+ ...number(TYPES.bytestring, Valtype.i32),
3311
3348
  ...setLastType(scope)
3312
3349
  ],
3313
3350
 
@@ -3476,7 +3513,7 @@ const internalConstrs = {
3476
3513
  ...number(pointer)
3477
3514
  ];
3478
3515
  },
3479
- type: TYPES._array,
3516
+ type: TYPES.array,
3480
3517
  length: 1
3481
3518
  },
3482
3519
 
@@ -3488,7 +3525,7 @@ const internalConstrs = {
3488
3525
  elements: decl.arguments
3489
3526
  }, global, name);
3490
3527
  },
3491
- type: TYPES._array,
3528
+ type: TYPES.array,
3492
3529
  notConstr: true,
3493
3530
  length: 0
3494
3531
  },
@@ -3581,6 +3618,39 @@ const internalConstrs = {
3581
3618
  type: TYPES.number,
3582
3619
  notConstr: true,
3583
3620
  length: 2
3621
+ },
3622
+
3623
+ __console_log: {
3624
+ generate: (scope, decl) => {
3625
+ const out = [];
3626
+
3627
+ for (let i = 0; i < decl.arguments.length; i++) {
3628
+ out.push(
3629
+ ...generateCall(scope, {
3630
+ callee: {
3631
+ type: 'Identifier',
3632
+ name: '__Porffor_print'
3633
+ },
3634
+ arguments: [ decl.arguments[i] ]
3635
+ }),
3636
+
3637
+ // print space
3638
+ ...number(32),
3639
+ [ Opcodes.call, importedFuncs.printChar ]
3640
+ );
3641
+ }
3642
+
3643
+ // print newline
3644
+ out.push(
3645
+ ...number(10),
3646
+ [ Opcodes.call, importedFuncs.printChar ]
3647
+ );
3648
+
3649
+ return out;
3650
+ },
3651
+ type: TYPES.undefined,
3652
+ notConstr: true,
3653
+ length: 0
3584
3654
  }
3585
3655
  };
3586
3656
 
@@ -3615,7 +3685,7 @@ export default program => {
3615
3685
 
3616
3686
  globalThis.valtype = 'f64';
3617
3687
 
3618
- const valtypeOpt = process.argv.find(x => x.startsWith('-valtype='));
3688
+ const valtypeOpt = process.argv.find(x => x.startsWith('--valtype='));
3619
3689
  if (valtypeOpt) valtype = valtypeOpt.split('=')[1];
3620
3690
 
3621
3691
  globalThis.valtypeBinary = Valtype[valtype];
@@ -3623,7 +3693,7 @@ export default program => {
3623
3693
  const valtypeInd = ['i32', 'i64', 'f64'].indexOf(valtype);
3624
3694
 
3625
3695
  globalThis.pageSize = PageSize;
3626
- const pageSizeOpt = process.argv.find(x => x.startsWith('-page-size='));
3696
+ const pageSizeOpt = process.argv.find(x => x.startsWith('--page-size='));
3627
3697
  if (pageSizeOpt) pageSize = parseInt(pageSizeOpt.split('=')[1]) * 1024;
3628
3698
 
3629
3699
  // set generic opcodes for current valtype
@@ -110,7 +110,6 @@ export default (wasm, name = '', ind = 0, locals = {}, params = [], returns = []
110
110
 
111
111
  out += '\n';
112
112
  lastInst = inst;
113
- i++;
114
113
  }
115
114
 
116
115
  return highlightAsm(out);