porffor 0.56.3 → 0.56.5

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`);
@@ -39,14 +39,12 @@ export const __Array_from = (arg: any, mapFn: any): any[] => {
39
39
  if (arg == null) throw new TypeError('Argument cannot be nullish');
40
40
 
41
41
  let out: any[] = Porffor.allocate();
42
- let len: i32 = 0;
43
42
 
44
- const type = Porffor.type(arg);
45
43
  if (Porffor.fastOr(
46
- type == Porffor.TYPES.array,
47
- type == Porffor.TYPES.string, type == Porffor.TYPES.bytestring,
48
- type == Porffor.TYPES.set,
49
- Porffor.fastAnd(type >= Porffor.TYPES.uint8array, type <= Porffor.TYPES.float64array)
44
+ Porffor.type(arg) == Porffor.TYPES.array,
45
+ Porffor.type(arg) == Porffor.TYPES.string, Porffor.type(arg) == Porffor.TYPES.bytestring,
46
+ Porffor.type(arg) == Porffor.TYPES.set,
47
+ Porffor.fastAnd(Porffor.type(arg) >= Porffor.TYPES.uint8array, Porffor.type(arg) <= Porffor.TYPES.float64array)
50
48
  )) {
51
49
  let i: i32 = 0;
52
50
  if (Porffor.type(mapFn) != Porffor.TYPES.undefined) {
@@ -62,20 +60,23 @@ export const __Array_from = (arg: any, mapFn: any): any[] => {
62
60
  }
63
61
  }
64
62
 
65
- len = i;
63
+ out.length = i;
64
+ return out;
66
65
  }
67
66
 
68
- if (type == Porffor.TYPES.object) {
69
- len = ecma262.ToIntegerOrInfinity((arg as object)['length']);
67
+ if (Porffor.type(arg) == Porffor.TYPES.object) {
68
+ let len = ecma262.ToIntegerOrInfinity((arg as object)['length']);
70
69
  if (len > 4294967295) throw new RangeError('Invalid array length');
71
70
  if (len < 0) len = 0;
72
71
 
73
72
  for (let i: i32 = 0; i < len; i++) {
74
73
  out[i] = (arg as object)[i];
75
74
  }
75
+
76
+ out.length = len;
77
+ return out;
76
78
  }
77
79
 
78
- out.length = len;
79
80
  return out;
80
81
  };
81
82
 
@@ -646,16 +647,14 @@ export const __Array_prototype_sort = (_this: any[], callbackFn: any) => {
646
647
 
647
648
  // 23.1.3.30.2 CompareArrayElements (x, y, comparefn)
648
649
  // https://tc39.es/ecma262/#sec-comparearrayelements
649
- const xt: i32 = Porffor.type(x);
650
- const yt: i32 = Porffor.type(y);
651
650
  let v: number;
652
651
 
653
652
  // 1. If x and y are both undefined, return +0𝔽.
654
- if (xt == Porffor.TYPES.undefined && yt == Porffor.TYPES.undefined) v = 0;
653
+ if (Porffor.type(x) == Porffor.TYPES.undefined && Porffor.type(y) == Porffor.TYPES.undefined) v = 0;
655
654
  // 2. If x is undefined, return 1𝔽.
656
- else if (xt == Porffor.TYPES.undefined) v = 1;
655
+ else if (Porffor.type(x) == Porffor.TYPES.undefined) v = 1;
657
656
  // 3. If y is undefined, return -1𝔽.
658
- else if (yt == Porffor.TYPES.undefined) v = -1;
657
+ else if (Porffor.type(y) == Porffor.TYPES.undefined) v = -1;
659
658
  else {
660
659
  // 4. If comparefn is not undefined, then
661
660
  // a. Let v be ? ToNumber(? Call(comparefn, undefined, « x, y »)).
@@ -690,10 +689,9 @@ export const __Array_prototype_toString = (_this: any[]) => {
690
689
  if (i > 0) Porffor.bytestring.appendChar(out, 44);
691
690
 
692
691
  const element: any = _this[i++];
693
- const type: i32 = Porffor.type(element);
694
692
  if (element != 0 || Porffor.fastAnd(
695
- type != Porffor.TYPES.undefined, // undefined
696
- type != Porffor.TYPES.object // null
693
+ Porffor.type(element) != Porffor.TYPES.undefined, // undefined
694
+ Porffor.type(element) != Porffor.TYPES.object // null
697
695
  )) {
698
696
  Porffor.bytestring.appendStr(out, ecma262.ToString(element));
699
697
  }
@@ -722,10 +720,9 @@ export const __Array_prototype_join = (_this: any[], _separator: any) => {
722
720
  if (i > 0) Porffor.bytestring.appendStr(out, separator);
723
721
 
724
722
  const element: any = _this[i++];
725
- const type: i32 = Porffor.type(element);
726
723
  if (element != 0 || Porffor.fastAnd(
727
- type != Porffor.TYPES.undefined, // undefined
728
- type != Porffor.TYPES.object // null
724
+ Porffor.type(element) != Porffor.TYPES.undefined, // undefined
725
+ Porffor.type(element) != Porffor.TYPES.object // null
729
726
  )) {
730
727
  Porffor.bytestring.appendStr(out, ecma262.ToString(element));
731
728
  }
@@ -892,4 +889,43 @@ export const __Porffor_array_fastIndexOf = (arr: any[], el: number): i32 => {
892
889
  }
893
890
 
894
891
  return -1;
892
+ };
893
+
894
+ // functional to arr.splice(i, 1)
895
+ export const __Porffor_array_fastRemove = (arr: any[], i: i32, len: i32): void => {
896
+ arr.length = len - 1;
897
+
898
+ // offset all elements after by -1 ind
899
+ Porffor.wasm`
900
+ local offset i32
901
+ local.get ${i}
902
+ i32.to_u
903
+ i32.const 9
904
+ i32.mul
905
+ local.get ${arr}
906
+ i32.to_u
907
+ i32.add
908
+ i32.const 4
909
+ i32.add
910
+ local.set offset
911
+
912
+ ;; dst = offset (this element)
913
+ local.get offset
914
+
915
+ ;; src = offset + 9 (this element + 1 element)
916
+ local.get offset
917
+ i32.const 9
918
+ i32.add
919
+
920
+ ;; size = (size - i - 1) * 9
921
+ local.get ${len}
922
+ local.get ${i}
923
+ f64.sub
924
+ i32.to_u
925
+ i32.const 1
926
+ i32.sub
927
+ i32.const 9
928
+ i32.mul
929
+
930
+ memory.copy 0 0`;
895
931
  };
@@ -1,12 +1,10 @@
1
1
  import type {} from './porffor.d.ts';
2
2
 
3
3
  export const __ArrayBuffer_isView = (value: any): boolean => {
4
- const t: i32 = Porffor.type(value);
5
- if (Porffor.fastOr(
6
- t == Porffor.TYPES.dataview,
7
- Porffor.fastAnd(t >= Porffor.TYPES.uint8array, t <= Porffor.TYPES.float64array)
8
- )) return true;
9
- return false;
4
+ return Porffor.fastOr(
5
+ Porffor.type(value) == Porffor.TYPES.dataview,
6
+ Porffor.fastAnd(Porffor.type(value) >= Porffor.TYPES.uint8array, Porffor.type(value) <= Porffor.TYPES.float64array)
7
+ );
10
8
  };
11
9
 
12
10
  export const __Porffor_arraybuffer_detach = (buffer: any): void => {
@@ -9,10 +9,9 @@ export const DataView = function (arg: any, byteOffset: any, length: any): DataV
9
9
  let len: i32 = 0;
10
10
  let bufferPtr: i32;
11
11
 
12
- const type: i32 = Porffor.type(arg);
13
12
  if (Porffor.fastOr(
14
- type == Porffor.TYPES.arraybuffer,
15
- type == Porffor.TYPES.sharedarraybuffer
13
+ Porffor.type(arg) == Porffor.TYPES.arraybuffer,
14
+ Porffor.type(arg) == Porffor.TYPES.sharedarraybuffer
16
15
  )) {
17
16
  bufferPtr = Porffor.wasm`local.get ${arg}`;
18
17
 
@@ -1925,19 +1925,16 @@ export const Date = function (v0: unknown, v1: unknown, v2: unknown, v3: unknown
1925
1925
  // 4. Else if numberOfArgs = 1, the n
1926
1926
  // a. Let value be values[0].
1927
1927
  const value: any = v0;
1928
-
1929
- const valueType: i32 = Porffor.type(v0);
1930
-
1931
1928
  let tv: number = 0;
1932
1929
 
1933
1930
  // b. If value is an Object and value has a [[DateValue]] internal slot, then
1934
- if (valueType == Porffor.TYPES.date) {
1931
+ if (Porffor.type(v0) == Porffor.TYPES.date) {
1935
1932
  // i. Let tv be value.[[DateValue]].
1936
1933
  tv = __Porffor_date_read(value);
1937
1934
  } else {
1938
1935
  // c. Else,
1939
1936
  // ii. If v is a String, then
1940
- if (Porffor.fastOr(valueType == Porffor.TYPES.string, valueType == Porffor.TYPES.bytestring)) {
1937
+ if (Porffor.fastOr(Porffor.type(v0) == Porffor.TYPES.string, Porffor.type(v0) == Porffor.TYPES.bytestring)) {
1941
1938
  // 1. Assert: The next step never returns an abrupt completion because v is a String.
1942
1939
 
1943
1940
  // 2. Let tv be the result of parsing v as a date, in exactly the same manner as for the parse method (21.4.3.2).
@@ -6,10 +6,9 @@ export const __Porffor_json_serialize = (value: any, depth: i32, space: bytestri
6
6
  if (value === true) return 'true';
7
7
  if (value === false) return 'false';
8
8
 
9
- const t: i32 = Porffor.type(value);
10
9
  if (Porffor.fastOr(
11
- (t | 0b10000000) == Porffor.TYPES.bytestring,
12
- t == Porffor.TYPES.stringobject
10
+ (Porffor.type(value) | 0b10000000) == Porffor.TYPES.bytestring,
11
+ Porffor.type(value) == Porffor.TYPES.stringobject
13
12
  )) { // string
14
13
  const out: bytestring = Porffor.allocate();
15
14
  Porffor.bytestring.appendChar(out, 34); // start "
@@ -71,14 +70,14 @@ export const __Porffor_json_serialize = (value: any, depth: i32, space: bytestri
71
70
  }
72
71
 
73
72
  if (Porffor.fastOr(
74
- t == Porffor.TYPES.number,
75
- t == Porffor.TYPES.numberobject
73
+ Porffor.type(value) == Porffor.TYPES.number,
74
+ Porffor.type(value) == Porffor.TYPES.numberobject
76
75
  )) { // number
77
76
  if (Number.isFinite(value)) return __Number_prototype_toString(value, 10);
78
77
  return 'null';
79
78
  }
80
79
 
81
- if (t == Porffor.TYPES.array) {
80
+ if (Porffor.type(value) == Porffor.TYPES.array) {
82
81
  const out: bytestring = Porffor.allocate();
83
82
  Porffor.bytestring.appendChar(out, 91); // [
84
83
 
@@ -115,7 +114,7 @@ export const __Porffor_json_serialize = (value: any, depth: i32, space: bytestri
115
114
  return out;
116
115
  }
117
116
 
118
- if (t > 0x06) {
117
+ if (Porffor.type(value) > 0x06) {
119
118
  // non-function object
120
119
  const out: bytestring = Porffor.allocate();
121
120
  Porffor.bytestring.appendChar(out, 123); // {
@@ -167,7 +166,7 @@ export const __Porffor_json_serialize = (value: any, depth: i32, space: bytestri
167
166
  return out;
168
167
  }
169
168
 
170
- if (t == 0x04) {
169
+ if (Porffor.type(value) == 0x04) {
171
170
  // bigint
172
171
  throw new TypeError('Cannot serialize BigInts');
173
172
  }
@@ -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) {
@@ -20,8 +20,7 @@ export const __Object_keys = (obj: any): any[] => {
20
20
  const out: any[] = Porffor.allocate();
21
21
 
22
22
  obj = __Porffor_object_underlying(obj);
23
- const t: i32 = Porffor.type(obj);
24
- if (t == Porffor.TYPES.object) {
23
+ if (Porffor.type(obj) == Porffor.TYPES.object) {
25
24
  let ptr: i32 = Porffor.wasm`local.get ${obj}` + 8;
26
25
  const endPtr: i32 = ptr + Porffor.wasm.i32.load16_u(obj, 0, 0) * 18;
27
26
 
@@ -76,8 +75,7 @@ export const __Object_values = (obj: any): any[] => {
76
75
  const out: any[] = Porffor.allocate();
77
76
 
78
77
  obj = __Porffor_object_underlying(obj);
79
- const t: i32 = Porffor.type(obj);
80
- if (t == Porffor.TYPES.object) {
78
+ if (Porffor.type(obj) == Porffor.TYPES.object) {
81
79
  let ptr: i32 = Porffor.wasm`local.get ${obj}` + 8;
82
80
  const endPtr: i32 = ptr + Porffor.wasm.i32.load16_u(obj, 0, 0) * 18;
83
81
 
@@ -146,8 +144,7 @@ export const __Object_prototype_hasOwnProperty = (_this: any, prop: any) => {
146
144
  if (_this == null) throw new TypeError('Argument is nullish, expected object');
147
145
  const p: any = ecma262.ToPropertyKey(prop);
148
146
 
149
- const t: i32 = Porffor.type(_this);
150
- if (t == Porffor.TYPES.object) {
147
+ if (Porffor.type(_this) == Porffor.TYPES.object) {
151
148
  return Porffor.object.lookup(_this, p, __Porffor_object_hash(p)) != -1;
152
149
  }
153
150
 
@@ -414,8 +411,7 @@ export const __Object_getOwnPropertyNames = (obj: any): any[] => {
414
411
  const out: any[] = Porffor.allocate();
415
412
 
416
413
  obj = __Porffor_object_underlying(obj);
417
- const t: i32 = Porffor.type(obj);
418
- if (t == Porffor.TYPES.object) {
414
+ if (Porffor.type(obj) == Porffor.TYPES.object) {
419
415
  let ptr: i32 = Porffor.wasm`local.get ${obj}` + 8;
420
416
  const endPtr: i32 = ptr + Porffor.wasm.i32.load16_u(obj, 0, 0) * 18;
421
417
 
@@ -469,8 +465,7 @@ export const __Object_getOwnPropertySymbols = (obj: any): any[] => {
469
465
  const out: any[] = Porffor.allocate();
470
466
 
471
467
  obj = __Porffor_object_underlying(obj);
472
- const t: i32 = Porffor.type(obj);
473
- if (t == Porffor.TYPES.object) {
468
+ if (Porffor.type(obj) == Porffor.TYPES.object) {
474
469
  let ptr: i32 = Porffor.wasm`local.get ${obj}` + 8;
475
470
  const endPtr: i32 = ptr + Porffor.wasm.i32.load16_u(obj, 0, 0) * 18;
476
471
 
@@ -686,22 +681,20 @@ export const __Object_prototype_toString = (_this: any) => {
686
681
  if (_this === null) return '[object Null]';
687
682
 
688
683
  // todo: toStringTag support
689
-
690
- const t: i32 = Porffor.type(_this);
691
- if (t == Porffor.TYPES.array) return '[object Array]';
692
- if (t == Porffor.TYPES.function) return '[object Function]';
684
+ if (Porffor.type(_this) == Porffor.TYPES.array) return '[object Array]';
685
+ if (Porffor.type(_this) == Porffor.TYPES.function) return '[object Function]';
693
686
  if (Porffor.fastOr(
694
- t == Porffor.TYPES.boolean,
695
- t == Porffor.TYPES.booleanobject)) return '[object Boolean]';
687
+ Porffor.type(_this) == Porffor.TYPES.boolean,
688
+ Porffor.type(_this) == Porffor.TYPES.booleanobject)) return '[object Boolean]';
696
689
  if (Porffor.fastOr(
697
- t == Porffor.TYPES.number,
698
- t == Porffor.TYPES.numberobject)) return '[object Number]';
690
+ Porffor.type(_this) == Porffor.TYPES.number,
691
+ Porffor.type(_this) == Porffor.TYPES.numberobject)) return '[object Number]';
699
692
  if (Porffor.fastOr(
700
- t == Porffor.TYPES.string,
701
- t == Porffor.TYPES.bytestring,
702
- t == Porffor.TYPES.stringobject)) return '[object String]';
703
- if (t == Porffor.TYPES.date) return '[object Date]';
704
- if (t == Porffor.TYPES.regexp) return '[object RegExp]';
693
+ Porffor.type(_this) == Porffor.TYPES.string,
694
+ Porffor.type(_this) == Porffor.TYPES.bytestring,
695
+ Porffor.type(_this) == Porffor.TYPES.stringobject)) return '[object String]';
696
+ if (Porffor.type(_this) == Porffor.TYPES.date) return '[object Date]';
697
+ if (Porffor.type(_this) == Porffor.TYPES.regexp) return '[object RegExp]';
705
698
 
706
699
  return '[object Object]';
707
700
  };
@@ -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: {
@@ -89,8 +89,7 @@ export const __Reflect_ownKeys = (target: any) => {
89
89
  const out: any[] = Porffor.allocate();
90
90
 
91
91
  target = __Porffor_object_underlying(target);
92
- const t: i32 = Porffor.type(target);
93
- if (t == Porffor.TYPES.object) {
92
+ if (Porffor.type(target) == Porffor.TYPES.object) {
94
93
  let ptr: i32 = Porffor.wasm`local.get ${target}` + 8;
95
94
  const endPtr: i32 = ptr + Porffor.wasm.i32.load16_u(target, 0, 0) * 18;
96
95