porffor 0.18.20 → 0.18.21
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/array.ts +3 -3
- package/compiler/builtins/typedarray.js +50 -14
- package/compiler/builtins/typedarray.ts +19 -0
- package/compiler/builtins.js +12 -5
- package/compiler/codegen.js +7 -2
- package/compiler/generated_builtins.js +352 -285
- package/compiler/types.js +1 -0
- package/compiler/wrap.js +7 -2
- package/package.json +1 -1
- package/runner/index.js +1 -1
@@ -36,7 +36,7 @@ export const __Array_prototype_slice = (_this: any[], start: number, end: number
|
|
36
36
|
|
37
37
|
while (thisPtr < thisPtrEnd) {
|
38
38
|
Porffor.wasm.f64.store(outPtr, Porffor.wasm.f64.load(thisPtr, 0, 4), 0, 4);
|
39
|
-
Porffor.wasm.i32.store8(outPtr
|
39
|
+
Porffor.wasm.i32.store8(outPtr, Porffor.wasm.i32.load8_u(thisPtr, 0, 12), 0, 12);
|
40
40
|
|
41
41
|
thisPtr += 9;
|
42
42
|
outPtr += 9;
|
@@ -72,7 +72,7 @@ export const __Array_prototype_splice = (_this: any[], start: number, deleteCoun
|
|
72
72
|
|
73
73
|
while (thisPtr < thisPtrEnd) {
|
74
74
|
Porffor.wasm.f64.store(outPtr, Porffor.wasm.f64.load(thisPtr, 0, 4), 0, 4);
|
75
|
-
Porffor.wasm.i32.store8(outPtr
|
75
|
+
Porffor.wasm.i32.store8(outPtr, Porffor.wasm.i32.load8_u(thisPtr, 0, 12), 0, 12);
|
76
76
|
|
77
77
|
thisPtr += 9;
|
78
78
|
outPtr += 9;
|
@@ -133,7 +133,7 @@ memory.copy 0 0`;
|
|
133
133
|
|
134
134
|
while (thisPtr < thisPtrEnd) {
|
135
135
|
Porffor.wasm.f64.store(thisPtr, Porffor.wasm.f64.load(itemsPtr, 0, 4), 0, 4);
|
136
|
-
Porffor.wasm.i32.store8(thisPtr
|
136
|
+
Porffor.wasm.i32.store8(thisPtr, Porffor.wasm.i32.load8_u(itemsPtr, 0, 12), 0, 12);
|
137
137
|
|
138
138
|
thisPtr += 9;
|
139
139
|
itemsPtr += 9;
|
@@ -4,28 +4,64 @@ export default async () => {
|
|
4
4
|
const arrayCode = (await import('node:fs')).readFileSync(globalThis.precompileCompilerPath + '/builtins/array.ts', 'utf8');
|
5
5
|
const typedArrayFuncs = [...arrayCode.matchAll(/\/\/ @porf-typed-array[\s\S]+?^};$/gm)].map(x => x[0]);
|
6
6
|
|
7
|
-
|
7
|
+
// TypedArrays are stored like this in memory:
|
8
|
+
// length (i32)
|
9
|
+
// bufferPtr (i32)
|
10
|
+
|
11
|
+
const constr = name => out += `export const ${name} = function (arg: any, byteOffset: any, length: any): ${name} {
|
8
12
|
if (!new.target) throw new TypeError("Constructor ${name} requires 'new'");
|
9
13
|
|
10
|
-
const out: ${name} = Porffor.
|
14
|
+
const out: ${name} = Porffor.allocateBytes(8);
|
15
|
+
const outPtr: i32 = Porffor.wasm\`local.get \${out}\`;
|
16
|
+
|
11
17
|
let len: i32 = 0;
|
18
|
+
let bufferPtr: i32;
|
12
19
|
|
13
20
|
const type: i32 = Porffor.rawType(arg);
|
14
|
-
if (Porffor.
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
21
|
+
if (type == Porffor.TYPES.arraybuffer) {
|
22
|
+
bufferPtr = Porffor.wasm\`local.get \${arg}\`;
|
23
|
+
|
24
|
+
let offset: i32 = 0;
|
25
|
+
if (Porffor.rawType(byteOffset) != Porffor.TYPES.undefined) offset = Math.trunc(byteOffset);
|
26
|
+
|
27
|
+
Porffor.wasm.i32.store(outPtr, bufferPtr + offset, 0, 4);
|
28
|
+
|
29
|
+
if (Porffor.rawType(length) == Porffor.TYPES.undefined) {
|
30
|
+
const bufferLen: i32 = Porffor.wasm.i32.load(bufferPtr, 0, 0);
|
31
|
+
len = (bufferLen - byteOffset) / ${name}.BYTES_PER_ELEMENT;
|
32
|
+
|
33
|
+
if (!Number.isInteger(len)) throw new RangeError('byte length of ${name} should be divisible by BYTES_PER_ELEMENT');
|
34
|
+
} else len = Math.trunc(length);
|
35
|
+
} else {
|
36
|
+
bufferPtr = Porffor.allocate();
|
37
|
+
Porffor.wasm.i32.store(outPtr, bufferPtr, 0, 4);
|
38
|
+
|
39
|
+
if (Porffor.fastOr(
|
40
|
+
type == Porffor.TYPES.array,
|
41
|
+
type == Porffor.TYPES.string, type == Porffor.TYPES.bytestring,
|
42
|
+
type == Porffor.TYPES.set
|
43
|
+
)) {
|
44
|
+
let i: i32 = 0;
|
45
|
+
for (const x of arg) {
|
46
|
+
out[i++] = x;
|
47
|
+
}
|
48
|
+
len = i;
|
49
|
+
} else if (type == Porffor.TYPES.number) {
|
50
|
+
len = Math.trunc(arg);
|
22
51
|
}
|
23
|
-
|
24
|
-
|
25
|
-
len = arg;
|
52
|
+
|
53
|
+
Porffor.wasm.i32.store(bufferPtr, len * ${name}.BYTES_PER_ELEMENT, 0, 0);
|
26
54
|
}
|
27
55
|
|
28
|
-
|
56
|
+
if (len < 0) throw new RangeError('Invalid TypedArray length (negative)');
|
57
|
+
if (len > 34359738368) throw new RangeError('Invalid TypedArray length (>32GiB)');
|
58
|
+
|
59
|
+
Porffor.wasm.i32.store(outPtr, len, 0, 0);
|
60
|
+
return out;
|
61
|
+
};
|
62
|
+
|
63
|
+
export const __${name}_prototype_buffer$get = (_this: ${name}) => {
|
64
|
+
const out: ArrayBuffer = Porffor.wasm.i32.load(_this, 0, 4);
|
29
65
|
return out;
|
30
66
|
};
|
31
67
|
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import type {} from './porffor.d.ts';
|
2
|
+
|
3
|
+
export const ArrayBuffer = function (length: number): ArrayBuffer {
|
4
|
+
if (!new.target) throw new TypeError("Constructor ArrayBuffer requires 'new'");
|
5
|
+
|
6
|
+
if (length < 0) throw new RangeError('Invalid ArrayBuffer length (negative)');
|
7
|
+
if (length > 34359738368) throw new RangeError('Invalid ArrayBuffer length (>32GiB)');
|
8
|
+
|
9
|
+
length |= 0;
|
10
|
+
|
11
|
+
const out: ArrayBuffer = Porffor.allocateBytes(length + 4);
|
12
|
+
Porffor.wasm.i32.store(out, length, 0, 0);
|
13
|
+
|
14
|
+
return out;
|
15
|
+
};
|
16
|
+
|
17
|
+
export const __ArrayBuffer_prototype_byteLength$get = (_this: ArrayBuffer) => {
|
18
|
+
return Porffor.wasm.i32.load(_this, 0, 0);
|
19
|
+
};
|
package/compiler/builtins.js
CHANGED
@@ -1159,7 +1159,7 @@ export const BuiltinFuncs = function() {
|
|
1159
1159
|
[ Opcodes.global_get, 1 ],
|
1160
1160
|
...number(pageSize, Valtype.i32),
|
1161
1161
|
[ Opcodes.i32_ge_s ],
|
1162
|
-
[ Opcodes.if,
|
1162
|
+
[ Opcodes.if, Valtype.i32 ],
|
1163
1163
|
// bytesWritten = bytesToAllocate
|
1164
1164
|
[ Opcodes.local_get, 0 ],
|
1165
1165
|
[ Opcodes.global_set, 1 ],
|
@@ -1168,20 +1168,27 @@ export const BuiltinFuncs = function() {
|
|
1168
1168
|
...number(1, Valtype.i32),
|
1169
1169
|
[ Opcodes.memory_grow, 0x00 ],
|
1170
1170
|
|
1171
|
-
// currentPtr = old page count * pageSize
|
1171
|
+
// currentPtr = old page count * pageSize + bytesToAllocate
|
1172
1172
|
...number(pageSize, Valtype.i32),
|
1173
1173
|
[ Opcodes.i32_mul ],
|
1174
|
+
[ Opcodes.local_get, 0 ],
|
1175
|
+
[ Opcodes.i32_add ],
|
1174
1176
|
[ Opcodes.global_set, 0 ],
|
1177
|
+
|
1178
|
+
// return currentPtr - bytesToAllocate
|
1179
|
+
[ Opcodes.global_get, 0 ],
|
1180
|
+
[ Opcodes.local_get, 0 ],
|
1181
|
+
[ Opcodes.i32_sub ],
|
1175
1182
|
[ Opcodes.else ],
|
1176
1183
|
// else, currentPtr += bytesToAllocate
|
1177
1184
|
[ Opcodes.global_get, 0 ],
|
1178
1185
|
[ Opcodes.local_get, 0 ],
|
1179
1186
|
[ Opcodes.i32_add ],
|
1180
1187
|
[ Opcodes.global_set, 0 ],
|
1181
|
-
[ Opcodes.end ],
|
1182
1188
|
|
1183
|
-
|
1184
|
-
|
1189
|
+
// return currentPtr
|
1190
|
+
[ Opcodes.global_get, 0 ],
|
1191
|
+
[ Opcodes.end ]
|
1185
1192
|
]
|
1186
1193
|
};
|
1187
1194
|
|
package/compiler/codegen.js
CHANGED
@@ -2916,6 +2916,8 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
2916
2916
|
prelude: [
|
2917
2917
|
...generate(scope, decl.left.object),
|
2918
2918
|
Opcodes.i32_to_u,
|
2919
|
+
[ Opcodes.i32_load, 0, 4 ],
|
2920
|
+
|
2919
2921
|
...generate(scope, decl.left.property),
|
2920
2922
|
Opcodes.i32_to_u,
|
2921
2923
|
],
|
@@ -3577,6 +3579,7 @@ const generateForOf = (scope, decl) => {
|
|
3577
3579
|
[ Opcodes.loop, Blocktype.void ],
|
3578
3580
|
|
3579
3581
|
[ Opcodes.local_get, pointer ],
|
3582
|
+
[ Opcodes.i32_load, 0, 4 ],
|
3580
3583
|
[ Opcodes.local_get, counter ]
|
3581
3584
|
],
|
3582
3585
|
postlude: [
|
@@ -4230,7 +4233,7 @@ const generateMember = (scope, decl, _global, _name) => {
|
|
4230
4233
|
}
|
4231
4234
|
|
4232
4235
|
// todo: generate this array procedurally during builtinFuncs creation
|
4233
|
-
if (['size', 'description', 'byteLength'].includes(decl.property.name)) {
|
4236
|
+
if (['size', 'description', 'byteLength', 'buffer'].includes(decl.property.name)) {
|
4234
4237
|
const bc = {};
|
4235
4238
|
const cands = Object.keys(builtinFuncs).filter(x => x.startsWith('__') && x.endsWith('_prototype_' + decl.property.name + '$get'));
|
4236
4239
|
|
@@ -4408,6 +4411,8 @@ const generateMember = (scope, decl, _global, _name) => {
|
|
4408
4411
|
prelude: [
|
4409
4412
|
...object,
|
4410
4413
|
Opcodes.i32_to_u,
|
4414
|
+
[ Opcodes.i32_load, 0, 4 ],
|
4415
|
+
|
4411
4416
|
...property,
|
4412
4417
|
Opcodes.i32_to_u
|
4413
4418
|
],
|
@@ -4436,7 +4441,7 @@ const objectHack = node => {
|
|
4436
4441
|
if (!objectName) objectName = objectHack(node.object)?.name?.slice?.(2);
|
4437
4442
|
|
4438
4443
|
// if .name or .length, give up (hack within a hack!)
|
4439
|
-
if (['name', 'length', 'size', 'description', 'byteLength'].includes(node.property.name)) {
|
4444
|
+
if (['name', 'length', 'size', 'description', 'byteLength', 'buffer'].includes(node.property.name)) {
|
4440
4445
|
node.object = objectHack(node.object);
|
4441
4446
|
return;
|
4442
4447
|
}
|