porffor 0.2.0-ef043de → 0.2.0-f435128

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.
@@ -1,4 +1,4 @@
1
- // @porf -funsafe-no-unlikely-proto-checks -valtype=i32
1
+ // @porf --funsafe-no-unlikely-proto-checks --valtype=i32
2
2
 
3
3
  export const __String_fromCharCode = (code: i32) => {
4
4
  // todo: support >1 arg
@@ -1,4 +1,4 @@
1
- // // @porf -funsafe-no-unlikely-proto-checks -valtype=i32
1
+ // // @porf --funsafe-no-unlikely-proto-checks --valtype=i32
2
2
 
3
3
  export const __Boolean_prototype_toString = (_this: boolean) => {
4
4
  let out: bytestring = '';
@@ -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 => {
@@ -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 [
@@ -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),
@@ -1820,20 +1827,20 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
1820
1827
  idx = funcIndex[name];
1821
1828
 
1822
1829
  // infer arguments types from builtins params
1823
- const func = funcs.find(x => x.name === name);
1824
- for (let i = 0; i < decl.arguments.length; i++) {
1825
- const arg = decl.arguments[i];
1826
- if (!arg.name) continue;
1827
-
1828
- const local = scope.locals[arg.name];
1829
- if (!local) continue;
1830
-
1831
- local.type = func.params[i];
1832
- if (local.type === Valtype.v128) {
1833
- // specify vec subtype inferred from last vec type in function name
1834
- local.vecType = name.split('_').reverse().find(x => x.includes('x'));
1835
- }
1836
- }
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
+ // }
1837
1844
  }
1838
1845
 
1839
1846
  if (idx === undefined && internalConstrs[name]) return internalConstrs[name].generate(scope, decl, _global, _name);
@@ -2205,6 +2212,7 @@ const generateVar = (scope, decl) => {
2205
2212
 
2206
2213
  // global variable if in top scope (main) and var ..., or if wanted
2207
2214
  const global = topLevel || decl._bare; // decl.kind === 'var';
2215
+ const target = global ? globals : scope.locals;
2208
2216
 
2209
2217
  for (const x of decl.declarations) {
2210
2218
  const name = mapName(x.id.name);
@@ -2226,6 +2234,10 @@ const generateVar = (scope, decl) => {
2226
2234
  continue; // always ignore
2227
2235
  }
2228
2236
 
2237
+ // // generate init before allocating var
2238
+ // let generated;
2239
+ // if (x.init) generated = generate(scope, x.init, global, name);
2240
+
2229
2241
  const typed = typedInput && x.id.typeAnnotation;
2230
2242
  let idx = allocVar(scope, name, global, !(typed && extractTypeAnnotation(x.id).type != null));
2231
2243
 
@@ -2234,9 +2246,17 @@ const generateVar = (scope, decl) => {
2234
2246
  }
2235
2247
 
2236
2248
  if (x.init) {
2237
- out = out.concat(generate(scope, x.init, global, name));
2238
-
2239
- out.push([ global ? Opcodes.global_set : Opcodes.local_set, idx ]);
2249
+ const generated = generate(scope, x.init, global, name);
2250
+ if (scope.arrays?.get(name) != null) {
2251
+ // hack to set local as pointer before
2252
+ out.push(...number(scope.arrays.get(name)), [ global ? Opcodes.global_set : Opcodes.local_set, idx ]);
2253
+ if (generated.at(-1) == Opcodes.i32_from_u) generated.pop();
2254
+ generated.pop();
2255
+ out = out.concat(generated);
2256
+ } else {
2257
+ out = out.concat(generated);
2258
+ out.push([ global ? Opcodes.global_set : Opcodes.local_set, idx ]);
2259
+ }
2240
2260
  out.push(...setType(scope, name, getNodeType(scope, x.init)));
2241
2261
  }
2242
2262
 
@@ -2263,6 +2283,8 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
2263
2283
  return [];
2264
2284
  }
2265
2285
 
2286
+ const op = decl.operator.slice(0, -1) || '=';
2287
+
2266
2288
  // hack: .length setter
2267
2289
  if (decl.left.type === 'MemberExpression' && decl.left.property.name === 'length') {
2268
2290
  const name = decl.left.object.name;
@@ -2271,14 +2293,20 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
2271
2293
  const aotPointer = Prefs.aotPointerOpt && pointer != null;
2272
2294
 
2273
2295
  const newValueTmp = localTmp(scope, '__length_setter_tmp');
2296
+ const pointerTmp = op === '=' ? null : localTmp(scope, '__member_setter_ptr_tmp', Valtype.i32);
2274
2297
 
2275
2298
  return [
2276
2299
  ...(aotPointer ? number(0, Valtype.i32) : [
2277
2300
  ...generate(scope, decl.left.object),
2278
2301
  Opcodes.i32_to_u
2279
2302
  ]),
2303
+ ...(!pointerTmp ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
2280
2304
 
2281
- ...generate(scope, decl.right),
2305
+ ...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
2306
+ [ Opcodes.local_get, pointerTmp ],
2307
+ [ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
2308
+ Opcodes.i32_from_u
2309
+ ], generate(scope, decl.right), number(TYPES.number, Valtype.i32), getNodeType(scope, decl.right))),
2282
2310
  [ Opcodes.local_tee, newValueTmp ],
2283
2311
 
2284
2312
  Opcodes.i32_to_u,
@@ -2288,8 +2316,6 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
2288
2316
  ];
2289
2317
  }
2290
2318
 
2291
- const op = decl.operator.slice(0, -1) || '=';
2292
-
2293
2319
  // arr[i]
2294
2320
  if (decl.left.type === 'MemberExpression' && decl.left.computed) {
2295
2321
  const name = decl.left.object.name;
@@ -3093,12 +3119,14 @@ const makeArray = (scope, decl, global = false, name = '$undeclared', initEmpty
3093
3119
  // todo: can we just have 1 undeclared array? probably not? but this is not really memory efficient
3094
3120
  const uniqueName = name === '$undeclared' ? name + Math.random().toString().slice(2) : name;
3095
3121
 
3096
- if (Prefs.scopedPageNames) scope.arrays.set(name, allocPage(scope, `${scope.name} | ${getAllocType(itemType)}: ${uniqueName}`, itemType) * pageSize);
3122
+ if (Prefs.scopedPageNames) scope.arrays.set(name, allocPage(scope, `${getAllocType(itemType)}: ${scope.name}/${uniqueName}`, itemType) * pageSize);
3097
3123
  else scope.arrays.set(name, allocPage(scope, `${getAllocType(itemType)}: ${uniqueName}`, itemType) * pageSize);
3098
3124
  }
3099
3125
 
3100
3126
  const pointer = scope.arrays.get(name);
3101
3127
 
3128
+ const local = global ? globals[name] : scope.locals[name];
3129
+
3102
3130
  const useRawElements = !!decl.rawElements;
3103
3131
  const elements = useRawElements ? decl.rawElements : decl.elements;
3104
3132
 
@@ -3131,11 +3159,22 @@ const makeArray = (scope, decl, global = false, name = '$undeclared', initEmpty
3131
3159
  return [ out, pointer ];
3132
3160
  }
3133
3161
 
3162
+ const pointerTmp = local != null ? localTmp(scope, '#makearray_pointer_tmp', Valtype.i32) : null;
3163
+ if (pointerTmp != null) {
3164
+ out.push(
3165
+ [ global ? Opcodes.global_get : Opcodes.local_get, local.idx ],
3166
+ Opcodes.i32_to_u,
3167
+ [ Opcodes.local_set, pointerTmp ]
3168
+ );
3169
+ }
3170
+
3171
+ const pointerWasm = pointerTmp != null ? [ [ Opcodes.local_get, pointerTmp ] ] : number(pointer, Valtype.i32);
3172
+
3134
3173
  // store length as 0th array
3135
3174
  out.push(
3136
- ...number(0, Valtype.i32),
3175
+ ...pointerWasm,
3137
3176
  ...number(length, Valtype.i32),
3138
- [ Opcodes.i32_store, Math.log2(ValtypeSize.i32) - 1, ...unsignedLEB128(pointer) ]
3177
+ [ Opcodes.i32_store, Math.log2(ValtypeSize.i32) - 1, 0 ]
3139
3178
  );
3140
3179
 
3141
3180
  const storeOp = StoreOps[itemType];
@@ -3144,14 +3183,14 @@ const makeArray = (scope, decl, global = false, name = '$undeclared', initEmpty
3144
3183
  if (elements[i] == null) continue;
3145
3184
 
3146
3185
  out.push(
3147
- ...number(0, Valtype.i32),
3186
+ ...pointerWasm,
3148
3187
  ...(useRawElements ? number(elements[i], Valtype[valtype]) : generate(scope, elements[i])),
3149
- [ storeOp, (Math.log2(ValtypeSize[itemType]) || 1) - 1, ...unsignedLEB128(pointer + ValtypeSize.i32 + i * ValtypeSize[itemType]) ]
3188
+ [ storeOp, (Math.log2(ValtypeSize[itemType]) || 1) - 1, ...unsignedLEB128(ValtypeSize.i32 + i * ValtypeSize[itemType]) ]
3150
3189
  );
3151
3190
  }
3152
3191
 
3153
3192
  // local value as pointer
3154
- out.push(...number(pointer));
3193
+ out.push(...pointerWasm, Opcodes.i32_from_u);
3155
3194
 
3156
3195
  return [ out, pointer ];
3157
3196
  };
@@ -3649,7 +3688,7 @@ export default program => {
3649
3688
 
3650
3689
  globalThis.valtype = 'f64';
3651
3690
 
3652
- const valtypeOpt = process.argv.find(x => x.startsWith('-valtype='));
3691
+ const valtypeOpt = process.argv.find(x => x.startsWith('--valtype='));
3653
3692
  if (valtypeOpt) valtype = valtypeOpt.split('=')[1];
3654
3693
 
3655
3694
  globalThis.valtypeBinary = Valtype[valtype];
@@ -3657,7 +3696,7 @@ export default program => {
3657
3696
  const valtypeInd = ['i32', 'i64', 'f64'].indexOf(valtype);
3658
3697
 
3659
3698
  globalThis.pageSize = PageSize;
3660
- const pageSizeOpt = process.argv.find(x => x.startsWith('-page-size='));
3699
+ const pageSizeOpt = process.argv.find(x => x.startsWith('--page-size='));
3661
3700
  if (pageSizeOpt) pageSize = parseInt(pageSizeOpt.split('=')[1]) * 1024;
3662
3701
 
3663
3702
  // 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);