porffor 0.20.0 → 0.20.2
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/compiler/2c.js +93 -45
- package/compiler/builtins/string_f64.ts +1 -1
- package/package.json +1 -1
- package/runner/index.js +1 -1
package/compiler/2c.js
CHANGED
@@ -27,7 +27,8 @@ typedef uint64_t u64;
|
|
27
27
|
typedef float f32;
|
28
28
|
typedef double f64;
|
29
29
|
|
30
|
-
f64
|
30
|
+
const f64 NaN = 0e+0/0e+0;
|
31
|
+
const f64 Infinity = 1e+0/0e+0;
|
31
32
|
|
32
33
|
struct ReturnValue {
|
33
34
|
f64 value;
|
@@ -187,7 +188,11 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
|
|
187
188
|
}
|
188
189
|
return out;
|
189
190
|
};
|
190
|
-
const sanitize = str =>
|
191
|
+
const sanitize = str => {
|
192
|
+
if (str === 'char') return '_' + str;
|
193
|
+
|
194
|
+
return str.replace(/[^0-9a-zA-Z_]/g, _ => codeToSanitizedStr(_.charCodeAt(0)));
|
195
|
+
};
|
191
196
|
|
192
197
|
for (const x in invGlobals) {
|
193
198
|
invGlobals[x] = sanitize(invGlobals[x]);
|
@@ -226,6 +231,20 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
|
|
226
231
|
prependMain.set('argv', `_argc = argc; _argv = argv;`);
|
227
232
|
}
|
228
233
|
|
234
|
+
prepend.set('func decls', funcs.filter(x => x.name !== 'main').map(f => {
|
235
|
+
const returns = f.returns.length > 0;
|
236
|
+
const typedReturns = f.returnType == null;
|
237
|
+
|
238
|
+
const invLocals = inv(f.locals, x => x.idx);
|
239
|
+
for (const x in invLocals) {
|
240
|
+
invLocals[x] = sanitize(invLocals[x]);
|
241
|
+
}
|
242
|
+
|
243
|
+
const shouldInline = false;
|
244
|
+
|
245
|
+
return `${!typedReturns ? (returns ? CValtype[f.returns[0]] : 'void') : 'struct ReturnValue'} ${shouldInline ? 'inline ' : ''}${sanitize(f.name)}(${f.params.map((x, i) => `${CValtype[x]} ${invLocals[i]}`).join(', ')});`;
|
246
|
+
}).join('\n'));
|
247
|
+
|
229
248
|
if (out) out += '\n';
|
230
249
|
|
231
250
|
const line = (str, semi = true) => out += `${str}${semi ? ';' : ''}\n`;
|
@@ -304,11 +323,26 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
|
|
304
323
|
let tmpId = 0;
|
305
324
|
|
306
325
|
const invLocals = inv(f.locals, x => x.idx);
|
307
|
-
|
326
|
+
const invLocalTypes = {};
|
308
327
|
for (const x in invLocals) {
|
328
|
+
invLocalTypes[x] = CValtype[f.locals[invLocals[x]].type];
|
309
329
|
invLocals[x] = sanitize(invLocals[x]);
|
310
330
|
}
|
311
331
|
|
332
|
+
let localTmpId = 0;
|
333
|
+
const localGet = idx => {
|
334
|
+
if (Prefs['2cDirectLocalGet']) {
|
335
|
+
// this just does local.get via the variable name
|
336
|
+
// nice but does not get the value at this moment
|
337
|
+
// so breaks some wasm principles :(
|
338
|
+
vals.push(`${invLocals[i[1]]}`);
|
339
|
+
} else {
|
340
|
+
const id = localTmpId++;
|
341
|
+
line(`const ${invLocalTypes[idx]} _get${id} = ${invLocals[idx]}`);
|
342
|
+
vals.push(`_get${id}`);
|
343
|
+
}
|
344
|
+
};
|
345
|
+
|
312
346
|
const returns = f.returns.length > 0;
|
313
347
|
const typedReturns = f.returnType == null;
|
314
348
|
|
@@ -394,33 +428,31 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
|
|
394
428
|
switch (i[0]) {
|
395
429
|
case Opcodes.i32_const:
|
396
430
|
case Opcodes.i64_const:
|
397
|
-
|
398
|
-
vals.push(new String(read_signedLEB128(i.slice(1)).toString()));
|
399
|
-
vals.at(-1).offset = _;
|
431
|
+
vals.push(read_signedLEB128(i.slice(1)).toString());
|
400
432
|
break;
|
401
433
|
|
402
434
|
case Opcodes.f64_const: {
|
403
|
-
|
404
|
-
|
405
|
-
// vals.push(val == 'NaN' ? 'NAN' : val);
|
406
|
-
vals.push(val == 'NaN' ? new String('NAN') : val);
|
407
|
-
vals.at(-1).offset = _;
|
435
|
+
const val = read_ieee754_binary64(i.slice(1)).toExponential();
|
436
|
+
vals.push(val);
|
408
437
|
break;
|
409
438
|
}
|
410
439
|
|
411
|
-
case Opcodes.local_get:
|
412
|
-
|
440
|
+
case Opcodes.local_get: {
|
441
|
+
localGet(i[1]);
|
413
442
|
break;
|
443
|
+
}
|
414
444
|
|
415
445
|
case Opcodes.local_set:
|
416
446
|
line(`${invLocals[i[1]]} = ${removeBrackets(vals.pop())}`);
|
417
447
|
break;
|
418
448
|
|
419
|
-
case Opcodes.local_tee:
|
449
|
+
case Opcodes.local_tee: {
|
420
450
|
line(`${invLocals[i[1]]} = ${removeBrackets(vals.pop())}`);
|
421
|
-
|
451
|
+
localGet(i[1]);
|
452
|
+
|
422
453
|
// vals.push(`((${invLocals[i[1]]} = ${vals.pop()}))`);
|
423
454
|
break;
|
455
|
+
}
|
424
456
|
|
425
457
|
case Opcodes.global_get:
|
426
458
|
vals.push(`${invGlobals[i[1]]}`);
|
@@ -430,11 +462,6 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
|
|
430
462
|
line(`${invGlobals[i[1]]} = ${removeBrackets(vals.pop())}`);
|
431
463
|
break;
|
432
464
|
|
433
|
-
case Opcodes.f64_trunc:
|
434
|
-
// vals.push(`trunc(${vals.pop()})`);
|
435
|
-
vals.push(`(i32)(${removeBrackets(vals.pop())})`); // this is ~10x faster with clang??
|
436
|
-
break;
|
437
|
-
|
438
465
|
case Opcodes.f64_convert_i32_u:
|
439
466
|
case Opcodes.f64_convert_i32_s:
|
440
467
|
case Opcodes.f64_convert_i64_u:
|
@@ -686,6 +713,15 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
|
|
686
713
|
break;
|
687
714
|
}
|
688
715
|
|
716
|
+
case Opcodes.select: {
|
717
|
+
const cond = vals.pop();
|
718
|
+
const b = vals.pop();
|
719
|
+
const a = vals.pop();
|
720
|
+
|
721
|
+
vals.push(`(${cond} ? ${a} : ${b})`);
|
722
|
+
break;
|
723
|
+
}
|
724
|
+
|
689
725
|
case Opcodes.throw: {
|
690
726
|
const id = vals.pop();
|
691
727
|
|
@@ -697,29 +733,6 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
|
|
697
733
|
break;
|
698
734
|
}
|
699
735
|
|
700
|
-
case Opcodes.f64_abs: {
|
701
|
-
break;
|
702
|
-
}
|
703
|
-
case Opcodes.f64_neg: {
|
704
|
-
break;
|
705
|
-
}
|
706
|
-
|
707
|
-
case Opcodes.f64_ceil: {
|
708
|
-
break;
|
709
|
-
}
|
710
|
-
case Opcodes.f64_floor: {
|
711
|
-
break;
|
712
|
-
}
|
713
|
-
case Opcodes.f64_trunc: {
|
714
|
-
break;
|
715
|
-
}
|
716
|
-
case Opcodes.f64_nearest: {
|
717
|
-
break;
|
718
|
-
}
|
719
|
-
|
720
|
-
case Opcodes.f64_sqrt: {
|
721
|
-
break;
|
722
|
-
}
|
723
736
|
case Opcodes.f64_min: {
|
724
737
|
const b = vals.pop();
|
725
738
|
const a = vals.pop();
|
@@ -740,10 +753,45 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
|
|
740
753
|
vals.push(`(_tmp${id}a > _tmp${id}b ? _tmp${id}a : _tmp${id}b)`);
|
741
754
|
break;
|
742
755
|
}
|
743
|
-
|
756
|
+
|
757
|
+
case Opcodes.f64_abs: {
|
758
|
+
const id = tmpId++;
|
759
|
+
line(`const f64 _tmp${id} = ${vals.pop()}`);
|
760
|
+
vals.push(`(_tmp${id} < 0 ? -_tmp${id} : _tmp${id})`);
|
761
|
+
break;
|
762
|
+
}
|
763
|
+
case Opcodes.f64_neg: {
|
764
|
+
vals.push(`(-${vals.pop()})`);
|
744
765
|
break;
|
745
766
|
}
|
746
767
|
|
768
|
+
case Opcodes.f64_ceil:
|
769
|
+
vals.push(`ceil(${vals.pop()})`);
|
770
|
+
includes.set('math.h', true);
|
771
|
+
break;
|
772
|
+
case Opcodes.f64_floor:
|
773
|
+
vals.push(`floor(${vals.pop()})`);
|
774
|
+
includes.set('math.h', true);
|
775
|
+
break;
|
776
|
+
case Opcodes.f64_trunc:
|
777
|
+
// vals.push(`trunc(${vals.pop()})`);
|
778
|
+
// includes.set('math.h', true);
|
779
|
+
|
780
|
+
vals.push(`(i32)(${removeBrackets(vals.pop())})`); // this is ~10x faster with clang??
|
781
|
+
break;
|
782
|
+
case Opcodes.f64_nearest:
|
783
|
+
vals.push(`round(${vals.pop()})`);
|
784
|
+
includes.set('math.h', true);
|
785
|
+
break;
|
786
|
+
|
787
|
+
// case Opcodes.f64_sqrt: {
|
788
|
+
// break;
|
789
|
+
// }
|
790
|
+
|
791
|
+
// case Opcodes.f64_copysign: {
|
792
|
+
// break;
|
793
|
+
// }
|
794
|
+
|
747
795
|
default:
|
748
796
|
if (CMemFuncs[i[0]]) {
|
749
797
|
const name = invOpcodes[i[0]];
|
@@ -763,7 +811,7 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
|
|
763
811
|
break;
|
764
812
|
}
|
765
813
|
|
766
|
-
log.warning('2c', `unimplemented op: ${invOpcodes[i[0]]}`);
|
814
|
+
log.warning('2c', `unimplemented op: ${invOpcodes[i[0]]} \x1b[90m(${f.name})`);
|
767
815
|
}
|
768
816
|
|
769
817
|
lastCond = false;
|
@@ -4,7 +4,7 @@ import type {} from './porffor.d.ts';
|
|
4
4
|
// todo: support constructor/string objects properly
|
5
5
|
export const String = function (value: any): bytestring {
|
6
6
|
if (!new.target && Porffor.rawType(value) == Porffor.TYPES.symbol) return __Symbol_prototype_toString(value);
|
7
|
-
return
|
7
|
+
return ecma262.ToString(value);
|
8
8
|
};
|
9
9
|
|
10
10
|
export const __String_fromCharCode = (...codes: any[]): bytestring|string => {
|
package/package.json
CHANGED