porffor 0.17.0-93ba20045 → 0.17.0-94400a2b8

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.
@@ -2,17 +2,18 @@
2
2
  import type {} from './porffor.d.ts';
3
3
 
4
4
  export const btoa = (input: bytestring): bytestring => {
5
+ // todo: throw on invalid chars
6
+
5
7
  const keyStr: bytestring = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
6
8
  const keyStrPtr: i32 = Porffor.wasm`local.get ${keyStr}`;
7
9
 
8
10
  let len: i32 = input.length;
9
11
  let output: bytestring = '';
10
- output.length = 4 * (len / 3 + !!(len % 3));
11
12
 
12
13
  let i: i32 = Porffor.wasm`local.get ${input}`,
13
14
  j: i32 = Porffor.wasm`local.get ${output}`;
14
15
 
15
- // todo/perf: add some per 6 char variant using bitwise magic
16
+ // todo/perf: add some per 6 char variant using bitwise magic?
16
17
 
17
18
  const endPtr = i + len;
18
19
  while (i < endPtr) {
@@ -38,40 +39,43 @@ export const btoa = (input: bytestring): bytestring => {
38
39
  Porffor.wasm.i32.store8(j++, Porffor.wasm.i32.load8_u(keyStrPtr + enc4, 0, 4), 0, 4);
39
40
  }
40
41
 
42
+ output.length = j - Porffor.wasm`local.get ${output}`;
41
43
  return output;
42
44
  };
43
45
 
44
- // todo: impl atob by converting below to "porf ts"
45
- /* var atob = function (input) {
46
- const keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
46
+ export const atob = (input: bytestring): bytestring => {
47
+ // todo: throw on non-base64 chars
48
+
49
+ const lut: bytestring = '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@>@@@?456789:;<=@@@@@@@\x00\x01\x02\x03\x04\x05\x06\x07\b\t\n\x0B\f\r\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19@@@@@@\x1A\x1B\x1C\x1D\x1E\x1F !"#$%&\'()*+,-./0123';
50
+ const lutPtr: i32 = Porffor.wasm`local.get ${lut}`;
51
+
52
+ let output: bytestring = '';
47
53
 
48
- let output = "";
49
- let chr1, chr2, chr3;
50
- let enc1, enc2, enc3, enc4;
51
- let i = 0;
54
+ let i: i32 = Porffor.wasm`local.get ${input}`,
55
+ j: i32 = Porffor.wasm`local.get ${output}`;
52
56
 
53
- while (i < input.length) {
54
- enc1 = keyStr.indexOf(input.charAt(i++));
55
- enc2 = keyStr.indexOf(input.charAt(i++));
56
- enc3 = keyStr.indexOf(input.charAt(i++));
57
- enc4 = keyStr.indexOf(input.charAt(i++));
57
+ const endPtr = i + input.length;
58
+ while (i < endPtr) {
59
+ const enc1: i32 = Porffor.wasm.i32.load8_u(lutPtr + Porffor.wasm.i32.load8_u(i++, 0, 4), 0, 4);
60
+ const enc2: i32 = i < endPtr ? Porffor.wasm.i32.load8_u(lutPtr + Porffor.wasm.i32.load8_u(i++, 0, 4), 0, 4) : -1;
61
+ const enc3: i32 = i < endPtr ? Porffor.wasm.i32.load8_u(lutPtr + Porffor.wasm.i32.load8_u(i++, 0, 4), 0, 4) : -1;
62
+ const enc4: i32 = i < endPtr ? Porffor.wasm.i32.load8_u(lutPtr + Porffor.wasm.i32.load8_u(i++, 0, 4), 0, 4) : -1;
58
63
 
59
- chr1 = (enc1 << 2) | (enc2 >> 4);
60
- chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
61
- chr3 = ((enc3 & 3) << 6) | enc4;
64
+ const chr1: i32 = (enc1 << 2) | (enc2 == -1 ? 0 : (enc2 >> 4));
65
+ const chr2: i32 = ((enc2 & 15) << 4) | (enc3 == -1 ? 0 : (enc3 >> 2));
66
+ const chr3: i32 = ((enc3 & 3) << 6) | (enc4 == -1 ? 0 : enc4);
62
67
 
63
- // output += String.fromCharCode(chr1);
64
- Porffor.bytestring.appendCharCode(output, chr1);
68
+ Porffor.wasm.i32.store8(j++, chr1, 0, 4);
65
69
 
66
70
  if (enc3 != 64) {
67
- // output += String.fromCharCode(chr2);
68
- Porffor.bytestring.appendCharCode(output, chr2);
71
+ Porffor.wasm.i32.store8(j++, chr2, 0, 4);
69
72
  }
73
+
70
74
  if (enc4 != 64) {
71
- // output += String.fromCharCode(chr3);
72
- Porffor.bytestring.appendCharCode(output, chr3);
75
+ Porffor.wasm.i32.store8(j++, chr3, 0, 4);
73
76
  }
74
77
  }
75
78
 
79
+ output.length = j - Porffor.wasm`local.get ${output}`;
76
80
  return output;
77
- }; */
81
+ };
@@ -195,3 +195,8 @@ export const __Set_prototype_union = (_this: Set, other: any) => {
195
195
  }
