porffor 0.56.3 → 0.56.4

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 CHANGED
@@ -395,6 +395,21 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
395
395
  for (let _ = 0; _ < f.wasm.length; _++) {
396
396
  const i = f.wasm[_];
397
397
 
398
+ if (i[0] === null && i[1] === 'c') {
399
+ // inline c
400
+ let c = i[2];
401
+ c = c.replace(/^\s*(?:(?:inline|static)\s+)?\w+\s+\*?\s*\w+\s*\(.*?\)\s* {([\w\W]*?)\n}/gm, _ => {
402
+ prepend.set(_, _);
403
+ return '';
404
+ });
405
+ line(c);
406
+
407
+ // hack: add includes for some common calls
408
+ if (c.includes('printf')) includes.set('stdio.h', true);
409
+
410
+ continue;
411
+ }
412
+
398
413
  if (i[0] === null && i[1] === 'dlopen') {
399
414
  // special ffi time
400
415
  const path = i[2];
@@ -607,6 +622,11 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
607
622
  winIncludes.set('windows.h', true);
608
623
  break;
609
624
 
625
+ case 'timeOrigin':
626
+ // todo: actually implement
627
+ vals.push('0');
628
+ break;
629
+
610
630
  case '__Porffor_readArgv': {
611
631
  prepend.set('__Porffor_readArgv',
612
632
  `i32 __Porffor_readArgv(u32 index, u32 outPtr) {
@@ -721,7 +741,7 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
721
741
  break;
722
742
 
723
743
  case Opcodes.call_indirect:
724
- // todo: stub
744
+ // stub
725
745
  if (Prefs.d) log.warning('2c', `unimplemented op: ${invOpcodes[i[0]]} \x1b[2m(${f.name})`);
726
746
  vals.pop();
727
747
  vals.push('0', '0');
@@ -774,10 +794,15 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
774
794
  }
775
795
 
776
796
  case Opcodes.throw: {
777
- // todo: actually print exception
778
- vals.pop();
779
- vals.pop();
780
- line(`printf("Uncaught exception\\n")`);
797
+ // todo: allow catching
798
+ const type = vals.pop();
799
+ const val = vals.pop();
800
+ line(`printf("Uncaught ")`);
801
+
802
+ const id = tmpId++;
803
+ line(`const struct ReturnValue _t${id} = __ecma262_ToString(${val}, ${type})`);
804
+ line(`__Porffor_printString(_t${id}.value, _t${id}.type)`);
805
+ line(`printf("\\n")`);
781
806
  line(`exit(1)`);
782
807
 
783
808
  includes.set('stdio.h', true);
@@ -827,24 +852,13 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
827
852
  includes.set('math.h', true);
828
853
  break;
829
854
  case Opcodes.f64_trunc:
830
- // vals.push(`trunc(${vals.pop()})`);
831
- // includes.set('math.h', true);
832
-
833
- vals.push(`(i32)(${removeBrackets(vals.pop())})`); // this is ~10x faster with clang??
855
+ vals.push(`(i32)(${removeBrackets(vals.pop())})`); // this is ~10x faster than math.h's trunc() with clang??
834
856
  break;
835
857
  case Opcodes.f64_nearest:
836
858
  vals.push(`round(${vals.pop()})`);
837
859
  includes.set('math.h', true);
838
860
  break;
839
861
 
840
- // case Opcodes.f64_sqrt: {
841
- // break;
842
- // }
843
-
844
- // case Opcodes.f64_copysign: {
845
- // break;
846
- // }
847
-
848
862
  case Opcodes.memory_grow: {
849
863
  const id = localTmpId++;
850
864
  line(`const u32 _oldPages${id} = _memoryPages`);
@@ -892,4 +892,43 @@ export const __Porffor_array_fastIndexOf = (arr: any[], el: number): i32 => {
892
892
  }
893
893
 
894
894
  return -1;
895
+ };
896
+
897
+ // functional to arr.splice(i, 1)
898
+ export const __Porffor_array_fastRemove = (arr: any[], i: i32, len: i32): void => {
899
+ arr.length = len - 1;
900
+
901
+ // offset all elements after by -1 ind
902
+ Porffor.wasm`
903
+ local offset i32
904
+ local.get ${i}
905
+ i32.to_u
906
+ i32.const 9
907
+ i32.mul
908
+ local.get ${arr}
909
+ i32.to_u
910
+ i32.add
911
+ i32.const 4
912
+ i32.add
913
+ local.set offset
914
+
915
+ ;; dst = offset (this element)
916
+ local.get offset
917
+
918
+ ;; src = offset + 9 (this element + 1 element)
919
+ local.get offset
920
+ i32.const 9
921
+ i32.add
922
+
923
+ ;; size = (size - i - 1) * 9
924
+ local.get ${len}
925
+ local.get ${i}
926
+ f64.sub
927
+ i32.to_u
928
+ i32.const 1
929
+ i32.sub
930
+ i32.const 9
931
+ i32.mul
932
+
933
+ memory.copy 0 0`;
895
934
  };
@@ -5,31 +5,33 @@ export const __Map_prototype_size$get = (_this: Map) => {
5
5
  };
6
6
 
7
7
  export const __Map_prototype_has = (_this: Map, key: any) => {
8
- const keys: Set = Porffor.wasm.i32.load(_this, 0, 0);
9
- return __Set_prototype_has(keys, key);
8
+ const keys: any[] = Porffor.wasm.i32.load(_this, 0, 0);
9
+ for (const x of keys) {
10
+ if (x === key) return true;
11
+ }
12
+
13
+ return false;
10
14
  };
11
15
 
12
16
  export const __Map_prototype_get = (_this: Map, key: any) => {
13
- const keys: Set = Porffor.wasm.i32.load(_this, 0, 0);
17
+ const keys: any[] = Porffor.wasm.i32.load(_this, 0, 0);
14
18
  const vals: any[] = Porffor.wasm.i32.load(_this, 0, 4);
15
19
 
16
20
  const size: i32 = Porffor.wasm.i32.load(keys, 0, 0);
17
-
18
21
  for (let i: i32 = 0; i < size; i++) {
19
- if (Porffor.set.read(keys, i) === key) return vals[i];
22
+ if (keys[i] === key) return vals[i];
20
23
  }
21
24
 
22
25
  return undefined;
23
26
  };
24
27
 
25
28
  export const __Map_prototype_set = (_this: Map, key: any, value: any) => {
26
- const keys: Set = Porffor.wasm.i32.load(_this, 0, 0);
29
+ const keys: any[] = Porffor.wasm.i32.load(_this, 0, 0);
27
30
  const vals: any[] = Porffor.wasm.i32.load(_this, 0, 4);
28
31
 
29
- const size: i32 = Porffor.wasm.i32.load(keys, 0, 0);
30
-
32
+ const size: i32 = keys.length;
31
33
  for (let i: i32 = 0; i < size; i++) {
32
- if (Porffor.set.read(keys, i) === key) {
34
+ if (keys[i] === key) {
33
35
  vals[i] = value;
34
36
  return _this;
35
37
  }
@@ -37,28 +39,24 @@ export const __Map_prototype_set = (_this: Map, key: any, value: any) => {
37
39
 
38
40
  // add key if non-existent
39
41
  // increment size by 1
40
- Porffor.wasm.i32.store(keys, size + 1, 0, 0);
42
+ keys.length = size + 1;
41
43
 
42
- // write new key at end
43
- Porffor.set.write(keys, size, key);
44
-
45
- // write new value at end
44
+ // write new key and value at end
45
+ keys[size] = key;
46
46
  vals[size] = value;
47
47
 
48
48
  return _this;
49
49
  };
50
50
 
51
51
  export const __Map_prototype_delete = (_this: Map, key: any) => {
52
- const keys: Set = Porffor.wasm.i32.load(_this, 0, 0);
52
+ const keys: any[] = Porffor.wasm.i32.load(_this, 0, 0);
53
53
  const vals: any[] = Porffor.wasm.i32.load(_this, 0, 4);
54
54
 
55
- const size: i32 = Porffor.wasm.i32.load(keys, 0, 0);
56
-
55
+ const size: i32 = keys.length;
57
56
  for (let i: i32 = 0; i < size; i++) {
58
- if (Porffor.set.read(keys, i) === key) {
59
- __Set_prototype_delete(keys, key);
60
- __Array_prototype_splice(vals, i, 1);
61
-
57
+ if (keys[i] === key) {
58
+ Porffor.array.fastRemove(keys, i, size);
59
+ Porffor.array.fastRemove(vals, i, size);
62
60
  return true;
63
61
  }
64
62
  }
@@ -67,22 +65,22 @@ export const __Map_prototype_delete = (_this: Map, key: any) => {
67
65
  };
68
66
 
69
67
  export const __Map_prototype_clear = (_this: Map) => {
70
- const keys: Set = Porffor.wasm.i32.load(_this, 0, 0);
71
- __Set_prototype_clear(keys);
68
+ const keys: any[] = Porffor.wasm.i32.load(_this, 0, 0);
69
+ keys.length = 0;
72
70
 
73
71
  const vals: any[] = Porffor.wasm.i32.load(_this, 0, 4);
74
72
  vals.length = 0;
75
73
  };
76
74
 
77
75
  export const __Map_prototype_forEach = (_this: Map, callbackFn: any) => {
78
- const keys: Set = Porffor.wasm.i32.load(_this, 0, 0);
76
+ const keys: any[] = Porffor.wasm.i32.load(_this, 0, 0);
79
77
  const vals: any[] = Porffor.wasm.i32.load(_this, 0, 4);
80
78
 
81
79
  const size: i32 = Porffor.wasm.i32.load(keys, 0, 0);
82
80
 
83
81
  let i: i32 = 0;
84
82
  while (i < size) {
85
- callbackFn(vals[i], Porffor.set.read(keys, i++), _this);
83
+ callbackFn(vals[i], keys[i++], _this);
86
84
  }
87
85
  };
88
86
 
@@ -91,10 +89,9 @@ export const Map = function (iterable: any): Map {
91
89
 
92
90
  const out: Map = Porffor.allocateBytes(8);
93
91
 
94
- const keys: Set = Porffor.allocate();
95
- Porffor.wasm.i32.store(out, keys, 0, 0);
96
-
92
+ const keys: any[] = Porffor.allocate();
97
93
  const vals: any[] = Porffor.allocate();
94
+ Porffor.wasm.i32.store(out, keys, 0, 0);
98
95
  Porffor.wasm.i32.store(out, vals, 0, 4);
99
96
 
100
97
  if (iterable != null) for (const x of iterable) {
@@ -106,7 +103,7 @@ export const Map = function (iterable: any): Map {
106
103
  };
107
104
 
108
105
  export const __Map_prototype_keys = (_this: Map) => {
109
- const keys: Set = Porffor.wasm.i32.load(_this, 0, 0);
106
+ const keys: any[] = Porffor.wasm.i32.load(_this, 0, 0);
110
107
  const out: any[] = Porffor.allocate();
111
108
 
112
109
  for (const x of keys) {
@@ -38,6 +38,7 @@ type PorfforGlobal = {
38
38
  array: {
39
39
  fastPush(arr: any[], el: any): i32;
40
40
  fastIndexOf(arr: any[], el: any): i32;
41
+ fastRemove(arr: any[], i: i32): void;
41
42
  }
42
43
 
43
44
  arraybuffer: {
@@ -1,50 +1,5 @@
1
1
  import type {} from './porffor.d.ts';
2
2
 
3
- // dark wasm magic for dealing with memory, sorry.
4
- export const __Porffor_set_read = (set: Set, index: number): any => {
5
- Porffor.wasm`
6
- local offset i32
7
- local.get ${index}
8
- i32.to_u
9
- i32.const 9
10
- i32.mul
11
- local.get ${set}
12
- i32.to_u
13
- i32.add
14
- local.set offset
15
-
16
- local.get offset
17
- f64.load 0 4
18
-
19
- local.get offset
20
- i32.load8_u 0 12
21
- return`;
22
- };
23
-
24
- export const __Porffor_set_write = (set: Set, index: number, value: any): boolean => {
25
- Porffor.wasm`
26
- local offset i32
27
- local.get ${index}
28
- i32.to_u
29
- i32.const 9
30
- i32.mul
31
- local.get ${set}
32
- i32.to_u
33
- i32.add
34
- local.set offset
35
-
36
- local.get offset
37
- local.get ${value}
38
- f64.store 0 4
39
-
40
- local.get offset
41
- local.get ${value+1}
42
- i32.store8 0 12`;
43
-
44
- return true;
45
- };
46
-
47
-
48
3
  export const __Set_prototype_size$get = (_this: Set) => {
49
4
  return Porffor.wasm.i32.load(_this, 0, 0);
50
5
  };
@@ -55,8 +10,7 @@ export const __Set_prototype_values = (_this: Set) => {
55
10
 
56
11
  const out: any[] = __Porffor_allocate();
57
12
  for (let i: number = 0; i < size; i++) {
58
- const val: any = __Porffor_set_read(_this, i);
59
- Porffor.array.fastPush(out, val);
13
+ Porffor.array.fastPush(out, (_this as any[])[i]);
60
14
  }
61
15
 
62
16
  return out;
@@ -70,7 +24,7 @@ export const __Set_prototype_has = (_this: Set, value: any) => {
70
24
  const size: number = Porffor.wasm.i32.load(_this, 0, 0);
71
25
 
72
26
  for (let i: number = 0; i < size; i++) {
73
- if (__Porffor_set_read(_this, i) === value) return true;
27
+ if ((_this as any[])[i] === value) return true;
74
28
  }
75
29
 
76
30
  return false;
@@ -81,7 +35,7 @@ export const __Set_prototype_add = (_this: Set, value: any) => {
81
35
 
82
36
  // check if already in set
83
37
  for (let i: number = 0; i < size; i++) {
84
- if (__Porffor_set_read(_this, i) === value) return _this;
38
+ if ((_this as any[])[i] === value) return _this;
85
39
  }
86
40
 
87
41
  // not, add it
@@ -89,55 +43,18 @@ export const __Set_prototype_add = (_this: Set, value: any) => {
89
43
  Porffor.wasm.i32.store(_this, size + 1, 0, 0);
90
44
 
91
45
  // write new value at end
92
- __Porffor_set_write(_this, size, value);
46
+ (_this as any[])[size] = value;
93
47
 
94
48
  return _this;
95
49
  };
96
50
 
97
51
  export const __Set_prototype_delete = (_this: Set, value: any) => {
98
- const size: number = Porffor.wasm.i32.load(_this, 0, 0);
99
-
100
52
  // check if already in set
53
+ const size: number = Porffor.wasm.i32.load(_this, 0, 0);
101
54
  for (let i: number = 0; i < size; i++) {
102
- if (__Porffor_set_read(_this, i) === value) {
55
+ if ((_this as any[])[i] === value) {
103
56
  // found, delete
104
- // decrement size by 1
105
- Porffor.wasm.i32.store(_this, size - 1, 0, 0);
106
-
107
- // offset all elements after by -1 ind
108
- Porffor.wasm`
109
- local offset i32
110
- local.get ${i}
111
- i32.to_u
112
- i32.const 9
113
- i32.mul
114
- local.get ${_this}
115
- i32.to_u
116
- i32.add
117
- i32.const 4
118
- i32.add
119
- local.set offset
120
-
121
- ;; dst = offset (this element)
122
- local.get offset
123
-
124
- ;; src = offset + 9 (this element + 1 element)
125
- local.get offset
126
- i32.const 9
127
- i32.add
128
-
129
- ;; size = (size - i - 1) * 9
130
- local.get ${size}
131
- local.get ${i}
132
- f64.sub
133
- i32.to_u
134
- i32.const 1
135
- i32.sub
136
- i32.const 9
137
- i32.mul
138
-
139
- memory.copy 0 0`;
140
-
57
+ Porffor.array.fastRemove(_this, i, size);
141
58
  return true;
142
59
  }
143
60
  }
@@ -148,8 +65,7 @@ memory.copy 0 0`;
148
65
 
149
66
  export const __Set_prototype_clear = (_this: Set) => {
150
67
  // just set size to 0
151
- // do not need to delete any as will not be accessed anymore,
152
- // and will be overwritten with new add
68
+ // do not need to delete any as old will just be overwritten
153
69
  Porffor.wasm.i32.store(_this, 0, 0, 0);
154
70
  };
155
71
 
@@ -1,21 +1,18 @@
1
1
  import type {} from './porffor.d.ts';
2
2
 
3
3
  export const __WeakMap_prototype_has = (_this: WeakMap, key: any) => {
4
- const map: Map = _this;
5
- return __Map_prototype_has(map, key);
4
+ return __Map_prototype_has(_this as Map, key);
6
5
  };
7
6
 
8
7
  export const __WeakMap_prototype_set = (_this: WeakMap, key: any, value: any) => {
9
8
  if (!Porffor.object.isObjectOrSymbol(key)) throw new TypeError('Value in WeakSet needs to be an object or symbol');
10
9
 
11
- const map: Map = _this;
12
- __Map_prototype_set(map, key, value);
10
+ __Map_prototype_set(_this as Map, key, value);
13
11
  return _this;
14
12
  };
15
13
 
16
14
  export const __WeakMap_prototype_delete = (_this: WeakMap, key: any) => {
17
- const map: Map = _this;
18
- return __Map_prototype_delete(map, key);
15
+ return __Map_prototype_delete(_this as Map, key);
19
16
  };
20
17
 
21
18
  export const WeakMap = function (iterable: any): WeakMap {
@@ -23,10 +20,9 @@ export const WeakMap = function (iterable: any): WeakMap {
23
20
 
24
21
  const out: WeakMap = Porffor.allocateBytes(8);
25
22
 
26
- const keys: Set = Porffor.allocate();
27
- Porffor.wasm.i32.store(out, keys, 0, 0);
28
-
23
+ const keys: any[] = Porffor.allocate();
29
24
  const vals: any[] = Porffor.allocate();
25
+ Porffor.wasm.i32.store(out, keys, 0, 0);
30
26
  Porffor.wasm.i32.store(out, vals, 0, 4);
31
27
 
32
28
  if (iterable != null) for (const x of iterable) {
@@ -1,28 +1,24 @@
1
1
  import type {} from './porffor.d.ts';
2
2
 
3
3
  export const __WeakSet_prototype_has = (_this: WeakSet, value: any) => {
4
- const set: Set = _this;
5
- return __Set_prototype_has(set, value);
4
+ return __Set_prototype_has(_this as Set, value);
6
5
  };
7
6
 
8
7
  export const __WeakSet_prototype_add = (_this: WeakSet, value: any) => {
9
8
  if (!Porffor.object.isObjectOrSymbol(value)) throw new TypeError('Value in WeakSet needs to be an object or symbol');
10
9
 
11
- const set: Set = _this;
12
- __Set_prototype_add(set, value);
10
+ __Set_prototype_add(_this as Set, value);
13
11
  return _this;
14
12
  };
15
13
 
16
14
  export const __WeakSet_prototype_delete = (_this: WeakSet, value: any) => {
17
- const set: Set = _this;
18
- return __Set_prototype_delete(set, value);
15
+ return __Set_prototype_delete(_this as Set, value);
19
16
  };
20
17
 
21
18
  export const WeakSet = function (iterable: any): WeakSet {
22
19
  if (!new.target) throw new TypeError("Constructor WeakSet requires 'new'");
23
20
 
24
21
  const out: WeakSet = __Porffor_allocate();
25
-
26
22
  if (iterable != null) for (const x of iterable) {
27
23
  __WeakSet_prototype_add(out, x);
28
24
  }