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
package/compiler/prototype.js
DELETED
@@ -1,407 +0,0 @@
|
|
1
|
-
import { Opcodes, Blocktype, Valtype, ValtypeSize } from './wasmSpec.js';
|
2
|
-
import { number } from './encoding.js';
|
3
|
-
import { UNDEFINED } from './builtins.js';
|
4
|
-
import { TYPES } from './types.js';
|
5
|
-
import './prefs.js';
|
6
|
-
|
7
|
-
// todo: turn these into built-ins once arrays and these become less hacky
|
8
|
-
|
9
|
-
export const PrototypeFuncs = function() {
|
10
|
-
const noUnlikelyChecks = Prefs.funsafeNoUnlikelyProtoChecks;
|
11
|
-
|
12
|
-
let zeroChecks;
|
13
|
-
if (Prefs.zeroChecks) zeroChecks = Prefs.zeroChecks.split(',').reduce((acc, x) => { acc[x.toLowerCase()] = true; return acc; }, {});
|
14
|
-
else zeroChecks = {};
|
15
|
-
|
16
|
-
this[TYPES.array] = {
|
17
|
-
pop: ({ pointer, length, iTmp, unusedValue, setType }) => [
|
18
|
-
// if length == 0, noop
|
19
|
-
...length.getCachedI32(),
|
20
|
-
[ Opcodes.i32_eqz ],
|
21
|
-
[ Opcodes.if, Blocktype.void ],
|
22
|
-
...(unusedValue() ? [] : [
|
23
|
-
number(UNDEFINED),
|
24
|
-
...setType(TYPES.undefined)
|
25
|
-
]),
|
26
|
-
[ Opcodes.br, 1 ],
|
27
|
-
[ Opcodes.end ],
|
28
|
-
|
29
|
-
// todo: should we store 0/undefined in "removed" element?
|
30
|
-
|
31
|
-
// decrement length by 1
|
32
|
-
...length.setI32([
|
33
|
-
...length.getCachedI32(),
|
34
|
-
number(1, Valtype.i32),
|
35
|
-
[ Opcodes.i32_sub ],
|
36
|
-
|
37
|
-
...(unusedValue() ? [] : [
|
38
|
-
...length.setCachedI32(),
|
39
|
-
...length.getCachedI32(),
|
40
|
-
])
|
41
|
-
]),
|
42
|
-
|
43
|
-
// load last element
|
44
|
-
...(unusedValue() ? [] : [
|
45
|
-
...length.getCachedI32(),
|
46
|
-
number(ValtypeSize[valtype] + 1, Valtype.i32),
|
47
|
-
[ Opcodes.i32_mul ],
|
48
|
-
|
49
|
-
...pointer,
|
50
|
-
[ Opcodes.i32_add ],
|
51
|
-
[ Opcodes.local_set, iTmp ],
|
52
|
-
|
53
|
-
[ Opcodes.local_get, iTmp ],
|
54
|
-
[ Opcodes.load, 0, ValtypeSize.i32 ],
|
55
|
-
|
56
|
-
[ Opcodes.local_get, iTmp ],
|
57
|
-
[ Opcodes.i32_load8_u, 0, ValtypeSize.i32 + ValtypeSize[valtype] ],
|
58
|
-
...setType()
|
59
|
-
])
|
60
|
-
],
|
61
|
-
|
62
|
-
shift: ({ pointer, length, setType }) => [
|
63
|
-
// if length == 0, noop
|
64
|
-
...length.getCachedI32(),
|
65
|
-
[ Opcodes.i32_eqz ],
|
66
|
-
[ Opcodes.if, Blocktype.void ],
|
67
|
-
number(UNDEFINED),
|
68
|
-
...setType(TYPES.undefined),
|
69
|
-
[ Opcodes.br, 1 ],
|
70
|
-
[ Opcodes.end ],
|
71
|
-
|
72
|
-
// todo: should we store 0/undefined in "removed" element?
|
73
|
-
|
74
|
-
// decrement length by 1
|
75
|
-
...length.setI32([
|
76
|
-
...length.getCachedI32(),
|
77
|
-
number(1, Valtype.i32),
|
78
|
-
[ Opcodes.i32_sub ],
|
79
|
-
|
80
|
-
...length.setCachedI32(),
|
81
|
-
...length.getCachedI32(),
|
82
|
-
]),
|
83
|
-
|
84
|
-
// load first element
|
85
|
-
// todo/perf: unusedValue opt
|
86
|
-
...pointer,
|
87
|
-
[ Opcodes.load, 0, ValtypeSize.i32 ],
|
88
|
-
|
89
|
-
...pointer,
|
90
|
-
[ Opcodes.i32_load8_u, 0, ValtypeSize.i32 + ValtypeSize[valtype] ],
|
91
|
-
...setType(),
|
92
|
-
|
93
|
-
// offset page by -1 ind
|
94
|
-
// number(pointer + ValtypeSize.i32, Valtype.i32), // dst = base array index + length size
|
95
|
-
// number(pointer + ValtypeSize.i32 + ValtypeSize[valtype], Valtype.i32), // src = base array index + length size + an index
|
96
|
-
// number(pageSize - ValtypeSize.i32 - ValtypeSize[valtype], Valtype.i32), // size = PageSize - length size - an index
|
97
|
-
// [ ...Opcodes.memory_copy, 0x00, 0x00 ]
|
98
|
-
|
99
|
-
// offset all elements by -1 ind
|
100
|
-
|
101
|
-
// dst = base array index + length size
|
102
|
-
number(ValtypeSize.i32, Valtype.i32),
|
103
|
-
...pointer,
|
104
|
-
[ Opcodes.i32_add ],
|
105
|
-
|
106
|
-
// src = base array index + length size + an index
|
107
|
-
number(ValtypeSize.i32 + ValtypeSize[valtype] + 1, Valtype.i32),
|
108
|
-
...pointer,
|
109
|
-
[ Opcodes.i32_add ],
|
110
|
-
|
111
|
-
// size = new length * sizeof element
|
112
|
-
...length.getCachedI32(),
|
113
|
-
number(ValtypeSize[valtype] + 1, Valtype.i32),
|
114
|
-
[ Opcodes.i32_mul ],
|
115
|
-
[ ...Opcodes.memory_copy, 0x00, 0x00 ]
|
116
|
-
|
117
|
-
// move pointer + sizeof element
|
118
|
-
// ...pointer.get(),
|
119
|
-
// number(ValtypeSize[valtype], Valtype.i32),
|
120
|
-
// [ Opcodes.i32_add ],
|
121
|
-
// ...pointer.set(),
|
122
|
-
|
123
|
-
// // write length - 1 in new address
|
124
|
-
// ...length.setI32([
|
125
|
-
// ...length.getCachedI32(),
|
126
|
-
// number(1, Valtype.i32),
|
127
|
-
// [ Opcodes.i32_sub ]
|
128
|
-
// ]),
|
129
|
-
]
|
130
|
-
};
|
131
|
-
|
132
|
-
this[TYPES.array].pop.local = Valtype.i32;
|
133
|
-
|
134
|
-
this[TYPES.string] = {
|
135
|
-
at: ({ pointer, length, arg, iTmp, iTmp2, alloc, setType }) => [
|
136
|
-
// setup out string and use pointer for store
|
137
|
-
...alloc(8),
|
138
|
-
[ Opcodes.local_tee, iTmp2 ],
|
139
|
-
|
140
|
-
// out.length = 1
|
141
|
-
[ Opcodes.local_get, iTmp2 ],
|
142
|
-
number(1, Valtype.i32),
|
143
|
-
[ Opcodes.i32_store, 0, 0 ],
|
144
|
-
|
145
|
-
...arg,
|
146
|
-
Opcodes.i32_to_u,
|
147
|
-
[ Opcodes.local_tee, iTmp ],
|
148
|
-
|
149
|
-
// if index < 0: access index + array length
|
150
|
-
number(0, Valtype.i32),
|
151
|
-
[ Opcodes.i32_lt_s ],
|
152
|
-
[ Opcodes.if, Blocktype.void ],
|
153
|
-
[ Opcodes.local_get, iTmp ],
|
154
|
-
...length.getCachedI32(),
|
155
|
-
[ Opcodes.i32_add ],
|
156
|
-
[ Opcodes.local_set, iTmp ],
|
157
|
-
[ Opcodes.end ],
|
158
|
-
|
159
|
-
// if still < 0 or >= length: return undefined
|
160
|
-
[ Opcodes.local_get, iTmp ],
|
161
|
-
number(0, Valtype.i32),
|
162
|
-
[ Opcodes.i32_lt_s ],
|
163
|
-
|
164
|
-
[ Opcodes.local_get, iTmp ],
|
165
|
-
...length.getCachedI32(),
|
166
|
-
[ Opcodes.i32_ge_s ],
|
167
|
-
[ Opcodes.i32_or ],
|
168
|
-
|
169
|
-
[ Opcodes.if, Blocktype.void ],
|
170
|
-
number(UNDEFINED),
|
171
|
-
...setType(TYPES.undefined),
|
172
|
-
[ Opcodes.br, 1 ],
|
173
|
-
[ Opcodes.end ],
|
174
|
-
|
175
|
-
[ Opcodes.local_get, iTmp ],
|
176
|
-
number(ValtypeSize.i16, Valtype.i32),
|
177
|
-
[ Opcodes.i32_mul ],
|
178
|
-
|
179
|
-
...pointer,
|
180
|
-
[ Opcodes.i32_add ],
|
181
|
-
|
182
|
-
// load current string ind {arg}
|
183
|
-
[ Opcodes.i32_load16_u, Math.log2(ValtypeSize.i16) - 1, ValtypeSize.i32 ],
|
184
|
-
|
185
|
-
// store to new string ind 0
|
186
|
-
[ Opcodes.i32_store16, Math.log2(ValtypeSize.i16) - 1, ValtypeSize.i32 ],
|
187
|
-
|
188
|
-
// return new string (pointer)
|
189
|
-
[ Opcodes.local_get, iTmp2 ],
|
190
|
-
Opcodes.i32_from_u,
|
191
|
-
|
192
|
-
...setType(TYPES.string)
|
193
|
-
],
|
194
|
-
|
195
|
-
// todo: out of bounds properly
|
196
|
-
charAt: ({ pointer, arg, iTmp, alloc, setType }) => [
|
197
|
-
// setup out string and use as pointer for store
|
198
|
-
...alloc(8),
|
199
|
-
[ Opcodes.local_tee, iTmp ],
|
200
|
-
|
201
|
-
// out.length = 1
|
202
|
-
[ Opcodes.local_get, iTmp ],
|
203
|
-
number(1, Valtype.i32),
|
204
|
-
[ Opcodes.i32_store, 0, 0 ],
|
205
|
-
|
206
|
-
...arg,
|
207
|
-
Opcodes.i32_to,
|
208
|
-
|
209
|
-
number(ValtypeSize.i16, Valtype.i32),
|
210
|
-
[ Opcodes.i32_mul ],
|
211
|
-
|
212
|
-
...pointer,
|
213
|
-
[ Opcodes.i32_add ],
|
214
|
-
|
215
|
-
// load current string ind {arg}
|
216
|
-
[ Opcodes.i32_load16_u, Math.log2(ValtypeSize.i16) - 1, ValtypeSize.i32 ],
|
217
|
-
|
218
|
-
// store to new string ind 0
|
219
|
-
[ Opcodes.i32_store16, Math.log2(ValtypeSize.i16) - 1, ValtypeSize.i32 ],
|
220
|
-
|
221
|
-
// return new string (page)
|
222
|
-
[ Opcodes.local_get, iTmp ],
|
223
|
-
Opcodes.i32_from_u,
|
224
|
-
|
225
|
-
...setType(TYPES.string)
|
226
|
-
],
|
227
|
-
|
228
|
-
charCodeAt: ({ pointer, length, arg, iTmp, setType }) => [
|
229
|
-
...setType(TYPES.number),
|
230
|
-
|
231
|
-
...arg,
|
232
|
-
Opcodes.i32_to,
|
233
|
-
|
234
|
-
...(zeroChecks.charcodeat ? [] : [
|
235
|
-
[ Opcodes.local_set, iTmp ],
|
236
|
-
|
237
|
-
// index < 0
|
238
|
-
...(noUnlikelyChecks ? [] : [
|
239
|
-
[ Opcodes.local_get, iTmp ],
|
240
|
-
number(0, Valtype.i32),
|
241
|
-
[ Opcodes.i32_lt_s ],
|
242
|
-
]),
|
243
|
-
|
244
|
-
// index >= length
|
245
|
-
[ Opcodes.local_get, iTmp ],
|
246
|
-
...length.getCachedI32(),
|
247
|
-
[ Opcodes.i32_ge_s ],
|
248
|
-
|
249
|
-
...(noUnlikelyChecks ? [] : [ [ Opcodes.i32_or ] ]),
|
250
|
-
[ Opcodes.if, Blocktype.void ],
|
251
|
-
number(valtype === 'i32' ? -1 : NaN),
|
252
|
-
[ Opcodes.br, 1 ],
|
253
|
-
[ Opcodes.end ],
|
254
|
-
|
255
|
-
[ Opcodes.local_get, iTmp ],
|
256
|
-
]),
|
257
|
-
|
258
|
-
number(ValtypeSize.i16, Valtype.i32),
|
259
|
-
[ Opcodes.i32_mul ],
|
260
|
-
|
261
|
-
...pointer,
|
262
|
-
[ Opcodes.i32_add ],
|
263
|
-
|
264
|
-
// load current string ind {arg}
|
265
|
-
[ Opcodes.i32_load16_u, Math.log2(ValtypeSize.i16) - 1, ValtypeSize.i32 ],
|
266
|
-
Opcodes.i32_from_u
|
267
|
-
]
|
268
|
-
};
|
269
|
-
|
270
|
-
this[TYPES.string].at.local = Valtype.i32;
|
271
|
-
this[TYPES.string].at.local2 = Valtype.i32;
|
272
|
-
this[TYPES.string].charAt.local = Valtype.i32;
|
273
|
-
this[TYPES.string].charCodeAt.local = Valtype.i32;
|
274
|
-
|
275
|
-
this[TYPES.bytestring] = {
|
276
|
-
at: ({ pointer, length, arg, iTmp, iTmp2, alloc, setType }) => [
|
277
|
-
// setup out string and use pointer for store
|
278
|
-
...alloc(8),
|
279
|
-
[ Opcodes.local_tee, iTmp2 ],
|
280
|
-
|
281
|
-
// out.length = 1
|
282
|
-
[ Opcodes.local_get, iTmp2 ],
|
283
|
-
number(1, Valtype.i32),
|
284
|
-
[ Opcodes.i32_store, 0, 0 ],
|
285
|
-
|
286
|
-
...arg,
|
287
|
-
Opcodes.i32_to_u,
|
288
|
-
[ Opcodes.local_tee, iTmp ],
|
289
|
-
|
290
|
-
// if index < 0: access index + array length
|
291
|
-
number(0, Valtype.i32),
|
292
|
-
[ Opcodes.i32_lt_s ],
|
293
|
-
[ Opcodes.if, Blocktype.void ],
|
294
|
-
[ Opcodes.local_get, iTmp ],
|
295
|
-
...length.getCachedI32(),
|
296
|
-
[ Opcodes.i32_add ],
|
297
|
-
[ Opcodes.local_set, iTmp ],
|
298
|
-
[ Opcodes.end ],
|
299
|
-
|
300
|
-
// if still < 0 or >= length: return undefined
|
301
|
-
[ Opcodes.local_get, iTmp ],
|
302
|
-
number(0, Valtype.i32),
|
303
|
-
[ Opcodes.i32_lt_s ],
|
304
|
-
|
305
|
-
[ Opcodes.local_get, iTmp ],
|
306
|
-
...length.getCachedI32(),
|
307
|
-
[ Opcodes.i32_ge_s ],
|
308
|
-
[ Opcodes.i32_or ],
|
309
|
-
|
310
|
-
[ Opcodes.if, Blocktype.void ],
|
311
|
-
number(UNDEFINED),
|
312
|
-
...setType(TYPES.undefined),
|
313
|
-
[ Opcodes.br, 1 ],
|
314
|
-
[ Opcodes.end ],
|
315
|
-
|
316
|
-
[ Opcodes.local_get, iTmp ],
|
317
|
-
|
318
|
-
...pointer,
|
319
|
-
[ Opcodes.i32_add ],
|
320
|
-
|
321
|
-
// load current string ind {arg}
|
322
|
-
[ Opcodes.i32_load8_u, 0, ValtypeSize.i32 ],
|
323
|
-
|
324
|
-
// store to new string ind 0
|
325
|
-
[ Opcodes.i32_store8, 0, ValtypeSize.i32 ],
|
326
|
-
|
327
|
-
// return new string (pointer)
|
328
|
-
[ Opcodes.local_get, iTmp2 ],
|
329
|
-
Opcodes.i32_from_u,
|
330
|
-
|
331
|
-
...setType(TYPES.bytestring)
|
332
|
-
],
|
333
|
-
|
334
|
-
// todo: out of bounds properly
|
335
|
-
charAt: ({ pointer, arg, iTmp, alloc, setType }) => [
|
336
|
-
// setup out string and use as pointer for store
|
337
|
-
...alloc(8),
|
338
|
-
[ Opcodes.local_tee, iTmp ],
|
339
|
-
|
340
|
-
// out.length = 1
|
341
|
-
[ Opcodes.local_get, iTmp ],
|
342
|
-
number(1, Valtype.i32),
|
343
|
-
[ Opcodes.i32_store, 0, 0 ],
|
344
|
-
|
345
|
-
...arg,
|
346
|
-
Opcodes.i32_to,
|
347
|
-
|
348
|
-
...pointer,
|
349
|
-
[ Opcodes.i32_add ],
|
350
|
-
|
351
|
-
// load current string ind {arg}
|
352
|
-
[ Opcodes.i32_load8_u, 0, ValtypeSize.i32 ],
|
353
|
-
|
354
|
-
// store to new string ind 0
|
355
|
-
[ Opcodes.i32_store8, 0, ValtypeSize.i32 ],
|
356
|
-
|
357
|
-
// return new string (page)
|
358
|
-
[ Opcodes.local_get, iTmp ],
|
359
|
-
Opcodes.i32_from_u,
|
360
|
-
|
361
|
-
...setType(TYPES.bytestring)
|
362
|
-
],
|
363
|
-
|
364
|
-
charCodeAt: ({ pointer, length, arg, iTmp, setType }) => [
|
365
|
-
...setType(TYPES.number),
|
366
|
-
|
367
|
-
...arg,
|
368
|
-
Opcodes.i32_to,
|
369
|
-
|
370
|
-
...(zeroChecks.charcodeat ? [] : [
|
371
|
-
[ Opcodes.local_set, iTmp ],
|
372
|
-
|
373
|
-
// index < 0
|
374
|
-
...(noUnlikelyChecks ? [] : [
|
375
|
-
[ Opcodes.local_get, iTmp ],
|
376
|
-
number(0, Valtype.i32),
|
377
|
-
[ Opcodes.i32_lt_s ],
|
378
|
-
]),
|
379
|
-
|
380
|
-
// index >= length
|
381
|
-
[ Opcodes.local_get, iTmp ],
|
382
|
-
...length.getCachedI32(),
|
383
|
-
[ Opcodes.i32_ge_s ],
|
384
|
-
|
385
|
-
...(noUnlikelyChecks ? [] : [ [ Opcodes.i32_or ] ]),
|
386
|
-
[ Opcodes.if, Blocktype.void ],
|
387
|
-
number(valtype === 'i32' ? -1 : NaN),
|
388
|
-
[ Opcodes.br, 1 ],
|
389
|
-
[ Opcodes.end ],
|
390
|
-
|
391
|
-
[ Opcodes.local_get, iTmp ],
|
392
|
-
]),
|
393
|
-
|
394
|
-
...pointer,
|
395
|
-
[ Opcodes.i32_add ],
|
396
|
-
|
397
|
-
// load current string ind {arg}
|
398
|
-
[ Opcodes.i32_load8_u, 0, ValtypeSize.i32 ],
|
399
|
-
Opcodes.i32_from_u
|
400
|
-
]
|
401
|
-
};
|
402
|
-
|
403
|
-
this[TYPES.bytestring].at.local = Valtype.i32;
|
404
|
-
this[TYPES.bytestring].at.local2 = Valtype.i32;
|
405
|
-
this[TYPES.bytestring].charAt.local = Valtype.i32;
|
406
|
-
this[TYPES.bytestring].charCodeAt.local = Valtype.i32;
|
407
|
-
};
|