porffor 0.55.32 → 0.55.33

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.
@@ -43,7 +43,7 @@ const funcRef = func => {
43
43
  if (!doNotMarkFuncRef) func.referenced = true;
44
44
 
45
45
  if (globalThis.precompile) return [
46
- [ Opcodes.const, 'funcref', func.name ]
46
+ [ 'funcref', Opcodes.const, func.name ]
47
47
  ];
48
48
 
49
49
  func.generate?.();
@@ -76,7 +76,7 @@ const funcRef = func => {
76
76
  name: '',
77
77
  jsLength: 0
78
78
  },
79
- indirectIndex: indirectFuncs.length
79
+ indirectIndex: 0
80
80
  };
81
81
 
82
82
  // check not being constructed
@@ -89,8 +89,7 @@ const funcRef = func => {
89
89
  );
90
90
 
91
91
  // have empty func as indirect funcs 0 and 1
92
- indirectFuncs.push(emptyFunc);
93
- indirectFuncs.push(emptyFunc);
92
+ indirectFuncs.push(emptyFunc, emptyFunc);
94
93
  }
95
94
 
96
95
  const wasm = [];
@@ -2470,7 +2469,10 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
2470
2469
  i32_const: { imms: 1, args: [], returns: 0 },
2471
2470
 
2472
2471
  // dst, src, size, _, _
2473
- memory_copy: { imms: 2, args: [ true, true, true ], returns: 0, addValue: true }
2472
+ memory_copy: { imms: 2, args: [ true, true, true ], returns: 0, addValue: true },
2473
+
2474
+ // a, b
2475
+ f64_eq: { imms: 0, args: [ false, false ], returns: 1 }
2474
2476
  };
2475
2477
 
2476
2478
  const opName = name.slice('__Porffor_wasm_'.length);
@@ -2670,16 +2672,10 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
2670
2672
  continue;
2671
2673
  }
2672
2674
 
