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.
- package/AGENT.md +22 -0
- package/compiler/assemble.js +2 -13
- package/compiler/builtins/array.ts +48 -0
- package/compiler/builtins/regexp.ts +61 -14
- package/compiler/builtins/string.ts +70 -42
- package/compiler/builtins/string_f64.ts +116 -0
- package/compiler/builtins.js +30 -37
- package/compiler/builtins_precompiled.js +617 -557
- package/compiler/codegen.js +65 -111
- package/compiler/pgo.js +21 -43
- package/compiler/precompile.js +1 -1
- package/compiler/wrap.js +3 -8
- package/fuzz/index.js +1 -1
- package/package.json +1 -1
- package/runtime/debug.js +1 -1
- package/runtime/index.js +1 -1
- package/runtime/profile.js +1 -1
- package/runtime/repl.js +1 -1
- package/compiler/prototype.js +0 -407
@@ -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
|
};
|
package/compiler/builtins.js
CHANGED
@@ -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
|
9
|
-
|
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
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
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
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
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
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
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
|
|