porffor 0.34.5 → 0.34.7
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/assemble.js +12 -12
- package/compiler/builtins/__internal_string.ts +48 -0
- package/compiler/builtins/_internal_object.ts +2 -3
- package/compiler/builtins/_internal_string.ts +38 -0
- package/compiler/builtins/crypto.ts +12 -1
- package/compiler/builtins/object.ts +6 -0
- package/compiler/builtins/promise.ts +5 -5
- package/compiler/builtins.js +5 -5
- package/compiler/builtins_precompiled.js +254 -234
- package/compiler/codegen.js +21 -175
- package/compiler/wrap.js +2 -2
- package/package.json +1 -1
- package/runner/index.js +1 -1
- package/runner/repl.js +2 -2
package/compiler/assemble.js
CHANGED
@@ -21,7 +21,7 @@ const chHint = (topTier, baselineTier, strategy) => {
|
|
21
21
|
return (strategy | (baselineTier << 2) | (topTier << 4));
|
22
22
|
};
|
23
23
|
|
24
|
-
const encodeNames =
|
24
|
+
const encodeNames = funcs => {
|
25
25
|
const encodeSection = (id, section) => [
|
26
26
|
id,
|
27
27
|
...unsignedLEB128(section.length),
|
@@ -30,11 +30,11 @@ const encodeNames = (funcs) => {
|
|
30
30
|
|
31
31
|
const moduleSection = encodeString('js'); // TODO: filename?
|
32
32
|
const functionsSection = encodeVector(
|
33
|
-
funcs.map(
|
33
|
+
funcs.map(x => unsignedLEB128(x.asmIndex).concat(encodeString(x.name))),
|
34
34
|
);
|
35
35
|
const localsSection = encodeVector(
|
36
|
-
funcs.map(
|
37
|
-
unsignedLEB128(x.
|
36
|
+
funcs.map(x =>
|
37
|
+
unsignedLEB128(x.asmIndex).concat(
|
38
38
|
encodeVector(
|
39
39
|
Object.entries(x.locals).map(([name, local]) =>
|
40
40
|
unsignedLEB128(local.idx).concat(encodeString(name)),
|
@@ -99,10 +99,7 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
|
|
99
99
|
// also fix call_indirect types
|
100
100
|
// also encode call indexes
|
101
101
|
for (const f of funcs) {
|
102
|
-
|
103
|
-
f.originalIndex = f.index;
|
104
|
-
f.index -= importDelta;
|
105
|
-
}
|
102
|
+
f.asmIndex = f.index - importDelta;
|
106
103
|
}
|
107
104
|
|
108
105
|
|
@@ -130,7 +127,7 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
|
|
130
127
|
encodeVector([ [
|
131
128
|
0x00,
|
132
129
|
Opcodes.i32_const, 0, Opcodes.end,
|
133
|
-
...encodeVector(funcs.map(x => unsignedLEB128(x.
|
130
|
+
...encodeVector(funcs.map(x => unsignedLEB128(x.asmIndex)))
|
134
131
|
] ])
|
135
132
|
);
|
136
133
|
|
@@ -173,7 +170,7 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
|
|
173
170
|
|
174
171
|
bytes.push(...new Uint8Array(new Int32Array([ name.length ]).buffer));
|
175
172
|
|
176
|
-
for (let i = 0; i < (
|
173
|
+
for (let i = 0; i < (64 - 5 - 4); i++) {
|
177
174
|
const c = name.charCodeAt(i);
|
178
175
|
bytes.push((c || 0) % 256);
|
179
176
|
}
|
@@ -238,7 +235,7 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
|
|
238
235
|
// };
|
239
236
|
// }
|
240
237
|
|
241
|
-
const exports = funcs.filter(x => x.export).map((x, i) => [ ...encodeString(x.name === 'main' ? 'm' : x.name), ExportDesc.func, ...unsignedLEB128(x.
|
238
|
+
const exports = funcs.filter(x => x.export).map((x, i) => [ ...encodeString(x.name === 'main' ? 'm' : x.name), ExportDesc.func, ...unsignedLEB128(x.asmIndex) ]);
|
242
239
|
|
243
240
|
if (Prefs.alwaysMemory && pages.size === 0) pages.set('--always-memory', 0);
|
244
241
|
if (optLevel === 0) pages.set('O0 precaution', 0);
|
@@ -358,11 +355,14 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
|
|
358
355
|
const dataSection = data.length === 0 ? [] : createSection(
|
359
356
|
Section.data,
|
360
357
|
encodeVector(data.map(x => {
|
358
|
+
if (Prefs.d && x.bytes.length > PageSize) log.warning('assemble', `data (${x.page}) has more bytes than Wasm page size! (${x.bytes.length})`);
|
359
|
+
|
361
360
|
const bytes = encodeVector(x.bytes);
|
362
361
|
|
363
362
|
if (x.page != null) {
|
364
363
|
// type: active
|
365
|
-
|
364
|
+
let offset = pages.get(x.page).ind * pageSize;
|
365
|
+
if (offset === 0) offset = 16;
|
366
366
|
bytes.unshift(0x00, Opcodes.i32_const, ...signedLEB128(offset), Opcodes.end);
|
367
367
|
} else {
|
368
368
|
// type: passive
|
@@ -0,0 +1,48 @@
|
|
1
|
+
// @porf --valtype=i32
|
2
|
+
import type {} from './porffor.d.ts';
|
3
|
+
|
4
|
+
export const __Porffor_strcmp = (a: any, b: any): boolean => {
|
5
|
+
// a and b must be string or bytestring
|
6
|
+
// fast path: check if pointers are equal
|
7
|
+
if (Porffor.wasm`local.get ${a}` == Porffor.wasm`local.get ${b}`) return true;
|
8
|
+
|
9
|
+
const al: i32 = Porffor.wasm.i32.load(a, 0, 0);
|
10
|
+
const bl: i32 = Porffor.wasm.i32.load(b, 0, 0);
|
11
|
+
|
12
|
+
// fast path: check if lengths are inequal
|
13
|
+
if (al != bl) return false;
|
14
|
+
|
15
|
+
if (Porffor.wasm`local.get ${a+1}` == Porffor.TYPES.bytestring) {
|
16
|
+
if (Porffor.wasm`local.get ${b+1}` == Porffor.TYPES.bytestring) {
|
17
|
+
// bytestring, bytestring
|
18
|
+
for (let i: i32 = 0; i < al; i++) {
|
19
|
+
if (Porffor.wasm.i32.load8_u(Porffor.wasm`local.get ${a}` + i, 0, 4) !=
|
20
|
+
Porffor.wasm.i32.load8_u(Porffor.wasm`local.get ${b}` + i, 0, 4)) return false;
|
21
|
+
}
|
22
|
+
return true;
|
23
|
+
} else {
|
24
|
+
// bytestring, string
|
25
|
+
for (let i: i32 = 0; i < al; i++) {
|
26
|
+
if (Porffor.wasm.i32.load8_u(Porffor.wasm`local.get ${a}` + i, 0, 4) !=
|
27
|
+
Porffor.wasm.i32.load16_u(Porffor.wasm`local.get ${b}` + i*2, 0, 4)) return false;
|
28
|
+
}
|
29
|
+
return true;
|
30
|
+
}
|
31
|
+
} else {
|
32
|
+
if (Porffor.wasm`local.get ${b+1}` == Porffor.TYPES.bytestring) {
|
33
|
+
// string, bytestring
|
34
|
+
for (let i: i32 = 0; i < al; i++) {
|
35
|
+
if (Porffor.wasm.i32.load16_u(Porffor.wasm`local.get ${a}` + i*2, 0, 4) !=
|
36
|
+
Porffor.wasm.i32.load8_u(Porffor.wasm`local.get ${b}` + i, 0, 4)) return false;
|
37
|
+
}
|
38
|
+
return true;
|
39
|
+
} else {
|
40
|
+
// string, string
|
41
|
+
for (let i: i32 = 0; i < al; i++) {
|
42
|
+
if (Porffor.wasm.i32.load16_u(Porffor.wasm`local.get ${a}` + i*2, 0, 4) !=
|
43
|
+
Porffor.wasm.i32.load16_u(Porffor.wasm`local.get ${b}` + i*2, 0, 4)) return false;
|
44
|
+
}
|
45
|
+
return true;
|
46
|
+
}
|
47
|
+
}
|
48
|
+
};
|
@@ -199,11 +199,10 @@ return`;
|
|
199
199
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) obj = __Porffor_object_getObject(obj);
|
200
200
|
let entryPtr: i32 = __Porffor_object_lookup(obj, key);
|
201
201
|
if (entryPtr == -1) {
|
202
|
-
const protoKey: bytestring = '__proto__';
|
203
|
-
|
204
202
|
if (Porffor.wasm`local.get ${obj+1}` == Porffor.TYPES.object) {
|
205
203
|
// check prototype chain
|
206
|
-
|
204
|
+
const protoKey: bytestring = '__proto__';
|
205
|
+
let lastProto: any = obj;
|
207
206
|
if (key != protoKey) {
|
208
207
|
while (true) {
|
209
208
|
obj = __Porffor_object_get(obj, protoKey);
|
@@ -0,0 +1,38 @@
|
|
1
|
+
import type {} from './porffor.d.ts';
|
2
|
+
|
3
|
+
export const __Porffor_compareStrings = (a: any, b: any): boolean => {
|
4
|
+
let at: i32 = Porffor.rawType(a);
|
5
|
+
let bt: i32 = Porffor.rawType(b);
|
6
|
+
|
7
|
+
if ((at | 0b10000000) != Porffor.TYPES.bytestring) {
|
8
|
+
// a is not string or bytestring
|
9
|
+
// check if it is bad type or value
|
10
|
+
if (Porffor.fastOr(
|
11
|
+
a == null,
|
12
|
+
|
13
|
+
at == Porffor.TYPES.symbol,
|
14
|
+
at == Porffor.TYPES.boolean
|
15
|
+
)) return false;
|
16
|
+
|
17
|
+
// todo/perf: just use a.toString()?
|
18
|
+
a = ecma262.ToString(a);
|
19
|
+
at = Porffor.rawType(a);
|
20
|
+
}
|
21
|
+
|
22
|
+
if ((bt | 0b10000000) != Porffor.TYPES.bytestring) {
|
23
|
+
// b is not string or bytestring
|
24
|
+
// check if it is bad type or value
|
25
|
+
if (Porffor.fastOr(
|
26
|
+
b == null,
|
27
|
+
|
28
|
+
bt == Porffor.TYPES.symbol,
|
29
|
+
bt == Porffor.TYPES.boolean
|
30
|
+
)) return false;
|
31
|
+
|
32
|
+
// todo/perf: just use b.toString()?
|
33
|
+
b = ecma262.ToString(b);
|
34
|
+
bt = Porffor.rawType(b);
|
35
|
+
}
|
36
|
+
|
37
|
+
return Porffor.strcmp(a, b);
|
38
|
+
};
|
@@ -118,4 +118,15 @@ export const __crypto_randomUUID = (): bytestring => {
|
|
118
118
|
|
119
119
|
|
120
120
|
return output;
|
121
|
-
};
|
121
|
+
};
|
122
|
+
|
123
|
+
export const __crypto_getRandomValues = (buffer: Uint8Array): Uint8Array => {
|
124
|
+
let i: i32 = 0;
|
125
|
+
let endPtr: i32 = buffer.length;
|
126
|
+
while (i < endPtr) {
|
127
|
+
buffer[i] = Porffor.randomByte();
|
128
|
+
i++;
|
129
|
+
}
|
130
|
+
|
131
|
+
return buffer;
|
132
|
+
};
|
@@ -651,6 +651,12 @@ export const __Object_setPrototypeOf = (obj: any, proto: any) => {
|
|
651
651
|
return obj;
|
652
652
|
};
|
653
653
|
|
654
|
+
export const __Object_prototype_isPrototypeOf = (_this: any, obj: any) => {
|
655
|
+
if (_this == null) throw new TypeError('This is nullish, expected object');
|
656
|
+
|
657
|
+
return _this == obj.__proto__;
|
658
|
+
};
|
659
|
+
|
654
660
|
|
655
661
|
export const __Object_prototype_toString = (_this: any) => {
|
656
662
|
let out: bytestring = Porffor.allocate();
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import type {} from './porffor.d.ts';
|
2
2
|
|
3
3
|
export const __ecma262_NewPromiseReactionJob = (reaction: any[], argument: any): any[] => {
|
4
|
-
const job: any[] = Porffor.allocateBytes(
|
4
|
+
const job: any[] = Porffor.allocateBytes(32);
|
5
5
|
job[0] = reaction;
|
6
6
|
job[1] = argument;
|
7
7
|
|
@@ -118,7 +118,7 @@ export const __Porffor_promise_reject = (promise: any, reason: any): any => {
|
|
118
118
|
|
119
119
|
export const __Porffor_promise_create = (): any[] => {
|
120
120
|
// Promise [ result, state, fulfillReactions, rejectReactions ]
|
121
|
-
const obj: any[] = Porffor.allocateBytes(
|
121
|
+
const obj: any[] = Porffor.allocateBytes(64);
|
122
122
|
|
123
123
|
// result = undefined
|
124
124
|
obj[0] = undefined;
|
@@ -128,11 +128,11 @@ export const __Porffor_promise_create = (): any[] => {
|
|
128
128
|
obj[1] = 0;
|
129
129
|
|
130
130
|
// fulfillReactions = []
|
131
|
-
const fulfillReactions: any[] = Porffor.allocateBytes(
|
131
|
+
const fulfillReactions: any[] = Porffor.allocateBytes(512);
|
132
132
|
obj[2] = fulfillReactions;
|
133
133
|
|
134
134
|
// rejectReactions = []
|
135
|
-
const rejectReactions: any[] = Porffor.allocateBytes(
|
135
|
+
const rejectReactions: any[] = Porffor.allocateBytes(512);
|
136
136
|
obj[3] = rejectReactions;
|
137
137
|
|
138
138
|
return obj;
|
@@ -140,7 +140,7 @@ export const __Porffor_promise_create = (): any[] => {
|
|
140
140
|
|
141
141
|
export const __Porffor_promise_newReaction = (handler: Function, promise: any, type: i32): any[] => {
|
142
142
|
// enum ReactionType { then = 0, finally = 1 }
|
143
|
-
const out: any[] = Porffor.allocateBytes(
|
143
|
+
const out: any[] = Porffor.allocateBytes(32);
|
144
144
|
out[0] = handler;
|
145
145
|
out[1] = promise;
|
146
146
|
out[2] = type;
|
package/compiler/builtins.js
CHANGED
@@ -1012,7 +1012,7 @@ export const BuiltinFuncs = function() {
|
|
1012
1012
|
returnType: TYPES.number,
|
1013
1013
|
wasm: (scope, { allocPage }) => [
|
1014
1014
|
[ Opcodes.local_get, 0 ],
|
1015
|
-
...number(
|
1015
|
+
...number(64, Valtype.i32),
|
1016
1016
|
[ Opcodes.i32_mul ],
|
1017
1017
|
...number(4, Valtype.i32),
|
1018
1018
|
[ Opcodes.i32_add ],
|
@@ -1027,7 +1027,7 @@ export const BuiltinFuncs = function() {
|
|
1027
1027
|
returnType: TYPES.number,
|
1028
1028
|
wasm: (scope, { allocPage }) => [
|
1029
1029
|
[ Opcodes.local_get, 0 ],
|
1030
|
-
...number(
|
1030
|
+
...number(64, Valtype.i32),
|
1031
1031
|
[ Opcodes.i32_mul ],
|
1032
1032
|
...number(2, Valtype.i32),
|
1033
1033
|
[ Opcodes.i32_add ],
|
@@ -1042,7 +1042,7 @@ export const BuiltinFuncs = function() {
|
|
1042
1042
|
returnType: TYPES.bytestring,
|
1043
1043
|
wasm: (scope, { allocPage }) => [
|
1044
1044
|
[ Opcodes.local_get, 0 ],
|
1045
|
-
...number(
|
1045
|
+
...number(64, Valtype.i32),
|
1046
1046
|
[ Opcodes.i32_mul ],
|
1047
1047
|
...number(5, Valtype.i32),
|
1048
1048
|
[ Opcodes.i32_add ],
|
@@ -1057,7 +1057,7 @@ export const BuiltinFuncs = function() {
|
|
1057
1057
|
returns: [],
|
1058
1058
|
wasm: (scope, { allocPage }) => [
|
1059
1059
|
[ Opcodes.local_get, 0 ],
|
1060
|
-
...number(
|
1060
|
+
...number(64, Valtype.i32),
|
1061
1061
|
[ Opcodes.i32_mul ],
|
1062
1062
|
...number(2, Valtype.i32),
|
1063
1063
|
[ Opcodes.i32_add ],
|
@@ -1076,7 +1076,7 @@ export const BuiltinFuncs = function() {
|
|
1076
1076
|
returns: [],
|
1077
1077
|
wasm: (scope, { allocPage }) => [
|
1078
1078
|
[ Opcodes.local_get, 0 ],
|
1079
|
-
...number(
|
1079
|
+
...number(64, Valtype.i32),
|
1080
1080
|
[ Opcodes.i32_mul ],
|
1081
1081
|
...number(5, Valtype.i32),
|
1082
1082
|
[ Opcodes.i32_add ],
|