porffor 0.34.8 → 0.34.10

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,5 +1,5 @@
1
1
  import { Valtype, FuncType, ExportDesc, Section, Magic, ModuleVersion, Opcodes, PageSize, Reftype } from './wasmSpec.js';
2
- import { encodeVector, encodeString, encodeLocal, unsignedLEB128, signedLEB128, unsignedLEB128_into, signedLEB128_into, ieee754_binary64_into } from './encoding.js';
2
+ import { encodeVector, encodeString, encodeLocal, unsignedLEB128, signedLEB128, unsignedLEB128_into, signedLEB128_into, ieee754_binary64, ieee754_binary64_into } from './encoding.js';
3
3
  import { importedFuncs } from './builtins.js';
4
4
  import { log } from './log.js';
5
5
  import {} from './prefs.js';
@@ -72,6 +72,14 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
72
72
  return typeCache[hash] = idx;
73
73
  };
74
74
 
75
+ let t = performance.now();
76
+ const time = msg => {
77
+ if (!Prefs.profileAssemble) return;
78
+
79
+ console.log(`${' '.repeat(50)}\r[${(performance.now() - t).toFixed(2)}ms] ${msg}`);
80
+ t = performance.now();
81
+ };
82
+
75
83
  let importFuncs = [], importDelta = 0;
76
84
  if (optLevel < 1 || !Prefs.treeshakeWasmImports || noTreeshake) {
77
85
  importFuncs = importedFuncs;
@@ -81,7 +89,7 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
81
89
  // tree shake imports
82
90
  for (const f of funcs) {
83
91
  for (const inst of f.wasm) {
84
- if ((inst[0] === Opcodes.call || inst[0] === Opcodes.return_call) && inst[1] < importedFuncs.length) {
92
+ if ((inst[0] === Opcodes.call /* || inst[0] === Opcodes.return_call */) && inst[1] < importedFuncs.length) {
85
93
  const idx = inst[1];
86
94
  const func = importedFuncs[idx];
87
95
 
@@ -95,24 +103,25 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
95
103
  importDelta = importedFuncs.length - importFuncs.length;
96
104
  }
97
105
 
98
- // fix call indexes for non-imports
99
- // also fix call_indirect types
100
- // also encode call indexes
101
106
  for (const f of funcs) {
102
107
  f.asmIndex = f.index - importDelta;
103
108
  }
104
109
 
110
+ time('treeshake import funcs');
111
+
105
112
  if (Prefs.optLog) log('assemble', `treeshake: using ${importFuncs.length}/${importedFuncs.length} imports`);
106
113
 
107
114
  const importSection = importFuncs.length === 0 ? [] : createSection(
108
115
  Section.import,
109
116
  encodeVector(importFuncs.map(x => [ 0, ...encodeString(x.import), ExportDesc.func, getType(typeof x.params === 'object' ? x.params : new Array(x.params).fill(valtypeBinary), new Array(x.returns).fill(valtypeBinary)) ]))
110
117
  );
118
+ time('import section');
111
119
 
112
120
  const funcSection = createSection(
113
121
  Section.func,
114
122
  encodeVector(funcs.map(x => getType(x.params, x.returns))) // type indexes
115
123
  );
124
+ time('func section');
116
125
 
117
126
  const nameSection = Prefs.d ? customSection('name', encodeNames(funcs)) : [];
118
127
 
@@ -120,6 +129,7 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
120
129
  Section.table,
121
130
  encodeVector([ [ Reftype.funcref, 0x00, ...unsignedLEB128(funcs.length) ] ])
122
131
  );
132
+ time('table section');
123
133
 
124
134
  const elementSection = !funcs.table ? [] : createSection(
125
135
  Section.element,
@@ -129,6 +139,7 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
129
139
  ...encodeVector(funcs.map(x => unsignedLEB128(x.asmIndex)))
130
140
  ] ])
131
141
  );
142
+ time('element section');
132
143
 
133
144
  if (pages.has('func lut')) {
134
145
  const offset = pages.get('func lut').ind * pageSize;
@@ -181,8 +192,7 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
181
192
  });
182
193
  data.addedFuncArgcLut = true;
183
194
  }
184
-
185
- // const t0 = performance.now();
195
+ time('func lut');
186
196
 
187
197
  // specially optimized assembly for globals as this version is much (>5x) faster than traditional createSection()
188
198
  const globalsValues = Object.values(globals);
@@ -224,17 +234,7 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
224
234
  unsignedLEB128_into(data.length, globalSection);
225
235
  globalSection = globalSection.concat(data);
226
236
  }
