porffor 0.17.0-bf4206d7b → 0.17.0-c2af76d41

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
@@ -182,7 +182,15 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
182
182
  }, {});
183
183
  const invGlobals = inv(globals, x => x.idx);
184
184
 
185
- const sanitize = str => str.replace(/[^0-9a-zA-Z_]/g, _ => String.fromCharCode(97 + _.charCodeAt(0) % 32));
185
+ const codeToSanitizedStr = code => {
186
+ let out = '';
187
+ while (code > 0) {
188
+ out += String.fromCharCode(97 + code % 26);
189
+ code -= 26;
190
+ }
191
+ return out;
192
+ };
193
+ const sanitize = str => str.replace(/[^0-9a-zA-Z_]/g, _ => codeToSanitizedStr(_.charCodeAt(0)));
186
194
 
187
195
  for (const x in invGlobals) {
188
196
  invGlobals[x] = sanitize(invGlobals[x]);
@@ -273,10 +281,11 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
273
281
  }
274
282
 
275
283
  const returns = f.returns.length > 0;
284
+ const typedReturns = f.returnType == null;
276
285
 
277
286
  const shouldInline = false; // f.internal;
278
287
  if (f.name === 'main') out += `int main(${prependMain.has('argv') ? 'int argc, char* argv[]' : ''}) {\n`;
279
- else out += `${f.internal ? (returns ? 'f64' : 'void') : 'struct ReturnValue'} ${shouldInline ? 'inline ' : ''}${sanitize(f.name)}(${f.params.map((x, i) => `${CValtype[x]} ${invLocals[i]}`).join(', ')}) {\n`;
288
+ else out += `${!typedReturns ? (returns ? CValtype[f.returns[0]] : 'void') : 'struct ReturnValue'} ${shouldInline ? 'inline ' : ''}${sanitize(f.name)}(${f.params.map((x, i) => `${CValtype[x]} ${invLocals[i]}`).join(', ')}) {\n`;
280
289
 
