porffor 0.34.10 → 0.34.12
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/README.md +2 -4
- package/compiler/builtins/string.ts +40 -3
- package/compiler/builtins_precompiled.js +14 -4
- package/compiler/prototype.js +0 -87
- package/package.json +1 -1
- package/runner/index.js +1 -1
package/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# Porffor <sup><sub>/ˈpɔrfɔr/ *(poor-for)*</sup></sub>
|
2
|
-
A from-scratch experimental **AOT** optimizing JS/TS -> Wasm/C engine/compiler/runtime in JS.
|
2
|
+
A from-scratch experimental **AOT** optimizing JS/TS -> Wasm/C engine/compiler/runtime in JS. Research project, not yet intended for serious use.<br>
|
3
3
|
|
4
4
|
<img src="https://github.com/CanadaHonk/porffor/assets/19228318/de8ad753-8ce3-4dcd-838e-f4d49452f8f8" alt="Screenshot of terminal showing Porffor running and compiling a hello world" width="60%">
|
5
5
|
|
@@ -279,7 +279,6 @@ No particular order and no guarentees, just what could happen soon™
|
|
279
279
|
- Support memory
|
280
280
|
- Support exceptions
|
281
281
|
- Exceptions
|
282
|
-
- `try { } finally { }`
|
283
282
|
- Rethrowing inside catch
|
284
283
|
- Optimizations
|
285
284
|
- Rewrite local indexes per func for smallest local header and remove unused idxs
|
@@ -323,8 +322,7 @@ Porffor intentionally does not use Wasm proposals which are not commonly impleme
|
|
323
322
|
`purple` in Welsh is `porffor`. Why purple?
|
324
323
|
- No other JS engine is purple colored
|
325
324
|
- Purple is pretty cool
|
326
|
-
- Purple apparently represents "ambition", which is
|
327
|
-
- The hard to speak name is also the noise your brain makes in reaction to this idea!
|
325
|
+
- Purple apparently represents "ambition", which is one word to describe this project
|
328
326
|
|
329
327
|
### 2. Why at all?
|
330
328
|
Yes!
|
@@ -1146,8 +1146,9 @@ local.set ${x}`;
|
|
1146
1146
|
return out;
|
1147
1147
|
};
|
1148
1148
|
|
1149
|
-
export const __String_prototype_repeat = (_this: string,
|
1149
|
+
export const __String_prototype_repeat = (_this: string, cnt: any) => {
|
1150
1150
|
let out: string = Porffor.allocate();
|
1151
|
+
const count: number = ecma262.ToIntegerOrInfinity(cnt);
|
1151
1152
|
|
1152
1153
|
count |= 0;
|
1153
1154
|
if (count < 0) throw new RangeError('Invalid count value');
|
@@ -1179,8 +1180,9 @@ memory.copy 0 0`;
|
|
1179
1180
|
return out;
|
1180
1181
|
};
|
1181
1182
|
|
1182
|
-
export const __ByteString_prototype_repeat = (_this: string,
|
1183
|
+
export const __ByteString_prototype_repeat = (_this: string, cnt: any) => {
|
1183
1184
|
let out: bytestring = Porffor.allocate();
|
1185
|
+
const count: number = ecma262.ToIntegerOrInfinity(cnt);
|
1184
1186
|
|
1185
1187
|
count |= 0;
|
1186
1188
|
if (count < 0) throw new RangeError('Invalid count value');
|
@@ -1495,6 +1497,41 @@ export const __ByteString_prototype_localeCompare = (_this: bytestring, compareS
|
|
1495
1497
|
};
|
1496
1498
|
|
1497
1499
|
|
1500
|
+
export const __String_prototype_isWellFormed = (_this: string) => {
|
1501
|
+
let ptr: i32 = Porffor.wasm`local.get ${_this}`;
|
1502
|
+
const endPtr: i32 = ptr + _this.length * 2;
|
1503
|
+
while (ptr < endPtr) {
|
1504
|
+
const c1: i32 = Porffor.wasm.i32.load16_u(ptr, 0, 4);
|
1505
|
+
|
1506
|
+
if (Porffor.fastAnd(c1 >= 0xDC00, c1 <= 0xDFFF)) {
|
1507
|
+
// lone trailing surrogate, bad
|
1508
|
+
return false;
|
1509
|
+
}
|
1510
|
+
|
1511
|
+
if (Porffor.fastAnd(c1 >= 0xD800, c1 <= 0xDBFF)) {
|
1512
|
+
// leading surrogate, peek if next is trailing
|
1513
|
+
const c2: i32 = ptr + 2 < endPtr ? Porffor.wasm.i32.load16_u(ptr + 2, 0, 4) : 0;
|
1514
|
+
|
1515
|
+
if (Porffor.fastAnd(c2 >= 0xDC00, c2 <= 0xDFFF)) {
|
1516
|
+
// next is trailing surrogate, skip it too
|
1517
|
+
ptr += 2;
|
1518
|
+
} else {
|
1519
|
+
// lone leading surrogate, bad
|
1520
|
+
return false;
|
1521
|
+
}
|
1522
|
+
}
|
1523
|
+
|
1524
|
+
ptr += 2;
|
1525
|
+
}
|
1526
|
+
|
1527
|
+
return true;
|
1528
|
+
};
|
1529
|
+
|
1530
|
+
export const __ByteString_prototype_isWellFormed = (_this: bytestring) => {
|
1531
|
+
// bytestrings cannot have surrogates, so always true
|
1532
|
+
return true;
|
1533
|
+
};
|
1534
|
+
|
1498
1535
|
export const __String_prototype_toWellFormed = (_this: string) => {
|
1499
1536
|
let out: string = Porffor.allocate();
|
1500
1537
|
Porffor.clone(_this, out);
|
@@ -1562,4 +1599,4 @@ export const __String_prototype_valueOf = (_this: string) => {
|
|
1562
1599
|
export const __ByteString_prototype_valueOf = (_this: bytestring) => {
|
1563
1600
|
// 1. Return ? ThisStringValue(this value).
|
1564
1601
|
return _this;
|
1565
|
-
};
|
1602
|
+
};
|
@@ -2224,14 +2224,14 @@ locals:[127,127,127,127,127,127,127,127,127,127,127],localNames:["_this","_this#
|
|
2224
2224
|
hasRestArgument:1,
|
2225
2225
|
};
|
2226
2226
|
this.__String_prototype_repeat = {
|
2227
|
-
wasm:(_,{builtin,internalThrow})=>[[16,builtin('__Porffor_allocate')],[33,4],[32,2],[65,0],[114],[34,
|
2227
|
+
wasm:(_,{builtin,internalThrow})=>[[16,builtin('__Porffor_allocate')],[33,4],[32,2],[184],[32,3],[16,builtin('__ecma262_ToIntegerOrInfinity')],[33,6],[252,2],[34,5],[65,0],[114],[34,5],[65,0],[72],[4,64],...internalThrow(_,'RangeError',`Invalid count value`),[11],[32,0],[40,1,0],[65,2],[108],[33,7],[65,0],[33,8],[3,64],[32,8],[32,5],[72],[4,64],[32,4],[65,4],[106],[32,8],[32,7],[108],[106],[32,0],[65,4],[106],[32,7],[252,10,0,0],[32,8],[65,1],[106],[33,8],[12,1],[11],[11],[32,4],[32,7],[32,5],[108],[54,0,0],[32,4],[65,195,0],[15]],
|
2228
2228
|
params:[127,127,127,127],typedParams:1,returns:[127,127],typedReturns:1,
|
2229
|
-
locals:[127,127,127],localNames:["_this","_this#type","
|
2229
|
+
locals:[127,127,127,127,127],localNames:["_this","_this#type","cnt","cnt#type","out","count","#last_type","thisLen","i"],
|
2230
2230
|
};
|
2231
2231
|
this.__ByteString_prototype_repeat = {
|
2232
|
-
wasm:(_,{builtin,internalThrow})=>[[16,builtin('__Porffor_allocate')],[33,4],[32,2],[65,0],[114],[34,
|
2232
|
+
wasm:(_,{builtin,internalThrow})=>[[16,builtin('__Porffor_allocate')],[33,4],[32,2],[184],[32,3],[16,builtin('__ecma262_ToIntegerOrInfinity')],[33,6],[252,2],[34,5],[65,0],[114],[34,5],[65,0],[72],[4,64],...internalThrow(_,'RangeError',`Invalid count value`),[11],[32,0],[40,1,0],[33,7],[65,0],[33,8],[3,64],[32,8],[32,5],[72],[4,64],[32,4],[65,4],[106],[32,8],[32,7],[108],[106],[32,0],[65,4],[106],[32,7],[252,10,0,0],[32,8],[65,1],[106],[33,8],[12,1],[11],[11],[32,4],[32,7],[32,5],[108],[54,0,0],[32,4],[65,195,1],[15]],
|
2233
2233
|
params:[127,127,127,127],typedParams:1,returns:[127,127],typedReturns:1,
|
2234
|
-
locals:[127,127,127],localNames:["_this","_this#type","
|
2234
|
+
locals:[127,127,127,127,127],localNames:["_this","_this#type","cnt","cnt#type","out","count","#last_type","thisLen","i"],
|
2235
2235
|
};
|
2236
2236
|
this.__String_prototype_split = {
|
2237
2237
|
wasm:(_,{builtin,internalThrow})=>[[16,builtin('__Porffor_allocate')],[33,6],[65,0],[33,7],[65,195,0],[33,8],[32,5],[65,128,1],[70],[4,64],[65,255,255,255,255,7],[34,4],[65,1],[33,5],[26],[11],[32,4],[65,0],[114],[34,4],[65,1],[33,5],[26],[32,4],[65,0],[72],[4,64],[65,255,255,255,255,7],[34,4],[65,1],[33,5],[26],[11],[16,builtin('__Porffor_allocate')],[33,9],[65,0],[33,10],[32,0],[40,1,0],[65,2],[108],[33,11],[32,2],[40,1,0],[34,12],[65,1],[70],[4,64],[32,2],[34,15],[40,1,0],[33,14],[32,3],[33,18],[2,127],[32,18],[65,195,0],[70],[4,64,"TYPESWITCH|String"],[2,127],[65,0],[34,16],[32,14],[78],[4,64],[65,127],[12,1],[11],[32,16],[65,2],[108],[32,15],[106],[47,0,4],[65,1],[33,17],[11],[12,1],[11],[32,18],[65,195,1],[70],[4,64,"TYPESWITCH|ByteString"],[2,127],[65,0],[34,16],[32,14],[78],[4,64],[65,127],[12,1],[11],[32,16],[32,15],[106],[45,0,4],[65,1],[33,17],[11],[12,1],[11],...internalThrow(_,'TypeError',`'charCodeAt' proto func tried to be called on a type without an impl`),[11,"TYPESWITCH_end"],[33,13],[65,0],[33,19],[3,64],[32,19],[32,11],[72],[4,64],[2,64],[32,0],[32,19],[106],[47,0,4],[34,20],[32,13],[70],[4,64],[32,7],[32,4],[78],[4,64],[32,6],[34,22],[32,7],[34,21],[54,1,0],[32,6],[65,208,0],[15],[11],[32,9],[34,22],[32,10],[34,21],[54,1,0],[32,6],[32,7],[65,9],[108],[106],[32,9],[184],[57,0,4],[32,6],[32,7],[65,9],[108],[106],[32,8],[58,0,12],[32,7],[65,1],[106],[33,7],[16,builtin('__Porffor_allocate')],[33,9],[65,0],[33,10],[12,1],[11],[32,9],[32,10],[65,2],[108],[106],[32,20],[59,0,4],[32,10],[65,1],[106],[33,10],[11],[32,19],[65,2],[106],[34,19],[12,1],[11],[11],[5],[65,0],[33,23],[65,0],[33,19],[3,64],[32,19],[32,11],[72],[4,64],[2,64],[32,0],[32,19],[106],[47,0,4],[34,20],[32,2],[34,15],[40,1,0],[33,14],[32,3],[33,18],[2,127],[32,18],[65,195,0],[70],[4,64,"TYPESWITCH|String"],[2,127],[32,23],[34,16],[32,14],[78],[4,64],[65,127],[12,1],[11],[32,16],[65,2],[108],[32,15],[106],[47,0,4],[65,1],[33,17],[11],[12,1],[11],[32,18],[65,195,1],[70],[4,64,"TYPESWITCH|ByteString"],[2,127],[32,23],[34,16],[32,14],[78],[4,64],[65,127],[12,1],[11],[32,16],[32,15],[106],[45,0,4],[65,1],[33,17],[11],[12,1],[11],...internalThrow(_,'TypeError',`'charCodeAt' proto func tried to be called on a type without an impl`),[11,"TYPESWITCH_end"],[70],[4,64],[32,23],[65,1],[106],[34,23],[32,12],[70],[4,64],[32,7],[32,4],[78],[4,64],[32,6],[34,22],[32,7],[34,21],[54,1,0],[32,6],[65,208,0],[15],[11],[32,9],[34,22],[32,10],[32,12],[65,1],[107],[107],[34,21],[54,1,0],[32,6],[32,7],[65,9],[108],[106],[32,9],[184],[57,0,4],[32,6],[32,7],[65,9],[108],[106],[32,8],[58,0,12],[32,7],[65,1],[106],[33,7],[16,builtin('__Porffor_allocate')],[33,9],[65,0],[33,10],[12,2],[11],[5],[65,0],[33,23],[11],[32,9],[32,10],[106],[32,20],[59,0,4],[32,10],[65,1],[106],[33,10],[11],[32,19],[65,2],[106],[34,19],[12,1],[11],[11],[11],[32,10],[65,0],[74],[34,24],[4,127],[32,7],[32,4],[72],[65,2],[33,17],[5],[32,24],[65,2],[33,17],[11],[33,25],[32,17],[33,18],[2,127],[32,18],[65,195,0],[70],[4,64,"TYPESWITCH|String"],[32,25],[40,1,0],[12,1],[11],[32,18],[65,195,1],[70],[4,64,"TYPESWITCH|ByteString"],[32,25],[40,1,0],[12,1],[11],[32,25],[11,"TYPESWITCH_end"],[4,64],[32,9],[34,22],[32,10],[34,21],[54,1,0],[32,6],[32,7],[65,9],[108],[106],[32,9],[184],[57,0,4],[32,6],[32,7],[65,9],[108],[106],[32,8],[58,0,12],[32,7],[65,1],[106],[33,7],[11],[32,6],[34,22],[32,7],[34,21],[54,1,0],[32,6],[65,208,0],[15]],
|
@@ -2253,6 +2253,16 @@ wasm:(_,{builtin,internalThrow})=>[[32,2],[184],[32,3],[16,builtin('__ecma262_To
|
|
2253
2253
|
params:[127,127,127,127],typedParams:1,returns:[127,127],typedReturns:1,
|
2254
2254
|
locals:[127,127,127,127,127,127,127,127,127,127,127],localNames:["_this","_this#type","compareString","compareString#type","#last_type","thisLen","compareLen","maxLen","i","a","__proto_length_cache","__proto_pointer_cache","__charCodeAt_tmp","b","#typeswitch_tmp1"],
|
2255
2255
|
};
|
2256
|
+
this.__String_prototype_isWellFormed = {
|
2257
|
+
wasm:()=>[[32,0],[34,2],[32,0],[40,1,0],[65,2],[108],[106],[33,3],[3,64],[32,2],[32,3],[72],[4,64],[32,2],[47,0,4],[34,4],[65,128,184,3],[78],[32,4],[65,255,191,3],[76],[113],[4,64],[65,0],[65,2],[15],[11],[32,4],[65,128,176,3],[78],[32,4],[65,255,183,3],[76],[113],[4,64],[32,2],[65,2],[106],[32,3],[72],[4,127],[32,2],[65,2],[106],[47,0,4],[65,1],[33,6],[5],[65,0],[65,1],[33,6],[11],[34,5],[65,128,184,3],[78],[32,5],[65,255,191,3],[76],[113],[4,64],[32,2],[65,2],[106],[33,2],[5],[65,0],[65,2],[15],[11],[11],[32,2],[65,2],[106],[33,2],[12,1],[11],[11],[65,1],[65,2],[15]],
|
2258
|
+
params:[127,127],typedParams:1,returns:[127,127],typedReturns:1,
|
2259
|
+
locals:[127,127,127,127,127],localNames:["_this","_this#type","ptr","endPtr","c1","c2","#last_type"],
|
2260
|
+
};
|
2261
|
+
this.__ByteString_prototype_isWellFormed = {
|
2262
|
+
wasm:()=>[[65,1],[65,2],[15]],
|
2263
|
+
params:[127,127],typedParams:1,returns:[127,127],typedReturns:1,
|
2264
|
+
locals:[],localNames:["_this","_this#type"],
|
2265
|
+
};
|
2256
2266
|
this.__String_prototype_toWellFormed = {
|
2257
2267
|
wasm:(_,{builtin})=>[[16,builtin('__Porffor_allocate')],[33,2],[32,0],[32,2],[16,builtin('__Porffor_clone')],[32,2],[34,3],[32,2],[40,1,0],[65,2],[108],[106],[33,4],[3,64],[32,3],[32,4],[72],[4,64],[32,3],[47,0,4],[34,5],[65,128,184,3],[78],[32,5],[65,255,191,3],[76],[113],[4,64],[32,3],[65,253,255,3],[59,0,4],[11],[32,5],[65,128,176,3],[78],[32,5],[65,255,183,3],[76],[113],[4,64],[32,3],[65,2],[106],[32,4],[72],[4,127],[32,3],[65,2],[106],[47,0,4],[65,1],[33,7],[5],[65,0],[65,1],[33,7],[11],[34,6],[65,128,184,3],[78],[32,6],[65,255,191,3],[76],[113],[4,64],[32,3],[65,2],[106],[33,3],[5],[32,3],[65,253,255,3],[59,0,4],[11],[11],[32,3],[65,2],[106],[33,3],[12,1],[11],[11],[32,2],[65,195,0],[15]],
|
2258
2268
|
params:[127,127],typedParams:1,returns:[127,127],typedReturns:1,
|
package/compiler/prototype.js
CHANGED
@@ -296,80 +296,6 @@ export const PrototypeFuncs = function() {
|
|
296
296
|
// load current string ind {arg}
|
297
297
|
[ Opcodes.i32_load16_u, Math.log2(ValtypeSize.i16) - 1, ValtypeSize.i32 ],
|
298
298
|
Opcodes.i32_from_u
|
299
|
-
],
|
300
|
-
|
301
|
-
isWellFormed: (pointer, length, _1, _2, iTmp, iTmp2) => [
|
302
|
-
// note: we cannot presume it begins as 0 in case it was used previously
|
303
|
-
...pointer,
|
304
|
-
[ Opcodes.local_set, iTmp ],
|
305
|
-
|
306
|
-
// use cached length as end pointer
|
307
|
-
...length.getCachedI32(),
|
308
|
-
...number(ValtypeSize.i16, Valtype.i32),
|
309
|
-
[ Opcodes.i32_mul ],
|
310
|
-
...pointer,
|
311
|
-
[ Opcodes.i32_add ],
|
312
|
-
...length.setCachedI32(),
|
313
|
-
|
314
|
-
[ Opcodes.loop, Blocktype.void ],
|
315
|
-
|
316
|
-
[ Opcodes.block, Blocktype.void ],
|
317
|
-
|
318
|
-
[ Opcodes.local_get, iTmp ],
|
319
|
-
[ Opcodes.i32_load16_u, Math.log2(ValtypeSize.i16) - 1, ValtypeSize.i32 ],
|
320
|
-
[ Opcodes.local_set, iTmp2 ],
|
321
|
-
|
322
|
-
// if not surrogate, continue
|
323
|
-
[ Opcodes.local_get, iTmp2 ],
|
324
|
-
...number(0xF800, Valtype.i32),
|
325
|
-
[ Opcodes.i32_and ],
|
326
|
-
...number(0xD800, Valtype.i32),
|
327
|
-
[ Opcodes.i32_ne ],
|
328
|
-
[ Opcodes.br_if, 0 ],
|
329
|
-
|
330
|
-
// if not leading surrogate, return false
|
331
|
-
[ Opcodes.local_get, iTmp2 ],
|
332
|
-
...number(0xDC00, Valtype.i32),
|
333
|
-
[ Opcodes.i32_ge_s ],
|
334
|
-
[ Opcodes.if, Blocktype.void ],
|
335
|
-
...number(0),
|
336
|
-
[ Opcodes.br, 3 ],
|
337
|
-
[ Opcodes.end ],
|
338
|
-
|
339
|
-
// if not followed by trailing surrogate, return false
|
340
|
-
[ Opcodes.local_get, iTmp ],
|
341
|
-
[ Opcodes.i32_load16_u, Math.log2(ValtypeSize.i16) - 1, ValtypeSize.i32 + ValtypeSize.i16 ],
|
342
|
-
...number(0xFC00, Valtype.i32),
|
343
|
-
[ Opcodes.i32_and ],
|
344
|
-
...number(0xDC00, Valtype.i32),
|
345
|
-
[ Opcodes.i32_ne ],
|
346
|
-
[ Opcodes.if, Blocktype.void ],
|
347
|
-
...number(0),
|
348
|
-
[ Opcodes.br, 3 ],
|
349
|
-
[ Opcodes.end ],
|
350
|
-
|
351
|
-
// bump index again since gone through two valid chars
|
352
|
-
[ Opcodes.local_get, iTmp ],
|
353
|
-
...number(ValtypeSize.i16, Valtype.i32),
|
354
|
-
[ Opcodes.i32_add ],
|
355
|
-
[ Opcodes.local_set, iTmp ],
|
356
|
-
|
357
|
-
[ Opcodes.end ],
|
358
|
-
|
359
|
-
// bump pointer and loop if not at the end
|
360
|
-
[ Opcodes.local_get, iTmp ],
|
361
|
-
...number(ValtypeSize.i16, Valtype.i32),
|
362
|
-
[ Opcodes.i32_add ],
|
363
|
-
[ Opcodes.local_tee, iTmp ],
|
364
|
-
|
365
|
-
...length.getCachedI32(), // end pointer
|
366
|
-
[ Opcodes.i32_ne ],
|
367
|
-
[ Opcodes.br_if, 0 ],
|
368
|
-
|
369
|
-
[ Opcodes.end ],
|
370
|
-
|
371
|
-
// return true
|
372
|
-
...number(1)
|
373
299
|
]
|
374
300
|
};
|
375
301
|
|
@@ -380,10 +306,6 @@ export const PrototypeFuncs = function() {
|
|
380
306
|
this[TYPES.string].charCodeAt.local = Valtype.i32;
|
381
307
|
this[TYPES.string].charCodeAt.noPointerCache = zeroChecks.charcodeat;
|
382
308
|
|
383
|
-
this[TYPES.string].isWellFormed.local = Valtype.i32;
|
384
|
-
this[TYPES.string].isWellFormed.local2 = Valtype.i32;
|
385
|
-
this[TYPES.string].isWellFormed.returnType = TYPES.boolean;
|
386
|
-
|
387
309
|
if (Prefs.bytestring) {
|
388
310
|
this[TYPES.bytestring] = {
|
389
311
|
at: (pointer, length, wIndex, wType, iTmp, _, arrayShell) => {
|
@@ -499,11 +421,6 @@ export const PrototypeFuncs = function() {
|
|
499
421
|
// load current string ind {arg}
|
500
422
|
[ Opcodes.i32_load8_u, 0, ValtypeSize.i32 ],
|
501
423
|
Opcodes.i32_from_u
|
502
|
-
],
|
503
|
-
|
504
|
-
isWellFormed: () => [
|
505
|
-
// we know it must be true as it is a bytestring lol
|
506
|
-
...number(1)
|
507
424
|
]
|
508
425
|
};
|
509
426
|
|
@@ -513,9 +430,5 @@ export const PrototypeFuncs = function() {
|
|
513
430
|
this[TYPES.bytestring].charCodeAt.returnType = TYPES.number;
|
514
431
|
this[TYPES.bytestring].charCodeAt.local = Valtype.i32;
|
515
432
|
this[TYPES.bytestring].charCodeAt.noPointerCache = zeroChecks.charcodeat;
|
516
|
-
|
517
|
-
this[TYPES.bytestring].isWellFormed.local = Valtype.i32;
|
518
|
-
this[TYPES.bytestring].isWellFormed.local2 = Valtype.i32;
|
519
|
-
this[TYPES.bytestring].isWellFormed.returnType = TYPES.boolean;
|
520
433
|
}
|
521
434
|
};
|
package/package.json
CHANGED