227
-
228
- // if (Prefs.profileCompiler) {
229
- // const log = console.log;
230
- // console.log = function () {
231
- // log.apply(this, arguments);
232
- // console.log = log;
233
- // console.log(` a. assembled global section in ${(performance.now() - t0).toFixed(2)}ms\n`);
234
- // };
235
- // }
236
-
237
- const exports = funcs.filter(x => x.export).map((x, i) => [ ...encodeString(x.name === 'main' ? 'm' : x.name), ExportDesc.func, ...unsignedLEB128(x.asmIndex) ]);
237
+ time('global section');
238
238
 
239
239
  if (Prefs.alwaysMemory && pages.size === 0) pages.set('--always-memory', 0);
240
240
  if (optLevel === 0) pages.set('O0 precaution', 0);
@@ -244,9 +244,13 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
244
244
  Section.memory,
245
245
  encodeVector([ [ 0x00, ...unsignedLEB128(Math.ceil((pages.size * pageSize) / PageSize)) ] ])
246
246
  );
247
+ time('memory section');
248
+
249
+ const exports = funcs.filter(x => x.export).map((x, i) => [ ...encodeString(x.name === 'main' ? 'm' : x.name), ExportDesc.func, ...unsignedLEB128(x.asmIndex) ]);
247
250
 
248
251
  // export memory if used
249
252
  if (usesMemory) exports.unshift([ ...encodeString('$'), ExportDesc.mem, 0x00 ]);
253
+ time('gen exports');
250
254
 
