porffor 0.17.0-9c7bd8098 → 0.17.0-a23029b3a

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.
@@ -718,108 +718,6 @@ export const __Porffor_date_write = (ptr: Date, val: number) => {
718
718
  Porffor.wasm.f64.store(ptr, val, 0, 0);
719
719
  };
720
720
 
721
- // 21.4.2.1 Date (...values)
722
- // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date
723
- export const Date$constructor = (v0: unknown, v1: unknown, v2: unknown, v3: unknown, v4: unknown, v5: unknown, v6: unknown): Date => {
724
- // todo: passing undefined to params should not act like no arg was passed
725
-
726
- // 2. Let numberOfArgs be the number of elements in values.
727
- // sorry.
728
- const numberOfArgs: i32 =
729
- (Porffor.rawType(v0) != Porffor.TYPES.undefined) +
730
- (Porffor.rawType(v1) != Porffor.TYPES.undefined) +
731
- (Porffor.rawType(v2) != Porffor.TYPES.undefined) +
732
- (Porffor.rawType(v3) != Porffor.TYPES.undefined) +
733
- (Porffor.rawType(v4) != Porffor.TYPES.undefined) +
734
- (Porffor.rawType(v5) != Porffor.TYPES.undefined) +
735
- (Porffor.rawType(v6) != Porffor.TYPES.undefined);
736
-
737
- let dv: number = 0;
738
-
739
- // 3. If numberOfArgs = 0, then
740
- if (numberOfArgs == 0) {
741
- // a. Let dv be the time value (UTC) identifying the current time.
742
- dv = __Date_now();
743
- } else if (numberOfArgs == 1) {
744
- // 4. Else if numberOfArgs = 1, the n
745
- // a. Let value be values[0].
746
- const value: any = v0;
747
-
748
- const valueType: i32 = Porffor.rawType(v0);
749
-
750
- let tv: number = 0;
751
-
752
- // b. If value is an Object and value has a [[DateValue]] internal slot, then
753
- if (valueType == Porffor.TYPES.date) {
754
- // i. Let tv be value.[[DateValue]].
755
- tv = __Porffor_date_read(value);
756
- } else {
757
- // c. Else,
758
- // ii. If v is a String, then
759
- if (Porffor.fastOr(valueType == Porffor.TYPES.string, valueType == Porffor.TYPES.bytestring)) {
760
- // 1. Assert: The next step never returns an abrupt completion because v is a String.
761
-
762
- // 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).
763
- tv = __Date_parse(value);
764
- } else {
765
- // iii. Else,
766
- // 1. Let tv be ? ToNumber(v).
767
- tv = Number(value);
768
- }
769
- }
770
-
771
- // d. Let dv be TimeClip(tv).
772
- dv = __ecma262_TimeClip(tv);
773
- } else {
774
- // 5. Else,
775
- // a. Assert: numberOfArgs ≥ 2.
776
-
777
- // b. Let y be ? ToNumber(values[0]).
778
- const y: number = Number(v0);
779
-
780
- // c. Let m be ? ToNumber(values[1]).
781
- const m: number = Number(v1);
782
-
783
- // d. If numberOfArgs > 2, let dt be ? ToNumber(values[2]); else let dt be 1𝔽.
784
- let dt: number = 1;
785
- if (numberOfArgs > 2) dt = Number(v2);
786
-
787
- // e. If numberOfArgs > 3, let h be ? ToNumber(values[3]); else let h be +0𝔽.
788
- let h: number = 0;
789
- if (numberOfArgs > 3) h = Number(v3);
790
-
791
- // f. If numberOfArgs > 4, let min be ? ToNumber(values[4]); else let min be +0𝔽.
792
- let min: number = 0;
793
- if (numberOfArgs > 4) min = Number(v4);
794
-
795
- // g. If numberOfArgs > 5, let s be ? ToNumber(values[5]); else let s be +0𝔽.
796
- let s: number = 0;
797
- if (numberOfArgs > 5) s = Number(v5);
798
-
799
- // h. If numberOfArgs > 6, let milli be ? ToNumber(values[6]); else let milli be +0𝔽.
800
- let milli: number = 0;
801
- if (numberOfArgs > 6) milli = Number(v6);
802
-
803
- // i. Let yr be MakeFullYear(y).
804
- const yr: number = __ecma262_MakeFullYear(y);
805
-
806
- // j. Let finalDate be MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli)).
807
- const finalDate: number = __ecma262_MakeDate(__ecma262_MakeDay(yr, m, dt), __ecma262_MakeTime(h, min, s, milli));
808
-
809
- // k. Let dv be TimeClip(UTC(finalDate)).
810
- dv = __ecma262_TimeClip(__ecma262_UTC(finalDate));
811
- }
812
-
813
- // 6. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%Date.prototype%", « [[DateValue]] »).
814
- const O: Date = __Porffor_date_allocate();
815
-
816
- // 7. Set O.[[DateValue]] to dv.
817
- __Porffor_date_write(O, dv);
818
-
819
- // 8. Return O.
820
- return O;
821
- };
822
-
823
721
 
