porffor 0.56.2 → 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,15 +741,14 @@ _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');
728
748
  break;
729
749
 
730
750
  case Opcodes.drop:
731
- // line(vals.pop());
732
- vals.pop();
751
+ if (vals.length > 0) line(`(void) ${vals.pop()}`);
733
752
  break;
734
753
 
735
754
  case Opcodes.block:
@@ -775,10 +794,15 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
775
794
  }
776
795
 
777
796
  case Opcodes.throw: {
778
- // todo: actually print exception
779
- vals.pop();
780
- vals.pop();
781
- 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")`);
782
806
  line(`exit(1)`);
783
807
 
784
808
  includes.set('stdio.h', true);
@@ -828,24 +852,13 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
828
852
  includes.set('math.h', true);
829
853
  break;
830
854
  case Opcodes.f64_trunc:
831
- // vals.push(`trunc(${vals.pop()})`);
832
- // includes.set('math.h', true);
833
-
834
- 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??
835
856
  break;
836
857
  case Opcodes.f64_nearest:
837
858
  vals.push(`round(${vals.pop()})`);
838
859
  includes.set('math.h', true);
839
860
  break;
840
861
 
841
- // case Opcodes.f64_sqrt: {
842
- // break;
843
- // }
844
-
845
- // case Opcodes.f64_copysign: {
846
- // break;
847
- // }
848
-
849
862
  case Opcodes.memory_grow: {
850
863
  const id = localTmpId++;
851
864
  line(`const u32 _oldPages${id} = _memoryPages`);
@@ -29,6 +29,8 @@ export const allocPage = ({ scope, pages }, name) => {
29
29
  };
30
30
 
31
31
  export const allocBytes = ({ scope, pages }, reason, bytes) => {
32
+ bytes += 2; // overallocate by 2 bytes to ensure null termination
33
+
32
34
  const allocs = pages.allocs ??= new Map();
33
35
  const bins = pages.bins ??= [];
34
36
 
@@ -522,10 +522,6 @@ export const __Porffor_object_accessorSet = (entryPtr: i32): Function|undefined
522
522
 
523
523
  export const __Porffor_object_lookup = (obj: any, target: any, targetHash: i32): i32 => {
524
524
  if (Porffor.wasm`local.get ${obj}` == 0) return -1;
525
- if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) {
526
- obj = __Porffor_object_underlying(obj);
527
- if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) return -1;
528
- }
529
525
 
530
526
  let ptr: i32 = Porffor.wasm`local.get ${obj}` + 8;
531
527
  const endPtr: i32 = ptr + Porffor.wasm.i32.load16_u(obj, 0, 0) * 18;
@@ -616,6 +612,7 @@ local.get ${obj+1}
616
612
  return`;
617
613
  }
618
614
 
615
+ if (Porffor.type(obj) != Porffor.TYPES.object) obj = __Porffor_object_underlying(obj);
619
616
  let lastProto: any = obj;
620
617
  while (true) {
621
618
  if ((entryPtr = __Porffor_object_lookup(obj, key, hash)) != -1) break;
@@ -630,6 +627,7 @@ local.set ${obj}
630
627
  i32.load8_u 0 3
631
628
  local.set ${obj+1}`;
632
629
  } else obj = __Porffor_object_getPrototype(obj);
630
+ if (Porffor.type(obj) != Porffor.TYPES.object) obj = __Porffor_object_underlying(obj);
633
631
 
634
632
  if (Porffor.fastOr(obj == null, Porffor.wasm`local.get ${obj}` == Porffor.wasm`local.get ${lastProto}`)) break;
635
633
  lastProto = obj;
@@ -691,11 +689,13 @@ export const __Porffor_object_set = (obj: any, key: any, value: any): any => {
691
689
  // check prototype chain for setter
692
690
  let proto: any = __Porffor_object_getPrototype(obj);
693
691
  if (proto != null) {
692
+ if (Porffor.type(proto) != Porffor.TYPES.object) proto = __Porffor_object_underlying(proto);
694
693
  let lastProto: any = proto;
695
694
  while (true) {
696
695
  if ((entryPtr = __Porffor_object_lookup(proto, key, hash)) != -1) break;
697
696
 
698
697
  proto = __Porffor_object_getPrototype(proto);
698
+ if (Porffor.type(proto) != Porffor.TYPES.object) proto = __Porffor_object_underlying(proto);
699
699
  if (Porffor.fastOr(proto == null, Porffor.wasm`local.get ${proto}` == Porffor.wasm`local.get ${lastProto}`)) break;
700
700
  lastProto = proto;
701
701
  }
@@ -795,11 +795,14 @@ export const __Porffor_object_setStrict = (obj: any, key: any, value: any): any
795
795
  // check prototype chain for setter
796
796
  let proto: any = __Porffor_object_getPrototype(obj);
797
797
  if (proto != null) {
798
+ if (Porffor.type(proto) != Porffor.TYPES.object) proto = __Porffor_object_underlying(proto);
799
+
798
800
  let lastProto: any = proto;
799
801
  while (true) {
800
802
  if ((entryPtr = __Porffor_object_lookup(proto, key, hash)) != -1) break;
801
803
 
802
804
  proto = __Porffor_object_getPrototype(proto);
805
+ if (Porffor.type(proto) != Porffor.TYPES.object) proto = __Porffor_object_underlying(proto);
803
806
  if (Porffor.fastOr(proto == null, Porffor.wasm`local.get ${proto}` == Porffor.wasm`local.get ${lastProto}`)) break;
804
807
  lastProto = proto;
805
808
  }
@@ -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) {
@@ -345,6 +345,7 @@ export const __Object_getOwnPropertyDescriptor = (obj: any, prop: any): object|u
345
345
  if (obj == null) throw new TypeError('Argument is nullish, expected object');
346
346
  const p: any = ecma262.ToPropertyKey(prop);
347
347
 
348
+ obj = __Porffor_object_underlying(obj);
348
349
  const entryPtr: i32 = Porffor.object.lookup(obj, p, __Porffor_object_hash(p));
349
350
  if (entryPtr == -1) {
350
351
  if (Porffor.type(obj) == Porffor.TYPES.function) {
@@ -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
  }