251
255
  const tagSection = tags.length === 0 ? [] : createSection(
252
256
  Section.tag,
@@ -255,16 +259,20 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
255
259
 
256
260
  // export first tag if used
257
261
  if (tags.length !== 0) exports.unshift([ ...encodeString('0'), ExportDesc.tag, 0x00 ]);
262
+ time('tag section');
258
263
 
259
264
  const exportSection = createSection(
260
265
  Section.export,
261
266
  encodeVector(exports)
262
267
  );
268
+ time('export section');
263
269
 
264
270
  const codeSection = createSection(
265
271
  Section.code,
266
272
  encodeVector(funcs.map(x => {
267
- const locals = Object.values(x.locals).sort((a, b) => a.idx - b.idx).slice(x.params.length).sort((a, b) => a.idx - b.idx);
273
+ // time(x.name);
274
+ const locals = Object.values(x.locals).sort((a, b) => a.idx - b.idx).slice(x.params.length);
275
+ // time(' locals gen');
268
276
 
269
277
  let localDecl = [], typeCount = 0, lastType;
270
278
  for (let i = 0; i < locals.length; i++) {
@@ -279,6 +287,7 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
279
287
  }
280
288
 
281
289
  if (typeCount !== 0) localDecl.push(encodeLocal(typeCount, lastType));
290
+ // time(' localDecl gen');
282
291
 
283
292
  const makeAssembled = Prefs.d;
284
293
  let wasm = [], wasmNonFlat = [];
@@ -287,7 +296,8 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
287
296
 
288
297
  // encode local/global ops as unsigned leb128 from raw number
289
298
  if (
290
- (o[0] === Opcodes.local_get || o[0] === Opcodes.local_set || o[0] === Opcodes.local_tee || o[0] === Opcodes.global_get || o[0] === Opcodes.global_set) &&
299
+ // (o[0] === Opcodes.local_get || o[0] === Opcodes.local_set || o[0] === Opcodes.local_tee || o[0] === Opcodes.global_get || o[0] === Opcodes.global_set) &&
300
+ (o[0] >= Opcodes.local_get && o[0] <= Opcodes.global_set) &&
291
301
  o[1] > 127
292
302
  ) {
293
303
  const n = o[1];
@@ -298,14 +308,17 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
298
308
  // encode f64.const ops as ieee754 from raw number
299
309
  if (o[0] === Opcodes.f64_const) {
300
310
  const n = o[1];
301
- o = [ o[0] ];
302
- ieee754_binary64_into(n, o);
311
+ // o = [ o[0] ];
312
+ // ieee754_binary64_into(n, o);
313
+ o = ieee754_binary64(n);
314
+ if (o.length === 8) o.unshift(Opcodes.f64_const);
303
315
  }
304
316
 
305
317
  // encode call ops as unsigned leb128 from raw number
306
- if ((o[0] === Opcodes.call || o[0] === Opcodes.return_call) && o[1] >= importedFuncs.length) {
318
+ if ((o[0] === Opcodes.call /* || o[0] === Opcodes.return_call */) && o[1] >= importedFuncs.length) {
307
319
  const n = o[1] - importDelta;
308
- o = [ o[0] ];
320
+ // o = [ o[0] ];
321
+ o = [ Opcodes.call ];
309
322
  unsignedLEB128_into(n, o);
310
323
  }
311
324
 
@@ -334,27 +347,35 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
334
347
 
335
348
  if (makeAssembled) wasmNonFlat.push(o);
336
349
  }
350
+ // time(' wasm transform');
337
351
 
338
352
  if (makeAssembled) {
339
353
  x.assembled = { localDecl, wasm, wasmNonFlat };
340
354
  }
341
355
 
342
- return encodeVector([ ...encodeVector(localDecl), ...wasm, Opcodes.end ]);
356
+ let out = unsignedLEB128(localDecl.length)
357
+ .concat(localDecl.flat(), wasm, Opcodes.end);
358
+
359
+ out.unshift(...unsignedLEB128(out.length));
360
+
361
+ // time(' finish');
362
+ return out;
343
363
  }))
344
364
  );
365
+ time('code section');
345
366
 
346
367
  const typeSection = createSection(
347
368
  Section.type,
348
369
  encodeVector(types)
349
370
  );
371
+ time('type section');
350
372
 
351
373
  const dataSection = data.length === 0 ? [] : createSection(
352
374
  Section.data,
353
375
  encodeVector(data.map(x => {
354
376
  if (Prefs.d && x.bytes.length > PageSize) log.warning('assemble', `data (${x.page}) has more bytes than Wasm page size! (${x.bytes.length})`);
355
377
 
356
- const bytes = encodeVector(x.bytes);
357
-
378
+ const bytes = unsignedLEB128(x.bytes.length).concat(x.bytes);
358
379
  if (x.page != null) {
359
380
  // type: active
360
381
  let offset = pages.get(x.page).ind * pageSize;
@@ -368,11 +389,13 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
368
389
  return bytes;
369
390
  }))
370
391
  );
392
+ time('data section');
371
393
 
372
394
  const dataCountSection = data.length === 0 ? [] : createSection(
373
395
  Section.data_count,
374
396
  unsignedLEB128(data.length)
375
397
  );
398
+ time('datacount section');
376
399
 
377
400
  if (Prefs.sections) console.log({
378
401
  typeSection: typeSection.map(x => x.toString(16)),
@@ -5,8 +5,13 @@ export const __Porffor_object_getObject = (obj: any): any => {
5
5
  let underlying: object = underlyingFuncObjs.get(funcI32);
6
6
  if (underlying == null) {
7
7
  underlying = {};
8
- underlying.prototype = {};
9
- underlying.prototype.constructor = obj;
8
+
9
+ const proto = {};
10
+ const key1: bytestring = 'prototype';
11
+ __Porffor_object_expr_initWithFlags(underlying, key1, proto, 0b1000);
12
+
13
+ const key2: bytestring = 'constructor';
14
+ __Porffor_object_expr_initWithFlags(proto, key2, obj, 0b1010);
10
15
 
11
16
  underlyingFuncObjs.set(funcI32, underlying);
12
17
  }
@@ -572,6 +572,30 @@ export const __Porffor_object_expr_init = (obj: any, key: any, value: any): void
572
572
  0, 12);
573
573
  };
574
574
 
575
+ export const __Porffor_object_expr_initWithFlags = (obj: any, key: any, value: any, flags: i32): void => {
576
+ if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) obj = __Porffor_object_getObject(obj);
577
+ let entryPtr: i32 = __Porffor_object_lookup(obj, key);
578
+ if (entryPtr == -1) {
579
+ // add new entry
580
+ // bump size +1
581
+ const size: i32 = Porffor.wasm.i32.load(obj, 0, 0);
582
+ Porffor.wasm.i32.store(obj, size + 1, 0, 0);
583
+
584
+ // entryPtr = current end of object
585
+ entryPtr = Porffor.wasm`local.get ${obj}` + 5 + size * 14;
586
+
587
+ __Porffor_object_writeKey(entryPtr, key);
588
+ }
589
+
590
+ // write new value value (lol)
591
+ Porffor.wasm.f64.store(entryPtr, value, 0, 4);
592
+
593
+ // write new tail (value type + flags)
594
+ Porffor.wasm.i32.store16(entryPtr,
595
+ flags + (Porffor.wasm`local.get ${value+1}` << 8),
596
+ 0, 12);
597
+ };
598
+
575
599
  // used for { get foo() {} }
576
600
  export const __Porffor_object_expr_get = (obj: any, key: any, get: any): void => {
577
601
  if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) obj = __Porffor_object_getObject(obj);
@@ -1746,9 +1746,7 @@ export const __ecma262_ToDateString = (tv: number) => {
1746
1746
  out.length = 0;
1747
1747
 
1748
1748
  // 1. If tv is NaN, return "Invalid Date".
1749
- if (Number.isNaN(tv)) {
1750
- return out = 'Invalid Date';
1751
- }
1749
+ if (Number.isNaN(tv)) return out = 'Invalid Date';
1752
1750
 
1753
1751
  // 2. Let t be LocalTime(tv).
1754
1752
  const t: number = __ecma262_LocalTime(tv);
@@ -1788,10 +1786,7 @@ export const __Date_prototype_toTimeString = (_this: Date) => {
1788
1786
  let out: bytestring = Porffor.allocateBytes(27);
1789
1787
  out.length = 0;
1790
1788
 
1791
- if (Number.isNaN(tv)) {
1792
- out = 'Invalid Date';
1793
- return out;
1794
- }
1789
+ if (Number.isNaN(tv)) return out = 'Invalid Date';
1795
1790
 
1796
1791
  // 5. Let t be LocalTime(tv).
1797
1792
  const t: number = __ecma262_LocalTime(tv);
@@ -1816,10 +1811,7 @@ export const __Date_prototype_toDateString = (_this: Date) => {
1816
1811
  let out: bytestring = Porffor.allocateBytes(20);
1817
1812
  out.length = 0;
1818
1813
 
1819
- if (Number.isNaN(tv)) {
1820
- out = 'Invalid Date';
1821
- return out;
1822
- }
1814
+ if (Number.isNaN(tv)) return out = 'Invalid Date';
1823
1815
 
1824
1816
  // 5. Let t be LocalTime(tv).
1825
1817
  const t: number = __ecma262_LocalTime(tv);
@@ -3,10 +3,10 @@ import { number } from './embedding.js';
3
3
 
4
4
  export const BuiltinFuncs = function() {
5
5
  this.__Porffor_object_getObject = {
6
- wasm:(_,{glbl,builtin,internalThrow})=>[[32,1],[184],[68,6],[97],[4,64],[32,0],[33,2],...glbl(35,'underlyingFuncObjs',124),[33,4],[65,20],[33,5],[32,4],[32,5],[32,2],[65,1],[16,builtin('__Map_prototype_get')],[26],[34,3],[68,0],[97],[4,64],[16,builtin('__Porffor_allocate')],[184],[34,3],[33,9],[16,builtin('__Porffor_allocate')],[34,11],[65,9],[54,1,0],[32,11],[65,240,0],[58,0,4],[32,11],[65,242,0],[58,0,5],[32,11],[65,239,0],[58,0,6],[32,11],[65,244,0],[58,0,7],[32,11],[65,239,0],[58,0,8],[32,11],[65,244,0],[58,0,9],[32,11],[65,249,0],[58,0,10],[32,11],[65,240,0],[58,0,11],[32,11],[65,229,0],[58,0,12],[32,11],[184],[33,10],[32,9],[252,3],[65,7],[32,10],[65,195,1],[16,builtin('__ecma262_ToPropertyKey')],[33,12],[252,3],[32,12],[16,builtin('__Porffor_allocate')],[184],[65,7],[16,builtin('__Porffor_object_set')],[26],[26],[32,3],[33,9],[65,128,128,4],[34,11],[65,9],[54,1,0],[32,11],[65,240,0],[58,0,4],[32,11],[65,242,0],[58,0,5],[32,11],[65,239,0],[58,0,6],[32,11],[65,244,0],[58,0,7],[32,11],[65,239,0],[58,0,8],[32,11],[65,244,0],[58,0,9],[32,11],[65,249,0],[58,0,10],[32,11],[65,240,0],[58,0,11],[32,11],[65,229,0],[58,0,12],[32,11],[184],[33,13],[32,9],[252,3],[65,7],[32,13],[65,195,1],[16,builtin('__ecma262_ToPropertyKey')],[33,12],[252,3],[32,12],[16,builtin('__Porffor_object_get')],[33,6],[33,9],[16,builtin('__Porffor_allocate')],[34,11],[65,11],[54,1,0],[32,11],[65,227,0],[58,0,4],[32,11],[65,239,0],[58,0,5],[32,11],[65,238,0],[58,0,6],[32,11],[65,243,0],[58,0,7],[32,11],[65,244,0],[58,0,8],[32,11],[65,242,0],[58,0,9],[32,11],[65,245,0],[58,0,10],[32,11],[65,227,0],[58,0,11],[32,11],[65,244,0],[58,0,12],[32,11],[65,239,0],[58,0,13],[32,11],[65,242,0],[58,0,14],[32,11],[184],[33,10],[32,6],[33,16],[2,124],[32,16],[65,6],[70],[4,64,"TYPESWITCH|Function"],[32,9],[252,3],[32,6],[32,10],[65,195,1],[16,builtin('__ecma262_ToPropertyKey')],[33,12],[252,3],[32,12],[32,0],[32,1],[16,builtin('__Porffor_object_set')],[26],[12,1],[11],[32,16],[65,7],[70],[4,64,"TYPESWITCH|Object"],[32,9],[252,3],[32,6],[32,10],[65,195,1],[16,builtin('__ecma262_ToPropertyKey')],[33,12],[252,3],[32,12],[32,0],[32,1],[16,builtin('__Porffor_object_set')],[26],[12,1],[11],[32,16],[65,208,0],[70],[4,64,"TYPESWITCH|Array"],[32,9],[252,3],[32,10],[252,3],[65,9],[108],[106],[34,8],[32,0],[34,7],[57,0,4],[32,8],[32,1],[58,0,12],[32,7],[12,1],[11],[32,16],[65,216,0],[70],[4,64,"TYPESWITCH|Uint8Array"],[32,9],[252,3],[40,0,4],[32,10],[252,3],[106],[32,0],[34,7],[252,3],[58,0,4],[32,7],[12,1],[11],[32,16],[65,217,0],[70],[4,64,"TYPESWITCH|Int8Array"],[32,9],[252,3],[40,0,4],[32,10],[252,3],[106],[32,0],[34,7],[252,2],[58,0,4],[32,7],[12,1],[11],[32,16],[65,218,0],[70],[4,64,"TYPESWITCH|Uint8ClampedArray"],[32,9],[252,3],[40,0,4],[32,10],[252,3],[106],[32,0],[34,7],[68,0],[165],[68,255],[164],[252,3],[58,0,4],[32,7],[12,1],[11],[32,16],[65,219,0],[70],[4,64,"TYPESWITCH|Uint16Array"],[32,9],[252,3],[40,0,4],[32,10],[252,3],[65,2],[108],[106],[32,0],[34,7],[252,3],[59,0,4],[32,7],[12,1],[11],[32,16],[65,220,0],[70],[4,64,"TYPESWITCH|Int16Array"],[32,9],[252,3],[40,0,4],[32,10],[252,3],[65,2],[108],[106],[32,0],[34,7],[252,2],[59,0,4],[32,7],[12,1],[11],[32,16],[65,221,0],[70],[4,64,"TYPESWITCH|Uint32Array"],[32,9],[252,3],[40,0,4],[32,10],[252,3],[65,4],[108],[106],[32,0],[34,7],[252,3],[54,0,4],[32,7],[12,1],[11],[32,16],[65,222,0],[70],[4,64,"TYPESWITCH|Int32Array"],[32,9],[252,3],[40,0,4],[32,10],[252,3],[65,4],[108],[106],[32,0],[34,7],[252,2],[54,0,4],[32,7],[12,1],[11],[32,16],[65,223,0],[70],[4,64,"TYPESWITCH|Float32Array"],[32,9],[252,3],[40,0,4],[32,10],[252,3],[65,4],[108],[106],[32,0],[34,7],[182],[56,0,4],[32,7],[12,1],[11],[32,16],[65,224,0],[70],[4,64,"TYPESWITCH|Float64Array"],[32,9],[252,3],[40,0,4],[32,10],[252,3],[65,8],[108],[106],[32,0],[34,7],[57,0,4],[32,7],[12,1],[11],[32,16],[65,128,1],[70],[4,64,"TYPESWITCH|undefined"],...internalThrow(_,'TypeError',`Cannot set property of undefined`),[68,0],[12,1],[11],[32,0],[11,"TYPESWITCH_end"],[26],...glbl(35,'underlyingFuncObjs',124),[33,4],[65,20],[33,5],[32,4],[32,5],[32,2],[65,1],[32,3],[65,7],[16,builtin('__Map_prototype_set')],[33,6],[26],[11],[32,3],[65,7],[15],[11],[32,0],[32,1],[15]],
6
+ wasm:(_,{allocPage,glbl,builtin})=>[[32,1],[184],[68,6],[97],[4,64],[32,0],[33,2],...glbl(35,'underlyingFuncObjs',124),[33,4],[65,20],[33,5],[32,4],[32,5],[32,2],[65,1],[16,builtin('__Map_prototype_get')],[26],[34,3],[68,0],[97],[4,64],[16,builtin('__Porffor_allocate')],[184],[33,3],[16,builtin('__Porffor_allocate')],[184],[33,7],[65,7],[33,8],...number(allocPage(_,'bytestring: __Porffor_object_getObject/key1','i8'),124),[33,9],[32,3],[252,2],[65,7],[32,9],[252,2],[65,195,1],[32,7],[32,8],[65,8],[65,1],[16,builtin('__Porffor_object_expr_initWithFlags')],[33,6],[183],[26],...number(allocPage(_,'bytestring: __Porffor_object_getObject/key2','i8'),124),[33,10],[32,7],[252,2],[32,8],[32,10],[252,2],[65,195,1],[32,0],[32,1],[65,10],[65,1],[16,builtin('__Porffor_object_expr_initWithFlags')],[33,6],[183],[26],...glbl(35,'underlyingFuncObjs',124),[33,4],[65,20],[33,5],[32,4],[32,5],[32,2],[65,1],[32,3],[65,7],[16,builtin('__Map_prototype_set')],[33,6],[26],[11],[32,3],[65,7],[15],[11],[32,0],[32,1],[15]],
7
7
  params:[124,127],typedParams:1,returns:[124,127],typedReturns:1,
8
- locals:[124,124,124,127,127,124,127,124,124,127,127,124,127,127,127],localNames:["obj","obj#type","funcI32","underlying","#proto_target","#proto_target#type","#last_type","#member_setter_val_tmp","#member_setter_ptr_tmp","#member_obj","#member_prop_assign","#makearray_pointer_tmp","#swap","#member_prop","#loadArray_offset","#member_allocd","#typeswitch_tmp1"],
9
- globalInits:{underlyingFuncObjs:(_,{glbl,builtin})=>[[68,1],[65,6],[16,builtin('__Porffor_allocate')],[184],[65,7],[68,0],[65,128,1],[16,builtin('Map')],[26],...glbl(36,'underlyingFuncObjs',124)]},
8
+ locals:[124,124,124,127,127,124,127,124,124],localNames:["obj","obj#type","funcI32","underlying","#proto_target","#proto_target#type","#last_type","proto","proto#type","key1","key2"],
9
+ globalInits:{underlyingFuncObjs:(_,{glbl,builtin})=>[[68,1],[65,6],[16,builtin('__Porffor_allocate')],[184],[65,7],[68,0],[65,128,1],[16,builtin('Map')],[26],...glbl(36,'underlyingFuncObjs',124)]},data:{"bytestring: __Porffor_object_getObject/key1":[9,0,0,0,112,114,111,116,111,116,121,112,101],"bytestring: __Porffor_object_getObject/key2":[11,0,0,0,99,111,110,115,116,114,117,99,116,111,114]},
10
10
  };
11
11
  this.__Porffor_strcmp = {
12
12
  wasm:()=>[[32,0],[32,2],[70],[4,64],[65,1],[65,2],[15],[11],[32,0],[40,0,0],[33,4],[32,2],[40,0,0],[33,5],[32,4],[32,5],[71],[4,64],[65,0],[65,2],[15],[11],[32,1],[65,195,1],[70],[4,64],[32,3],[65,195,1],[70],[4,64],[65,0],[33,6],[3,64],[32,6],[32,4],[72],[4,64],[32,0],[32,6],[106],[45,0,4],[32,2],[32,6],[106],[45,0,4],[71],[4,64],[65,0],[65,2],[15],[11],[32,6],[65,1],[106],[33,6],[12,1],[11],[11],[65,1],[65,2],[15],[5],[65,0],[33,6],[3,64],[32,6],[32,4],[72],[4,64],[32,0],[32,6],[106],[45,0,4],[32,2],[32,6],[65,2],[108],[106],[47,0,4],[71],[4,64],[65,0],[65,2],[15],[11],[32,6],[65,1],[106],[33,6],[12,1],[11],[11],[65,1],[65,2],[15],[11],[5],[32,3],[65,195,1],[70],[4,64],[65,0],[33,6],[3,64],[32,6],[32,4],[72],[4,64],[32,0],[32,6],[65,2],[108],[106],[47,0,4],[32,2],[32,6],[106],[45,0,4],[71],[4,64],[65,0],[65,2],[15],[11],[32,6],[65,1],[106],[33,6],[12,1],[11],[11],[65,1],[65,2],[15],[5],[65,0],[33,6],[3,64],[32,6],[32,4],[72],[4,64],[32,0],[32,6],[65,2],[108],[106],[47,0,4],[32,2],[32,6],[65,2],[108],[106],[47,0,4],[71],[4,64],[65,0],[65,2],[15],[11],[32,6],[65,1],[106],[33,6],[12,1],[11],[11],[65,1],[65,2],[15],[11],[11],[65,0],[65,128,1],[15]],
@@ -105,6 +105,11 @@ wasm:(_,{builtin})=>[[32,1],[65,7],[71],[4,64],[32,0],[184],[32,1],[16,builtin('
105
105
  params:[127,127,127,127,124,127],typedParams:1,returns:[127,127],typedReturns:1,
106
106
  locals:[127,127,127],localNames:["obj","obj#type","key","key#type","value","value#type","#last_type","entryPtr","size"],
107
107
  };
108
+ this.__Porffor_object_expr_initWithFlags = {
109
+ wasm:(_,{builtin})=>[[32,1],[65,7],[71],[4,64],[32,0],[184],[32,1],[16,builtin('__Porffor_object_getObject')],[33,8],[252,2],[34,0],[32,8],[33,1],[26],[11],[32,0],[32,1],[32,2],[32,3],[16,builtin('__Porffor_object_lookup')],[26],[34,9],[65,127],[70],[4,64],[32,0],[40,0,0],[33,10],[32,0],[32,10],[65,1],[106],[54,0,0],[32,0],[65,5],[106],[32,10],[65,14],[108],[106],[34,9],[65,1],[32,2],[32,3],[16,builtin('__Porffor_object_writeKey')],[33,8],[26],[11],[32,9],[32,4],[57,0,4],[32,9],[32,6],[32,5],[65,8],[116],[106],[59,0,12],[65,0],[65,128,1],[15]],
110
+ params:[127,127,127,127,124,127,127,127],typedParams:1,returns:[127,127],typedReturns:1,
111
+ locals:[127,127,127],localNames:["obj","obj#type","key","key#type","value","value#type","flags","flags#type","#last_type","entryPtr","size"],
112
+ };
108
113
  this.__Porffor_object_expr_get = {
109
114
  wasm:(_,{builtin})=>[[32,1],[65,7],[71],[4,64],[32,0],[184],[32,1],[16,builtin('__Porffor_object_getObject')],[33,6],[252,2],[34,0],[32,6],[33,1],[26],[11],[32,0],[32,1],[32,2],[32,3],[16,builtin('__Porffor_object_lookup')],[26],[33,7],[65,0],[33,8],[65,128,1],[33,9],[32,7],[65,127],[70],[4,64],[32,0],[40,0,0],[33,10],[32,0],[32,10],[65,1],[106],[54,0,0],[32,0],[65,5],[106],[32,10],[65,14],[108],[106],[34,7],[65,1],[32,2],[32,3],[16,builtin('__Porffor_object_writeKey')],[33,6],[26],[5],[32,7],[65,1],[16,builtin('__Porffor_object_accessorSet')],[33,9],[33,8],[11],[32,7],[32,4],[32,5],[32,8],[32,9],[16,builtin('__Porffor_object_packAccessor')],[33,6],[57,0,4],[32,7],[65,15],[65,1],[65,8],[116],[106],[59,0,12],[65,0],[65,128,1],[15]],
110
115
  params:[127,127,127,127,127,127],typedParams:1,returns:[127,127],typedReturns:1,
@@ -102,7 +102,7 @@ const generate = (scope, decl, global = false, name = undefined, valueUnused = f
102
102
  return cacheAst(decl, generateNew(scope, decl, global, name));
103
103
 
104
104
  case 'ThisExpression':
105
- return cacheAst(decl, generateThis(scope, decl, global, name));
105
+ return cacheAst(decl, generateThis(scope, decl));
106
106
 
107
107
  case 'Literal':
108
108
  return cacheAst(decl, generateLiteral(scope, decl, global, name));
@@ -2629,7 +2629,7 @@ const generateNew = (scope, decl, _global, _name) => generateCall(scope, {
2629
2629
  _new: true
2630
2630
  }, _global, _name);
2631
2631
 
2632
- const generateThis = (scope, decl, _global, _name) => {
2632
+ const generateThis = (scope, decl) => {
2633
2633
  if (!scope.constr) {
2634
2634
  // this in a non-constructor context is a reference to globalThis
2635
2635
  return [
@@ -2639,7 +2639,7 @@ const generateThis = (scope, decl, _global, _name) => {
2639
2639
  }
2640
2640
 
2641
2641
  // opt: do not check for pure constructors
2642
- if (scope._onlyConstr) return [
2642
+ if (scope._onlyConstr || scope._onlyThisMethod || decl._noGlobalThis) return [
2643
2643
  [ Opcodes.local_get, scope.locals['#this'].idx ],
2644
2644
  ...setLastType(scope, [ [ Opcodes.local_get, scope.locals['#this#type'].idx ] ])
2645
2645
  ];
@@ -5163,7 +5163,7 @@ const generateObject = (scope, decl, global = false, name = '$undeclared') => {
5163
5163
 
5164
5164
  for (const x of decl.properties) {
5165
5165
  // method, shorthand are made into useful values by parser for us :)
5166
- const { type, argument, computed, kind, key, value } = x;
5166
+ let { type, argument, computed, kind, key, value } = x;
5167
5167
 
5168
5168
  if (type === 'SpreadElement') {
5169
5169
  out.push(
@@ -5189,6 +5189,18 @@ const generateObject = (scope, decl, global = false, name = '$undeclared') => {
5189
5189
  value: key.name
5190
5190
  };
5191
5191
 
5192
+ if (isFuncType(value.type)) {
5193
+ let id = value.id;
5194
+
5195
+ // todo: support computed names properly
5196
+ if (typeof k.value === 'string') id ??= {
5197
+ type: 'Identifier',
5198
+ name: k.value
5199
+ };
5200
+
5201
+ value = { ...value, id };
5202
+ }
5203
+
5192
5204
  out.push(
5193
5205
  [ Opcodes.local_get, tmp ],
5194
5206
  ...number(TYPES.object, Valtype.i32),
@@ -5695,7 +5707,7 @@ const generateClass = (scope, decl) => {
5695
5707
  body: []
5696
5708
  }
5697
5709
  }),
5698
- id: root,
5710
+ id: root
5699
5711
  };
5700
5712
 
5701
5713
  const [ func, out ] = generateFunc(scope, {
@@ -5759,11 +5771,28 @@ const generateClass = (scope, decl) => {
5759
5771
  outArr = func.wasm;
5760
5772
  outOp = 'unshift';
5761
5773
  object = {
5762
- type: 'ThisExpression'
5774
+ type: 'ThisExpression',
5775
+ _noGlobalThis: true
5763
5776
  };
5764
5777
  outScope = func;
5765
5778
  }
5766
5779
 
5780
+ if (isFuncType(value.type) && type === 'MethodDefinition') {
5781
+ let id = value.id;
5782
+
5783
+ // todo: support computed names properly
5784
+ if (typeof k.value === 'string') id ??= {
5785
+ type: 'Identifier',
5786
+ name: k.value
5787
+ };
5788
+
5789
+ value = {
5790
+ ...value,
5791
+ id,
5792
+ _onlyThisMethod: true
5793
+ };
5794
+ }
5795
+
5767
5796
  outArr[outOp](
5768
5797
  ...generate(outScope, object),
5769
5798
  Opcodes.i32_to_u,
@@ -5884,7 +5913,7 @@ const generateFunc = (scope, decl, outUnused = false) => {
5884
5913
  (decl.type && decl.type !== 'ArrowFunctionExpression' && decl.type !== 'Program') &&
5885
5914
  // not async or generator
5886
5915
  !decl.async && !decl.generator,
5887
- _onlyConstr: decl._onlyConstr,
5916
+ _onlyConstr: decl._onlyConstr, _onlyThisMethod: decl._onlyThisMethod,
5888
5917
  strict: scope.strict,
5889
5918
 
5890
5919
  generate() {
@@ -5941,7 +5970,7 @@ const generateFunc = (scope, decl, outUnused = false) => {
5941
5970
  // todo: wrap in try and reject thrown value once supported
5942
5971
  }
5943
5972
 
5944
- if (!globalThis.precompile && func.constr) {
5973
+ if (!globalThis.precompile && func.constr && !func._onlyThisMethod) {
5945
5974
  wasm.unshift(
5946
5975
  // opt: do not check for pure constructors
5947
5976
  ...(func._onlyConstr ? [] : [
@@ -5951,7 +5980,7 @@ const generateFunc = (scope, decl, outUnused = false) => {
5951
5980
  [ Opcodes.if, Blocktype.void ],
5952
5981
  ]),
5953
5982
  // set prototype of this ;)
5954
- ...generate(func, setObjProp({ type: 'ThisExpression' }, '__proto__', getObjProp(func.name, 'prototype'))),
5983
+ ...generate(func, setObjProp({ type: 'ThisExpression', _noGlobalThis: true }, '__proto__', getObjProp(func.name, 'prototype'))),
5955
5984
  ...(func._onlyConstr ? [] : [ [ Opcodes.end ] ])
5956
5985
  );
5957
5986
  }
@@ -99,7 +99,7 @@ export default (wasm, name = '', ind = 0, locals = {}, params = [], returns = []
99
99
 
100
100
  if (inst[0] === Opcodes.call || inst[0] === Opcodes.return_call) {
101
101
  const idx = inst[1];
102
- const callFunc = funcs.find(x => (x.asmIndex ?? x.index) === idx);
102
+ const callFunc = funcs.find(x => x.index === idx);
103
103
  if (callFunc) out += ` ;; $${callFunc.name} ${makeSignature(callFunc.params, callFunc.returns)}`;
104
104
  if (globalThis.importFuncs && idx < importFuncs.length) {
105
105
  const importFunc = importFuncs[idx];
@@ -59,6 +59,7 @@ const compile = async (file, _funcs) => {
59
59
  const paramOverrides = {
60
60
  __Porffor_object_set: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32 ],
61
61
  __Porffor_object_expr_init: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32 ],
62
+ __Porffor_object_expr_initWithFlags: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32, Valtype.i32, Valtype.i32 ],
62
63
  __Porffor_object_define: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32, Valtype.i32, Valtype.i32 ],
63
64
  };
64
65
 
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.34.8+3c064d5f4",
4
+ "version": "0.34.10+ab92b7b63",
5
5
  "author": "CanadaHonk",
6
6
  "license": "MIT",
7
7
  "scripts": {},
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.34.8+3c064d5f4';
3
+ globalThis.version = '0.34.10+ab92b7b63';
4
4
 
5
5
  // deno compat
6
6
  if (typeof process === 'undefined' && typeof Deno !== 'undefined') {