porffor 0.2.0-eeb45f8 → 0.2.0-fbab1de

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/README.md CHANGED
@@ -121,7 +121,7 @@ No particular order and no guarentees, just what could happen soon™
121
121
  - *Basic* Wasm engine (interpreter) in JS
122
122
  - More math operators (`**`, etc)
123
123
  - `do { ... } while (...)`
124
- - Rewrite `console.log` to work with strings/arrays
124
+ - Typed export inputs (array)
125
125
  - Exceptions
126
126
  - Rewrite to use actual strings (optional?)
127
127
  - `try { } finally { }`
@@ -130,7 +130,7 @@ No particular order and no guarentees, just what could happen soon™
130
130
  - Rewrite local indexes per func for smallest local header and remove unused idxs
131
131
  - Smarter inline selection (snapshots?)
132
132
  - Remove const ifs (`if (true)`, etc)
133
- - Experiment with byte strings?
133
+ - Memory alignment
134
134
  - Runtime
135
135
  - WASI target
136
136
  - Run precompiled Wasm file if given
@@ -147,7 +147,7 @@ No particular order and no guarentees, just what could happen soon™
147
147
  - Self hosted testing?
148
148
 
149
149
  ## Performance
150
- *For the things it supports most of the time*, Porffor is blazingly fast compared to most interpreters, and common engines running without JIT. For those with JIT, it is not that much slower like a traditional interpreter would be; mostly the same or a bit faster/slower depending on what.
150
+ *For the things it supports most of the time*, Porffor is *blazingly fast* compared to most interpreters, and common engines running without JIT. For those with JIT, it is usually slower by default, but can catch up with compiler arguments and typed input.
151
151
 
