porffor 0.2.0-5ad562e → 0.2.0-5c24120
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 +6 -5
- package/compiler/builtins/annexb_string.js +1 -1
- package/compiler/builtins/annexb_string.ts +4 -4
- package/compiler/builtins/array.ts +9 -9
- package/compiler/builtins/boolean.ts +20 -0
- package/compiler/builtins/date.ts +50 -51
- package/compiler/builtins/escape.ts +1 -1
- package/compiler/builtins/function.ts +7 -0
- package/compiler/builtins/int.ts +2 -2
- package/compiler/builtins/number.ts +8 -1
- package/compiler/builtins/object.ts +6 -0
- package/compiler/builtins/string.ts +46 -21
- package/compiler/builtins.js +4 -4
- package/compiler/codegen.js +69 -50
- package/compiler/generated_builtins.js +177 -141
- package/compiler/precompile.js +1 -1
- package/compiler/prefs.js +1 -1
- package/compiler/prototype.js +14 -14
- package/compiler/types.js +1 -1
- package/compiler/wrap.js +3 -3
- package/package.json +1 -1
- package/compiler/builtins/tostring.ts +0 -45
@@ -37,7 +37,7 @@ export const __String_prototype_toUpperCase = (_this: string) => {
|
|
37
37
|
return out;
|
38
38
|
};
|
39
39
|
|
40
|
-
export const
|
40
|
+
export const __ByteString_prototype_toUpperCase = (_this: bytestring) => {
|
41
41
|
const len: i32 = _this.length;
|
42
42
|
|
43
43
|
let out: bytestring = '';
|
@@ -83,7 +83,7 @@ export const __String_prototype_toLowerCase = (_this: string) => {
|
|
83
83
|
return out;
|
84
84
|
};
|
85
85
|
|
86
|
-
export const
|
86
|
+
export const __ByteString_prototype_toLowerCase = (_this: bytestring) => {
|
87
87
|
const len: i32 = _this.length;
|
88
88
|
|
89
89
|
let out: bytestring = '';
|
@@ -134,10 +134,10 @@ export const __String_prototype_startsWith = (_this: string, searchString: strin
|
|
134
134
|
return true;
|
135
135
|
};
|
136
136
|
|
137
|
-
export const
|
137
|
+
export const __ByteString_prototype_startsWith = (_this: bytestring, searchString: bytestring, position: number) => {
|
138
138
|
// if searching non-bytestring, bytestring will not start with it
|
139
139
|
// todo: change this to just check if = string and ToString others
|
140
|
-
if (Porffor.wasm`local.get ${searchString+1}` != Porffor.TYPES.
|
140
|
+
if (Porffor.wasm`local.get ${searchString+1}` != Porffor.TYPES.bytestring) return false;
|
141
141
|
|
142
142
|
// todo/perf: investigate whether for counter vs while ++s are faster
|
143
143
|
|
@@ -204,10 +204,10 @@ export const __String_prototype_endsWith = (_this: string, searchString: string,
|
|
204
204
|
return true;
|
205
205
|
};
|
206
206
|
|
207
|
-
export const
|
207
|
+
export const __ByteString_prototype_endsWith = (_this: bytestring, searchString: bytestring, endPosition: number) => {
|
208
208
|
// if searching non-bytestring, bytestring will not start with it
|
209
209
|
// todo: change this to just check if = string and ToString others
|
210
|
-
if (Porffor.wasm`local.get ${searchString+1}` != Porffor.TYPES.
|
210
|
+
if (Porffor.wasm`local.get ${searchString+1}` != Porffor.TYPES.bytestring) return false;
|
211
211
|
|
212
212
|
let i: i32 = Porffor.wasm`local.get ${_this}`,
|
213
213
|
j: i32 = Porffor.wasm`local.get ${searchString}`;
|
@@ -282,10 +282,10 @@ export const __String_prototype_indexOf = (_this: string, searchString: string,
|
|
282
282
|
return -1;
|
283
283
|
};
|
284
284
|
|
285
|
-
export const
|
285
|
+
export const __ByteString_prototype_indexOf = (_this: bytestring, searchString: bytestring, position: number) => {
|
286
286
|
// if searching non-bytestring, bytestring will not start with it
|
287
287
|
// todo: change this to just check if = string and ToString others
|
288
|
-
if (Porffor.wasm`local.get ${searchString+1}` != Porffor.TYPES.
|
288
|
+
if (Porffor.wasm`local.get ${searchString+1}` != Porffor.TYPES.bytestring) return -1;
|
289
289
|
|
290
290
|
let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
|
291
291
|
const searchPtr: i32 = Porffor.wasm`local.get ${searchString}`;
|
@@ -369,10 +369,10 @@ export const __String_prototype_lastIndexOf = (_this: string, searchString: stri
|
|
369
369
|
return -1;
|
370
370
|
};
|
371
371
|
|
372
|
-
export const
|
372
|
+
export const __ByteString_prototype_lastIndexOf = (_this: bytestring, searchString: bytestring, position: number) => {
|
373
373
|
// if searching non-bytestring, bytestring will not start with it
|
374
374
|
// todo: change this to just check if = string and ToString others
|
375
|
-
if (Porffor.wasm`local.get ${searchString+1}` != Porffor.TYPES.
|
375
|
+
if (Porffor.wasm`local.get ${searchString+1}` != Porffor.TYPES.bytestring) return -1;
|
376
376
|
|
377
377
|
let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
|
378
378
|
const searchPtr: i32 = Porffor.wasm`local.get ${searchString}`;
|
@@ -455,10 +455,10 @@ export const __String_prototype_includes = (_this: string, searchString: string,
|
|
455
455
|
return false;
|
456
456
|
};
|
457
457
|
|
458
|
-
export const
|
458
|
+
export const __ByteString_prototype_includes = (_this: bytestring, searchString: bytestring, position: number) => {
|
459
459
|
// if searching non-bytestring, bytestring will not start with it
|
460
460
|
// todo: change this to just check if = string and ToString others
|
461
|
-
if (Porffor.wasm`local.get ${searchString+1}` != Porffor.TYPES.
|
461
|
+
if (Porffor.wasm`local.get ${searchString+1}` != Porffor.TYPES.bytestring) return -1;
|
462
462
|
|
463
463
|
let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
|
464
464
|
const searchPtr: i32 = Porffor.wasm`local.get ${searchString}`;
|
@@ -542,7 +542,7 @@ export const __String_prototype_padStart = (_this: string, targetLength: number,
|
|
542
542
|
return out;
|
543
543
|
};
|
544
544
|
|
545
|
-
export const
|
545
|
+
export const __ByteString_prototype_padStart = (_this: bytestring, targetLength: number, padString: bytestring) => {
|
546
546
|
// todo: handle padString being non-bytestring
|
547
547
|
|
548
548
|
let out: bytestring = Porffor.bs``;
|
@@ -631,7 +631,7 @@ export const __String_prototype_padEnd = (_this: string, targetLength: number, p
|
|
631
631
|
return out;
|
632
632
|
};
|
633
633
|
|
634
|
-
export const
|
634
|
+
export const __ByteString_prototype_padEnd = (_this: bytestring, targetLength: number, padString: bytestring) => {
|
635
635
|
// todo: handle padString being non-bytestring
|
636
636
|
|
637
637
|
let out: bytestring = Porffor.bs``;
|
@@ -713,7 +713,7 @@ export const __String_prototype_substring = (_this: string, start: number, end:
|
|
713
713
|
return out;
|
714
714
|
};
|
715
715
|
|
716
|
-
export const
|
716
|
+
export const __ByteString_prototype_substring = (_this: bytestring, start: number, end: number) => {
|
717
717
|
const len: i32 = _this.length;
|
718
718
|
if (Porffor.wasm`local.get ${end+1}` == Porffor.TYPES.undefined) end = len;
|
719
719
|
else if (start > end) {
|
@@ -786,7 +786,7 @@ export const __String_prototype_substr = (_this: string, start: number, length:
|
|
786
786
|
return out;
|
787
787
|
};
|
788
788
|
|
789
|
-
export const
|
789
|
+
export const __ByteString_prototype_substr = (_this: string, start: number, length: number) => {
|
790
790
|
const len: i32 = _this.length;
|
791
791
|
|
792
792
|
start |= 0;
|
@@ -862,7 +862,7 @@ export const __String_prototype_slice = (_this: string, start: number, end: numb
|
|
862
862
|
return out;
|
863
863
|
};
|
864
864
|
|
865
|
-
export const
|
865
|
+
export const __ByteString_prototype_slice = (_this: bytestring, start: number, end: number) => {
|
866
866
|
const len: i32 = _this.length;
|
867
867
|
if (Porffor.wasm`local.get ${end+1}` == Porffor.TYPES.undefined) end = len;
|
868
868
|
|
@@ -935,7 +935,7 @@ export const __String_prototype_trimStart = (_this: string) => {
|
|
935
935
|
return out;
|
936
936
|
};
|
937
937
|
|
938
|
-
export const
|
938
|
+
export const __ByteString_prototype_trimStart = (_this: bytestring) => {
|
939
939
|
let out: bytestring = Porffor.bs``;
|
940
940
|
|
941
941
|
let outPtr: i32 = Porffor.wasm`local.get ${out}`;
|
@@ -1006,7 +1006,7 @@ export const __String_prototype_trimEnd = (_this: string) => {
|
|
1006
1006
|
return out;
|
1007
1007
|
};
|
1008
1008
|
|
1009
|
-
export const
|
1009
|
+
export const __ByteString_prototype_trimEnd = (_this: bytestring) => {
|
1010
1010
|
let out: bytestring = Porffor.bs``;
|
1011
1011
|
|
1012
1012
|
let outPtr: i32 = Porffor.wasm`local.get ${out}`;
|
@@ -1049,7 +1049,32 @@ export const __String_prototype_trim = (_this: string) => {
|
|
1049
1049
|
return __String_prototype_trimStart(__String_prototype_trimEnd(_this));
|
1050
1050
|
};
|
1051
1051
|
|
1052
|
-
export const
|
1052
|
+
export const __ByteString_prototype_trim = (_this: bytestring) => {
|
1053
1053
|
// todo/perf: optimize and not just reuse
|
1054
|
-
return
|
1054
|
+
return __ByteString_prototype_trimStart(__ByteString_prototype_trimEnd(_this));
|
1055
|
+
};
|
1056
|
+
|
1057
|
+
// 22.1.3.29 String.prototype.toString ()
|
1058
|
+
// https://tc39.es/ecma262/#sec-string.prototype.tostring
|
1059
|
+
export const __String_prototype_toString = (_this: string) => {
|
1060
|
+
// 1. Return ? ThisStringValue(this value).
|
1061
|
+
return _this;
|
1062
|
+
};
|
1063
|
+
|
1064
|
+
export const __ByteString_prototype_toString = (_this: bytestring) => {
|
1065
|
+
// 1. Return ? ThisStringValue(this value).
|
1066
|
+
return _this;
|
1067
|
+
};
|
1068
|
+
|
1069
|
+
|
1070
|
+
// 22.1.3.35 String.prototype.valueOf ()
|
1071
|
+
// https://tc39.es/ecma262/#sec-string.prototype.valueof
|
1072
|
+
export const __String_prototype_valueOf = (_this: string) => {
|
1073
|
+
// 1. Return ? ThisStringValue(this value).
|
1074
|
+
return _this;
|
1075
|
+
};
|
1076
|
+
|
1077
|
+
export const __ByteString_prototype_valueOf = (_this: bytestring) => {
|
1078
|
+
// 1. Return ? ThisStringValue(this value).
|
1079
|
+
return _this;
|
1055
1080
|
};
|
package/compiler/builtins.js
CHANGED
@@ -141,7 +141,7 @@ export const BuiltinVars = function() {
|
|
141
141
|
|
142
142
|
// wintercg(tm)
|
143
143
|
this.__navigator_userAgent = (scope, { makeString }) => makeString(scope, `Porffor/0.2.0`, false, '__navigator_userAgent');
|
144
|
-
this.__navigator_userAgent.type = Prefs.bytestring ? TYPES.
|
144
|
+
this.__navigator_userAgent.type = Prefs.bytestring ? TYPES.bytestring : TYPES.string;
|
145
145
|
|
146
146
|
for (const x in TYPES) {
|
147
147
|
this['__Porffor_TYPES_' + x] = number(TYPES[x]);
|
@@ -273,7 +273,7 @@ export const BuiltinFuncs = function() {
|
|
273
273
|
|
274
274
|
[ Opcodes.end ]
|
275
275
|
],
|
276
|
-
[TYPES.
|
276
|
+
[TYPES.bytestring]: [
|
277
277
|
// simply print a (byte)string :))
|
278
278
|
// cache input pointer as i32
|
279
279
|
[ Opcodes.local_get, 0 ],
|
@@ -307,7 +307,7 @@ export const BuiltinFuncs = function() {
|
|
307
307
|
|
308
308
|
[ Opcodes.end ]
|
309
309
|
],
|
310
|
-
[TYPES.
|
310
|
+
[TYPES.array]: [
|
311
311
|
...printStaticStr('[ '),
|
312
312
|
|
313
313
|
// cache input pointer as i32
|
@@ -1039,7 +1039,7 @@ export const BuiltinFuncs = function() {
|
|
1039
1039
|
typedParams: true,
|
1040
1040
|
locals: [ Valtype.i32, Valtype.i32 ],
|
1041
1041
|
returns: [ valtypeBinary ],
|
1042
|
-
returnType: Prefs.bytestring ? TYPES.
|
1042
|
+
returnType: Prefs.bytestring ? TYPES.bytestring : TYPES.string,
|
1043
1043
|
wasm: (scope, { TYPE_NAMES, typeSwitch, makeString }) => {
|
1044
1044
|
const bc = {};
|
1045
1045
|
for (const x in TYPE_NAMES) {
|
package/compiler/codegen.js
CHANGED
@@ -59,6 +59,10 @@ const todo = (scope, msg, expectsValue = undefined) => {
|
|
59
59
|
};
|
60
60
|
|
61
61
|
const isFuncType = type => type === 'FunctionDeclaration' || type === 'FunctionExpression' || type === 'ArrowFunctionExpression';
|
62
|
+
const hasFuncWithName = name => {
|
63
|
+
const func = funcs.find(x => x.name === name);
|
64
|
+
return !!(func || builtinFuncs[name] || importedFuncs[name] || internalConstrs[name]);
|
65
|
+
};
|
62
66
|
const generate = (scope, decl, global = false, name = undefined, valueUnused = false) => {
|
63
67
|
switch (decl.type) {
|
64
68
|
case 'BinaryExpression':
|
@@ -219,8 +223,8 @@ const generate = (scope, decl, global = false, name = undefined, valueUnused = f
|
|
219
223
|
__Porffor_bs: str => [
|
220
224
|
...makeString(scope, str, global, name, true),
|
221
225
|
|
222
|
-
...(name ? setType(scope, name, TYPES.
|
223
|
-
...number(TYPES.
|
226
|
+
...(name ? setType(scope, name, TYPES.bytestring) : [
|
227
|
+
...number(TYPES.bytestring, Valtype.i32),
|
224
228
|
...setLastType(scope)
|
225
229
|
])
|
226
230
|
],
|
@@ -723,7 +727,7 @@ const truthy = (scope, wasm, type, intIn = false, intOut = false) => {
|
|
723
727
|
|
724
728
|
...typeSwitch(scope, type, {
|
725
729
|
// [TYPES.number]: def,
|
726
|
-
[TYPES.
|
730
|
+
[TYPES.array]: [
|
727
731
|
// arrays are always truthy
|
728
732
|
...number(1, intOut ? Valtype.i32 : valtypeBinary)
|
729
733
|
],
|
@@ -739,7 +743,7 @@ const truthy = (scope, wasm, type, intIn = false, intOut = false) => {
|
|
739
743
|
[ Opcodes.i32_eqz ], */
|
740
744
|
...(intOut ? [] : [ Opcodes.i32_from_u ])
|
741
745
|
],
|
742
|
-
[TYPES.
|
746
|
+
[TYPES.bytestring]: [ // duplicate of string
|
743
747
|
...(!useTmp ? [] : [ [ Opcodes.local_get, tmp ] ]),
|
744
748
|
...(intIn ? [] : [ Opcodes.i32_to_u ]),
|
745
749
|
|
@@ -762,7 +766,7 @@ const falsy = (scope, wasm, type, intIn = false, intOut = false) => {
|
|
762
766
|
...(!useTmp ? [] : [ [ Opcodes.local_set, tmp ] ]),
|
763
767
|
|
764
768
|
...typeSwitch(scope, type, {
|
765
|
-
[TYPES.
|
769
|
+
[TYPES.array]: [
|
766
770
|
// arrays are always truthy
|
767
771
|
...number(0, intOut ? Valtype.i32 : valtypeBinary)
|
768
772
|
],
|
@@ -777,7 +781,7 @@ const falsy = (scope, wasm, type, intIn = false, intOut = false) => {
|
|
777
781
|
[ Opcodes.i32_eqz ],
|
778
782
|
...(intOut ? [] : [ Opcodes.i32_from_u ])
|
779
783
|
],
|
780
|
-
[TYPES.
|
784
|
+
[TYPES.bytestring]: [ // duplicate of string
|
781
785
|
...(!useTmp ? [] : [ [ Opcodes.local_get, tmp ] ]),
|
782
786
|
...(intIn ? [] : [ Opcodes.i32_to_u ]),
|
783
787
|
|
@@ -922,7 +926,7 @@ const performOp = (scope, op, left, right, leftType, rightType, _global = false,
|
|
922
926
|
}
|
923
927
|
}
|
924
928
|
|
925
|
-
if (knownLeft === TYPES.
|
929
|
+
if (knownLeft === TYPES.bytestring || knownRight === TYPES.bytestring) {
|
926
930
|
if (op === '+') {
|
927
931
|
// todo: this should be dynamic too but for now only static
|
928
932
|
// string concat (a + b)
|
@@ -1041,12 +1045,12 @@ const performOp = (scope, op, left, right, leftType, rightType, _global = false,
|
|
1041
1045
|
|
1042
1046
|
// if left is bytestring
|
1043
1047
|
...leftType,
|
1044
|
-
...number(TYPES.
|
1048
|
+
...number(TYPES.bytestring, Valtype.i32),
|
1045
1049
|
[ Opcodes.i32_eq ],
|
1046
1050
|
|
1047
1051
|
// if right is bytestring
|
1048
1052
|
...rightType,
|
1049
|
-
...number(TYPES.
|
1053
|
+
...number(TYPES.bytestring, Valtype.i32),
|
1050
1054
|
[ Opcodes.i32_eq ],
|
1051
1055
|
|
1052
1056
|
// if both are true
|
@@ -1177,7 +1181,6 @@ const generateLogicExp = (scope, decl) => {
|
|
1177
1181
|
// js type: 4 bits
|
1178
1182
|
// internal type: ? bits
|
1179
1183
|
// pointer: 32 bits
|
1180
|
-
|
1181
1184
|
// generic
|
1182
1185
|
// 1 23 4 5
|
1183
1186
|
// 0 11111111111 11TTTTIIII??????????PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
|
@@ -1188,7 +1191,7 @@ const generateLogicExp = (scope, decl) => {
|
|
1188
1191
|
// 5: pointer
|
1189
1192
|
|
1190
1193
|
const isExistingProtoFunc = name => {
|
1191
|
-
if (name.startsWith('__Array_prototype')) return !!prototypeFuncs[TYPES.
|
1194
|
+
if (name.startsWith('__Array_prototype')) return !!prototypeFuncs[TYPES.array][name.slice(18)];
|
1192
1195
|
if (name.startsWith('__String_prototype_')) return !!prototypeFuncs[TYPES.string][name.slice(19)];
|
1193
1196
|
|
1194
1197
|
return false;
|
@@ -1247,9 +1250,9 @@ const setLastType = scope => {
|
|
1247
1250
|
const getNodeType = (scope, node) => {
|
1248
1251
|
const inner = () => {
|
1249
1252
|
if (node.type === 'Literal') {
|
1250
|
-
if (node.regex) return TYPES.
|
1253
|
+
if (node.regex) return TYPES.regexp;
|
1251
1254
|
|
1252
|
-
if (typeof node.value === 'string' && byteStringable(node.value)) return TYPES.
|
1255
|
+
if (typeof node.value === 'string' && byteStringable(node.value)) return TYPES.bytestring;
|
1253
1256
|
|
1254
1257
|
return TYPES[typeof node.value];
|
1255
1258
|
}
|
@@ -1303,7 +1306,7 @@ const getNodeType = (scope, node) => {
|
|
1303
1306
|
const spl = name.slice(2).split('_');
|
1304
1307
|
|
1305
1308
|
const func = spl[spl.length - 1];
|
1306
|
-
const protoFuncs = Object.keys(prototypeFuncs).filter(x => x != TYPES.
|
1309
|
+
const protoFuncs = Object.keys(prototypeFuncs).filter(x => x != TYPES.bytestring && prototypeFuncs[x][func] != null);
|
1307
1310
|
if (protoFuncs.length === 1) return protoFuncs[0].returnType ?? TYPES.number;
|
1308
1311
|
}
|
1309
1312
|
|
@@ -1355,7 +1358,7 @@ const getNodeType = (scope, node) => {
|
|
1355
1358
|
}
|
1356
1359
|
|
1357
1360
|
if (node.type === 'ArrayExpression') {
|
1358
|
-
return TYPES.
|
1361
|
+
return TYPES.array;
|
1359
1362
|
}
|
1360
1363
|
|
1361
1364
|
if (node.type === 'BinaryExpression') {
|
@@ -1367,7 +1370,7 @@ const getNodeType = (scope, node) => {
|
|
1367
1370
|
|
1368
1371
|
// todo: this should be dynamic but for now only static
|
1369
1372
|
if (knownLeft === TYPES.string || knownRight === TYPES.string) return TYPES.string;
|
1370
|
-
if (knownLeft === TYPES.
|
1373
|
+
if (knownLeft === TYPES.bytestring || knownRight === TYPES.bytestring) return TYPES.bytestring;
|
1371
1374
|
|
1372
1375
|
return TYPES.number;
|
1373
1376
|
|
@@ -1393,19 +1396,28 @@ const getNodeType = (scope, node) => {
|
|
1393
1396
|
if (node.operator === '!') return TYPES.boolean;
|
1394
1397
|
if (node.operator === 'void') return TYPES.undefined;
|
1395
1398
|
if (node.operator === 'delete') return TYPES.boolean;
|
1396
|
-
if (node.operator === 'typeof') return Prefs.bytestring ? TYPES.
|
1399
|
+
if (node.operator === 'typeof') return Prefs.bytestring ? TYPES.bytestring : TYPES.string;
|
1397
1400
|
|
1398
1401
|
return TYPES.number;
|
1399
1402
|
}
|
1400
1403
|
|
1401
1404
|
if (node.type === 'MemberExpression') {
|
1405
|
+
// hack: if something.name, string type
|
1406
|
+
if (node.property.name === 'name') {
|
1407
|
+
if (hasFuncWithName(node.object.name)) {
|
1408
|
+
return TYPES.bytestring;
|
1409
|
+
} else {
|
1410
|
+
return TYPES.undefined;
|
1411
|
+
}
|
1412
|
+
}
|
1413
|
+
|
1402
1414
|
// hack: if something.length, number type
|
1403
1415
|
if (node.property.name === 'length') return TYPES.number;
|
1404
1416
|
|
1405
1417
|
// ts hack
|
1406
1418
|
if (scope.locals[node.object.name]?.metadata?.type === TYPES.string) return TYPES.string;
|
1407
|
-
if (scope.locals[node.object.name]?.metadata?.type === TYPES.
|
1408
|
-
if (scope.locals[node.object.name]?.metadata?.type === TYPES.
|
1419
|
+
if (scope.locals[node.object.name]?.metadata?.type === TYPES.bytestring) return TYPES.bytestring;
|
1420
|
+
if (scope.locals[node.object.name]?.metadata?.type === TYPES.array) return TYPES.number;
|
1409
1421
|
|
1410
1422
|
if (scope.locals['#last_type']) return getLastType(scope);
|
1411
1423
|
|
@@ -2092,7 +2104,7 @@ const brTable = (input, bc, returns) => {
|
|
2092
2104
|
};
|
2093
2105
|
|
2094
2106
|
const typeSwitch = (scope, type, bc, returns = valtypeBinary) => {
|
2095
|
-
if (!Prefs.bytestring) delete bc[TYPES.
|
2107
|
+
if (!Prefs.bytestring) delete bc[TYPES.bytestring];
|
2096
2108
|
|
2097
2109
|
const known = knownType(scope, type);
|
2098
2110
|
if (known != null) {
|
@@ -2195,7 +2207,7 @@ const extractTypeAnnotation = decl => {
|
|
2195
2207
|
const typeName = type;
|
2196
2208
|
type = typeAnnoToPorfType(type);
|
2197
2209
|
|
2198
|
-
if (type === TYPES.
|
2210
|
+
if (type === TYPES.bytestring && !Prefs.bytestring) type = TYPES.string;
|
2199
2211
|
|
2200
2212
|
// if (decl.name) console.log(decl.name, { type, elementType });
|
2201
2213
|
|
@@ -2325,7 +2337,7 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
2325
2337
|
|
2326
2338
|
return [
|
2327
2339
|
...typeSwitch(scope, getNodeType(scope, decl.left.object), {
|
2328
|
-
[TYPES.
|
2340
|
+
[TYPES.array]: [
|
2329
2341
|
...(aotPointer ? [] : [
|
2330
2342
|
...generate(scope, decl.left.object),
|
2331
2343
|
Opcodes.i32_to_u
|
@@ -2527,7 +2539,7 @@ const generateUnary = (scope, decl) => {
|
|
2527
2539
|
[TYPES.undefined]: makeString(scope, 'undefined', false, '#typeof_result'),
|
2528
2540
|
[TYPES.function]: makeString(scope, 'function', false, '#typeof_result'),
|
2529
2541
|
|
2530
|
-
[TYPES.
|
2542
|
+
[TYPES.bytestring]: makeString(scope, 'string', false, '#typeof_result'),
|
2531
2543
|
|
2532
2544
|
// object and internal types
|
2533
2545
|
default: makeString(scope, 'object', false, '#typeof_result'),
|
@@ -2763,7 +2775,7 @@ const generateForOf = (scope, decl) => {
|
|
2763
2775
|
// set type for local
|
2764
2776
|
// todo: optimize away counter and use end pointer
|
2765
2777
|
out.push(...typeSwitch(scope, getNodeType(scope, decl.right), {
|
2766
|
-
[TYPES.
|
2778
|
+
[TYPES.array]: [
|
2767
2779
|
...setType(scope, leftName, TYPES.number),
|
2768
2780
|
|
2769
2781
|
[ Opcodes.loop, Blocktype.void ],
|
@@ -2846,8 +2858,8 @@ const generateForOf = (scope, decl) => {
|
|
2846
2858
|
[ Opcodes.end ],
|
2847
2859
|
[ Opcodes.end ]
|
2848
2860
|
],
|
2849
|
-
[TYPES.
|
2850
|
-
...setType(scope, leftName, TYPES.
|
2861
|
+
[TYPES.bytestring]: [
|
2862
|
+
...setType(scope, leftName, TYPES.bytestring),
|
2851
2863
|
|
2852
2864
|
[ Opcodes.loop, Blocktype.void ],
|
2853
2865
|
|
@@ -3229,6 +3241,20 @@ export const generateMember = (scope, decl, _global, _name) => {
|
|
3229
3241
|
|
3230
3242
|
const aotPointer = Prefs.aotPointerOpt && pointer != null;
|
3231
3243
|
|
3244
|
+
// hack: .name
|
3245
|
+
if (decl.property.name === 'name') {
|
3246
|
+
if (hasFuncWithName(name)) {
|
3247
|
+
let nameProp = name;
|
3248
|
+
|
3249
|
+
// eg: __String_prototype_toLowerCase -> toLowerCase
|
3250
|
+
if (nameProp.startsWith('__')) nameProp = nameProp.split('_').pop();
|
3251
|
+
|
3252
|
+
return makeString(scope, nameProp, _global, _name, true);
|
3253
|
+
} else {
|
3254
|
+
return generate(scope, DEFAULT_VALUE);
|
3255
|
+
}
|
3256
|
+
}
|
3257
|
+
|
3232
3258
|
// hack: .length
|
3233
3259
|
if (decl.property.name === 'length') {
|
3234
3260
|
const func = funcs.find(x => x.name === name);
|
@@ -3238,6 +3264,16 @@ export const generateMember = (scope, decl, _global, _name) => {
|
|
3238
3264
|
return number(typedParams ? func.params.length / 2 : func.params.length);
|
3239
3265
|
}
|
3240
3266
|
|
3267
|
+
if (builtinFuncs[name + '$constructor']) {
|
3268
|
+
const regularFunc = builtinFuncs[name];
|
3269
|
+
const regularParams = regularFunc.typedParams ? (regularFunc.params.length / 2) : regularFunc.params.length;
|
3270
|
+
|
3271
|
+
const constructorFunc = builtinFuncs[name + '$constructor'];
|
3272
|
+
const constructorParams = constructorFunc.typedParams ? (constructorFunc.params.length / 2) : constructorFunc.params.length;
|
3273
|
+
|
3274
|
+
return number(Math.max(regularParams, constructorParams));
|
3275
|
+
}
|
3276
|
+
|
3241
3277
|
if (builtinFuncs[name]) return number(builtinFuncs[name].typedParams ? (builtinFuncs[name].params.length / 2) : builtinFuncs[name].params.length);
|
3242
3278
|
if (importedFuncs[name]) return number(importedFuncs[name].params);
|
3243
3279
|
if (internalConstrs[name]) return number(internalConstrs[name].length ?? 0);
|
@@ -3266,7 +3302,7 @@ export const generateMember = (scope, decl, _global, _name) => {
|
|
3266
3302
|
}
|
3267
3303
|
|
3268
3304
|
return typeSwitch(scope, getNodeType(scope, decl.object), {
|
3269
|
-
[TYPES.
|
3305
|
+
[TYPES.array]: [
|
3270
3306
|
// get index as valtype
|
3271
3307
|
...property,
|
3272
3308
|
|
@@ -3319,7 +3355,7 @@ export const generateMember = (scope, decl, _global, _name) => {
|
|
3319
3355
|
...number(TYPES.string, Valtype.i32),
|
3320
3356
|
...setLastType(scope)
|
3321
3357
|
],
|
3322
|
-
[TYPES.
|
3358
|
+
[TYPES.bytestring]: [
|
3323
3359
|
// setup new/out array
|
3324
3360
|
...newOut,
|
3325
3361
|
[ Opcodes.drop ],
|
@@ -3344,7 +3380,7 @@ export const generateMember = (scope, decl, _global, _name) => {
|
|
3344
3380
|
// return new string (page)
|
3345
3381
|
...number(newPointer),
|
3346
3382
|
|
3347
|
-
...number(TYPES.
|
3383
|
+
...number(TYPES.bytestring, Valtype.i32),
|
3348
3384
|
...setLastType(scope)
|
3349
3385
|
],
|
3350
3386
|
|
@@ -3369,8 +3405,8 @@ const objectHack = node => {
|
|
3369
3405
|
|
3370
3406
|
if (!objectName) objectName = objectHack(node.object)?.name?.slice?.(2);
|
3371
3407
|
|
3372
|
-
// if .length, give up (hack within a hack!)
|
3373
|
-
if (node.property.name
|
3408
|
+
// if .name or .length, give up (hack within a hack!)
|
3409
|
+
if (['name', 'length'].includes(node.property.name)) {
|
3374
3410
|
node.object = objectHack(node.object);
|
3375
3411
|
return;
|
3376
3412
|
}
|
@@ -3513,7 +3549,7 @@ const internalConstrs = {
|
|
3513
3549
|
...number(pointer)
|
3514
3550
|
];
|
3515
3551
|
},
|
3516
|
-
type: TYPES.
|
3552
|
+
type: TYPES.array,
|
3517
3553
|
length: 1
|
3518
3554
|
},
|
3519
3555
|
|
@@ -3525,7 +3561,7 @@ const internalConstrs = {
|
|
3525
3561
|
elements: decl.arguments
|
3526
3562
|
}, global, name);
|
3527
3563
|
},
|
3528
|
-
type: TYPES.
|
3564
|
+
type: TYPES.array,
|
3529
3565
|
notConstr: true,
|
3530
3566
|
length: 0
|
3531
3567
|
},
|
@@ -3654,23 +3690,6 @@ const internalConstrs = {
|
|
3654
3690
|
}
|
3655
3691
|
};
|
3656
3692
|
|
3657
|
-
// const _ = Array.prototype.push;
|
3658
|
-
// Array.prototype.push = function (a) {
|
3659
|
-
// const check = arr => {
|
3660
|
-
// for (const x of arr) {
|
3661
|
-
// if (x === undefined) {
|
3662
|
-
// console.trace(arr);
|
3663
|
-
// process.exit();
|
3664
|
-
// }
|
3665
|
-
// if (Array.isArray(x)) check(x);
|
3666
|
-
// }
|
3667
|
-
// };
|
3668
|
-
// if (Array.isArray(a) && !new Error().stack.includes('node:')) check(a);
|
3669
|
-
// // if (Array.isArray(a)) check(a);
|
3670
|
-
|
3671
|
-
// return _.apply(this, arguments);
|
3672
|
-
// };
|
3673
|
-
|
3674
3693
|
export default program => {
|
3675
3694
|
globals = {};
|
3676
3695
|
globalInd = 0;
|