porffor 0.58.18 → 0.59.0

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.
@@ -103,4 +103,120 @@ export const __String_fromCharCode = (...codes: any[]): bytestring|string => {
103
103
  }
104
104
 
105
105
  return out;
106
+ };
107
+
108
+ export const __String_fromCodePoint = (...codePoints: any[]): string => {
109
+ let out: string = Porffor.allocate();
110
+
111
+ const len: i32 = codePoints.length;
112
+ let outLength: i32 = 0;
113
+
114
+ for (let i: i32 = 0; i < len; i++) {
115
+ const codepoint: number = ecma262.ToNumber(codePoints[i]);
116
+
117
+ if (codepoint != (codepoint | 0)) {
118
+ throw new RangeError('Invalid code point');
119
+ }
120
+
121
+ // Check if code point is valid (0 to 0x10FFFF)
122
+ if (Porffor.fastOr(codepoint < 0, codepoint > 0x10FFFF)) {
123
+ throw new RangeError('Invalid code point');
124
+ }
125
+
126
+ if (codepoint <= 0xFFFF) {
127
+ // BMP code point - single 16-bit unit
128
+ outLength++;
129
+ } else {
130
+ // Supplementary code point - surrogate pair (2 units)
131
+ outLength += 2;
132
+ }
133
+ }
134
+
135
+ out.length = outLength;
136
+ let outIndex: i32 = 0;
137
+
138
+ for (let i: i32 = 0; i < len; i++) {
139
+ const codepoint: number = ecma262.ToNumber(codePoints[i]);
140
+
141
+ if (codepoint <= 0xFFFF) {
142
+ // BMP code point
143
+ Porffor.wasm.i32.store16(Porffor.wasm`local.get ${out}` + outIndex * 2, codepoint, 0, 4);
144
+ outIndex++;
145
+ } else {
146
+ // Supplementary code point - encode as surrogate pair
147
+ const cpMinusBase: i32 = codepoint - 0x10000;
148
+ const highSurrogate: i32 = 0xD800 + (cpMinusBase >> 10);
149
+ const lowSurrogate: i32 = 0xDC00 + (cpMinusBase & 0x3FF);
150
+
151
+ Porffor.wasm.i32.store16(Porffor.wasm`local.get ${out}` + outIndex * 2, highSurrogate, 0, 4);
152
+ Porffor.wasm.i32.store16(Porffor.wasm`local.get ${out}` + outIndex * 2, lowSurrogate, 0, 6);
153
+ outIndex += 2;
154
+ }
155
+ }
156
+
157
+ return out;
158
+ };
159
+
160
+ // in f64 file as returns NaN which returns 0 in i32
161
+ export const __String_prototype_charCodeAt = (_this: string, index: number) => {
162
+ const len: i32 = _this.length;
163
+
164
+ index |= 0;
165
+ if (Porffor.fastOr(index < 0, index >= len)) return NaN;
166
+
167
+ return Porffor.wasm.i32.load16_u(Porffor.wasm`local.get ${_this}` + index * 2, 0, 4);
168
+ };
169
+
170
+ export const __ByteString_prototype_charCodeAt = (_this: bytestring, index: number) => {
171
+ const len: i32 = _this.length;
172
+
173
+ index |= 0;
174
+ if (Porffor.fastOr(index < 0, index >= len)) return NaN;
175
+
176
+ return Porffor.wasm.i32.load8_u(Porffor.wasm`local.get ${_this}` + index, 0, 4);
177
+ };
178
+
179
+ // 22.1.2.4 String.raw ( template, ...substitutions )
180
+ // https://tc39.es/ecma262/#sec-string.raw
181
+ export const __String_raw = (template: any, ...substitutions: any[]): string => {
182
+ // 1. Let substitutionCount be the number of elements in substitutions.
183
+ const substitutionCount: i32 = substitutions.length;
184
+
185
+ // 2. Let cooked be ? ToObject(template).
186
+ // 3. Let literals be ? ToObject(? Get(cooked, "raw")).
187
+ const literals: any = template.raw;
188
+
189
+ // 4. Let literalCount be ? LengthOfArrayLike(literals).
190
+ const literalCount: number = ecma262.ToIntegerOrInfinity(Porffor.type(literals) == Porffor.TYPES.object ? (literals as object)['length'] : literals.length);
191
+
192
+ // 5. If literalCount ≤ 0, return the empty String.
193
+ if (literalCount <= 0) return '';
194
+
195
+ // 6. Let R be the empty String.
196
+ let R: string = '';
197
+
198
+ // 7. Let nextIndex be 0.
199
+ let nextIndex: i32 = 0;
200
+
201
+ // 8. Repeat,
202
+ while (true) {
203
+ // a. Let nextLiteralVal be ? Get(literals, ! ToString(𝔽(nextIndex))).
204
+ // b. Let nextLiteral be ? ToString(nextLiteralVal).
205
+ // c. Set R to the string-concatenation of R and nextLiteral.
206
+ R = __Porffor_concatStrings(R, literals[nextIndex]);
207
+
208
+ // d. If nextIndex + 1 = literalCount, return R.
209
+ if (nextIndex + 1 == literalCount) return R;
210
+
211
+ // e. If nextIndex < substitutionCount, then
212
+ if (nextIndex < substitutionCount) {
213
+ // i. Let nextSubVal be substitutions[nextIndex].
214
+ // ii. Let nextSub be ? ToString(nextSubVal).
215
+ // iii. Set R to the string-concatenation of R and nextSub.
216
+ R = __Porffor_concatStrings(R, substitutions[nextIndex]);
217
+ }
218
+
219
+ // f. Set nextIndex to nextIndex + 1.
220
+ nextIndex += 1;
221
+ }
106
222
  };