196
196
  return out;
197
197
  };
198
+
199
+ export const __Set_prototype_toString = (_this: Set) => {
200
+ const out: bytestring = '[object Set]';
201
+ return out;
202
+ };
@@ -264,10 +264,12 @@ const internalThrow = (scope, constructor, message, expectsValue = Prefs.alwaysV
264
264
  argument: {
265
265
  type: 'NewExpression',
266
266
  callee: {
267
+ type: 'Identifier',
267
268
  name: constructor
268
269
  },
269
270
  arguments: [
270
271
  {
272
+ type: 'Literal',
271
273
  value: message
272
274
  }
273
275
  ]
@@ -289,12 +291,13 @@ const generateIdent = (scope, decl) => {
289
291
  return wasm.slice();
290
292
  }
291
293
 
292
- if (Object.hasOwn(builtinFuncs, name) || Object.hasOwn(internalConstrs, name)) {
293
- // todo: return an actual something
294
- return number(1);
295
- }
294
+ // todo: enable this by default in future
295
+ // if (!Object.hasOwn(funcIndex, name) && Object.hasOwn(builtinFuncs, name)) {
296
+ // includeBuiltin(scope, name);
297
+ // return number(funcIndex[name] - importedFuncs.length);
298
+ // }
296
299
 
297
- if (isExistingProtoFunc(name)) {
300
+ if (isExistingProtoFunc(name) || Object.hasOwn(internalConstrs, name) || Object.hasOwn(builtinFuncs, name)) {
298
301
  // todo: return an actual something
299
302
  return number(1);
300
303
  }
@@ -973,6 +976,33 @@ const performOp = (scope, op, left, right, leftType, rightType, _global = false,
973
976
  };
974
977
 
975
978
  const generateBinaryExp = (scope, decl, _global, _name) => {
979
+ if (decl.operator === 'instanceof') {
980
+ // very hacky basic instanceof
981
+ // todo: support dynamic right-hand side
982
+
983
+ const out = generate(scope, decl.left);
984
+ disposeLeftover(out);
985
+
986
+ const rightName = decl.right.name;
987
+ if (!rightName) return todo(scope, 'instanceof dynamic right-hand side is not supported yet', true);
988
+
989
+ const checkType = TYPES[rightName.toLowerCase()];
990
+ if (checkType == null || rightName !== TYPE_NAMES[checkType] || checkType === TYPES.undefined) return todo(scope, 'instanceof right-hand side type unsupported', true);
991
+
992
+ if ([TYPES.number, TYPES.boolean, TYPES.string, TYPES.symbol, TYPES.object].includes(checkType)) {
993
+ out.push(...number(0));
994
+ } else {
995
+ out.push(
996
+ ...getNodeType(scope, decl.left),
997
+ ...number(checkType, Valtype.i32),
998
+ [ Opcodes.i32_eq ],
999
+ Opcodes.i32_from_u
1000
+ );
1001
+ }
1002
+
1003
+ return out;
1004
+ }
1005
+
976
1006
  const out = performOp(scope, decl.operator, generate(scope, decl.left), generate(scope, decl.right), getNodeType(scope, decl.left), getNodeType(scope, decl.right), _global, _name);
977
1007
 
978
1008
  if (valtype !== 'i32' && ['==', '===', '!=', '!==', '>', '>=', '<', '<='].includes(decl.operator)) out.push(Opcodes.i32_from_u);
@@ -1279,7 +1309,7 @@ const getNodeType = (scope, node) => {
1279
1309
  }
1280
1310
 
1281
1311
  if (node.type === 'BinaryExpression') {
1282
- if (['==', '===', '!=', '!==', '>', '>=', '<', '<='].includes(node.operator)) return TYPES.boolean;
1312
+ if (['==', '===', '!=', '!==', '>', '>=', '<', '<=', 'instanceof'].includes(node.operator)) return TYPES.boolean;
1283
1313
  if (node.operator !== '+') return TYPES.number;
1284
1314
 
1285
1315
  const knownLeft = knownType(scope, getNodeType(scope, node.left));
@@ -3029,32 +3059,101 @@ const generateLabel = (scope, decl) => {
3029
3059
  const generateThrow = (scope, decl) => {
3030
3060
  scope.throws = true;
3031
3061
 
3032
- let message = decl.argument.value, constructor = null;
3062
+ const exceptionMode = Prefs.exceptionMode ?? 'lut';
3063
+ if (exceptionMode === 'lut') {
3064
+ let message = decl.argument.value, constructor = null;
3065
+
3066
+ // support `throw (new)? Error(...)`
3067
+ if (!message && (decl.argument.type === 'NewExpression' || decl.argument.type === 'CallExpression')) {
3068
+ constructor = decl.argument.callee.name;
3069
+ message = decl.argument.arguments[0]?.value ?? '';
3070
+ }
3071
+
3072
+ if (tags.length === 0) tags.push({
3073
+ params: [ Valtype.i32 ],
3074
+ results: [],
3075
+ idx: tags.length
3076
+ });
3077
+
3078
+ let exceptId = exceptions.push({ constructor, message }) - 1;
3079
+
3080
+ scope.exceptions ??= [];
3081
+ scope.exceptions.push(exceptId);
3082
+
3083
+ return [
3084
+ [ Opcodes.i32_const, signedLEB128(exceptId) ],
3085
+ [ Opcodes.throw, tags[0].idx ]
3086
+ ];
3087
+ }
3033
3088
 
3034
- // hack: throw new X("...") -> throw "..."
3035
- if (!message && (decl.argument.type === 'NewExpression' || decl.argument.type === 'CallExpression')) {
3036
- constructor = decl.argument.callee.name;
3037
- message = decl.argument.arguments[0]?.value ?? '';
3089
+ if (exceptionMode === 'stack') {
3090
+ if (tags.length === 0) tags.push({
3091
+ params: [ valtypeBinary, Valtype.i32 ],
3092
+ results: [],
3093
+ idx: tags.length
3094
+ });
3095
+
3096
+ return [
3097
+ ...generate(scope, decl.argument),
3098
+ ...getNodeType(scope, decl.argument),
3099
+ [ Opcodes.throw, tags[0].idx ]
3100
+ ];
3038
3101
  }
3039
3102
 
3040
- if (tags.length === 0) tags.push({
3041
- params: [ Valtype.i32 ],
3042
- results: [],
3043
- idx: tags.length
3044
- });
3103
+ if (exceptionMode === 'stackest') {
3104
+ let message = decl.argument, constructor = null;
3045
3105
 
3046
- let exceptId = exceptions.push({ constructor, message }) - 1;
3047
- let tagIdx = tags[0].idx;
3106
+ // support `throw (new)? Error(...)`
3107
+ if (message.type === 'NewExpression' || message.type === 'CallExpression') {
3108
+ constructor = decl.argument.callee;
3109
+ message = decl.argument.arguments[0];
3110
+ }
3048
3111
 
3049
- scope.exceptions ??= [];
3050
- scope.exceptions.push(exceptId);
3112
+ message ??= DEFAULT_VALUE;
3051
3113
 
3052
- // todo: write a description of how this works lol
3114
+ if (tags.length === 0) tags.push({
3115
+ params: [ valtypeBinary, valtypeBinary, Valtype.i32 ],
3116
+ results: [],
3117
+ idx: tags.length
3118
+ });
3053
3119
 
3054
- return [
3055
- [ Opcodes.i32_const, signedLEB128(exceptId) ],
3056
- [ Opcodes.throw, tagIdx ]
3057
- ];
3120
+ return [
3121
+ ...(constructor == null ? number(-1) : generate(scope, constructor)),
3122
+ ...generate(scope, message),
3123
+ ...getNodeType(scope, message),
3124
+ [ Opcodes.throw, tags[0].idx ]
3125
+ ];
3126
+ }
3127
+
3128
+ if (exceptionMode === 'partial') {
3129
+ let message = decl.argument, constructor = null;
3130
+
3131
+ // support `throw (new)? Error(...)`
3132
+ if (message.type === 'NewExpression' || message.type === 'CallExpression') {
3133
+ constructor = decl.argument.callee.name;
3134
+ message = decl.argument.arguments[0];
3135
+ }
3136
+
3137
+ message ??= DEFAULT_VALUE;
3138
+
3139
+ if (tags.length === 0) tags.push({
3140
+ params: [ Valtype.i32, valtypeBinary, Valtype.i32 ],
3141
+ results: [],
3142
+ idx: tags.length
3143
+ });
3144
+
3145
+ let exceptId = exceptions.push({ constructor }) - 1;
3146
+
3147
+ scope.exceptions ??= [];
3148
+ scope.exceptions.push(exceptId);
3149
+
3150
+ return [
3151
+ [ Opcodes.i32_const, signedLEB128(exceptId) ],
3152
+ ...generate(scope, message),
3153
+ ...getNodeType(scope, message),
3154
+ [ Opcodes.throw, tags[0].idx ]
3155
+ ];
3156
+ }
3058
3157
  };
3059
3158
 
3060
3159
  const generateTry = (scope, decl) => {
@@ -3772,7 +3871,7 @@ const internalConstrs = {
3772
3871
 
3773
3872
  // todo: check in wasm instead of here
3774
3873
  const literalValue = arg.value ?? 0;
3775
- if (literalValue < 0 || !Number.isFinite(literalValue) || literalValue > 4294967295) return internalThrow(scope, 'RangeThrow', 'Invalid array length', true);
3874
+ if (literalValue < 0 || !Number.isFinite(literalValue) || literalValue > 4294967295) return internalThrow(scope, 'RangeError', 'Invalid array length', true);
3776
3875
 
3777
3876
  return [
3778
3877
  ...out,
@@ -409,15 +409,25 @@ export const BuiltinFuncs = function() {
409
409
  data: [{"bytes":[1,0,0,0,44],"offset":0}],
410
410
  };
411
411
  this.btoa = {
412
- wasm: (scope, {allocPage,}) => [...number(allocPage(scope, 'bytestring: btoa/keyStr', 'i8') * pageSize, 127),[34,2],[33,3],[32,0],[40,1,0],[33,4],...number(allocPage(scope, 'bytestring: btoa/output', 'i8') * pageSize, 127),[34,5],[65,4],[32,4],[65,3],[109],[32,4],[65,3],[111],[106],[108],[34,6],[54,1,0],[32,0],[33,7],[32,5],[33,8],[32,7],[32,4],[106],[33,9],[65,0],[33,10],[3,64],[32,7],[32,9],[72],[4,64],[32,7],[32,7],[65,1],[106],[33,7],[45,0,4],[33,11],[32,7],[32,9],[72],[4,127],[32,7],[32,7],[65,1],[106],[33,7],[45,0,4],[65,0],[33,13],[5],[65,127],[65,0],[33,13],[11],[33,12],[32,7],[32,9],[72],[4,127],[32,7],[32,7],[65,1],[106],[33,7],[45,0,4],[65,0],[33,13],[5],[65,127],[65,0],[33,13],[11],[33,14],[32,11],[65,2],[117],[33,15],[32,11],[65,3],[113],[65,4],[116],[32,12],[65,127],[70],[4,127],[65,0],[65,0],[33,13],[5],[32,12],[65,4],[117],[65,0],[33,13],[11],[114],[33,16],[32,12],[65,15],[113],[65,2],[116],[32,14],[65,127],[70],[4,127],[65,0],[65,0],[33,13],[5],[32,14],[65,6],[117],[65,0],[33,13],[11],[114],[33,17],[32,14],[65,63],[113],[33,18],[32,12],[65,127],[70],[4,64],[65,192,0],[33,17],[65,192,0],[33,18],[5],[32,14],[65,127],[70],[4,64],[65,192,0],[33,18],[11],[11],[32,8],[32,8],[65,1],[106],[33,8],[32,3],[32,15],[106],[45,0,4],[58,0,4],[32,8],[32,8],[65,1],[106],[33,8],[32,3],[32,16],[106],[45,0,4],[58,0,4],[32,8],[32,8],[65,1],[106],[33,8],[32,3],[32,17],[106],[45,0,4],[58,0,4],[32,8],[32,8],[65,1],[106],[33,8],[32,3],[32,18],[106],[45,0,4],[58,0,4],[12,1],[11],[11],[32,5],[15]],
412
+ wasm: (scope, {allocPage,}) => [...number(allocPage(scope, 'bytestring: btoa/keyStr', 'i8') * pageSize, 127),[34,2],[33,3],[32,0],[40,1,0],[33,4],...number(allocPage(scope, 'bytestring: btoa/output', 'i8') * pageSize, 127),[33,5],[32,0],[33,6],[32,5],[33,7],[32,6],[32,4],[106],[33,8],[65,0],[33,9],[3,64],[32,6],[32,8],[72],[4,64],[32,6],[32,6],[65,1],[106],[33,6],[45,0,4],[33,10],[32,6],[32,8],[72],[4,127],[32,6],[32,6],[65,1],[106],[33,6],[45,0,4],[65,0],[33,12],[5],[65,127],[65,0],[33,12],[11],[33,11],[32,6],[32,8],[72],[4,127],[32,6],[32,6],[65,1],[106],[33,6],[45,0,4],[65,0],[33,12],[5],[65,127],[65,0],[33,12],[11],[33,13],[32,10],[65,2],[117],[33,14],[32,10],[65,3],[113],[65,4],[116],[32,11],[65,127],[70],[4,127],[65,0],[65,0],[33,12],[5],[32,11],[65,4],[117],[65,0],[33,12],[11],[114],[33,15],[32,11],[65,15],[113],[65,2],[116],[32,13],[65,127],[70],[4,127],[65,0],[65,0],[33,12],[5],[32,13],[65,6],[117],[65,0],[33,12],[11],[114],[33,16],[32,13],[65,63],[113],[33,17],[32,11],[65,127],[70],[4,64],[65,192,0],[33,16],[65,192,0],[33,17],[5],[32,13],[65,127],[70],[4,64],[65,192,0],[33,17],[11],[11],[32,7],[32,7],[65,1],[106],[33,7],[32,3],[32,14],[106],[45,0,4],[58,0,4],[32,7],[32,7],[65,1],[106],[33,7],[32,3],[32,15],[106],[45,0,4],[58,0,4],[32,7],[32,7],[65,1],[106],[33,7],[32,3],[32,16],[106],[45,0,4],[58,0,4],[32,7],[32,7],[65,1],[106],[33,7],[32,3],[32,17],[106],[45,0,4],[58,0,4],[12,1],[11],[11],[32,5],[32,7],[32,5],[107],[34,18],[54,1,0],[32,5],[15]],
413
413
  params: [127,127],
414
414
  typedParams: true,
415
415
  returns: [127],
416
416
  returnType: 18,
417
417
  locals: [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127],
418
- localNames: ["input","input#type","keyStr","keyStrPtr","len","output","__length_setter_tmp","i","j","endPtr","endPtr#type","chr1","chr2","#last_type","chr3","enc1","enc2","enc3","enc4"],
418
+ localNames: ["input","input#type","keyStr","keyStrPtr","len","output","i","j","endPtr","endPtr#type","chr1","chr2","#last_type","chr3","enc1","enc2","enc3","enc4","__length_setter_tmp"],
419
419
  data: [{"bytes":[65,0,0,0,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,48,49,50,51,52,53,54,55,56,57,43,47,61],"offset":0}],
420
420
  };
421
+ this.atob = {
422
+ wasm: (scope, {allocPage,}) => [...number(allocPage(scope, 'bytestring: atob/lut', 'i8') * pageSize, 127),[34,2],[33,3],...number(allocPage(scope, 'bytestring: atob/output', 'i8') * pageSize, 127),[33,4],[32,0],[33,5],[32,4],[33,6],[32,5],[32,0],[40,1,0],[106],[33,7],[65,0],[33,8],[3,64],[32,5],[32,7],[72],[4,64],[32,3],[32,5],[32,5],[65,1],[106],[33,5],[45,0,4],[106],[45,0,4],[33,9],[32,5],[32,7],[72],[4,127],[32,3],[32,5],[32,5],[65,1],[106],[33,5],[45,0,4],[106],[45,0,4],[65,0],[33,11],[5],[65,127],[65,0],[33,11],[11],[33,10],[32,5],[32,7],[72],[4,127],[32,3],[32,5],[32,5],[65,1],[106],[33,5],[45,0,4],[106],[45,0,4],[65,0],[33,11],[5],[65,127],[65,0],[33,11],[11],[33,12],[32,5],[32,7],[72],[4,127],[32,3],[32,5],[32,5],[65,1],[106],[33,5],[45,0,4],[106],[45,0,4],[65,0],[33,11],[5],[65,127],[65,0],[33,11],[11],[33,13],[32,9],[65,2],[116],[32,10],[65,127],[70],[4,127],[65,0],[65,0],[33,11],[5],[32,10],[65,4],[117],[65,0],[33,11],[11],[114],[33,14],[32,10],[65,15],[113],[65,4],[116],[32,12],[65,127],[70],[4,127],[65,0],[65,0],[33,11],[5],[32,12],[65,2],[117],[65,0],[33,11],[11],[114],[33,15],[32,12],[65,3],[113],[65,6],[116],[32,13],[65,127],[70],[4,127],[65,0],[65,0],[33,11],[5],[32,13],[65,0],[33,11],[11],[114],[33,16],[32,6],[32,6],[65,1],[106],[33,6],[32,14],[58,0,4],[32,12],[65,192,0],[71],[4,64],[32,6],[32,6],[65,1],[106],[33,6],[32,15],[58,0,4],[11],[32,13],[65,192,0],[71],[4,64],[32,6],[32,6],[65,1],[106],[33,6],[32,16],[58,0,4],[11],[12,1],[11],[11],[32,4],[32,6],[32,4],[107],[34,17],[54,1,0],[32,4],[15]],
423
+ params: [127,127],
424
+ typedParams: true,
425
+ returns: [127],
426
+ returnType: 18,
427
+ locals: [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127],
428
+ localNames: ["input","input#type","lut","lutPtr","output","i","j","endPtr","endPtr#type","enc1","enc2","#last_type","enc3","enc4","chr1","chr2","chr3","__length_setter_tmp"],
429
+ data: [{"bytes":[123,0,0,0,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,62,64,64,64,63,52,53,54,55,56,57,58,59,60,61,64,64,64,64,64,64,64,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,64,64,64,64,64,64,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51],"offset":0}],
430
+ };
421
431
  this.__Boolean_prototype_toString = {
422
432
  wasm: (scope, {allocPage,}) => [...number(allocPage(scope, 'bytestring: __Boolean_prototype_toString/out', 'i8') * pageSize, 124),[33,2],[32,0],[252,3],[4,64],[32,2],[252,3],[34,3],[65,4],[54,1,0],[32,3],[65,244,0],[58,0,4],[32,3],[65,242,0],[58,0,5],[32,3],[65,245,0],[58,0,6],[32,3],[65,229,0],[58,0,7],[32,3],[184],[33,2],[5],[32,2],[252,3],[34,3],[65,5],[54,1,0],[32,3],[65,230,0],[58,0,4],[32,3],[65,225,0],[58,0,5],[32,3],[65,236,0],[58,0,6],[32,3],[65,243,0],[58,0,7],[32,3],[65,229,0],[58,0,8],[32,3],[184],[33,2],[11],[32,2],[65,18],[15]],
423
433
  params: [124,127],
@@ -1776,6 +1786,16 @@ export const BuiltinFuncs = function() {
1776
1786
  locals: [124,127,127,127,124,127,127,127],
1777
1787
  localNames: ["_this","_this#type","other","other#type","out","forof_base_pointer","forof_length","forof_counter","x","x#type","#last_type","#typeswitch_tmp"],
1778
1788
  };
1789
+ this.__Set_prototype_toString = {
1790
+ wasm: (scope, {allocPage,}) => [...number(allocPage(scope, 'bytestring: __Set_prototype_toString/out', 'i8') * pageSize, 124),[34,2],[65,18],[15]],
1791
+ params: [124,127],
1792
+ typedParams: true,
1793
+ returns: [124,127],
1794
+ typedReturns: true,
1795
+ locals: [124],
1796
+ localNames: ["_this","_this#type","out"],
1797
+ data: [{"bytes":[12,0,0,0,91,111,98,106,101,99,116,32,83,101,116,93],"offset":0}],
1798
+ };
1779
1799
  this.__String_fromCharCode = {
1780
1800
  wasm: (scope, {allocPage,}) => [[32,0],[65,128,2],[72],[4,64],...number(allocPage(scope, 'bytestring: __String_fromCharCode/out', 'i8') * pageSize, 127),[34,2],[32,0],[58,0,4],[32,2],[65,18],[15],[11],[32,2],[34,3],[65,1],[54,1,0],[32,3],[65,46],[59,0,4],[32,3],[34,2],[32,0],[59,0,4],[32,2],[65,2],[15]],
1781
1801
  params: [127,127],
@@ -2165,7 +2185,7 @@ export const BuiltinFuncs = function() {
2165
2185
  localNames: ["argument","argument#type","number"],
2166
2186
  };
2167
2187
  this.__ecma262_ToString = {
2168
- wasm: (scope, {allocPage,builtin,internalThrow,}) => [...number(allocPage(scope, 'bytestring: __ecma262_ToString/out', 'i8') * pageSize, 124),[33,2],[32,0],[32,1],[16, builtin('__Porffor_rawType')],[34,3],[68,0,0,0,0,0,0,0,64],[97],[32,3],[68,0,0,0,0,0,0,50,64],[97],[114],[4,64],[32,0],[15],[11],[32,3],[68,0,0,0,0,0,0,24,64],[97],[4,64],...internalThrow(scope, 'TypeError', `Cannot convert a Symbol value to a string`),[11],[32,3],[68,0,0,0,0,0,0,8,64],[97],[4,64],[32,2],[252,3],[34,4],[65,9],[54,1,0],[32,4],[65,245,0],[58,0,4],[32,4],[65,238,0],[58,0,5],[32,4],[65,228,0],[58,0,6],[32,4],[65,229,0],[58,0,7],[32,4],[65,230,0],[58,0,8],[32,4],[65,233,0],[58,0,9],[32,4],[65,238,0],[58,0,10],[32,4],[65,229,0],[58,0,11],[32,4],[65,228,0],[58,0,12],[32,4],[184],[34,2],[15],[11],[32,3],[68,0,0,0,0,0,0,16,64],[97],[32,0],[68,0,0,0,0,0,0,0,0],[97],[113],[4,64],[32,2],[252,3],[34,4],[65,4],[54,1,0],[32,4],[65,238,0],[58,0,4],[32,4],[65,245,0],[58,0,5],[32,4],[65,236,0],[58,0,6],[32,4],[65,236,0],[58,0,7],[32,4],[184],[34,2],[15],[11],[32,3],[68,0,0,0,0,0,0,240,63],[97],[4,64],[32,0],[68,0,0,0,0,0,0,240,63],[97],[4,64],[32,2],[252,3],[34,4],[65,4],[54,1,0],[32,4],[65,244,0],[58,0,4],[32,4],[65,242,0],[58,0,5],[32,4],[65,245,0],[58,0,6],[32,4],[65,229,0],[58,0,7],[32,4],[184],[34,2],[15],[11],[32,2],[252,3],[34,4],[65,5],[54,1,0],[32,4],[65,230,0],[58,0,4],[32,4],[65,225,0],[58,0,5],[32,4],[65,236,0],[58,0,6],[32,4],[65,243,0],[58,0,7],[32,4],[65,229,0],[58,0,8],[32,4],[184],[34,2],[15],[11],[32,1],[33,6],[2,124],[32,6],[65,0],[70],[4,64,"TYPESWITCH|Number"],[32,0],[32,1],[68,0,0,0,0,0,0,0,0],[65,3],[16, builtin('__Number_prototype_toString')],[26],[12,1],[11],[32,6],[65,1],[70],[4,64,"TYPESWITCH|Boolean"],[32,0],[32,1],[16, builtin('__Boolean_prototype_toString')],[26],[12,1],[11],[32,6],[65,2],[70],[4,64,"TYPESWITCH|String"],[32,0],[252,2],[32,1],[16, builtin('__String_prototype_toString')],[26],[183],[12,1],[11],[32,6],[65,4],[70],[4,64,"TYPESWITCH|Object"],[32,0],[32,1],[16, builtin('__Object_prototype_toString')],[26],[12,1],[11],[32,6],[65,5],[70],[4,64,"TYPESWITCH|Function"],[32,0],[32,1],[16, builtin('__Function_prototype_toString')],[26],[12,1],[11],[32,6],[65,6],[70],[4,64,"TYPESWITCH|Symbol"],[32,0],[32,1],[16, builtin('__Symbol_prototype_toString')],[26],[12,1],[11],[32,6],[65,16],[70],[4,64,"TYPESWITCH|Array"],[32,0],[32,1],[16, builtin('__Array_prototype_toString')],[26],[12,1],[11],[32,6],[65,18],[70],[4,64,"TYPESWITCH|ByteString"],[32,0],[252,2],[32,1],[16, builtin('__ByteString_prototype_toString')],[26],[183],[12,1],[11],[32,6],[65,19],[70],[4,64,"TYPESWITCH|Date"],[32,0],[32,1],[16, builtin('__Date_prototype_toString')],[26],[12,1],[11],...internalThrow(scope, 'TypeError', `'toString' proto func tried to be called on a type without an impl`),[11,"TYPESWITCH_end"],[15]],
2188
+ wasm: (scope, {allocPage,builtin,internalThrow,}) => [...number(allocPage(scope, 'bytestring: __ecma262_ToString/out', 'i8') * pageSize, 124),[33,2],[32,0],[32,1],[16, builtin('__Porffor_rawType')],[34,3],[68,0,0,0,0,0,0,0,64],[97],[32,3],[68,0,0,0,0,0,0,50,64],[97],[114],[4,64],[32,0],[15],[11],[32,3],[68,0,0,0,0,0,0,24,64],[97],[4,64],...internalThrow(scope, 'TypeError', `Cannot convert a Symbol value to a string`),[11],[32,3],[68,0,0,0,0,0,0,8,64],[97],[4,64],[32,2],[252,3],[34,4],[65,9],[54,1,0],[32,4],[65,245,0],[58,0,4],[32,4],[65,238,0],[58,0,5],[32,4],[65,228,0],[58,0,6],[32,4],[65,229,0],[58,0,7],[32,4],[65,230,0],[58,0,8],[32,4],[65,233,0],[58,0,9],[32,4],[65,238,0],[58,0,10],[32,4],[65,229,0],[58,0,11],[32,4],[65,228,0],[58,0,12],[32,4],[184],[34,2],[15],[11],[32,3],[68,0,0,0,0,0,0,16,64],[97],[32,0],[68,0,0,0,0,0,0,0,0],[97],[113],[4,64],[32,2],[252,3],[34,4],[65,4],[54,1,0],[32,4],[65,238,0],[58,0,4],[32,4],[65,245,0],[58,0,5],[32,4],[65,236,0],[58,0,6],[32,4],[65,236,0],[58,0,7],[32,4],[184],[34,2],[15],[11],[32,3],[68,0,0,0,0,0,0,240,63],[97],[4,64],[32,0],[68,0,0,0,0,0,0,240,63],[97],[4,64],[32,2],[252,3],[34,4],[65,4],[54,1,0],[32,4],[65,244,0],[58,0,4],[32,4],[65,242,0],[58,0,5],[32,4],[65,245,0],[58,0,6],[32,4],[65,229,0],[58,0,7],[32,4],[184],[34,2],[15],[11],[32,2],[252,3],[34,4],[65,5],[54,1,0],[32,4],[65,230,0],[58,0,4],[32,4],[65,225,0],[58,0,5],[32,4],[65,236,0],[58,0,6],[32,4],[65,243,0],[58,0,7],[32,4],[65,229,0],[58,0,8],[32,4],[184],[34,2],[15],[11],[32,1],[33,6],[2,124],[32,6],[65,0],[70],[4,64,"TYPESWITCH|Number"],[32,0],[32,1],[68,0,0,0,0,0,0,0,0],[65,3],[16, builtin('__Number_prototype_toString')],[26],[12,1],[11],[32,6],[65,1],[70],[4,64,"TYPESWITCH|Boolean"],[32,0],[32,1],[16, builtin('__Boolean_prototype_toString')],[26],[12,1],[11],[32,6],[65,2],[70],[4,64,"TYPESWITCH|String"],[32,0],[252,2],[32,1],[16, builtin('__String_prototype_toString')],[26],[183],[12,1],[11],[32,6],[65,4],[70],[4,64,"TYPESWITCH|Object"],[32,0],[32,1],[16, builtin('__Object_prototype_toString')],[26],[12,1],[11],[32,6],[65,5],[70],[4,64,"TYPESWITCH|Function"],[32,0],[32,1],[16, builtin('__Function_prototype_toString')],[26],[12,1],[11],[32,6],[65,6],[70],[4,64,"TYPESWITCH|Symbol"],[32,0],[32,1],[16, builtin('__Symbol_prototype_toString')],[26],[12,1],[11],[32,6],[65,16],[70],[4,64,"TYPESWITCH|Array"],[32,0],[32,1],[16, builtin('__Array_prototype_toString')],[26],[12,1],[11],[32,6],[65,18],[70],[4,64,"TYPESWITCH|ByteString"],[32,0],[252,2],[32,1],[16, builtin('__ByteString_prototype_toString')],[26],[183],[12,1],[11],[32,6],[65,19],[70],[4,64,"TYPESWITCH|Date"],[32,0],[32,1],[16, builtin('__Date_prototype_toString')],[26],[12,1],[11],[32,6],[65,20],[70],[4,64,"TYPESWITCH|Set"],[32,0],[32,1],[16, builtin('__Set_prototype_toString')],[26],[12,1],[11],...internalThrow(scope, 'TypeError', `'toString' proto func tried to be called on a type without an impl`),[11,"TYPESWITCH_end"],[15]],
2169
2189
  params: [124,127],
2170
2190
  typedParams: true,
2171
2191
  returns: [124],
package/compiler/wrap.js CHANGED
@@ -127,7 +127,7 @@ export default (source, flags = [ 'module' ], customImports = {}, print = str =>
127
127
 
128
128
  globalThis.porfDebugInfo = { funcs, globals };
129
129
 
130
- if (source.includes?.('export ')) flags.push('module');
130
+ if (process.argv[1].includes('/runner') && source.includes?.('export ')) flags.push('module');
131
131
 
132
132
  // fs.writeFileSync('out.wasm', Buffer.from(wasm));
133
133
 
@@ -297,16 +297,58 @@ export default (source, flags = [ 'module' ], customImports = {}, print = str =>
297
297
  return porfToJSValue({ memory, funcs, pages }, ret[0], ret[1]);
298
298
  } catch (e) {
299
299
  if (e.is && e.is(exceptTag)) {
300
- const exceptId = e.getArg(exceptTag, 0);
301
- const exception = exceptions[exceptId];
300
+ const exceptionMode = Prefs.exceptionMode ?? 'lut';
301
+ if (exceptionMode === 'lut') {
302
+ const exceptId = e.getArg(exceptTag, 0);
303
+ const exception = exceptions[exceptId];
302
304
 
303
- const constructorName = exception.constructor;
305
+ const constructorName = exception.constructor;
304
306
 
305
- // no constructor, just throw message
306
- if (!constructorName) throw exception.message;
307
+ // no constructor, just throw message
308
+ if (!constructorName) throw exception.message;
307
309
 
308
- const constructor = globalThis[constructorName] ?? eval(`class ${constructorName} extends Error { constructor(message) { super(message); this.name = "${constructorName}"; } }; ${constructorName}`);
309
- throw new constructor(exception.message);
310
+ const constructor = globalThis[constructorName] ?? eval(`class ${constructorName} extends Error { constructor(message) { super(message); this.name = "${constructorName}"; } }; ${constructorName}`);
311
+ throw new constructor(exception.message);
312
+ }
313
+
314
+ if (exceptionMode === 'stack') {
315
+ const value = e.getArg(exceptTag, 0);
316
+ const type = e.getArg(exceptTag, 1);
317
+
318
+ throw porfToJSValue({ memory, funcs, pages }, value, type);
319
+ }
320
+
321
+ if (exceptionMode === 'stackest') {
322
+ const constructorIdx = e.getArg(exceptTag, 0);
323
+ const constructorName = constructorIdx == -1 ? null : funcs.find(x => ((x.originalIndex ?? x.index) - importedFuncs.length) === constructorIdx)?.name;
324
+
325
+ const value = e.getArg(exceptTag, 1);
326
+ const type = e.getArg(exceptTag, 2);
327
+ const message = porfToJSValue({ memory, funcs, pages }, value, type);
328
+
329
+ // no constructor, just throw message
330
+ if (!constructorName) throw message;
331
+
332
+ const constructor = globalThis[constructorName] ?? eval(`class ${constructorName} extends Error { constructor(message) { super(message); this.name = "${constructorName}"; } }; ${constructorName}`);
333
+ throw new constructor(message);
334
+ }
335
+
336
+ if (exceptionMode === 'partial') {
337
+ const exceptId = e.getArg(exceptTag, 0);
338
+ const exception = exceptions[exceptId];
339
+
340
+ const constructorName = exception.constructor;
341
+
342
+ const value = e.getArg(exceptTag, 1);
343
+ const type = e.getArg(exceptTag, 2);
344
+ const message = porfToJSValue({ memory, funcs, pages }, value, type);
345
+
346
+ // no constructor, just throw message
347
+ if (!constructorName) throw message;
348
+
349
+ const constructor = globalThis[constructorName] ?? eval(`class ${constructorName} extends Error { constructor(message) { super(message); this.name = "${constructorName}"; } }; ${constructorName}`);
350
+ throw new constructor(message);
351
+ }
310
352
  }
311
353
 
312
354
  if (e instanceof WebAssembly.RuntimeError) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "porffor",
3
3
  "description": "a basic experimental wip aot optimizing js -> wasm engine/compiler/runtime in js",
4
- "version": "0.17.0-93ba20045",
4
+ "version": "0.17.0-94400a2b8",
5
5
  "author": "CanadaHonk",
6
6
  "license": "MIT",
7
7
  "scripts": {},
package/runner/index.js CHANGED
@@ -145,7 +145,9 @@ try {
145
145
  // if (cache) process.stdout.write(cache);
146
146
  } catch (e) {
147
147
  // if (cache) process.stdout.write(cache);
148
- console.error(process.argv.includes('-i') ? e : `${e.constructor.name}: ${e.message}`);
148
+ let out = e;
149
+ if (!process.argv.includes('-i') && e.__proto__.message != null) out = `${e.constructor.name}${e.message != null ? `: ${e.message}` : ''}`;
150
+ console.error(out);
149
151
  }
150
152
 
151
153
  if (process.argv.includes('-t')) console.log(`${process.argv.includes('-b') ? '' : '\n\n'}total time: ${(performance.now() - start).toFixed(2)}ms\nexecution time: ${(performance.now() - runStart).toFixed(2)}ms`);