porffor 0.60.11 → 0.60.13
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/compiler/builtins/_internal_object.ts +6 -0
- package/compiler/builtins/function.ts +9 -0
- package/compiler/builtins/object_hiddenPrototype.js +1 -1
- package/compiler/builtins/regexp.ts +71 -30
- package/compiler/builtins_precompiled.js +241 -202
- package/compiler/codegen.js +7 -7
- package/compiler/precompile.js +2 -1
- package/deno.lock +18 -0
- package/foo.js +1 -15
- package/package.json +1 -1
- package/runtime/index.js +1 -1
@@ -489,6 +489,9 @@ i32.load 0 4
|
|
489
489
|
local.set ${obj}
|
490
490
|
i32.load8_u 0 3
|
491
491
|
local.set ${obj+1}`;
|
492
|
+
|
493
|
+
// if undefined, prototype is object.prototype
|
494
|
+
if (Porffor.type(obj) == Porffor.TYPES.undefined) obj = __Object_prototype;
|
492
495
|
} else obj = __Porffor_object_getPrototype(obj);
|
493
496
|
if (Porffor.type(obj) != Porffor.TYPES.object) obj = __Porffor_object_underlying(obj);
|
494
497
|
|
@@ -555,6 +558,9 @@ i32.load 0 4
|
|
555
558
|
local.set ${obj}
|
556
559
|
i32.load8_u 0 3
|
557
560
|
local.set ${obj+1}`;
|
561
|
+
|
562
|
+
// if undefined, prototype is object.prototype
|
563
|
+
if (Porffor.type(obj) == Porffor.TYPES.undefined) obj = __Object_prototype;
|
558
564
|
} else obj = __Porffor_object_getPrototype(obj);
|
559
565
|
if (Porffor.type(obj) != Porffor.TYPES.object) obj = __Porffor_object_underlying(obj);
|
560
566
|
|
@@ -1,5 +1,14 @@
|
|
1
1
|
import type {} from './porffor.d.ts';
|
2
2
|
|
3
|
+
// `eval` is invalid syntax so work around
|
4
|
+
export const _eval = (source: string) => {
|
5
|
+
throw new SyntaxError('Dynamic code evaluation is not supported');
|
6
|
+
};
|
7
|
+
|
8
|
+
export const Function = function (source: string) {
|
9
|
+
throw new SyntaxError('Dynamic code evaluation is not supported');
|
10
|
+
};
|
11
|
+
|
3
12
|
export const __Function_prototype_toString = (_this: Function) => {
|
4
13
|
const out: bytestring = Porffor.allocate();
|
5
14
|
|
@@ -23,7 +23,7 @@ export const __Porffor_object_getHiddenPrototype = (trueType: i32): any => {
|
|
23
23
|
}`;
|
24
24
|
|
25
25
|
for (const x in TYPES) {
|
26
|
-
if (['undefined', 'string', 'bytestring', 'stringobject', 'number', 'numberobject', 'boolean', 'booleanobject'].includes(x)) continue;
|
26
|
+
if (['object', 'undefined', 'string', 'bytestring', 'stringobject', 'number', 'numberobject', 'boolean', 'booleanobject'].includes(x)) continue;
|
27
27
|
|
28
28
|
const name = TYPE_NAMES[TYPES[x]];
|
29
29
|
out += `
|
@@ -989,26 +989,15 @@ export const __Porffor_regex_interpret = (regexp: RegExp, input: i32, isTest: bo
|
|
989
989
|
const sticky: boolean = (flags & 0b00100000) != 0;
|
990
990
|
|
991
991
|
const inputLen: i32 = Porffor.wasm.i32.load(input, 0, 0);
|
992
|
-
let
|
992
|
+
let lastIndex: i32 = 0;
|
993
993
|
if (global || sticky) {
|
994
|
-
|
994
|
+
lastIndex = Porffor.wasm.i32.load16_u(regexp, 0, 8);
|
995
995
|
}
|
996
996
|
|
997
|
-
|
998
|
-
|
999
|
-
return null;
|
1000
|
-
}
|
1001
|
-
|
1002
|
-
// todo: free all at the end (or statically allocate but = [] causes memory corruption)
|
1003
|
-
const backtrackStack: i32[] = Porffor.allocate();
|
1004
|
-
const captures: i32[] = Porffor.allocateBytes(6144);
|
1005
|
-
|
1006
|
-
for (let i: i32 = searchStart; i <= inputLen; i++) {
|
1007
|
-
if (sticky && i != searchStart) {
|
1008
|
-
if (isTest) return false;
|
1009
|
-
return null;
|
1010
|
-
}
|
997
|
+
const backtrackStack: i32[] = [];
|
998
|
+
const captures: i32[] = [];
|
1011
999
|
|
1000
|
+
for (let i: i32 = lastIndex; i <= inputLen; i++) {
|
1012
1001
|
backtrackStack.length = 0;
|
1013
1002
|
captures.length = 0;
|
1014
1003
|
|
@@ -1065,7 +1054,6 @@ export const __Porffor_regex_interpret = (regexp: RegExp, input: i32, isTest: bo
|
|
1065
1054
|
|
1066
1055
|
if (op == 0x01) { // single
|
1067
1056
|
if (sp >= inputLen) {
|
1068
|
-
// Porffor.log(`single: oob`);
|
1069
1057
|
backtrack = true;
|
1070
1058
|
} else {
|
1071
1059
|
let c1: i32 = Porffor.wasm.i32.load8_u(pc, 0, 1);
|
@@ -1075,11 +1063,9 @@ export const __Porffor_regex_interpret = (regexp: RegExp, input: i32, isTest: bo
|
|
1075
1063
|
if (c2 >= 97 && c2 <= 122) c2 -= 32;
|
1076
1064
|
}
|
1077
1065
|
if (c1 == c2) {
|
1078
|
-
// Porffor.log(`single: matched ${c1}`);
|
1079
1066
|
pc += 2;
|
1080
1067
|
sp += 1;
|
1081
1068
|
} else {
|
1082
|
-
// Porffor.log(`single: failed, expected ${c1}, got ${c2}`);
|
1083
1069
|
backtrack = true;
|
1084
1070
|
}
|
1085
1071
|
}
|
@@ -1291,7 +1277,6 @@ export const __Porffor_regex_interpret = (regexp: RegExp, input: i32, isTest: bo
|
|
1291
1277
|
const lookaheadEndPc = pc + jumpOffset + 3;
|
1292
1278
|
const savedSp = sp; // Save current string position
|
1293
1279
|
|
1294
|
-
|
1295
1280
|
// Use fork to test the lookahead pattern
|
1296
1281
|
Porffor.array.fastPushI32(backtrackStack, lookaheadEndPc); // Continue point after lookahead
|
1297
1282
|
Porffor.array.fastPushI32(backtrackStack, savedSp); // Restore original sp
|
@@ -1320,7 +1305,6 @@ export const __Porffor_regex_interpret = (regexp: RegExp, input: i32, isTest: bo
|
|
1320
1305
|
const capIndex = Porffor.wasm.i32.load8_u(pc, 0, 1);
|
1321
1306
|
const arrIndex = capIndex + 255; // + 255 offset for temp start, as it could never end properly
|
1322
1307
|
captures[arrIndex] = sp;
|
1323
|
-
// Porffor.log(`startCapture: captures[${arrIndex}] = ${sp} | captures.length = ${captures.length}`);
|
1324
1308
|
pc += 2;
|
1325
1309
|
} else if (op == 0x31) { // end capture
|
1326
1310
|
const capIndex = Porffor.wasm.i32.load8_u(pc, 0, 1);
|
@@ -1328,7 +1312,6 @@ export const __Porffor_regex_interpret = (regexp: RegExp, input: i32, isTest: bo
|
|
1328
1312
|
while (captures.length <= arrIndex) Porffor.array.fastPushI32(captures, -1);
|
1329
1313
|
captures[arrIndex - 1] = captures[capIndex + 255];
|
1330
1314
|
captures[arrIndex] = sp;
|
1331
|
-
// Porffor.log(`endCapture: captures[${arrIndex}] = ${sp} | captures.length = ${captures.length}`);
|
1332
1315
|
pc += 2;
|
1333
1316
|
} else { // unknown op
|
1334
1317
|
backtrack = true;
|
@@ -1337,7 +1320,6 @@ export const __Porffor_regex_interpret = (regexp: RegExp, input: i32, isTest: bo
|
|
1337
1320
|
if (backtrack) {
|
1338
1321
|
if (backtrackStack.length == 0) break;
|
1339
1322
|
|
1340
|
-
|
1341
1323
|
// Check if we're backtracking from a lookahead
|
1342
1324
|
if (backtrackStack.length >= 4) {
|
1343
1325
|
const marker = backtrackStack[backtrackStack.length - 1];
|
@@ -1365,11 +1347,9 @@ export const __Porffor_regex_interpret = (regexp: RegExp, input: i32, isTest: bo
|
|
1365
1347
|
}
|
1366
1348
|
|
1367
1349
|
// Normal backtracking
|
1368
|
-
// Porffor.log(`backtrack! before: captures.length = ${captures.length}, sp = ${sp}, pc = ${pc}`);
|
1369
1350
|
captures.length = Porffor.array.fastPopI32(backtrackStack);
|
1370
1351
|
sp = Porffor.array.fastPopI32(backtrackStack);
|
1371
1352
|
pc = Porffor.array.fastPopI32(backtrackStack);
|
1372
|
-
// Porffor.log(`backtrack! after: captures.length = ${captures.length}, sp = ${sp}, pc = ${pc}`);
|
1373
1353
|
}
|
1374
1354
|
}
|
1375
1355
|
|
@@ -1378,7 +1358,7 @@ export const __Porffor_regex_interpret = (regexp: RegExp, input: i32, isTest: bo
|
|
1378
1358
|
|
1379
1359
|
const matchStart: i32 = i;
|
1380
1360
|
if (global || sticky) {
|
1381
|
-
Porffor.wasm.i32.
|
1361
|
+
Porffor.wasm.i32.store16(regexp, finalSp, 0, 8); // write last index
|
1382
1362
|
}
|
1383
1363
|
|
1384
1364
|
const result: any[] = Porffor.allocateBytes(4096);
|
@@ -1404,10 +1384,16 @@ export const __Porffor_regex_interpret = (regexp: RegExp, input: i32, isTest: bo
|
|
1404
1384
|
|
1405
1385
|
return result;
|
1406
1386
|
}
|
1387
|
+
|
1388
|
+
if (sticky) { // sticky, do not go forward in string
|
1389
|
+
Porffor.wasm.i32.store16(regexp, 0, 0, 8); // failed, write 0 last index
|
1390
|
+
if (isTest) return false;
|
1391
|
+
return null;
|
1392
|
+
}
|
1407
1393
|
}
|
1408
1394
|
|
1409
1395
|
if (global || sticky) {
|
1410
|
-
Porffor.wasm.i32.
|
1396
|
+
Porffor.wasm.i32.store16(regexp, 0, 0, 8); // failed, write 0 last index
|
1411
1397
|
}
|
1412
1398
|
|
1413
1399
|
if (isTest) return false;
|
@@ -1419,6 +1405,10 @@ export const __RegExp_prototype_source$get = (_this: RegExp) => {
|
|
1419
1405
|
return Porffor.wasm.i32.load(_this, 0, 0) as bytestring;
|
1420
1406
|
};
|
1421
1407
|
|
1408
|
+
export const __RegExp_prototype_lastIndex$get = (_this: RegExp) => {
|
1409
|
+
return Porffor.wasm.i32.load16_u(_this, 0, 8);
|
1410
|
+
};
|
1411
|
+
|
1422
1412
|
// 22.2.6.4 get RegExp.prototype.flags
|
1423
1413
|
// https://tc39.es/ecma262/multipage/text-processing.html#sec-get-regexp.prototype.flags
|
1424
1414
|
export const __RegExp_prototype_flags$get = (_this: RegExp) => {
|
@@ -1532,12 +1522,63 @@ export const __RegExp_prototype_test = (_this: RegExp, input: any) => {
|
|
1532
1522
|
return __Porffor_regex_interpret(_this, input, true);
|
1533
1523
|
};
|
1534
1524
|
|
1535
|
-
|
1525
|
+
|
1526
|
+
export const __Porffor_regex_match = (regexp: any, input: any) => {
|
1536
1527
|
if (Porffor.type(regexp) !== Porffor.TYPES.regexp) regexp = new RegExp(regexp);
|
1537
|
-
|
1528
|
+
if (Porffor.type(input) !== Porffor.TYPES.bytestring) input = ecma262.ToString(input);
|
1529
|
+
|
1530
|
+
if (__RegExp_prototype_global$get(regexp)) {
|
1531
|
+
// global should return all matches as just complete string result
|
1532
|
+
const result: any[] = Porffor.allocateBytes(4096);
|
1533
|
+
let match: any;
|
1534
|
+
while (match = __Porffor_regex_interpret(regexp, input, false)) {
|
1535
|
+
// read ourselves as we are in i32 space
|
1536
|
+
Porffor.wasm`
|
1537
|
+
local.get ${result}
|
1538
|
+
f64.convert_i32_u
|
1539
|
+
local.get ${result+1}
|
1540
|
+
|
1541
|
+
local.get ${match}
|
1542
|
+
f64.load 0 4
|
1543
|
+
local.get ${match}
|
1544
|
+
i32.load8_u 0 12
|
1545
|
+
|
1546
|
+
call __Porffor_array_fastPush`;
|
1547
|
+
}
|
1548
|
+
return result;
|
1549
|
+
}
|
1550
|
+
|
1551
|
+
return __Porffor_regex_interpret(regexp, input, false);
|
1552
|
+
};
|
1553
|
+
|
1554
|
+
export const __String_prototype_match = (_this: string, regexp: any) => {
|
1555
|
+
return __Porffor_regex_match(regexp, _this);
|
1538
1556
|
};
|
1539
1557
|
|
1540
1558
|
export const __ByteString_prototype_match = (_this: bytestring, regexp: any) => {
|
1559
|
+
return __Porffor_regex_match(regexp, _this);
|
1560
|
+
};
|
1561
|
+
|
1562
|
+
|
1563
|
+
// todo: use actual iterator not array
|
1564
|
+
export const __Porffor_regex_matchAll = (regexp: any, input: any) => {
|
1541
1565
|
if (Porffor.type(regexp) !== Porffor.TYPES.regexp) regexp = new RegExp(regexp);
|
1542
|
-
|
1566
|
+
if (Porffor.type(input) !== Porffor.TYPES.bytestring) input = ecma262.ToString(input);
|
1567
|
+
|
1568
|
+
if (!__RegExp_prototype_global$get(regexp)) throw new TypeError('matchAll used with non-global RegExp');
|
1569
|
+
|
1570
|
+
const result: any[] = Porffor.allocateBytes(4096);
|
1571
|
+
let match: any;
|
1572
|
+
while (match = __Porffor_regex_interpret(regexp, input, false)) {
|
1573
|
+
Porffor.array.fastPush(result, match);
|
1574
|
+
}
|
1575
|
+
return result;
|
1576
|
+
};
|
1577
|
+
|
1578
|
+
export const __String_prototype_matchAll = (_this: string, regexp: any) => {
|
1579
|
+
return __Porffor_regex_matchAll(regexp, _this);
|
1580
|
+
};
|
1581
|
+
|
1582
|
+
export const __ByteString_prototype_matchAll = (_this: bytestring, regexp: any) => {
|
1583
|
+
return __Porffor_regex_matchAll(regexp, _this);
|
1543
1584
|
};
|