@@ -5,8 +5,11 @@ import { TYPES, TYPE_NAMES } from './types.js';
5
5
  import { number, unsignedLEB128 } from './encoding.js';
6
6
  import './prefs.js';
7
7
 
8
- export const importedFuncs = {};
9
- Object.defineProperty(importedFuncs, 'length', { configurable: true, writable: true, value: 0 });
8
+ export let importedFuncs;
9
+ export const setImports = (v = null) => {
10
+ importedFuncs = v ?? { length: 0 };
11
+ };
12
+ setImports();
10
13
 
11
14
  /**
12
15
  * Create an import function for the Porffor world to use.
@@ -18,51 +21,41 @@ Object.defineProperty(importedFuncs, 'length', { configurable: true, writable: t
18
21
  * @param {string} c - C source code to compile as import implementation
19
22
  */
20
23
  export const createImport = (name, params, returns, js = null, c = null) => {
21
- const lazy = () => {
22
- if (typeof params === 'function') params = params();
23
- if (typeof returns === 'function') returns = returns();
24
- if (typeof params === 'number') params = new Array(params).fill(valtypeBinary);
25
- if (typeof returns === 'number') returns = new Array(returns).fill(valtypeBinary);
26
- };
24
+ if (!globalThis.valtypeBinary) {
25
+ globalThis.valtype ??= Prefs.valtype ?? 'f64';
26
+ globalThis.valtypeBinary = Valtype[valtype];
27
+ }
28
+
29
+ if (typeof params === 'number') params = new Array(params).fill(valtypeBinary);
30
+ if (typeof returns === 'number') returns = new Array(returns).fill(valtypeBinary);
27
31
 
28
32
  if (name in importedFuncs) {
29
33
  // overwrite existing import
30
34
  const existing = importedFuncs[name];
31
- lazy();
32
-
33
- existing.params = params;
34
- existing.returns = returns;
35
- existing.js = js;
36
- existing.c = c;
35
+ const call = +existing;
36
+ const replacement = new Number(call);
37
+ replacement.name = name;
38
+ replacement.import = existing.import;
39
+ replacement.params = params;
40
+ replacement.returns = returns;
41
+ replacement.js = js;
42
+ replacement.c = c;
43
+
44
+ importedFuncs[name] = replacement;
37
45
  return;
38
46
  }
39
47
 
40
48
  const call = importedFuncs.length;
41
49
  const ident = String.fromCharCode(97 + importedFuncs.length);
42
- let obj;
43
- const get = () => {
44
- if (obj) return obj;
45
- lazy();
46
-
47
- obj = new Number(call);
48
- obj.name = name;
49
- obj.import = ident;
50
- obj.params = params;
51
- obj.returns = returns;
52
- obj.js = js;
53
- obj.c = c;
54
- return obj;
55
- };
56
50
 
57
- Object.defineProperty(importedFuncs, name, {
58
- get,
59
- configurable: true,
60
- enumerable: true
61
- });
62
- Object.defineProperty(importedFuncs, call, {
63
- get,
64
- configurable: true
65
- });
51
+ const obj = importedFuncs[name] = importedFuncs[call] = new Number(call);
52
+ obj.name = name;
53
+ obj.import = ident;
54
+ obj.params = params;
55
+ obj.returns = returns;
56
+ obj.js = js;
57
+ obj.c = c;
58
+
66
59
  importedFuncs.length = call + 1;
67
60
  };
68
61