152
152
  ![Screenshot of comparison chart](https://github.com/CanadaHonk/porffor/assets/19228318/76c75264-cc68-4be1-8891-c06dc389d97a)
153
153
 
@@ -1175,7 +1175,7 @@ const getNodeType = (scope, node) => {
1175
1175
  const spl = name.slice(2).split('_');
1176
1176
 
1177
1177
  const func = spl[spl.length - 1];
1178
- const protoFuncs = Object.values(prototypeFuncs).filter(x => x[func] != null);
1178
+ const protoFuncs = Object.keys(prototypeFuncs).filter(x => x != TYPES._bytestring && prototypeFuncs[x][func] != null);
1179
1179
  if (protoFuncs.length === 1) return protoFuncs[0].returnType ?? TYPES.number;
1180
1180
  }
1181
1181
 
@@ -1260,6 +1260,10 @@ const getNodeType = (scope, node) => {
1260
1260
  // hack: if something.length, number type
1261
1261
  if (node.property.name === 'length') return TYPES.number;
1262
1262
 
1263
+ // ts hack
1264
+ if (scope.locals[node.object.name]?.metadata?.type === TYPES.string) return TYPES.string;
1265
+ if (scope.locals[node.object.name]?.metadata?.type === TYPES._array) return TYPES.number;
1266
+
1263
1267
  if (scope.locals['#last_type']) return [ getLastType(scope) ];
1264
1268
 
1265
1269
  // presume
@@ -1279,23 +1283,6 @@ const getNodeType = (scope, node) => {
1279
1283
  return ret;
1280
1284
  };
1281
1285
 
1282
- const toString = (scope, wasm, type) => {
1283
- const tmp = localTmp(scope, '#tostring_tmp');
1284
- return [
1285
- ...wasm,
1286
- [ Opcodes.local_set, tmp ],
1287
-
1288
- ...typeSwitch(scope, type, {
1289
- [TYPES.string]: [
1290
- [ Opcodes.local_get, tmp ]
1291
- ],
1292
- [TYPES.undefined]: [
1293
- // [ Opcodes.]
1294
- ]
1295
- })
1296
- ]
1297
- };
1298
-
1299
1286
  const generateLiteral = (scope, decl, global, name) => {
1300
1287
  if (decl.value === null) return number(NULL);
1301
1288
 
@@ -1486,8 +1473,8 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
1486
1473
  // literal.func()
1487
1474
  if (!name && decl.callee.type === 'MemberExpression') {
1488
1475
  // megahack for /regex/.func()
1489
- if (decl.callee.object.regex) {
1490
- const funcName = decl.callee.property.name;
1476
+ const funcName = decl.callee.property.name;
1477
+ if (decl.callee.object.regex && Object.hasOwn(Rhemyn, funcName)) {
1491
1478
  const func = Rhemyn[funcName](decl.callee.object.regex.pattern, currentFuncIndex++);
1492
1479
 
1493
1480
  funcIndex[func.name] = func.index;
@@ -1529,8 +1516,7 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
1529
1516
 
1530
1517
  if (protoName) {
1531
1518
  const protoCands = Object.keys(prototypeFuncs).reduce((acc, x) => {
1532
- const f = prototypeFuncs[x][protoName];
1533
- if (f) acc[x] = f;
1519
+ if (Object.hasOwn(prototypeFuncs[x], protoName)) acc[x] = prototypeFuncs[x][protoName];
1534
1520
  return acc;
1535
1521
  }, {});
1536
1522
 
@@ -1928,6 +1914,8 @@ const extractTypeAnnotation = decl => {
1928
1914
  const typeName = type;
1929
1915
  type = typeAnnoToPorfType(type);
1930
1916
 
1917
+ if (type === TYPES._bytestring && !process.argv.includes('-bytestring')) type = TYPES.string;
1918
+
1931
1919
  // if (decl.name) console.log(decl.name, { type, elementType });
1932
1920
 
1933
1921
  return { type, typeName, elementType };
@@ -2327,8 +2315,10 @@ const generateFor = (scope, decl) => {
2327
2315
  out.push([ Opcodes.loop, Blocktype.void ]);
2328
2316
  depth.push('for');
2329
2317
 
2330
- out.push(...generate(scope, decl.test));
2331
- out.push(Opcodes.i32_to, [ Opcodes.if, Blocktype.void ]);
2318
+ if (decl.test) out.push(...generate(scope, decl.test), Opcodes.i32_to);
2319
+ else out.push(...number(1, Valtype.i32));
2320
+
2321
+ out.push([ Opcodes.if, Blocktype.void ]);
2332
2322
  depth.push('if');
2333
2323
 
2334
2324
  out.push([ Opcodes.block, Blocktype.void ]);
@@ -2336,8 +2326,7 @@ const generateFor = (scope, decl) => {
2336
2326
  out.push(...generate(scope, decl.body));
2337
2327
  out.push([ Opcodes.end ]);
2338
2328
 
2339
- out.push(...generate(scope, decl.update));
2340
- depth.pop();
2329
+ if (decl.update) out.push(...generate(scope, decl.update));
2341
2330
 
2342
2331
  out.push([ Opcodes.br, 1 ]);
2343
2332
  out.push([ Opcodes.end ], [ Opcodes.end ]);
@@ -2535,7 +2524,7 @@ const generateThrow = (scope, decl) => {
2535
2524
  // hack: throw new X("...") -> throw "..."
2536
2525
  if (!message && (decl.argument.type === 'NewExpression' || decl.argument.type === 'CallExpression')) {
2537
2526
  constructor = decl.argument.callee.name;
2538
- message = decl.argument.arguments[0].value;
2527
+ message = decl.argument.arguments[0]?.value ?? '';
2539
2528
  }
2540
2529
 
2541
2530
  if (tags.length === 0) tags.push({
@@ -2887,11 +2876,14 @@ const objectHack = node => {
2887
2876
  // if object is not identifier or another member exp, give up
2888
2877
  if (node.object.type !== 'Identifier' && node.object.type !== 'MemberExpression') return node;
2889
2878
 
2890
- if (!objectName) objectName = objectHack(node.object).name.slice(2);
2879
+ if (!objectName) objectName = objectHack(node.object)?.name?.slice?.(2);
2891
2880
 
2892
2881
  // if .length, give up (hack within a hack!)
2893
2882
  if (node.property.name === 'length') return node;
2894
2883
 
2884
+ // no object name, give up
2885
+ if (!objectName) return node;
2886
+
2895
2887
  const name = '__' + objectName + '_' + node.property.name;
2896
2888
  if (codeLog) log('codegen', `object hack! ${node.object.name}.${node.property.name} -> ${name}`);
2897
2889
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "porffor",
3
3
  "description": "a basic experimental wip aot optimizing js -> wasm engine/compiler/runtime in js",
4
- "version": "0.2.0-eeb45f8",
4
+ "version": "0.2.0-fbab1de",
5
5
  "author": "CanadaHonk",
6
6
  "license": "MIT",
7
7
  "dependencies": {
package/r.js ADDED
@@ -0,0 +1,9 @@
1
+ var count = 0;
2
+ for (let x = 0; x < 10;) {
3
+ x++;
4
+ count++;
5
+ {
6
+ let x = "hello";
7
+ continue;
8
+ }
9
+ }