porffor 0.2.0-ef043de → 0.2.0-f435128
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/CONTRIBUTING.md +181 -0
- package/README.md +18 -24
- package/asur/index.js +1 -1
- package/compiler/assemble.js +1 -1
- package/compiler/builtins/annexb_string.js +1 -1
- package/compiler/builtins/annexb_string.ts +1 -1
- package/compiler/builtins/array.ts +1 -1
- package/compiler/builtins/base64.ts +1 -1
- package/compiler/builtins/crypto.ts +1 -1
- package/compiler/builtins/date.ts +549 -63
- package/compiler/builtins/escape.ts +1 -1
- package/compiler/builtins/int.ts +1 -1
- package/compiler/builtins/number.ts +1 -1
- package/compiler/builtins/string.ts +1 -1
- package/compiler/builtins/tostring.ts +1 -1
- package/compiler/codegen.js +74 -35
- package/compiler/decompile.js +0 -1
- package/compiler/generated_builtins.js +266 -83
- package/compiler/parse.js +4 -2
- package/compiler/precompile.js +6 -1
- package/compiler/prefs.js +5 -4
- package/package.json +1 -1
- package/rhemyn/compile.js +42 -25
- package/rhemyn/parse.js +4 -5
- package/runner/index.js +34 -6
- package/runner/repl.js +2 -2
- package/runner/sizes.js +1 -1
- package/fib.js +0 -7
package/compiler/codegen.js
CHANGED
@@ -201,7 +201,7 @@ const generate = (scope, decl, global = false, name = undefined, valueUnused = f
|
|
201
201
|
}
|
202
202
|
|
203
203
|
let inst = Opcodes[asm[0].replace('.', '_')];
|
204
|
-
if (
|
204
|
+
if (inst == null) throw new Error(`inline asm: inst ${asm[0]} not found`);
|
205
205
|
|
206
206
|
if (!Array.isArray(inst)) inst = [ inst ];
|
207
207
|
const immediates = asm.slice(1).map(x => {
|
@@ -460,7 +460,7 @@ const concatStrings = (scope, left, right, global, name, assign = false, bytestr
|
|
460
460
|
const rightLength = localTmp(scope, 'concat_right_length', Valtype.i32);
|
461
461
|
const leftLength = localTmp(scope, 'concat_left_length', Valtype.i32);
|
462
462
|
|
463
|
-
if (assign) {
|
463
|
+
if (assign && Prefs.aotPointerOpt) {
|
464
464
|
const pointer = scope.arrays?.get(name ?? '$undeclared');
|
465
465
|
|
466
466
|
return [
|
@@ -1646,18 +1646,25 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
1646
1646
|
// megahack for /regex/.func()
|
1647
1647
|
const funcName = decl.callee.property.name;
|
1648
1648
|
if (decl.callee.object.regex && Object.hasOwn(Rhemyn, funcName)) {
|
1649
|
-
const
|
1649
|
+
const regex = decl.callee.object.regex.pattern;
|
1650
|
+
const rhemynName = `regex_${funcName}_${regex}`;
|
1650
1651
|
|
1651
|
-
funcIndex[
|
1652
|
-
|
1652
|
+
if (!funcIndex[rhemynName]) {
|
1653
|
+
const func = Rhemyn[funcName](regex, currentFuncIndex++, rhemynName);
|
1653
1654
|
|
1655
|
+
funcIndex[func.name] = func.index;
|
1656
|
+
funcs.push(func);
|
1657
|
+
}
|
1658
|
+
|
1659
|
+
const idx = funcIndex[rhemynName];
|
1654
1660
|
return [
|
1655
1661
|
// make string arg
|
1656
1662
|
...generate(scope, decl.arguments[0]),
|
1663
|
+
Opcodes.i32_to_u,
|
1664
|
+
...getNodeType(scope, decl.arguments[0]),
|
1657
1665
|
|
1658
1666
|
// call regex func
|
1659
|
-
Opcodes.
|
1660
|
-
[ Opcodes.call, func.index ],
|
1667
|
+
[ Opcodes.call, idx ],
|
1661
1668
|
Opcodes.i32_from_u,
|
1662
1669
|
|
1663
1670
|
...number(TYPES.boolean, Valtype.i32),
|
@@ -1820,20 +1827,20 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
1820
1827
|
idx = funcIndex[name];
|
1821
1828
|
|
1822
1829
|
// infer arguments types from builtins params
|
1823
|
-
const func = funcs.find(x => x.name === name);
|
1824
|
-
for (let i = 0; i < decl.arguments.length; i++) {
|
1825
|
-
|
1826
|
-
|
1827
|
-
|
1828
|
-
|
1829
|
-
|
1830
|
-
|
1831
|
-
|
1832
|
-
|
1833
|
-
|
1834
|
-
|
1835
|
-
|
1836
|
-
}
|
1830
|
+
// const func = funcs.find(x => x.name === name);
|
1831
|
+
// for (let i = 0; i < decl.arguments.length; i++) {
|
1832
|
+
// const arg = decl.arguments[i];
|
1833
|
+
// if (!arg.name) continue;
|
1834
|
+
|
1835
|
+
// const local = scope.locals[arg.name];
|
1836
|
+
// if (!local) continue;
|
1837
|
+
|
1838
|
+
// local.type = func.params[i];
|
1839
|
+
// if (local.type === Valtype.v128) {
|
1840
|
+
// // specify vec subtype inferred from last vec type in function name
|
1841
|
+
// local.vecType = name.split('_').reverse().find(x => x.includes('x'));
|
1842
|
+
// }
|
1843
|
+
// }
|
1837
1844
|
}
|
1838
1845
|
|
1839
1846
|
if (idx === undefined && internalConstrs[name]) return internalConstrs[name].generate(scope, decl, _global, _name);
|
@@ -2205,6 +2212,7 @@ const generateVar = (scope, decl) => {
|
|
2205
2212
|
|
2206
2213
|
// global variable if in top scope (main) and var ..., or if wanted
|
2207
2214
|
const global = topLevel || decl._bare; // decl.kind === 'var';
|
2215
|
+
const target = global ? globals : scope.locals;
|
2208
2216
|
|
2209
2217
|
for (const x of decl.declarations) {
|
2210
2218
|
const name = mapName(x.id.name);
|
@@ -2226,6 +2234,10 @@ const generateVar = (scope, decl) => {
|
|
2226
2234
|
continue; // always ignore
|
2227
2235
|
}
|
2228
2236
|
|
2237
|
+
// // generate init before allocating var
|
2238
|
+
// let generated;
|
2239
|
+
// if (x.init) generated = generate(scope, x.init, global, name);
|
2240
|
+
|
2229
2241
|
const typed = typedInput && x.id.typeAnnotation;
|
2230
2242
|
let idx = allocVar(scope, name, global, !(typed && extractTypeAnnotation(x.id).type != null));
|
2231
2243
|
|
@@ -2234,9 +2246,17 @@ const generateVar = (scope, decl) => {
|
|
2234
2246
|
}
|
2235
2247
|
|
2236
2248
|
if (x.init) {
|
2237
|
-
|
2238
|
-
|
2239
|
-
|
2249
|
+
const generated = generate(scope, x.init, global, name);
|
2250
|
+
if (scope.arrays?.get(name) != null) {
|
2251
|
+
// hack to set local as pointer before
|
2252
|
+
out.push(...number(scope.arrays.get(name)), [ global ? Opcodes.global_set : Opcodes.local_set, idx ]);
|
2253
|
+
if (generated.at(-1) == Opcodes.i32_from_u) generated.pop();
|
2254
|
+
generated.pop();
|
2255
|
+
out = out.concat(generated);
|
2256
|
+
} else {
|
2257
|
+
out = out.concat(generated);
|
2258
|
+
out.push([ global ? Opcodes.global_set : Opcodes.local_set, idx ]);
|
2259
|
+
}
|
2240
2260
|
out.push(...setType(scope, name, getNodeType(scope, x.init)));
|
2241
2261
|
}
|
2242
2262
|
|
@@ -2263,6 +2283,8 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
2263
2283
|
return [];
|
2264
2284
|
}
|
2265
2285
|
|
2286
|
+
const op = decl.operator.slice(0, -1) || '=';
|
2287
|
+
|
2266
2288
|
// hack: .length setter
|
2267
2289
|
if (decl.left.type === 'MemberExpression' && decl.left.property.name === 'length') {
|
2268
2290
|
const name = decl.left.object.name;
|
@@ -2271,14 +2293,20 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
2271
2293
|
const aotPointer = Prefs.aotPointerOpt && pointer != null;
|
2272
2294
|
|
2273
2295
|
const newValueTmp = localTmp(scope, '__length_setter_tmp');
|
2296
|
+
const pointerTmp = op === '=' ? null : localTmp(scope, '__member_setter_ptr_tmp', Valtype.i32);
|
2274
2297
|
|
2275
2298
|
return [
|
2276
2299
|
...(aotPointer ? number(0, Valtype.i32) : [
|
2277
2300
|
...generate(scope, decl.left.object),
|
2278
2301
|
Opcodes.i32_to_u
|
2279
2302
|
]),
|
2303
|
+
...(!pointerTmp ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
|
2280
2304
|
|
2281
|
-
...generate(scope, decl.right),
|
2305
|
+
...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
|
2306
|
+
[ Opcodes.local_get, pointerTmp ],
|
2307
|
+
[ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
|
2308
|
+
Opcodes.i32_from_u
|
2309
|
+
], generate(scope, decl.right), number(TYPES.number, Valtype.i32), getNodeType(scope, decl.right))),
|
2282
2310
|
[ Opcodes.local_tee, newValueTmp ],
|
2283
2311
|
|
2284
2312
|
Opcodes.i32_to_u,
|
@@ -2288,8 +2316,6 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
2288
2316
|
];
|
2289
2317
|
}
|
2290
2318
|
|
2291
|
-
const op = decl.operator.slice(0, -1) || '=';
|
2292
|
-
|
2293
2319
|
// arr[i]
|
2294
2320
|
if (decl.left.type === 'MemberExpression' && decl.left.computed) {
|
2295
2321
|
const name = decl.left.object.name;
|
@@ -3093,12 +3119,14 @@ const makeArray = (scope, decl, global = false, name = '$undeclared', initEmpty
|
|
3093
3119
|
// todo: can we just have 1 undeclared array? probably not? but this is not really memory efficient
|
3094
3120
|
const uniqueName = name === '$undeclared' ? name + Math.random().toString().slice(2) : name;
|
3095
3121
|
|
3096
|
-
if (Prefs.scopedPageNames) scope.arrays.set(name, allocPage(scope, `${
|
3122
|
+
if (Prefs.scopedPageNames) scope.arrays.set(name, allocPage(scope, `${getAllocType(itemType)}: ${scope.name}/${uniqueName}`, itemType) * pageSize);
|
3097
3123
|
else scope.arrays.set(name, allocPage(scope, `${getAllocType(itemType)}: ${uniqueName}`, itemType) * pageSize);
|
3098
3124
|
}
|
3099
3125
|
|
3100
3126
|
const pointer = scope.arrays.get(name);
|
3101
3127
|
|
3128
|
+
const local = global ? globals[name] : scope.locals[name];
|
3129
|
+
|
3102
3130
|
const useRawElements = !!decl.rawElements;
|
3103
3131
|
const elements = useRawElements ? decl.rawElements : decl.elements;
|
3104
3132
|
|
@@ -3131,11 +3159,22 @@ const makeArray = (scope, decl, global = false, name = '$undeclared', initEmpty
|
|
3131
3159
|
return [ out, pointer ];
|
3132
3160
|
}
|
3133
3161
|
|
3162
|
+
const pointerTmp = local != null ? localTmp(scope, '#makearray_pointer_tmp', Valtype.i32) : null;
|
3163
|
+
if (pointerTmp != null) {
|
3164
|
+
out.push(
|
3165
|
+
[ global ? Opcodes.global_get : Opcodes.local_get, local.idx ],
|
3166
|
+
Opcodes.i32_to_u,
|
3167
|
+
[ Opcodes.local_set, pointerTmp ]
|
3168
|
+
);
|
3169
|
+
}
|
3170
|
+
|
3171
|
+
const pointerWasm = pointerTmp != null ? [ [ Opcodes.local_get, pointerTmp ] ] : number(pointer, Valtype.i32);
|
3172
|
+
|
3134
3173
|
// store length as 0th array
|
3135
3174
|
out.push(
|
3136
|
-
...
|
3175
|
+
...pointerWasm,
|
3137
3176
|
...number(length, Valtype.i32),
|
3138
|
-
[ Opcodes.i32_store, Math.log2(ValtypeSize.i32) - 1,
|
3177
|
+
[ Opcodes.i32_store, Math.log2(ValtypeSize.i32) - 1, 0 ]
|
3139
3178
|
);
|
3140
3179
|
|
3141
3180
|
const storeOp = StoreOps[itemType];
|
@@ -3144,14 +3183,14 @@ const makeArray = (scope, decl, global = false, name = '$undeclared', initEmpty
|
|
3144
3183
|
if (elements[i] == null) continue;
|
3145
3184
|
|
3146
3185
|
out.push(
|
3147
|
-
...
|
3186
|
+
...pointerWasm,
|
3148
3187
|
...(useRawElements ? number(elements[i], Valtype[valtype]) : generate(scope, elements[i])),
|
3149
|
-
[ storeOp, (Math.log2(ValtypeSize[itemType]) || 1) - 1, ...unsignedLEB128(
|
3188
|
+
[ storeOp, (Math.log2(ValtypeSize[itemType]) || 1) - 1, ...unsignedLEB128(ValtypeSize.i32 + i * ValtypeSize[itemType]) ]
|
3150
3189
|
);
|
3151
3190
|
}
|
3152
3191
|
|
3153
3192
|
// local value as pointer
|
3154
|
-
out.push(...
|
3193
|
+
out.push(...pointerWasm, Opcodes.i32_from_u);
|
3155
3194
|
|
3156
3195
|
return [ out, pointer ];
|
3157
3196
|
};
|
@@ -3649,7 +3688,7 @@ export default program => {
|
|
3649
3688
|
|
3650
3689
|
globalThis.valtype = 'f64';
|
3651
3690
|
|
3652
|
-
const valtypeOpt = process.argv.find(x => x.startsWith('
|
3691
|
+
const valtypeOpt = process.argv.find(x => x.startsWith('--valtype='));
|
3653
3692
|
if (valtypeOpt) valtype = valtypeOpt.split('=')[1];
|
3654
3693
|
|
3655
3694
|
globalThis.valtypeBinary = Valtype[valtype];
|
@@ -3657,7 +3696,7 @@ export default program => {
|
|
3657
3696
|
const valtypeInd = ['i32', 'i64', 'f64'].indexOf(valtype);
|
3658
3697
|
|
3659
3698
|
globalThis.pageSize = PageSize;
|
3660
|
-
const pageSizeOpt = process.argv.find(x => x.startsWith('
|
3699
|
+
const pageSizeOpt = process.argv.find(x => x.startsWith('--page-size='));
|
3661
3700
|
if (pageSizeOpt) pageSize = parseInt(pageSizeOpt.split('=')[1]) * 1024;
|
3662
3701
|
|
3663
3702
|
// set generic opcodes for current valtype
|