281
290
  if (f.name === 'main') {
282
291
  out += ' ' + [...prependMain.values()].join('\n ');
@@ -418,11 +427,14 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
418
427
  continue;
419
428
 
420
429
  case Opcodes.return:
421
- // line(`return${returns ? ` ${removeBrackets(vals.pop())}` : ''}`);
422
- const b = vals.pop();
423
- const a = vals.pop();
430
+ if (!typedReturns) {
431
+ line(`return${returns ? ` ${removeBrackets(vals.pop())}` : ''}`);
432
+ break;
433
+ }
434
+
435
+ const b = returns ? vals.pop() : -1;
436
+ const a = returns ? vals.pop() : -1;
424
437
  line(`return${returns ? ` (struct ReturnValue){ ${removeBrackets(a)}, ${removeBrackets(b)} }` : ''}`);
425
- // line(`return${returns ? ` (struct ReturnValue){ ${removeBrackets(vals.pop())}, ${removeBrackets(vals.pop())} }` : ''}`);
426
438
  break;
427
439
 
428
440
  case Opcodes.if: {
@@ -549,10 +561,15 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
549
561
 
550
562
  prepend.set('__Porffor_readFile',
551
563
  `i32 __Porffor_readFile(u32 pathPtr, u32 outPtr) {
552
- char* path = _memory + pathPtr + 4;
553
- FILE* fp = fopen(path, "r");
554
- if (fp == NULL) {
555
- return -1;
564
+ FILE* fp;
565
+ if (pathPtr == 0) {
566
+ fp = stdin;
567
+ } else {
568
+ char* path = _memory + pathPtr + 4;
569
+ fp = fopen(path, "r");
570
+ if (fp == NULL) {
571
+ return -1;
572
+ }
556
573
  }
557
574
 
558
575
  u32 read = 0;
@@ -585,7 +602,7 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
585
602
  for (let j = 0; j < func.params.length; j++) args.unshift(removeBrackets(vals.pop()));
586
603
 
587
604
  if (func.returns.length > 0) {
588
- if (func.internal) {
605
+ if (func.returnType != null) {
589
606
  vals.push(`${sanitize(func.name)}(${args.join(', ')})`);
590
607
  } else {
591
608
  const id = retTmpId++;
@@ -4,6 +4,7 @@ export const __Array_isArray = (x: unknown): boolean =>
4
4
  // Porffor.wasm`local.get ${x+1}` == Porffor.TYPES.array;
5
5
  Porffor.rawType(x) == Porffor.TYPES.array;
6
6
 
7
+
7
8
  export const __Array_prototype_slice = (_this: any[], start: number, end: number) => {
8
9
  const len: i32 = _this.length;
9
10
  if (Porffor.rawType(end) == Porffor.TYPES.undefined) end = len;
@@ -22,7 +23,7 @@ export const __Array_prototype_slice = (_this: any[], start: number, end: number
22
23
  }
23
24
  if (end > len) end = len;
24
25
 
25
- let out: any[] = [];
26
+ let out: any[] = Porffor.allocate();
26
27
 
27
28
  if (start > end) return out;
28
29
 
@@ -42,10 +43,10 @@ export const __Array_prototype_slice = (_this: any[], start: number, end: number
42
43
  }
43
44
 
44
45
  out.length = end - start;
45
-
46
46
  return out;
47
47
  };
48
48
 
49
+ // @porf-typed-array
49
50
  export const __Array_prototype_indexOf = (_this: any[], searchElement: any, position: number) => {
50
51
  const len: i32 = _this.length;
51
52
  if (position > 0) {
@@ -60,6 +61,7 @@ export const __Array_prototype_indexOf = (_this: any[], searchElement: any, posi
60
61
  return -1;
61
62
  };
62
63
 
64
+ // @porf-typed-array
63
65
  export const __Array_prototype_lastIndexOf = (_this: any[], searchElement: any, position: number) => {
64
66
  const len: i32 = _this.length;
65
67
  if (position > 0) {
@@ -74,6 +76,7 @@ export const __Array_prototype_lastIndexOf = (_this: any[], searchElement: any,
74
76
  return -1;
75
77
  };
76
78
 
79
+ // @porf-typed-array
77
80
  export const __Array_prototype_includes = (_this: any[], searchElement: any, position: number) => {
78
81
  const len: i32 = _this.length;
79
82
  if (position > 0) {
@@ -88,6 +91,7 @@ export const __Array_prototype_includes = (_this: any[], searchElement: any, pos
88
91
  return false;
89
92
  };
90
93
 
94
+ // @porf-typed-array
91
95
  export const __Array_prototype_with = (_this: any[], index: number, value: any) => {
92
96
  const len: i32 = _this.length;
93
97
  if (index < 0) {
@@ -101,8 +105,7 @@ export const __Array_prototype_with = (_this: any[], index: number, value: any)
101
105
  throw new RangeError('Invalid index');
102
106
  }
103
107
 
104
- // todo: allocator is bad here?
105
- let out: any[] = [];
108
+ let out: any[] = Porffor.allocate();
106
109
 
107
110
  Porffor.clone(_this, out);
108
111
 
@@ -111,6 +114,7 @@ export const __Array_prototype_with = (_this: any[], index: number, value: any)
111
114
  return out;
112
115
  };
113
116
 
117
+ // @porf-typed-array
114
118
  export const __Array_prototype_reverse = (_this: any[]) => {
115
119
  const len: i32 = _this.length;
116
120
 
@@ -126,14 +130,14 @@ export const __Array_prototype_reverse = (_this: any[]) => {
126
130
  return _this;
127
131
  };
128
132
 
129
- // todo: this has memory/allocation bugs so sometimes crashes :(
133
+ // @porf-typed-array
130
134
  export const __Array_prototype_toReversed = (_this: any[]) => {
131
135
  const len: i32 = _this.length;
132
136
 
133
137
  let start: i32 = 0;
134
138
  let end: i32 = len - 1;
135
139
 
136
- let out: any[] = [];
140
+ let out: any[] = Porffor.allocate();
137
141
  out.length = len;
138
142
 
139
143
  while (start < end) {
@@ -144,11 +148,13 @@ export const __Array_prototype_toReversed = (_this: any[]) => {
144
148
  return out;
145
149
  };
146
150
 
151
+ // @porf-typed-array
147
152
  export const __Array_prototype_valueOf = (_this: any[]) => {
148
153
  return _this;
149
154
  };
150
155
 
151
156
 
157
+ // @porf-typed-array
152
158
  export const __Array_prototype_forEach = (_this: any[], callbackFn: any) => {
153
159
  const len: i32 = _this.length;
154
160
  let i: i32 = 0;
@@ -157,22 +163,26 @@ export const __Array_prototype_forEach = (_this: any[], callbackFn: any) => {
157
163
  }
158
164
  };
159
165
 
166
+ // @porf-typed-array
160
167
  export const __Array_prototype_filter = (_this: any[], callbackFn: any) => {
161
- const out: any[] = [];
168
+ const out: any[] = Porffor.allocate();
162
169
 
163
170
  const len: i32 = _this.length;
164
171
  let i: i32 = 0;
172
+ let j: i32 = 0;
165
173
  while (i < len) {
166
174
  const el: any = _this[i];
167
- if (Boolean(callbackFn(el, i++, _this))) out.push(el);
175
+ if (Boolean(callbackFn(el, i++, _this))) out[j++] = el;
168
176
  }
169
177
 
178
+ out.length = j;
170
179
  return out;
171
180
  };
172
181
 
182
+ // @porf-typed-array
173
183
  export const __Array_prototype_map = (_this: any[], callbackFn: any) => {
174
184
  const len: i32 = _this.length;
175
- const out: any[] = [];
185
+ const out: any[] = Porffor.allocate();
176
186
  out.length = len;
177
187
 
178
188
  let i: i32 = 0;
@@ -183,6 +193,7 @@ export const __Array_prototype_map = (_this: any[], callbackFn: any) => {
183
193
  return out;
184
194
  };
185
195
 
196
+ // @porf-typed-array
186
197
  export const __Array_prototype_find = (_this: any[], callbackFn: any) => {
187
198
  const len: i32 = _this.length;
188
199
  let i: i32 = 0;
@@ -192,6 +203,7 @@ export const __Array_prototype_find = (_this: any[], callbackFn: any) => {
192
203
  }
193
204
  };
194
205
 
206
+ // @porf-typed-array
195
207
  export const __Array_prototype_findLast = (_this: any[], callbackFn: any) => {
196
208
  let i: i32 = _this.length;
197
209
  while (i > 0) {
@@ -200,6 +212,7 @@ export const __Array_prototype_findLast = (_this: any[], callbackFn: any) => {
200
212
  }
201
213
  };
202
214
 
215
+ // @porf-typed-array
203
216
  export const __Array_prototype_findIndex = (_this: any[], callbackFn: any) => {
204
217
  const len: i32 = _this.length;
205
218
  let i: i32 = 0;
@@ -208,6 +221,7 @@ export const __Array_prototype_findIndex = (_this: any[], callbackFn: any) => {
208
221
  }
209
222
  };
210
223
 
224
+ // @porf-typed-array
211
225
  export const __Array_prototype_findLastIndex = (_this: any[], callbackFn: any) => {
212
226
  let i: i32 = _this.length;
213
227
  while (i > 0) {
@@ -215,6 +229,7 @@ export const __Array_prototype_findLastIndex = (_this: any[], callbackFn: any) =
215
229
  }
216
230
  };
217
231
 
232
+ // @porf-typed-array
218
233
  export const __Array_prototype_every = (_this: any[], callbackFn: any) => {
219
234
  const len: i32 = _this.length;
220
235
  let i: i32 = 0;
@@ -225,6 +240,18 @@ export const __Array_prototype_every = (_this: any[], callbackFn: any) => {
225
240
  return true;
226
241
  };
227
242
 
243
+ // @porf-typed-array
244
+ export const __Array_prototype_some = (_this: any[], callbackFn: any) => {
245
+ const len: i32 = _this.length;
246
+ let i: i32 = 0;
247
+ while (i < len) {
248
+ if (Boolean(callbackFn(_this[i], i++, _this))) return true;
249
+ }
250
+
251
+ return false;
252
+ };
253
+
254
+ // @porf-typed-array
228
255
  export const __Array_prototype_reduce = (_this: any[], callbackFn: any, initialValue: any) => {
229
256
  let acc: any = initialValue ?? _this[0];
230
257
 
@@ -237,6 +264,20 @@ export const __Array_prototype_reduce = (_this: any[], callbackFn: any, initialV
237
264
  return acc;
238
265
  };
239
266
 
267
+ // @porf-typed-array
268
+ export const __Array_prototype_reduceRight = (_this: any[], callbackFn: any, initialValue: any) => {
269
+ const len: i32 = _this.length;
270
+ let acc: any = initialValue ?? _this[len - 1];
271
+
272
+ let i: i32 = len;
273
+ while (i > 0) {
274
+ acc = callbackFn(acc, _this[--i], i, _this);
275
+ }
276
+
277
+ return acc;
278
+ };
279
+
280
+ // @porf-typed-array
240
281
  export const __Array_prototype_toString = (_this: any[]) => {
241
282
  // todo: this is bytestring only!
242
283
 
@@ -261,6 +302,7 @@ export const __Array_prototype_toString = (_this: any[]) => {
261
302
  return out;
262
303
  };
263
304
 
305
+ // @porf-typed-array
264
306
  export const __Array_prototype_join = (_this: any[], _separator: any) => {
265
307
  // todo: this is bytestring only!
266
308
  // todo/perf: optimize single char separators
@@ -16,7 +16,7 @@ export const __Math_exp = (x: number): number => {
16
16
  return 1 / Math.exp(-x);
17
17
  }
18
18
 
19
- const k: number = Math.floor(x / Math.LN2);
19
+ let k: number = Math.floor(x / Math.LN2);
20
20
  const r: number = x - k * Math.LN2;
21
21
 
22
22
  // Taylor series via Horner's method
@@ -30,7 +30,11 @@ export const __Math_exp = (x: number): number => {
30
30
  i++;
31
31
  }
32
32
 
33
- return sum * (1 << k);
33
+ while (k-- > 0) {
34
+ sum *= 2;
35
+ }
36
+
37
+ return sum;
34
38
  };
35
39
 
36
40
  export const __Math_log2 = (y: number): number => {
@@ -170,15 +170,8 @@ export const Set = () => {
170
170
  export const Set$constructor = (iterable: any): Set => {
171
171
  const out: Set = __Porffor_allocate();
172
172
 
173
- const type: number = Porffor.rawType(iterable);
174
- if (Porffor.fastOr(
175
- type == Porffor.TYPES.array,
176
- type == Porffor.TYPES.string, type == Porffor.TYPES.bytestring,
177
- type == Porffor.TYPES.set
178
- )) {
179
- for (const x of iterable) {
180
- __Set_prototype_add(out, x);
181
- }
173
+ if (Porffor.rawType(iterable) != Porffor.TYPES.undefined) for (const x of iterable) {
174
+ __Set_prototype_add(out, x);
182
175
  }
183
176
 
184
177
  return out;
@@ -195,3 +188,8 @@ export const __Set_prototype_union = (_this: Set, other: any) => {
195
188
  }
196
189
  return out;
197
190
  };
191
+
192
+ export const __Set_prototype_toString = (_this: Set) => {
193
+ const out: bytestring = '[object Set]';
194
+ return out;
195
+ };
@@ -0,0 +1,52 @@
1
+ export default async () => {
2
+ let out = '';
3
+
4
+ const arrayCode = (await import('node:fs')).readFileSync(globalThis.precompileCompilerPath + '/builtins/array.ts', 'utf8');
5
+ const typedArrayFuncs = [...arrayCode.matchAll(/\/\/ @porf-typed-array[\s\S]+?^};$/gm)].map(x => x[0]);
6
+
7
+ const constr = name => out += `export const ${name} = () => {
8
+ throw new TypeError("Constructor ${name} requires 'new'");
9
+ };
10
+
11
+ export const ${name}$constructor = (arg: any): ${name} => {
12
+ const out: ${name} = Porffor.allocate();
13
+ let len: i32 = 0;
14
+
15
+ const type: i32 = Porffor.rawType(arg);
16
+ if (Porffor.fastOr(
17
+ type == Porffor.TYPES.array,
18
+ type == Porffor.TYPES.string, type == Porffor.TYPES.bytestring,
19
+ type == Porffor.TYPES.set
20
+ )) {
21
+ let i: i32 = 0;
22
+ for (const x of arg) {
23
+ out[i++] = x;
24
+ }
25
+ len = i;
26
+ } else if (type == Porffor.TYPES.number) {
27
+ len = arg;
28
+ }
29
+
30
+ out.length = len;
31
+ return out;
32
+ };
33
+
34
+ export const __${name}_prototype_byteLength$get = (_this: ${name}) => {
35
+ return _this.length * ${name}.BYTES_PER_ELEMENT;
36
+ };
37
+
38
+ ${typedArrayFuncs.reduce((acc, x) => acc + x.replace('// @porf-typed-array\n', '').replaceAll('Array', name).replaceAll('any[]', name) + '\n\n', '')}
39
+ `;
40
+
41
+ constr('Uint8Array');
42
+ constr('Int8Array');
43
+ constr('Uint8ClampedArray');
44
+ constr('Uint16Array');
45
+ constr('Int16Array');
46
+ constr('Uint32Array');
47
+ constr('Int32Array');
48
+ constr('Float32Array');
49
+ constr('Float64Array');
50
+
51
+ return out;
52
+ };
@@ -160,6 +160,17 @@ export const BuiltinVars = function() {
160
160
  this.__performance_timeOrigin = [
161
161
  [ Opcodes.call, importedFuncs.timeOrigin ]
162
162
  ];
163
+
164
+
165
+ this.__Uint8Array_BYTES_PER_ELEMENT = number(1);
166
+ this.__Int8Array_BYTES_PER_ELEMENT = number(1);
167
+ this.__Uint8ClampedArray_BYTES_PER_ELEMENT = number(1);
168
+ this.__Uint16Array_BYTES_PER_ELEMENT = number(2);
169
+ this.__Int16Array_BYTES_PER_ELEMENT = number(2);
170
+ this.__Uint32Array_BYTES_PER_ELEMENT = number(4);
171
+ this.__Int32Array_BYTES_PER_ELEMENT = number(4);
172
+ this.__Float32Array_BYTES_PER_ELEMENT = number(4);
173
+ this.__Float64Array_BYTES_PER_ELEMENT = number(8);
163
174
  };
164
175
 
165
176
  export const BuiltinFuncs = function() {
@@ -184,6 +195,20 @@ export const BuiltinFuncs = function() {
184
195
  ]
185
196
  };
186
197
 
198
+ this['f64_**'] = this['i32_**'] = {
199
+ params: [ valtypeBinary, valtypeBinary ],
200
+ locals: [],
201
+ returns: [ valtypeBinary ],
202
+ returnType: TYPES.number,
203
+ wasm: (scope, { builtin }) => [
204
+ [ Opcodes.local_get, 0 ],
205
+ ...number(TYPES.number, Valtype.i32),
206
+ [ Opcodes.local_get, 1 ],
207
+ ...number(TYPES.number, Valtype.i32),
208
+ [ Opcodes.call, builtin('__Math_pow') ]
209
+ ]
210
+ };
211
+
187
212
  // add bitwise ops by converting operands to i32 first
188
213
  for (const [ char, op ] of [ ['&', Opcodes.i32_and], ['|', Opcodes.i32_or], ['^', Opcodes.i32_xor], ['<<', Opcodes.i32_shl], ['>>', Opcodes.i32_shr_s], ['>>>', Opcodes.i32_shr_u] ]) {
189
214
  this[`f64_${char}`] = {