2673
- if (valtypeBinary !== Valtype.i32 &&
2674
- (func && func.params[paramOffset + i * (typedParams ? 2 : 1)] === Valtype.i32)
2675
- ) {
2676
- out.push(Opcodes.i32_to);
2677
- }
2678
-
2679
- if (valtypeBinary === Valtype.i32 &&
2680
- (func && func.params[paramOffset + i * (typedParams ? 2 : 1)] === Valtype.f64)
2681
- ) {
2682
- out.push([ Opcodes.f64_convert_i32_s ]);
2675
+ const argType = func ? func.params[paramOffset + i * (typedParams ? 2 : 1)] : valtypeBinary;
2676
+ const localType = scope.locals[arg.name]?.type;
2677
+ if ((valtypeBinary !== argType && localType !== argType) || (localType && localType !== argType && valtypeBinary !== Valtype.f64)) {
2678
+ out.push(argType === Valtype.i32 ? Opcodes.i32_trunc_sat_f64_s : [ Opcodes.f64_convert_i32_s ]);
2683
2679
  }
2684
2680
 
2685
2681
  if (typedParams) out = out.concat(arg._callType ?? getNodeType(scope, arg));
@@ -2934,9 +2930,6 @@ const typeSwitch = (scope, type, bc, returns = valtypeBinary, fallthrough = fals
2934
2930
  for (const x of bc) {
2935
2931
  const k = x[0];
2936
2932
  if (k === 'default') continue;
2937
-
2938
- // uncomment if needed/used again
2939
- // x[0] = k.split(',').map(x => +x);
2940
2933
  x[0] = +k;
2941
2934
  }
2942
2935
  }
@@ -3614,7 +3607,6 @@ const coctcSetup = (scope, object, tmp, msg, wasm = generate(scope, object), was
3614
3607
  [ Opcodes.call, includeBuiltin(scope, '__Porffor_object_underlying').index ],
3615
3608
  [ Opcodes.drop ],
3616
3609
 
3617
- Opcodes.i32_to_u,
3618
3610
  [ Opcodes.local_set, tmp ],
3619
3611
 
3620
3612
  ...(known != null ? [] : [
@@ -5008,8 +5000,8 @@ const generateForIn = (scope, decl) => {
5008
5000
  };
5009
5001
 
5010
5002
  const generateSwitch = (scope, decl) => {
5011
- // special fast path just for `switch (Porffor.rawType(...))`
5012
- if (decl.discriminant.type === 'CallExpression' && decl.discriminant.callee.type === 'Identifier' && decl.discriminant.callee.name === '__Porffor_rawType') {
5003
+ // special fast path just for `switch (Porffor.type(...))`
5004
+ if (decl.discriminant.type === 'CallExpression' && decl.discriminant.callee.type === 'Identifier' && decl.discriminant.callee.name === '__Porffor_type') {
5013
5005
  const cases = []
5014
5006
  let canTypeCheck = true;
5015
5007
  for (const x of decl.cases) {
@@ -5403,7 +5395,7 @@ const makeString = (scope, str, forceBytestring = undefined) => {
5403
5395
  }
5404
5396
 
5405
5397
  if (globalThis.precompile) return [
5406
- [ Opcodes.const, 'str', str, forceBytestring ]
5398
+ [ 'str', Opcodes.const, str, forceBytestring ]
5407
5399
  ];
5408
5400
 
5409
5401
  const ptr = allocStr({ scope, pages }, str, bytestring);
@@ -5520,7 +5512,7 @@ const generateObject = (scope, decl, global = false, name = '$undeclared') => {
5520
5512
 
5521
5513
  for (const x of decl.properties) {
5522
5514
  // method, shorthand are made into useful values by parser for us :)
5523
- let { type, argument, computed, kind, key, value } = x;
5515
+ let { type, argument, computed, kind, value } = x;
5524
5516
 
5525
5517
  if (type === 'SpreadElement') {
5526
5518
  out.push(
@@ -5540,14 +5532,14 @@ const generateObject = (scope, decl, global = false, name = '$undeclared') => {
5540
5532
  continue;
5541
5533
  }
5542
5534
 
5543
- const k = getProperty(x, true);
5535
+ const key = getProperty(x, true);
5544
5536
  if (isFuncType(value.type)) {
5545
5537
  let id = value.id;
5546
5538
 
5547
5539
  // todo: support computed names properly
5548
- if (typeof k.value === 'string') id ??= {
5540
+ if (typeof key.value === 'string') id ??= {
5549
5541
  type: 'Identifier',
5550
- name: k.value
5542
+ name: key.value
5551
5543
  };
5552
5544
 
5553
5545
  value = { ...value, id };
@@ -5557,7 +5549,7 @@ const generateObject = (scope, decl, global = false, name = '$undeclared') => {
5557
5549
  [ Opcodes.local_get, tmp ],
5558
5550
  number(TYPES.object, Valtype.i32),
5559
5551
 
5560
- ...toPropertyKey(scope, generate(scope, k), getNodeType(scope, k), computed, true),
5552
+ ...toPropertyKey(scope, generate(scope, key), getNodeType(scope, key), computed, true),
5561
5553
 
5562
5554
  ...generate(scope, value),
5563
5555
  ...(kind !== 'init' ? [ Opcodes.i32_to_u ] : []),
@@ -6113,7 +6105,7 @@ const generateClass = (scope, decl) => {
6113
6105
  scope.overrideThisType = TYPES.function;
6114
6106
 
6115
6107
  for (const x of body) {
6116
- let { type, key, value, kind, static: _static, computed } = x;
6108
+ let { type, value, kind, static: _static, computed } = x;
6117
6109
  if (kind === 'constructor') continue;
6118
6110
 
6119
6111
  if (type === 'StaticBlock') {
@@ -6128,10 +6120,9 @@ const generateClass = (scope, decl) => {
6128
6120
  continue;
6129
6121
  }
6130
6122
 
6123
+ const key = getProperty(x, true);
6131
6124
  let object = _static ? root : proto;
6132
6125
 
6133
- const k = getProperty(x, true);
6134
-
6135
6126
  let initKind = type === 'MethodDefinition' ? 'method' : 'value';
6136
6127
  if (kind === 'get' || kind === 'set') initKind = kind;
6137
6128
 
@@ -6142,9 +6133,9 @@ const generateClass = (scope, decl) => {
6142
6133
  let id = value.id;
6143
6134
 
6144
6135
  // todo: support computed names properly
6145
- if (typeof k.value === 'string') id ??= {
6136
+ if (typeof key.value === 'string') id ??= {
6146
6137
  type: 'Identifier',
6147
- name: k.value
6138
+ name: key.value
6148
6139
  };
6149
6140
 
6150
6141
  value = {
@@ -6168,7 +6159,7 @@ const generateClass = (scope, decl) => {
6168
6159
  computedTmp = allocVar(scope, `#class_computed_prop${uniqId()}`, true, true, false, true);
6169
6160
 
6170
6161
  out.push(
6171
- ...toPropertyKey(scope, generate(scope, k), getNodeType(scope, k), computed, true),
6162
+ ...toPropertyKey(scope, generate(scope, key), getNodeType(scope, key), computed, true),
6172
6163
  [ Opcodes.global_set, computedTmp + 1 ],
6173
6164
  [ Opcodes.global_set, computedTmp ]
6174
6165
  );
@@ -6183,9 +6174,9 @@ const generateClass = (scope, decl) => {
6183
6174
  [ Opcodes.global_get, computedTmp ],
6184
6175
  [ Opcodes.global_get, computedTmp + 1 ],
6185
6176
  ] : [
6186
- ...generate(func, k),
6177
+ ...generate(func, key),
6187
6178
  Opcodes.i32_to_u,
6188
- ...getNodeType(func, k)
6179
+ ...getNodeType(func, key)
6189
6180
  ]),
6190
6181
 
6191
6182
  ...generate(func, value),
@@ -6200,7 +6191,7 @@ const generateClass = (scope, decl) => {
6200
6191
  Opcodes.i32_to_u,
6201
6192
  ...getNodeType(scope, object),
6202
6193
 
6203
- ...toPropertyKey(scope, generate(scope, k), getNodeType(scope, k), computed, true),
6194
+ ...toPropertyKey(scope, generate(scope, key), getNodeType(scope, key), computed, true),
6204
6195
 
6205
6196
  ...generate(scope, value),
6206
6197
  ...(initKind !== 'value' && initKind !== 'method' ? [ Opcodes.i32_to_u ] : []),
@@ -6468,8 +6459,7 @@ const generateFunc = (scope, decl, forceNoExpr = false) => {
6468
6459
  globalThis.funcBodies[name] = body;
6469
6460
  }
6470
6461
 
6471
- // todo: enable for all block statement bodies, not just main
6472
- if (name === '#main') {
6462
+ if (body.type === 'BlockStatement') {
6473
6463
  // hoist function declarations to the top of AST pre-codegen so
6474
6464
  // we can optimize function calls so calls before decl are not indirect
6475
6465
  // (without more post-codegen jank)
@@ -6860,7 +6850,7 @@ const internalConstrs = {
6860
6850
  length: 1
6861
6851
  },
6862
6852
 
6863
- __Porffor_rawType: {
6853
+ __Porffor_type: {
6864
6854
  generate: (scope, decl) => [
6865
6855
  ...getNodeType(scope, decl.arguments[0]),
6866
6856
  Opcodes.i32_from_u
@@ -26,10 +26,11 @@ globalThis.valtypeOverrides = {
26
26
  __Porffor_object_set: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32 ],
27
27
  __Porffor_object_setStrict: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32 ],
28
28
  __Porffor_object_expr_init: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32 ],
29
- __Porffor_object_expr_initWithFlags: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32, Valtype.i32, Valtype.i32 ],
29
+ __Porffor_object_fastAdd: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32, Valtype.i32, Valtype.i32 ],
30
30
  __Porffor_object_class_value: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32 ],
31
31
  __Porffor_object_class_method: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32 ],
32
32
  __Porffor_object_define: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32, Valtype.i32, Valtype.i32 ],
33
+ __Porffor_object_underlying: [ Valtype.f64, Valtype.i32 ]
33
34
  }
34
35
  };
35
36
 
@@ -230,8 +231,8 @@ ${funcs.map(x => {
230
231
  .replace(/\["global",(.*?),"(.*?)",(.*?)\]/g, (_, opcode, name, valtype) => `...glbl(${opcode},'${name}',${valtype})`)
231
232
  .replace(/\"local","(.*?)",(.*?)\]/g, (_, name, valtype) => `loc('${name}',${valtype})]`)
232
233
  .replace(/\[16,"(.*?)"]/g, (_, name) => `[16,builtin('${name}')]`)
233
- .replace(/\[(68|65),"funcref","(.*?)"]/g, (_1, op, name) => op === '65' ? `...i32ify(funcRef('${name}'))` : `...funcRef('${name}')`)
234
- .replace(/\[(68|65),"str","(.*?)",(.*?)]/g, (_1, op, str, forceBytestring) => op === '65' ? `...i32ify(makeString(_,"${str}",${forceBytestring ? 1 : 0}))` : `...makeString(_,"${str}",${forceBytestring ? 1 : 0})`)
234
+ .replace(/\["funcref",(.*?),"(.*?)"]/g, (_1, op, name) => op === '65' ? `...i32ify(funcRef('${name}'))` : `...funcRef('${name}')`)
235
+ .replace(/\["str",(.*?),"(.*?)",(.*?)]/g, (_1, op, str, forceBytestring) => op === '65' ? `...i32ify(makeString(_,"${str}",${forceBytestring ? 1 : 0}))` : `...makeString(_,"${str}",${forceBytestring ? 1 : 0})`)
235
236
  .replace(/\["throw","(.*?)","(.*?)"\]/g, (_, constructor, message) => `...internalThrow(_,'${constructor}',\`${message}\`)`)
236
237
  .replace(/\["get object","(.*?)"\]/g, (_, objName) => `...generateIdent(_,{name:'${objName}'})`)
237
238
  .replace(/\[null,"typeswitch case start",\[(.*?)\]\],/g, (_, types) => `...t([${types}],()=>[`)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "porffor",
3
3
  "description": "An ahead-of-time JavaScript compiler",
4
- "version": "0.55.32",
4
+ "version": "0.55.33",
5
5
  "author": "Oliver Medhurst <honk@goose.icu>",
6
6
  "license": "MIT",
7
7
  "scripts": {},
package/r.cjs CHANGED
@@ -1,12 +1,5 @@
1
- Foo.prototype.baz = function baz() {};
2
-
3
- function Foo() {
4
- this.bar = 1;
5
- }
6
-
7
- Foo.prototype.bar = function bar() {};
8
-
9
-
1
+ // function foo(x) {}
2
+ ({...({})})
10
3
 
11
4
  // var EQUAL = 1;
12
5
  // var NOT_EQUAL = -1;
package/runner/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import fs from 'node:fs';
3
- globalThis.version = '0.55.32';
3
+ globalThis.version = '0.55.33';
4
4
 
5
5
  // deno compat
6
6
  if (typeof process === 'undefined' && typeof Deno !== 'undefined') {
@@ -1,83 +0,0 @@
1
- const underlyingKeys: any[] = [];
2
- const underlyingVals: any[] = [];
3
- export const __Porffor_object_underlying = (obj: any): any => {
4
- const t: i32 = Porffor.rawType(obj);
5
- if (t == Porffor.TYPES.object) return obj;
6
-
7
- if (Porffor.fastAnd(
8
- t >= Porffor.TYPES.error,
9
- t < 0x40
10
- )) {
11
- return obj as object;
12
- }
13
-
14
- if (Porffor.fastAnd(t > 0x05, t != Porffor.TYPES.undefined)) {
15
- let idx: i32 = Porffor.array.fastIndexOf(underlyingKeys, obj);
16
- if (idx == -1) {
17
- const underlying: object = {};
18
-
19
- if (t == Porffor.TYPES.function) {
20
- if (ecma262.IsConstructor(obj)) { // constructor
21
- // set prototype and prototype.constructor if function and constructor
22
- const proto: object = {};
23
- const key1: bytestring = 'prototype';
24
- __Porffor_object_expr_initWithFlags(underlying, key1, proto, 0b1000);
25
-
26
- const key2: bytestring = 'constructor';
27
- __Porffor_object_expr_initWithFlags(proto, key2, obj, 0b1010);
28
- }
29
-
30
- const key3: bytestring = 'name';
31
- __Porffor_object_expr_initWithFlags(underlying, key3, __Porffor_funcLut_name(obj), 0b0010);
32
-
33
- const key4: bytestring = 'length';
34
- __Porffor_object_expr_initWithFlags(underlying, key4, __Porffor_funcLut_length(obj), 0b0010);
35
- }
36
-
37
- if (t == Porffor.TYPES.array) {
38
- const len: i32 = (obj as any[]).length;
39
-
40
- const key5: bytestring = 'length';
41
- __Porffor_object_expr_initWithFlags(underlying, key5, len, 0b1000);
42
-
43
- // todo: this should somehow be kept in sync?
44
- for (let i: i32 = 0; i < len; i++) {
45
- __Porffor_object_expr_initWithFlags(underlying, __Number_prototype_toString(i), (obj as any[])[i], 0b1110);
46
- }
47
- }
48
-
49
- if (Porffor.fastOr(t == Porffor.TYPES.string, t == Porffor.TYPES.stringobject)) {
50
- const len: i32 = (obj as string).length;
51
-
52
- const key6: bytestring = 'length';
53
- __Porffor_object_expr_initWithFlags(underlying, key6, len, 0b0000);
54
-
55
- for (let i: i32 = 0; i < len; i++) {
56
- __Porffor_object_expr_initWithFlags(underlying, __Number_prototype_toString(i), (obj as string)[i], 0b0100);
57
- }
58
-
59
- if (t == Porffor.TYPES.string) Porffor.object.preventExtensions(underlying);
60
- }
61
-
62
- if (t == Porffor.TYPES.bytestring) {
63
- const len: i32 = (obj as bytestring).length;
64
-
65
- const key7: bytestring = 'length';
66
- __Porffor_object_expr_initWithFlags(underlying, key7, len, 0b0000);
67
-
68
- for (let i: i32 = 0; i < len; i++) {
69
- __Porffor_object_expr_initWithFlags(underlying, __Number_prototype_toString(i), (obj as bytestring)[i], 0b0100);
70
- }
71
-
72
- Porffor.object.preventExtensions(underlying);
73
- }
74
-
75
- Porffor.array.fastPush(underlyingVals, underlying);
76
- idx = Porffor.array.fastPush(underlyingKeys, obj) - 1;
77
- }
78
-
79
- return underlyingVals[idx];
80
- }
81
-
82
- return obj;
83
- };