porffor 0.57.12 → 0.57.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/array.ts +1 -1
- package/compiler/builtins/arraybuffer.ts +1 -1
- package/compiler/builtins/atomics.js +169 -0
- package/compiler/builtins/typedarray.js +3 -4
- package/compiler/builtins_objects.js +1 -1
- package/compiler/builtins_precompiled.js +778 -707
- package/compiler/codegen.js +7 -3
- package/compiler/disassemble.js +1 -3
- package/compiler/types.js +1 -1
- package/compiler/wasmSpec.js +51 -1
- package/foo.js +10 -0
- package/foo.ts +10 -3
- package/package.json +1 -1
- package/runtime/index.js +1 -1
@@ -44,7 +44,7 @@ export const __Array_from = (arg: any, mapFn: any): any[] => {
|
|
44
44
|
Porffor.type(arg) == Porffor.TYPES.array,
|
45
45
|
Porffor.type(arg) == Porffor.TYPES.string, Porffor.type(arg) == Porffor.TYPES.bytestring,
|
46
46
|
Porffor.type(arg) == Porffor.TYPES.set,
|
47
|
-
Porffor.fastAnd(Porffor.type(arg) >= Porffor.TYPES.
|
47
|
+
Porffor.fastAnd(Porffor.type(arg) >= Porffor.TYPES.uint8clampedarray, Porffor.type(arg) <= Porffor.TYPES.float64array)
|
48
48
|
)) {
|
49
49
|
let i: i32 = 0;
|
50
50
|
if (Porffor.type(mapFn) != Porffor.TYPES.undefined) {
|
@@ -3,7 +3,7 @@ import type {} from './porffor.d.ts';
|
|
3
3
|
export const __ArrayBuffer_isView = (value: any): boolean => {
|
4
4
|
return Porffor.fastOr(
|
5
5
|
Porffor.type(value) == Porffor.TYPES.dataview,
|
6
|
-
Porffor.fastAnd(Porffor.type(value) >= Porffor.TYPES.
|
6
|
+
Porffor.fastAnd(Porffor.type(value) >= Porffor.TYPES.uint8clampedarray, Porffor.type(value) <= Porffor.TYPES.float64array)
|
7
7
|
);
|
8
8
|
};
|
9
9
|
|
@@ -0,0 +1,169 @@
|
|
1
|
+
export default () => {
|
2
|
+
let out = `
|
3
|
+
export const __Atomics_isLockFree = (x: number): boolean => {
|
4
|
+
switch (x) {
|
5
|
+
case 1:
|
6
|
+
case 2:
|
7
|
+
case 4:
|
8
|
+
case 8:
|
9
|
+
return true;
|
10
|
+
}
|
11
|
+
|
12
|
+
return false;
|
13
|
+
};`;
|
14
|
+
|
15
|
+
const func = (name, op, args, retType, wasm, only3264 = false) => {
|
16
|
+
const signed = type => {
|
17
|
+
switch (type) {
|
18
|
+
case 'uint8array':
|
19
|
+
case 'uint8clampedarray':
|
20
|
+
case 'uint16array':
|
21
|
+
case 'uint32array':
|
22
|
+
case 'biguint64array':
|
23
|
+
return false;
|
24
|
+
|
25
|
+
case 'int8array':
|
26
|
+
case 'int16array':
|
27
|
+
case 'int32array':
|
28
|
+
case 'bigint64array':
|
29
|
+
return true;
|
30
|
+
}
|
31
|
+
};
|
32
|
+
|
33
|
+
const getOp = (type, ret = true) => {
|
34
|
+
if (op === 'memory.atomic.notify') return `${op} 2 4\ni32.from_u`;
|
35
|
+
|
36
|
+
switch (type) {
|
37
|
+
case 'uint8array':
|
38
|
+
case 'uint8clampedarray':
|
39
|
+
case 'int8array':
|
40
|
+
return `${op}8 0 4${ret ? `\ni32.from${signed(type) ? '' : '_u'}` : ''}`;
|
41
|
+
|
42
|
+
case 'uint16array':
|
43
|
+
case 'int16array':
|
44
|
+
return `${op}16 1 4${ret ? `\ni32.from${signed(type) ? '' : '_u'}` : ''}`;
|
45
|
+
|
46
|
+
case 'uint32array':
|
47
|
+
case 'int32array':
|
48
|
+
return `${op} 2 4${ret ? `\ni32.from${signed(type) ? '' : '_u'}` : ''}`;
|
49
|
+
|
50
|
+
case 'biguint64array':
|
51
|
+
case 'bigint64array':
|
52
|
+
return `${op.replace('32', '64')} 3 4${ret ? `\ncall __Porffor_bigint_from${signed(type) ? 'S' : 'U'}64` : ''}`;
|
53
|
+
}
|
54
|
+
};
|
55
|
+
|
56
|
+
const bytes = type => {
|
57
|
+
switch (type) {
|
58
|
+
case 'uint8array':
|
59
|
+
case 'uint8clampedarray':
|
60
|
+
case 'int8array':
|
61
|
+
return 1;
|
62
|
+
|
63
|
+
case 'uint16array':
|
64
|
+
case 'int16array':
|
65
|
+
return 2;
|
66
|
+
|
67
|
+
case 'uint32array':
|
68
|
+
case 'int32array':
|
69
|
+
return 4;
|
70
|
+
|
71
|
+
case 'biguint64array':
|
72
|
+
case 'bigint64array':
|
73
|
+
return 8;
|
74
|
+
}
|
75
|
+
};
|
76
|
+
|
77
|
+
const getArg = (type, name, value = false) => {
|
78
|
+
if (!value) return `local.get ${name}
|
79
|
+
i32.to_u`;
|
80
|
+
|
81
|
+
switch (type) {
|
82
|
+
case 'biguint64array':
|
83
|
+
case 'bigint64array':
|
84
|
+
return `local.get ${name}
|
85
|
+
call __Porffor_bigint_toI64`;
|
86
|
+
}
|
87
|
+
|
88
|
+
return `local.get ${name}
|
89
|
+
i32.to${signed(type) ? '' : '_u'}`;
|
90
|
+
};
|
91
|
+
|
92
|
+
out += `export const __Atomics_${name} = (ta: any, index: any, ${args}): ${retType} => {
|
93
|
+
${only3264 ? `
|
94
|
+
if (Porffor.fastAnd(Porffor.type(ta) != Porffor.TYPES.int32array, Porffor.type(ta) != Porffor.TYPES.bigint64array))
|
95
|
+
throw new TypeError('Atomics.${name} can only be used with a Int32Array or BigInt64Array');
|
96
|
+
|
97
|
+
if (Porffor.type(ta.buffer) != Porffor.TYPES.sharedarraybuffer)
|
98
|
+
throw new TypeError('Atomics.${name} can only be used with a shared typed arrays');` : `
|
99
|
+
if (Porffor.fastOr(Porffor.type(ta) < Porffor.TYPES.uint8array, Porffor.type(ta) > Porffor.TYPES.bigint64array))
|
100
|
+
throw new TypeError('Atomics can only be used with an integer typed array');`}
|
101
|
+
|
102
|
+
index = ecma262.ToIntegerOrInfinity(index);
|
103
|
+
if (Porffor.fastOr(index < 0, index > ta.length))
|
104
|
+
throw new RangeError('Index out of bounds');
|
105
|
+
|
106
|
+
${args.split(',').map(arg => {
|
107
|
+
const [ name, _ ] = arg.split(':');
|
108
|
+
if (!_) return;
|
109
|
+
|
110
|
+
const [ type, value ] = _.split('=');
|
111
|
+
const nonfinite = value && value.includes('Infinity');
|
112
|
+
|
113
|
+
return `
|
114
|
+
${name} = ecma262.ToIntegerOrInfinity(${name});
|
115
|
+
${nonfinite ? `if (${name} == Infinity) ${name} = -1;` : ''}`;
|
116
|
+
}).join('')}
|
117
|
+
|
118
|
+
${(only3264 ? ['int32array', 'bigint64array'] : ['uint8array', 'uint8clampedarray', 'uint16array', 'int16array', 'uint32array', 'int32array', 'biguint64array', 'bigint64array']).map(x => `if (Porffor.type(ta) == Porffor.TYPES.${x}) {
|
119
|
+
Porffor.wasm\`
|
120
|
+
local.get ta
|
121
|
+
i32.to_u
|
122
|
+
i32.load 0 4
|
123
|
+
local.get index
|
124
|
+
i32.to_u
|
125
|
+
i32.const ${bytes(x)}
|
126
|
+
i32.mul
|
127
|
+
i32.add
|
128
|
+
${wasm({ arg: (name, value) => getArg(x, name, value), op: y => getOp(x, y) })}
|
129
|
+
return\`;
|
130
|
+
}`).join('\n')}
|
131
|
+
};\n`;
|
132
|
+
};
|
133
|
+
|
134
|
+
func('load', 'i32.atomic.load', '', 'f64', ({ op }) => `${op()}`);
|
135
|
+
func('store', 'i32.atomic.store', 'value: any', 'f64', ({ arg, op }) => `
|
136
|
+
${arg('value', true)}
|
137
|
+
${op(false)}
|
138
|
+
local.get value`);
|
139
|
+
|
140
|
+
for (const x of ['add', 'sub', 'and', 'or', 'xor'])
|
141
|
+
func(x, `i32.atomic.rmw.${x}`, 'value: any', 'f64', ({ arg, op }) => `
|
142
|
+
${arg('value', true)}
|
143
|
+
${op()}`);
|
144
|
+
|
145
|
+
func('exchange', 'i32.atomic.rmw.xchg', 'value: any', 'f64', ({ arg, op }) => `
|
146
|
+
${arg('value', true)}
|
147
|
+
${op()}`);
|
148
|
+
func('compareExchange', 'i32.atomic.rmw.cmpxchg', 'expected: any, replacement: any', 'f64', ({ arg, op }) => `
|
149
|
+
${arg('expected', true)}
|
150
|
+
${arg('replacement', true)}
|
151
|
+
${op()}`);
|
152
|
+
|
153
|
+
// todo: int -> string (0 = ok, 1 = not-equal, 2 = timed-out)
|
154
|
+
func('wait', 'memory.atomic.wait32', 'value: any, timeout: any = Infinity', 'bytestring', ({ arg, op }) => `
|
155
|
+
${arg('value', true)}
|
156
|
+
${arg('timeout')}
|
157
|
+
i64_extend_i32_u
|
158
|
+
i64.const 1000000 ;; ms -> ns
|
159
|
+
i64.mul
|
160
|
+
${op(false)}
|
161
|
+
i32.from_u`, true);
|
162
|
+
// todo: waitAsync
|
163
|
+
|
164
|
+
func('notify', 'memory.atomic.notify', 'count: any = Infinity', 'f64', ({ arg, op }) => `
|
165
|
+
${arg('count')}
|
166
|
+
${op()}`);
|
167
|
+
|
168
|
+
return out;
|
169
|
+
};
|
@@ -25,7 +25,6 @@ export default async () => {
|
|
25
25
|
Porffor.type(arg) == Porffor.TYPES.sharedarraybuffer
|
26
26
|
)) {
|
27
27
|
bufferPtr = Porffor.wasm\`local.get \${arg}\`;
|
28
|
-
|
29
28
|
if (arg.detached) throw new TypeError('Constructed ${name} with a detached ArrayBuffer');
|
30
29
|
|
31
30
|
let offset: i32 = 0;
|
@@ -49,7 +48,7 @@ export default async () => {
|
|
49
48
|
Porffor.type(arg) == Porffor.TYPES.array,
|
50
49
|
Porffor.type(arg) == Porffor.TYPES.string, Porffor.type(arg) == Porffor.TYPES.bytestring,
|
51
50
|
Porffor.type(arg) == Porffor.TYPES.set,
|
52
|
-
Porffor.fastAnd(Porffor.type(arg) >= Porffor.TYPES.
|
51
|
+
Porffor.fastAnd(Porffor.type(arg) >= Porffor.TYPES.uint8clampedarray, Porffor.type(arg) <= Porffor.TYPES.float64array)
|
53
52
|
)) {
|
54
53
|
let i: i32 = 0;
|
55
54
|
for (const x of arg) {
|
@@ -80,7 +79,7 @@ export const __${name}_from = (arg: any, mapFn: any): ${name} => {
|
|
80
79
|
Porffor.type(arg) == Porffor.TYPES.array,
|
81
80
|
Porffor.type(arg) == Porffor.TYPES.string, Porffor.type(arg) == Porffor.TYPES.bytestring,
|
82
81
|
Porffor.type(arg) == Porffor.TYPES.set,
|
83
|
-
Porffor.fastAnd(Porffor.type(arg) >= Porffor.TYPES.
|
82
|
+
Porffor.fastAnd(Porffor.type(arg) >= Porffor.TYPES.uint8clampedarray, Porffor.type(arg) <= Porffor.TYPES.float64array)
|
84
83
|
)) {
|
85
84
|
let i: i32 = 0;
|
86
85
|
if (Porffor.type(mapFn) != Porffor.TYPES.undefined) {
|
@@ -168,7 +167,7 @@ export const __${name}_prototype_set = (_this: ${name}, array: any, offset: numb
|
|
168
167
|
Porffor.type(array) == Porffor.TYPES.array,
|
169
168
|
Porffor.type(array) == Porffor.TYPES.string, Porffor.type(array) == Porffor.TYPES.bytestring,
|
170
169
|
Porffor.type(array) == Porffor.TYPES.set,
|
171
|
-
Porffor.fastAnd(Porffor.type(array) >= Porffor.TYPES.
|
170
|
+
Porffor.fastAnd(Porffor.type(array) >= Porffor.TYPES.uint8clampedarray, Porffor.type(array) <= Porffor.TYPES.float64array)
|
172
171
|
)) {
|
173
172
|
let i: i32 = offset;
|
174
173
|
for (const x of array) {
|
@@ -268,7 +268,7 @@ export default function({ builtinFuncs }, Prefs) {
|
|
268
268
|
object('Array', autoFuncs('Array'));
|
269
269
|
object('Symbol', autoFuncs('Symbol'));
|
270
270
|
object('Date', autoFuncs('Date'));
|
271
|
-
|
271
|
+
object('Atomics', autoFuncs('Atomics'));
|
272
272
|
|
273
273
|
// these technically not spec compliant as it should be classes or non-enumerable but eh
|
274
274
|
object('navigator', {
|