824
722
  // 21.4.4 Properties of the Date Prototype Object
825
723
  // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-properties-of-the-date-prototype-object
@@ -2034,9 +1932,109 @@ export const __Date_prototype_valueOf = (_this: Date) => {
2034
1932
 
2035
1933
  // 21.4.2.1 Date (...values)
2036
1934
  // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date
2037
- export const Date = (): bytestring => {
1935
+ export const Date = function (v0: unknown, v1: unknown, v2: unknown, v3: unknown, v4: unknown, v5: unknown, v6: unknown): bytestring|Date {
2038
1936
  // 1. If NewTarget is undefined, then
2039
- // a. Let now be the time value (UTC) identifying the current time.
2040
- // b. Return ToDateString(now).
2041
- return __ecma262_ToDateString(__Date_now());
1937
+ if (!new.target) {
1938
+ // a. Let now be the time value (UTC) identifying the current time.
1939
+ // b. Return ToDateString(now).
1940
+ return __ecma262_ToDateString(__Date_now());
1941
+ }
1942
+
1943
+ // todo: passing undefined to params should not act like no arg was passed
1944
+
1945
+ // 2. Let numberOfArgs be the number of elements in values.
1946
+ // sorry.
1947
+ const numberOfArgs: i32 =
1948
+ (Porffor.rawType(v0) != Porffor.TYPES.undefined) +
1949
+ (Porffor.rawType(v1) != Porffor.TYPES.undefined) +
1950
+ (Porffor.rawType(v2) != Porffor.TYPES.undefined) +
1951
+ (Porffor.rawType(v3) != Porffor.TYPES.undefined) +
1952
+ (Porffor.rawType(v4) != Porffor.TYPES.undefined) +
1953
+ (Porffor.rawType(v5) != Porffor.TYPES.undefined) +
1954
+ (Porffor.rawType(v6) != Porffor.TYPES.undefined);
1955
+
1956
+ let dv: number = 0;
1957
+
1958
+ // 3. If numberOfArgs = 0, then
1959
+ if (numberOfArgs == 0) {
1960
+ // a. Let dv be the time value (UTC) identifying the current time.
1961
+ dv = __Date_now();
1962
+ } else if (numberOfArgs == 1) {
1963
+ // 4. Else if numberOfArgs = 1, the n
1964
+ // a. Let value be values[0].
1965
+ const value: any = v0;
1966
+
1967
+ const valueType: i32 = Porffor.rawType(v0);
1968
+
1969
+ let tv: number = 0;
1970
+
1971
+ // b. If value is an Object and value has a [[DateValue]] internal slot, then
1972
+ if (valueType == Porffor.TYPES.date) {
1973
+ // i. Let tv be value.[[DateValue]].
1974
+ tv = __Porffor_date_read(value);
1975
+ } else {
1976
+ // c. Else,
1977
+ // ii. If v is a String, then
1978
+ if (Porffor.fastOr(valueType == Porffor.TYPES.string, valueType == Porffor.TYPES.bytestring)) {
1979
+ // 1. Assert: The next step never returns an abrupt completion because v is a String.
1980
+
1981
+ // 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).
1982
+ tv = __Date_parse(value);
1983
+ } else {
1984
+ // iii. Else,
1985
+ // 1. Let tv be ? ToNumber(v).
1986
+ tv = Number(value);
1987
+ }
1988
+ }
1989
+
1990
+ // d. Let dv be TimeClip(tv).
1991
+ dv = __ecma262_TimeClip(tv);
1992
+ } else {
1993
+ // 5. Else,
1994
+ // a. Assert: numberOfArgs ≥ 2.
1995
+
1996
+ // b. Let y be ? ToNumber(values[0]).
1997
+ const y: number = Number(v0);
1998
+
1999
+ // c. Let m be ? ToNumber(values[1]).
2000
+ const m: number = Number(v1);
2001
+
2002
+ // d. If numberOfArgs > 2, let dt be ? ToNumber(values[2]); else let dt be 1𝔽.
2003
+ let dt: number = 1;
2004
+ if (numberOfArgs > 2) dt = Number(v2);
2005
+
2006
+ // e. If numberOfArgs > 3, let h be ? ToNumber(values[3]); else let h be +0𝔽.
2007
+ let h: number = 0;
2008
+ if (numberOfArgs > 3) h = Number(v3);
2009
+
2010
+ // f. If numberOfArgs > 4, let min be ? ToNumber(values[4]); else let min be +0𝔽.
2011
+ let min: number = 0;
2012
+ if (numberOfArgs > 4) min = Number(v4);
2013
+
2014
+ // g. If numberOfArgs > 5, let s be ? ToNumber(values[5]); else let s be +0𝔽.
2015
+ let s: number = 0;
2016
+ if (numberOfArgs > 5) s = Number(v5);
2017
+
2018
+ // h. If numberOfArgs > 6, let milli be ? ToNumber(values[6]); else let milli be +0𝔽.
2019
+ let milli: number = 0;
2020
+ if (numberOfArgs > 6) milli = Number(v6);
2021
+
2022
+ // i. Let yr be MakeFullYear(y).
2023
+ const yr: number = __ecma262_MakeFullYear(y);
2024
+
2025
+ // j. Let finalDate be MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli)).
2026
+ const finalDate: number = __ecma262_MakeDate(__ecma262_MakeDay(yr, m, dt), __ecma262_MakeTime(h, min, s, milli));
2027
+
2028
+ // k. Let dv be TimeClip(UTC(finalDate)).
2029
+ dv = __ecma262_TimeClip(__ecma262_UTC(finalDate));
2030
+ }
2031
+
2032
+ // 6. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%Date.prototype%", « [[DateValue]] »).
2033
+ const O: Date = __Porffor_date_allocate();
2034
+
2035
+ // 7. Set O.[[DateValue]] to dv.
2036
+ __Porffor_date_write(O, dv);
2037
+
2038
+ // 8. Return O.
2039
+ return O;
2042
2040
  };
@@ -1,11 +1,8 @@
1
1
  export default () => {
2
2
  let out = '';
3
3
 
4
- const error = name => out += `export const ${name} = (message: bytestring) => {
5
- return {};
6
- };
7
-
8
- export const ${name}$constructor = (message: bytestring) => {
4
+ const error = name => out += `export const ${name} = function (message: bytestring) {
5
+ new.target;
9
6
  return {};
10
7
  };`;
11
8
 
@@ -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 => {
@@ -8,6 +8,7 @@ memory.grow 0
8
8
  i32.const 65536
9
9
  i32.mul
10
10
  i32.from_u
11
+ i32.const 0
11
12
  return`;
12
13
  };
13
14
 
@@ -163,22 +164,13 @@ export const __Set_prototype_clear = (_this: Set) => {
163
164
  Porffor.wasm.i32.store(_this, 0, 0, 0);
164
165
  };
165
166
 
166
- export const Set = () => {
167
- throw new TypeError("Constructor Set requires 'new'");
168
- };
167
+ export const Set = function (iterable: any): any {
168
+ if (!new.target) throw new TypeError("Constructor Set requires 'new'");
169
169
 
170
- export const Set$constructor = (iterable: any): Set => {
171
170
  const out: Set = __Porffor_allocate();
172
171
 
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
- }
172
+ if (Porffor.rawType(iterable) != Porffor.TYPES.undefined) for (const x of iterable) {
173
+ __Set_prototype_add(out, x);
182
174
  }
183
175
 
184
176
  return out;
@@ -189,9 +181,14 @@ export const __Set_prototype_union = (_this: Set, other: any) => {
189
181
  throw new TypeError("Set.prototype.union\'s \'other\' argument must be a Set");
190
182
  }
191
183
 
192
- const out: Set = Set$constructor(_this);
184
+ const out: Set = new Set(_this);
193
185
  for (const x of other) {
194
186
  out.add(x);
195
187
  }
196
188
  return out;
197
189
  };
190
+
191
+ export const __Set_prototype_toString = (_this: Set) => {
192
+ const out: bytestring = '[object Set]';
193
+ return out;
194
+ };
@@ -1,10 +1,8 @@
1
- // todo: support non-bytestring properly
2
- export const String = (value: any): bytestring => {
3
- if (Porffor.rawType(value) == Porffor.TYPES.symbol) return __Symbol_prototype_toString(value);
4
- return __ecma262_ToString(value);
5
- };
1
+ import type {} from './porffor.d.ts';
6
2
 
3
+ // todo: support non-bytestring properly
7
4
  // todo: support constructor/string objects properly
8
- export const String$constructor = (value: any): bytestring => {
5
+ export const String = function (value: any): bytestring {
6
+ if (!new.target && Porffor.rawType(value) == Porffor.TYPES.symbol) return __Symbol_prototype_toString(value);
9
7
  return __ecma262_ToString(value);
10
8
  };
@@ -17,7 +17,8 @@ export const __Porffor_symbol_descStore = (op: boolean, value: any): any => {
17
17
 
18
18
  export const Symbol = (description: any): Symbol => {
19
19
  // 1-based so always truthy as numeric value
20
- return __Porffor_symbol_descStore(true, description) + 1;
20
+ const ptr: Symbol = __Porffor_symbol_descStore(true, description) + 1;
21
+ return ptr;
21
22
  };
22
23
 
23
24
  export const __Symbol_prototype_description$get = (_this: Symbol) => {
@@ -0,0 +1,94 @@
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} = function (arg: any): ${name} {
8
+ if (!new.target) throw new TypeError("Constructor ${name} requires 'new'");
9
+
10
+ const out: ${name} = Porffor.allocate();
11
+ let len: i32 = 0;
12
+
13
+ const type: i32 = Porffor.rawType(arg);
14
+ if (Porffor.fastOr(
15
+ type == Porffor.TYPES.array,
16
+ type == Porffor.TYPES.string, type == Porffor.TYPES.bytestring,
17
+ type == Porffor.TYPES.set
18
+ )) {
19
+ let i: i32 = 0;
20
+ for (const x of arg) {
21
+ out[i++] = x;
22
+ }
23
+ len = i;
24
+ } else if (type == Porffor.TYPES.number) {
25
+ len = arg;
26
+ }
27
+
28
+ out.length = len;
29
+ return out;
30
+ };
31
+
32
+ export const __${name}_prototype_byteLength$get = (_this: ${name}) => {
33
+ return _this.length * ${name}.BYTES_PER_ELEMENT;
34
+ };
35
+
36
+ export const __${name}_prototype_at = (_this: ${name}, index: number) => {
37
+ const len: i32 = _this.length;
38
+ index |= 0;
39
+ if (index < 0) {
40
+ index = len + index;
41
+ if (index < 0) return undefined;
42
+ }
43
+ if (index >= len) return undefined;
44
+
45
+ return _this[index];
46
+ };
47
+
48
+ export const __${name}_prototype_slice = (_this: ${name}, start: number, end: number) => {
49
+ const len: i32 = _this.length;
50
+ if (Porffor.rawType(end) == Porffor.TYPES.undefined) end = len;
51
+
52
+ start |= 0;
53
+ end |= 0;
54
+
55
+ if (start < 0) {
56
+ start = len + start;
57
+ if (start < 0) start = 0;
58
+ }
59
+ if (start > len) start = len;
60
+ if (end < 0) {
61
+ end = len + end;
62
+ if (end < 0) end = 0;
63
+ }
64
+ if (end > len) end = len;
65
+
66
+ let out: ${name} = Porffor.allocate();
67
+
68
+ if (start > end) return out;
69
+
70
+ let i: i32 = start;
71
+ let j: i32 = 0;
72
+ while (i < end) {
73
+ out[j++] = _this[i++];
74
+ }
75
+
76
+ out.length = end - start;
77
+ return out;
78
+ };
79
+
80
+ ${typedArrayFuncs.reduce((acc, x) => acc + x.replace('// @porf-typed-array\n', '').replaceAll('Array', name).replaceAll('any[]', name) + '\n\n', '')}
81
+ `;
82
+
83
+ constr('Uint8Array');
84
+ constr('Int8Array');
85
+ constr('Uint8ClampedArray');
86
+ constr('Uint16Array');
87
+ constr('Int16Array');
88
+ constr('Uint32Array');
89
+ constr('Int32Array');
90
+ constr('Float32Array');
91
+ constr('Float64Array');
92
+
93
+ return out;
94
+ };
@@ -1,4 +1,5 @@
1
1
  // general widely used ecma262/spec functions
2
+ import type {} from './porffor.d.ts';
2
3
 
3
4
  // 7.1.5 ToIntegerOrInfinity (argument)
4
5
  // https://tc39.es/ecma262/#sec-tointegerorinfinity
@@ -160,6 +160,16 @@ export const BuiltinVars = function() {
160
160
  this.__performance_timeOrigin = [
161
161
  [ Opcodes.call, importedFuncs.timeOrigin ]
162
162
  ];
163
+
164
+ this.__Uint8Array_BYTES_PER_ELEMENT = number(1);
165
+ this.__Int8Array_BYTES_PER_ELEMENT = number(1);
166
+ this.__Uint8ClampedArray_BYTES_PER_ELEMENT = number(1);
167
+ this.__Uint16Array_BYTES_PER_ELEMENT = number(2);
168
+ this.__Int16Array_BYTES_PER_ELEMENT = number(2);
169
+ this.__Uint32Array_BYTES_PER_ELEMENT = number(4);
170
+ this.__Int32Array_BYTES_PER_ELEMENT = number(4);
171
+ this.__Float32Array_BYTES_PER_ELEMENT = number(4);
172
+ this.__Float64Array_BYTES_PER_ELEMENT = number(8);
163
173
  };
164
174
 
165
175
  export const BuiltinFuncs = function() {
@@ -184,6 +194,21 @@ export const BuiltinFuncs = function() {
184
194
  ]
185
195
  };
186
196
 
197
+ this['f64_**'] = this['i32_**'] = {
198
+ params: [ valtypeBinary, valtypeBinary ],
199
+ locals: [],
200
+ returns: [ valtypeBinary ],
201
+ returnType: TYPES.number,
202
+ wasm: (scope, { builtin }) => [
203
+ [ Opcodes.local_get, 0 ],
204
+ ...number(TYPES.number, Valtype.i32),
205
+ [ Opcodes.local_get, 1 ],
206
+ ...number(TYPES.number, Valtype.i32),
207
+ [ Opcodes.call, builtin('__Math_pow') ],
208
+ [ Opcodes.drop ],
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}`] = {