porffor 0.60.2 → 0.60.4

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/AGENT.md ADDED
@@ -0,0 +1,20 @@
1
+ you are an assistant coder for Porffor - an early javascript and typescript to webassembly and native ahead-of-time compiler. the codebase is written in js and ts.
2
+
3
+ - built-ins apis (Date, String.prototype, etc) are written in ts inside `compiler/builtins`
4
+ - once you update a file inside that directory, you MUST run `./porf precompile` to compile to make your changes effective
5
+ - test your work using the test262 tools available, iterate independently but do not get stuck on one chain of thought or approach. paths for test262 tools should be relative to the 'test262/test' directory (e.g., 'built-ins/RegExp' NOT 'test262/test/built-ins/RegExp').
6
+ - to get an overview of the most failing directories, use the command: `node test262/fails.cjs`
7
+ - to just evaluate code in the engine, use the command: `./porf -p "..."`
8
+ - after finishing, check if your work/diff could be simplified
9
+ - always use single quotes (unless double is required)
10
+ - 2-space indentation, LF line endings, no trailing whitespace
11
+ - built-in APIs in `compiler/builtins/` written in TypeScript
12
+ - inline code in built-ins, avoid helper functions
13
+ - use semicolons
14
+ - do not use trailing commas
15
+ - use const/let, avoid var
16
+ - follow existing naming: camelCase for variables, PascalCase for types
17
+ - when possible, do not concat strings and instead write to them directly using wasm memory
18
+ - there are no closures, you cannot use locals between functions. use arguments or globals if really necessary
19
+ - The user prefers that prototype functions not have explicit return types in this codebase.
20
+ - The user prefers not to use global variables in built-in functions.
package/compiler/2c.js CHANGED
@@ -612,6 +612,21 @@ export default ({ funcs, globals, data, pages }) => {
612
612
  let func = funcs.find(x => x.index === i[1]);
613
613
  if (!func) {
614
614
  const importFunc = importFuncs[i[1]];
615
+ if (Prefs['2cWasmImports']) {
616
+ const name = '__porf_import_' + importFunc.name;
617
+ if (!prepend.has(name)) {
618
+ prepend.set(name, `
619
+ __attribute__((import_module(""), import_name("${importFunc.import}")))
620
+ extern ${importFunc.returns.length > 0 ? CValtype[importFunc.returns[0]] : 'void'} ${name}(${importFunc.params.map(x => CValtype[x]).join(', ')});`);
621
+ }
622
+
623
+ const call = `${name}(${importFunc.params.length > 0 ? vals.pop() : ''})`;
624
+ if (importFunc.returns.length > 0) vals.push(call);
625
+ else line(call);
626
+
627
+ break;
628
+ }
629
+
615
630
  switch (importFunc.name) {
616
631
  case 'print':
617
632
  line(`printf("${valtype === 'f64' ? '%.15g' : '%i'}", ${vals.pop()})`);
@@ -807,6 +822,8 @@ export default ({ funcs, globals, data, pages }) => {
807
822
  // todo: allow catching
808
823
  const type = vals.pop();
809
824
  const val = vals.pop();
825
+ if (Prefs['2cWasmImports']) break;
826
+
810
827
  line(`printf("Uncaught ")`);
811
828
 
812
829
  // const id = tmpId++;
@@ -172,15 +172,15 @@ local.set ${obj}`;
172
172
  // it does not, make it
173
173
  const underlying: object = {};
174
174
  if (Porffor.type(_obj) == Porffor.TYPES.function) {
175
+ __Porffor_object_fastAdd(underlying, 'length', __Porffor_funcLut_length(obj), 0b0010);
176
+ __Porffor_object_fastAdd(underlying, 'name', __Porffor_funcLut_name(obj), 0b0010);
177
+
175
178
  if (ecma262.IsConstructor(_obj)) { // constructor
176
179
  // set prototype and prototype.constructor if function and constructor
177
180
  const proto: object = {};
178
181
  __Porffor_object_fastAdd(underlying, 'prototype', proto, 0b1000);
179
182
  __Porffor_object_fastAdd(proto, 'constructor', _obj, 0b1010);
180
183
  }
181
-
182
- __Porffor_object_fastAdd(underlying, 'name', __Porffor_funcLut_name(obj), 0b0010);
183
- __Porffor_object_fastAdd(underlying, 'length', __Porffor_funcLut_length(obj), 0b0010);
184
184
  }
185
185
 
186
186
  if (Porffor.type(_obj) == Porffor.TYPES.array) {
@@ -206,8 +206,8 @@ local.set x#type`;
206
206
 
207
207
  if (Porffor.fastOr(
208
208
  Porffor.type(_obj) == Porffor.TYPES.string,
209
- Porffor.type(_obj) == Porffor.TYPES.stringobject)
210
- ) {
209
+ Porffor.type(_obj) == Porffor.TYPES.stringobject
210
+ )) {
211
211
  const len: i32 = (obj as string).length;
212
212
  __Porffor_object_fastAdd(underlying, 'length', len, 0b0000);
213
213
 
@@ -42,7 +42,7 @@ export const __Array_from = (arg: any, mapFn: any): any[] => {
42
42
 
43
43
  if (Porffor.fastOr(
44
44
  Porffor.type(arg) == Porffor.TYPES.array,
45
- Porffor.type(arg) == Porffor.TYPES.string, Porffor.type(arg) == Porffor.TYPES.bytestring,
45
+ (Porffor.type(arg) | 0b10000000) == Porffor.TYPES.bytestring,
46
46
  Porffor.type(arg) == Porffor.TYPES.set,
47
47
  Porffor.fastAnd(Porffor.type(arg) >= Porffor.TYPES.uint8clampedarray, Porffor.type(arg) <= Porffor.TYPES.float64array)
48
48
  )) {
@@ -1832,7 +1832,7 @@ export const Date = function (v0: unknown, v1: unknown, v2: unknown, v3: unknown
1832
1832
  } else {
1833
1833
  // c. Else,
1834
1834
  // ii. If v is a String, then
1835
- if (Porffor.fastOr(Porffor.type(v0) == Porffor.TYPES.string, Porffor.type(v0) == Porffor.TYPES.bytestring)) {
1835
+ if ((Porffor.type(v0) | 0b10000000) == Porffor.TYPES.bytestring) {
1836
1836
  // 1. Assert: The next step never returns an abrupt completion because v is a String.
1837
1837
 
1838
1838
  // 2. Let tv be the result of parsing v as a date, in exactly the same manner as for the parse method (21.4.3.2).
@@ -311,7 +311,7 @@ export const __JSON_parse = (_: bytestring) => {
311
311
  Porffor.bytestring.appendChar(out, ch);
312
312
  pos++;
313
313
  }
314
- }3
314
+ }
315
315
  throw new SyntaxError('Unterminated string');
316
316
  }
317
317
 
@@ -326,7 +326,7 @@ export const __JSON_parse = (_: bytestring) => {
326
326
  }
327
327
 
328
328
  while (true) {
329
- arr.push(parseValue());
329
+ Porffor.array.fastPush(arr, parseValue());
330
330
  skipWhitespace();
331
331
  if (pos >= len) throw new SyntaxError('Unterminated array');
332
332
 
@@ -396,7 +396,7 @@ export const __JSON_parse = (_: bytestring) => {
396
396
  else break;
397
397
  }
398
398
 
399
- return +ecma262.StringToNumber(__ByteString_prototype_slice(text, start, pos));
399
+ return ecma262.StringToNumber(__ByteString_prototype_slice(text, start, pos));
400
400
  }
401
401
 
402
402
  throw new SyntaxError('Unexpected token');
@@ -690,8 +690,7 @@ export const __Object_prototype_toString = (_this: any) => {
690
690
  Porffor.type(_this) == Porffor.TYPES.number,
691
691
  Porffor.type(_this) == Porffor.TYPES.numberobject)) return '[object Number]';
692
692
  if (Porffor.fastOr(
693
- Porffor.type(_this) == Porffor.TYPES.string,
694
- Porffor.type(_this) == Porffor.TYPES.bytestring,
693
+ (Porffor.type(_this) | 0b10000000) == Porffor.TYPES.bytestring,
695
694
  Porffor.type(_this) == Porffor.TYPES.stringobject)) return '[object String]';
696
695
  if (Porffor.type(_this) == Porffor.TYPES.date) return '[object Date]';
697
696
  if (Porffor.type(_this) == Porffor.TYPES.regexp) return '[object RegExp]';
@@ -3,8 +3,7 @@ export default ({ TYPES, TYPE_NAMES }) => {
3
3
  export const __Porffor_object_getHiddenPrototype = (trueType: i32): any => {
4
4
  if (Porffor.comptime.flag\`hasFunc.#get___String_prototype\`) {
5
5
  if (Porffor.fastOr(
6
- trueType == Porffor.TYPES.string,
7
- trueType == Porffor.TYPES.bytestring,
6
+ (trueType | 0b10000000) == Porffor.TYPES.bytestring,
8
7
  trueType == Porffor.TYPES.stringobject
9
8
  )) return __String_prototype;
10
9
  }
@@ -46,7 +46,7 @@ export default async () => {
46
46
 
47
47
  if (Porffor.fastOr(
48
48
  Porffor.type(arg) == Porffor.TYPES.array,
49
- Porffor.type(arg) == Porffor.TYPES.string, Porffor.type(arg) == Porffor.TYPES.bytestring,
49
+ (Porffor.type(arg) | 0b10000000) == Porffor.TYPES.bytestring,
50
50
  Porffor.type(arg) == Porffor.TYPES.set,
51
51
  Porffor.fastAnd(Porffor.type(arg) >= Porffor.TYPES.uint8clampedarray, Porffor.type(arg) <= Porffor.TYPES.float64array)
52
52
  )) {
@@ -77,7 +77,7 @@ export const __${name}_from = (arg: any, mapFn: any): ${name} => {
77
77
 
78
78
  if (Porffor.fastOr(
79
79
  Porffor.type(arg) == Porffor.TYPES.array,
80
- Porffor.type(arg) == Porffor.TYPES.string, Porffor.type(arg) == Porffor.TYPES.bytestring,
80
+ (Porffor.type(arg) | 0b10000000) == Porffor.TYPES.bytestring,
81
81
  Porffor.type(arg) == Porffor.TYPES.set,
82
82
  Porffor.fastAnd(Porffor.type(arg) >= Porffor.TYPES.uint8clampedarray, Porffor.type(arg) <= Porffor.TYPES.float64array)
83
83
  )) {
@@ -164,7 +164,7 @@ export const __${name}_prototype_set = (_this: ${name}, array: any, offset: numb
164
164
 
165
165
  if (Porffor.fastOr(
166
166
  Porffor.type(array) == Porffor.TYPES.array,
167
- Porffor.type(array) == Porffor.TYPES.string, Porffor.type(array) == Porffor.TYPES.bytestring,
167
+ (Porffor.type(array) | 0b10000000) == Porffor.TYPES.bytestring,
168
168
  Porffor.type(array) == Porffor.TYPES.set,
169
169
  Porffor.fastAnd(Porffor.type(array) >= Porffor.TYPES.uint8clampedarray, Porffor.type(array) <= Porffor.TYPES.float64array)
170
170
  )) {
@@ -49,9 +49,8 @@ export const __ecma262_ToNumber = (argument: unknown): number => {
49
49
  if (argument === true) return 1;
50
50
 
51
51
  // 6. If argument is a String, return StringToNumber(argument).
52
- if (Porffor.fastOr(
53
- Porffor.type(argument) == Porffor.TYPES.string,
54
- Porffor.type(argument) == Porffor.TYPES.bytestring)) return __ecma262_StringToNumber(argument);
52
+ if ((Porffor.type(argument) | 0b10000000) == Porffor.TYPES.bytestring)
53
+ return __ecma262_StringToNumber(argument);
55
54
 
56
55
  // 7. Assert: argument is an Object.
57
56
  // 8. Let primValue be ? ToPrimitive(argument, number).
@@ -121,9 +120,8 @@ export const __ecma262_ToIndex = (value: unknown): number => {
121
120
  // https://tc39.es/ecma262/#sec-tostring
122
121
  export const __ecma262_ToString = (argument: unknown): any => {
123
122
  // 1. If argument is a String, return argument.
124
- if (Porffor.fastOr(
125
- Porffor.type(argument) == Porffor.TYPES.string,
126
- Porffor.type(argument) == Porffor.TYPES.bytestring)) return argument;
123
+ if ((Porffor.type(argument) | 0b10000000) == Porffor.TYPES.bytestring)
124
+ return argument;
127
125
 
128
126
  // 2. If argument is a Symbol, throw a TypeError exception.
129
127
  if (Porffor.type(argument) == Porffor.TYPES.symbol) throw new TypeError('Cannot convert a Symbol value to a string');