porffor 0.58.15 → 0.58.16
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/codegen.js +1 -0
- package/fuzz/generator.js +201 -0
- package/fuzz/index.js +270 -0
- package/package.json +1 -1
- package/runtime/index.js +1 -1
- package/AGENT.md +0 -13
- package/foo.js +0 -22
- package/slow.js +0 -6882
package/compiler/codegen.js
CHANGED
@@ -0,0 +1,201 @@
|
|
1
|
+
// Track declared variables to avoid undefined references
|
2
|
+
let declaredVars = [];
|
3
|
+
|
4
|
+
const generators = {
|
5
|
+
// Literals - wrap in parens to avoid identifier issues like 9.prototype
|
6
|
+
number: () => {
|
7
|
+
const num = Math.random() < 0.5 ? Math.floor(Math.random() * 100) : Math.random() * 100;
|
8
|
+
return `(${num})`;
|
9
|
+
},
|
10
|
+
string: () => {
|
11
|
+
const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
12
|
+
const len = Math.floor(Math.random() * 8) + 1;
|
13
|
+
return `'${Array.from({length: len}, () => chars[Math.floor(Math.random() * chars.length)]).join('')}'`;
|
14
|
+
},
|
15
|
+
boolean: () => Math.random() < 0.5 ? 'true' : 'false',
|
16
|
+
null: () => 'null',
|
17
|
+
undefined: () => 'undefined',
|
18
|
+
|
19
|
+
// Arrays - simple arrays only
|
20
|
+
array: (depth = 0) => {
|
21
|
+
if (depth > 2) return '[]';
|
22
|
+
const len = Math.floor(Math.random() * 3);
|
23
|
+
if (len === 0) return '[]';
|
24
|
+
const items = Array.from({length: len}, () => generateSimple());
|
25
|
+
return `[${items.join(', ')}]`;
|
26
|
+
},
|
27
|
+
|
28
|
+
// Objects - simple objects only
|
29
|
+
object: (depth = 0) => {
|
30
|
+
if (depth > 2) return '{}';
|
31
|
+
const len = Math.floor(Math.random() * 3);
|
32
|
+
if (len === 0) return '{}';
|
33
|
+
const props = Array.from({length: len}, () => {
|
34
|
+
const key = String.fromCharCode(97 + Math.floor(Math.random() * 26));
|
35
|
+
// Ensure valid property syntax
|
36
|
+
return `'${key}': ${generateSimple()}`;
|
37
|
+
});
|
38
|
+
return `({${props.join(', ')}})`;
|
39
|
+
},
|
40
|
+
|
41
|
+
// Variables - only use declared ones
|
42
|
+
variable: () => {
|
43
|
+
if (declaredVars.length === 0) return '42';
|
44
|
+
return declaredVars[Math.floor(Math.random() * declaredVars.length)];
|
45
|
+
}
|
46
|
+
};
|
47
|
+
|
48
|
+
// Generate simple expressions (no complex nesting)
|
49
|
+
function generateSimple() {
|
50
|
+
const simpleTypes = ['number', 'string', 'boolean', 'null', 'undefined'];
|
51
|
+
if (declaredVars.length > 0 && Math.random() < 0.3) {
|
52
|
+
simpleTypes.push('variable');
|
53
|
+
}
|
54
|
+
const type = simpleTypes[Math.floor(Math.random() * simpleTypes.length)];
|
55
|
+
const result = generators[type]();
|
56
|
+
// Ensure we never return undefined/null that could cause syntax issues
|
57
|
+
return result || '42';
|
58
|
+
}
|
59
|
+
|
60
|
+
// Generate expressions with controlled complexity
|
61
|
+
function generateExpression(depth = 0) {
|
62
|
+
if (depth > 2) return generateSimple();
|
63
|
+
|
64
|
+
const roll = Math.random();
|
65
|
+
|
66
|
+
if (roll < 0.4) {
|
67
|
+
// Simple value
|
68
|
+
return generateSimple();
|
69
|
+
} else if (roll < 0.6) {
|
70
|
+
// Binary operation
|
71
|
+
const ops = ['+', '-', '*', '/', '%', '===', '!==', '>', '<', '>=', '<=', '&&', '||'];
|
72
|
+
const op = ops[Math.floor(Math.random() * ops.length)];
|
73
|
+
return `(${generateExpression(depth + 1)} ${op} ${generateExpression(depth + 1)})`;
|
74
|
+
} else if (roll < 0.75) {
|
75
|
+
// Unary operation
|
76
|
+
const ops = ['!', '-', '+', 'typeof'];
|
77
|
+
const op = ops[Math.floor(Math.random() * ops.length)];
|
78
|
+
return `(${op} ${generateExpression(depth + 1)})`;
|
79
|
+
} else if (roll < 0.85) {
|
80
|
+
// Function call
|
81
|
+
const builtins = ['Math.abs', 'Math.floor', 'Math.ceil', 'String', 'Number', 'Boolean'];
|
82
|
+
const func = builtins[Math.floor(Math.random() * builtins.length)];
|
83
|
+
const argCount = Math.floor(Math.random() * 2);
|
84
|
+
const args = Array.from({length: argCount}, () => generateExpression(depth + 1));
|
85
|
+
return `${func}(${args.join(', ')})`;
|
86
|
+
} else if (roll < 0.95) {
|
87
|
+
// Conditional
|
88
|
+
return `(${generateExpression(depth + 1)} ? ${generateExpression(depth + 1)} : ${generateExpression(depth + 1)})`;
|
89
|
+
} else {
|
90
|
+
// Array or object
|
91
|
+
return Math.random() < 0.5 ? generators.array(depth) : generators.object(depth);
|
92
|
+
}
|
93
|
+
}
|
94
|
+
|
95
|
+
function generateStatement(depth = 0, inFunction = false) {
|
96
|
+
if (depth > 2) return `${generateSimple()};`;
|
97
|
+
|
98
|
+
const roll = Math.random();
|
99
|
+
|
100
|
+
if (roll < 0.3) {
|
101
|
+
// Variable declaration
|
102
|
+
const varName = `var${declaredVars.length}`;
|
103
|
+
declaredVars.push(varName);
|
104
|
+
return `var ${varName} = ${generateExpression()};`;
|
105
|
+
} else if (roll < 0.5 && declaredVars.length > 0) {
|
106
|
+
// Variable assignment
|
107
|
+
const varName = declaredVars[Math.floor(Math.random() * declaredVars.length)];
|
108
|
+
const ops = ['=', '+=', '-=', '*='];
|
109
|
+
const op = ops[Math.floor(Math.random() * ops.length)];
|
110
|
+
return `${varName} ${op} ${generateExpression()};`;
|
111
|
+
} else if (roll < 0.65) {
|
112
|
+
// If statement
|
113
|
+
if (Math.random() < 0.5) {
|
114
|
+
return `if (${generateExpression()}) { ${generateStatement(depth + 1, inFunction)} }`;
|
115
|
+
} else {
|
116
|
+
return `if (${generateExpression()}) { ${generateStatement(depth + 1, inFunction)} } else { ${generateStatement(depth + 1, inFunction)} }`;
|
117
|
+
}
|
118
|
+
} else if (roll < 0.75) {
|
119
|
+
// Loop
|
120
|
+
if (Math.random() < 0.5) {
|
121
|
+
const limit = Math.floor(Math.random() * 5) + 1;
|
122
|
+
return `for (let i = 0; i < ${limit}; i++) { ${generateStatement(depth + 1, inFunction)} }`;
|
123
|
+
} else {
|
124
|
+
return `while (${generateExpression(depth + 1)}) { ${generateStatement(depth + 1, inFunction)} break; }`;
|
125
|
+
}
|
126
|
+
} else if (roll < 0.85) {
|
127
|
+
// Try/catch
|
128
|
+
return `try { ${generateStatement(depth + 1, inFunction)} } catch (e) { ${generateStatement(depth + 1, inFunction)} }`;
|
129
|
+
} else if (roll < 0.95 && inFunction) {
|
130
|
+
// Return (only in functions)
|
131
|
+
return `return ${generateExpression()};`;
|
132
|
+
} else {
|
133
|
+
// Expression statement
|
134
|
+
return `${generateExpression()};`;
|
135
|
+
}
|
136
|
+
}
|
137
|
+
|
138
|
+
function generateFunction() {
|
139
|
+
const name = `func${Math.floor(Math.random() * 100)}`;
|
140
|
+
const paramCount = Math.floor(Math.random() * 3);
|
141
|
+
const params = Array.from({length: paramCount}, (_, i) => `param${i}`);
|
142
|
+
|
143
|
+
// Save current variables and add parameters
|
144
|
+
const savedVars = [...declaredVars];
|
145
|
+
params.forEach(p => declaredVars.push(p));
|
146
|
+
|
147
|
+
const stmtCount = Math.floor(Math.random() * 3) + 1;
|
148
|
+
const statements = [];
|
149
|
+
for (let i = 0; i < stmtCount; i++) {
|
150
|
+
statements.push(' ' + generateStatement(0, true));
|
151
|
+
}
|
152
|
+
|
153
|
+
// Always add a simple return to avoid syntax issues
|
154
|
+
statements.push(' return ' + generateSimple() + ';');
|
155
|
+
|
156
|
+
// Restore variables
|
157
|
+
declaredVars = savedVars;
|
158
|
+
|
159
|
+
return `function ${name}(${params.join(', ')}) {\n${statements.join('\n')}\n}`;
|
160
|
+
}
|
161
|
+
|
162
|
+
function generateProgram(options = {}) {
|
163
|
+
const {
|
164
|
+
maxStatements = 8,
|
165
|
+
maxFunctions = 2,
|
166
|
+
includeStrictMode = false
|
167
|
+
} = options;
|
168
|
+
|
169
|
+
declaredVars = [];
|
170
|
+
|
171
|
+
let code = '';
|
172
|
+
|
173
|
+
if (includeStrictMode) {
|
174
|
+
code += "'use strict';\n";
|
175
|
+
}
|
176
|
+
|
177
|
+
// Always declare some initial variables
|
178
|
+
const varCount = Math.floor(Math.random() * 3) + 2;
|
179
|
+
for (let i = 0; i < varCount; i++) {
|
180
|
+
const varName = `var${i}`;
|
181
|
+
declaredVars.push(varName);
|
182
|
+
code += `var ${varName} = ${generateExpression()};\n`;
|
183
|
+
}
|
184
|
+
|
185
|
+
const funcCount = Math.floor(Math.random() * maxFunctions) + 1;
|
186
|
+
for (let i = 0; i < funcCount; i++) {
|
187
|
+
code += generateFunction() + '\n\n';
|
188
|
+
}
|
189
|
+
|
190
|
+
const stmtCount = Math.floor(Math.random() * maxStatements) + 2;
|
191
|
+
for (let i = 0; i < stmtCount; i++) {
|
192
|
+
code += generateStatement() + '\n';
|
193
|
+
}
|
194
|
+
|
195
|
+
// Always end with a result
|
196
|
+
code += `var result = ${generateExpression()};\n`;
|
197
|
+
|
198
|
+
return code;
|
199
|
+
}
|
200
|
+
|
201
|
+
export { generateExpression as generate, generateStatement, generateFunction, generateProgram };
|
package/fuzz/index.js
ADDED
@@ -0,0 +1,270 @@
|
|
1
|
+
import cluster from 'node:cluster';
|
2
|
+
import fs from 'node:fs';
|
3
|
+
import os from 'node:os';
|
4
|
+
import process from 'node:process';
|
5
|
+
import { generateProgram } from './generator.js';
|
6
|
+
|
7
|
+
const workerDataPath = '/tmp/fuzzWorkerData.json';
|
8
|
+
|
9
|
+
if (cluster.isPrimary) {
|
10
|
+
const veryStart = performance.now();
|
11
|
+
|
12
|
+
// Parse CLI arguments
|
13
|
+
let threads = parseInt(process.argv.find(x => x.startsWith('--threads='))?.split('=')?.[1]);
|
14
|
+
if (Number.isNaN(threads)) {
|
15
|
+
threads = Math.max(1, os.cpus().length - 1);
|
16
|
+
console.log(`Using ${threads} threads (detected ${os.cpus().length} CPUs)`);
|
17
|
+
}
|
18
|
+
|
19
|
+
const duration = parseFloat(process.argv.find(x => x.startsWith('--duration='))?.split('=')?.[1]) || 60; // seconds
|
20
|
+
const maxStatements = parseInt(process.argv.find(x => x.startsWith('--max-statements='))?.split('=')?.[1]) || 8;
|
21
|
+
const maxFunctions = parseInt(process.argv.find(x => x.startsWith('--max-functions='))?.split('=')?.[1]) || 2;
|
22
|
+
const verbose = process.argv.includes('--verbose');
|
23
|
+
const saveFailures = process.argv.includes('--save-failures');
|
24
|
+
const plainResults = process.argv.includes('--plain-results');
|
25
|
+
|
26
|
+
console.log(`Starting fuzzer for ${duration}s with ${threads} threads`);
|
27
|
+
console.log(`Max statements: ${maxStatements}, Max functions: ${maxFunctions}`);
|
28
|
+
|
29
|
+
const table = (...arr) => {
|
30
|
+
let out = '';
|
31
|
+
const total = arr[0];
|
32
|
+
for (let i = 0; i < arr.length; i++) {
|
33
|
+
let icon = [ '🧪', '🤠', '❌', '💀', '🏗️', '💥', '⏰', '📝' ][i];
|
34
|
+
let iconDesc = [ 'total', 'pass', 'fail', 'runtime error', 'wasm compile error', 'compile error', 'timeout', 'todo' ][i];
|
35
|
+
|
36
|
+
let data = arr[i];
|
37
|
+
if (i > 0) data = ((data / total) * 100).toPrecision(2) + '%';
|
38
|
+
let str = `${plainResults ? iconDesc : icon} ${data}`;
|
39
|
+
if (i !== arr.length - 1) str += plainResults ? ' | ' : '\u001b[90m | \u001b[0m';
|
40
|
+
out += str;
|
41
|
+
}
|
42
|
+
return out;
|
43
|
+
};
|
44
|
+
|
45
|
+
// Stats tracking - same order as test262
|
46
|
+
let totalTests = 0;
|
47
|
+
let passes = 0;
|
48
|
+
let fails = 0;
|
49
|
+
let runtimeErrors = 0;
|
50
|
+
let wasmErrors = 0;
|
51
|
+
let compileErrors = 0;
|
52
|
+
let timeouts = 0;
|
53
|
+
let todos = 0;
|
54
|
+
|
55
|
+
const errorCounts = new Map();
|
56
|
+
const failureFiles = [];
|
57
|
+
|
58
|
+
const startTime = performance.now();
|
59
|
+
const endTime = startTime + (duration * 1000);
|
60
|
+
|
61
|
+
// Worker data
|
62
|
+
const workerData = {
|
63
|
+
maxStatements,
|
64
|
+
maxFunctions,
|
65
|
+
verbose,
|
66
|
+
saveFailures,
|
67
|
+
endTime
|
68
|
+
};
|
69
|
+
fs.writeFileSync(workerDataPath, JSON.stringify(workerData));
|
70
|
+
|
71
|
+
// Stats display
|
72
|
+
let lastUpdate = 0;
|
73
|
+
const updateInterval = 100;
|
74
|
+
let spinner = ['-', '\\', '|', '/'], spin = 0;
|
75
|
+
|
76
|
+
const updateStats = () => {
|
77
|
+
const now = performance.now();
|
78
|
+
if (now - lastUpdate < updateInterval) return;
|
79
|
+
lastUpdate = now;
|
80
|
+
|
81
|
+
const elapsed = (now - startTime) / 1000;
|
82
|
+
const remaining = Math.max(0, (endTime - now) / 1000);
|
83
|
+
const rate = totalTests / elapsed;
|
84
|
+
|
85
|
+
const tab = ` \u001b[90m${spinner[spin++ % 4]}\u001b[0m ` +
|
86
|
+
table(totalTests, passes, fails, runtimeErrors, wasmErrors, compileErrors, timeouts, todos);
|
87
|
+
|
88
|
+
process.stdout.write(`\r\u001b[K${tab} | ${rate.toFixed(0)}/s | ${remaining.toFixed(1)}s left`);
|
89
|
+
};
|
90
|
+
|
91
|
+
// Spawn workers with timeout handling like test262
|
92
|
+
const workers = [];
|
93
|
+
|
94
|
+
const spawn = (index) => {
|
95
|
+
const worker = cluster.fork();
|
96
|
+
workers[index] = worker;
|
97
|
+
|
98
|
+
let timeout;
|
99
|
+
const enqueue = () => {
|
100
|
+
if (performance.now() >= endTime) {
|
101
|
+
worker.kill();
|
102
|
+
return;
|
103
|
+
}
|
104
|
+
|
105
|
+
if (timeout) clearTimeout(timeout);
|
106
|
+
|
107
|
+
worker.send(null);
|
108
|
+
timeout = setTimeout(() => {
|
109
|
+
worker.kill();
|
110
|
+
|
111
|
+
totalTests++;
|
112
|
+
timeouts++;
|
113
|
+
errorCounts.set('timeout', (errorCounts.get('timeout') || 0) + 1);
|
114
|
+
|
115
|
+
if (saveFailures) {
|
116
|
+
const timestamp = Date.now();
|
117
|
+
const filename = `fuzz/failure_${timestamp}_timeout.js`;
|
118
|
+
fs.writeFileSync(filename, 'timeout');
|
119
|
+
failureFiles.push(filename);
|
120
|
+
}
|
121
|
+
|
122
|
+
updateStats();
|
123
|
+
spawn(index); // Respawn worker
|
124
|
+
}, 1000);
|
125
|
+
};
|
126
|
+
|
127
|
+
worker.on('message', msg => {
|
128
|
+
if (msg === null) {
|
129
|
+
enqueue();
|
130
|
+
return;
|
131
|
+
}
|
132
|
+
|
133
|
+
if (timeout) clearTimeout(timeout);
|
134
|
+
|
135
|
+
totalTests++;
|
136
|
+
|
137
|
+
// result encoding: pass=0, todo=1, wasmError=2, compileError=3, fail=4, timeout=5, runtimeError=6
|
138
|
+
const result = msg.result;
|
139
|
+
|
140
|
+
if (msg.error) {
|
141
|
+
const error = `${msg.error.name}: ${msg.error.message}`
|
142
|
+
.replace(/\([0-9]+:[0-9]+\)/, '')
|
143
|
+
.replace(/@\+[0-9]+/, '');
|
144
|
+
errorCounts.set(error, (errorCounts.get(error) || 0) + 1);
|
145
|
+
}
|
146
|
+
|
147
|
+
if (result === 0) {
|
148
|
+
passes++;
|
149
|
+
} else if (result === 1) {
|
150
|
+
todos++;
|
151
|
+
} else if (result === 2) {
|
152
|
+
wasmErrors++;
|
153
|
+
} else if (result === 3) {
|
154
|
+
compileErrors++;
|
155
|
+
} else if (result === 4) {
|
156
|
+
fails++;
|
157
|
+
} else if (result === 6) {
|
158
|
+
runtimeErrors++;
|
159
|
+
}
|
160
|
+
|
161
|
+
if (msg.code && (result !== 0 || verbose)) {
|
162
|
+
if (saveFailures && result !== 0) {
|
163
|
+
const timestamp = Date.now();
|
164
|
+
const resultNames = ['pass', 'todo', 'wasmError', 'compileError', 'fail', 'timeout', 'runtimeError'];
|
165
|
+
const filename = `fuzz/failure_${timestamp}_${resultNames[result]}.js`;
|
166
|
+
fs.writeFileSync(filename, msg.code);
|
167
|
+
failureFiles.push(filename);
|
168
|
+
}
|
169
|
+
|
170
|
+
if (verbose && result !== 0) {
|
171
|
+
const resultNames = ['PASS', 'TODO', 'WASM_ERROR', 'COMPILE_ERROR', 'FAIL', 'TIMEOUT', 'RUNTIME_ERROR'];
|
172
|
+
console.log('---');
|
173
|
+
console.log(`\n[${resultNames[result]}] ${msg.error?.message || 'Unknown error'}`);
|
174
|
+
console.log(msg.code);
|
175
|
+
console.log('---');
|
176
|
+
}
|
177
|
+
}
|
178
|
+
|
179
|
+
updateStats();
|
180
|
+
enqueue();
|
181
|
+
});
|
182
|
+
};
|
183
|
+
|
184
|
+
for (let i = 0; i < threads; i++) {
|
185
|
+
spawn(i);
|
186
|
+
}
|
187
|
+
|
188
|
+
// Handle cleanup
|
189
|
+
const cleanup = () => {
|
190
|
+
workers.forEach(worker => worker.kill());
|
191
|
+
|
192
|
+
console.log('\u001b[2F\u001b[0J\u001b[1m\u001b[4mfuzzing complete\u001b[0m');
|
193
|
+
|
194
|
+
console.log(table(totalTests, passes, fails, runtimeErrors, wasmErrors, compileErrors, timeouts, todos) + '\n\n');
|
195
|
+
|
196
|
+
if (errorCounts.size > 0) {
|
197
|
+
const sortedErrors = [...errorCounts.entries()].sort((a, b) => b[1] - a[1]).slice(0, 10);
|
198
|
+
sortedErrors.forEach(([error, count]) => {
|
199
|
+
console.log(`\u001b[90m${((count / totalTests) * 100).toPrecision(2).padStart(6, ' ')}%\u001b[0m \u001b[1m${error}\u001b[0m`);
|
200
|
+
});
|
201
|
+
}
|
202
|
+
|
203
|
+
if (failureFiles.length > 0) {
|
204
|
+
console.log(`\nFailure files saved: ${failureFiles.length}`);
|
205
|
+
failureFiles.slice(0, 5).forEach(file => console.log(` ${file}`));
|
206
|
+
if (failureFiles.length > 5) console.log(` ... and ${failureFiles.length - 5} more`);
|
207
|
+
}
|
208
|
+
|
209
|
+
const elapsed = (performance.now() - startTime) / 1000;
|
210
|
+
console.log(`\n\u001b[90mtook ${elapsed.toFixed(1)}s (${(totalTests / elapsed).toFixed(0)} tests/s)\u001b[0m`);
|
211
|
+
|
212
|
+
process.exit(0);
|
213
|
+
};
|
214
|
+
|
215
|
+
// Auto-stop after duration
|
216
|
+
if (duration !== Infinity) setTimeout(cleanup, duration * 1000);
|
217
|
+
|
218
|
+
// Handle Ctrl+C
|
219
|
+
process.on('SIGINT', cleanup);
|
220
|
+
process.on('SIGTERM', cleanup);
|
221
|
+
} else {
|
222
|
+
// Worker process
|
223
|
+
let { maxStatements, maxFunctions, verbose, saveFailures, endTime } = JSON.parse(fs.readFileSync(workerDataPath, 'utf8'));
|
224
|
+
endTime ??= Infinity;
|
225
|
+
const compile = (await import('../compiler/wrap.js')).default;
|
226
|
+
|
227
|
+
process.on('message', () => {
|
228
|
+
if (performance.now() >= endTime) {
|
229
|
+
process.exit(0);
|
230
|
+
}
|
231
|
+
|
232
|
+
const code = generateProgram({ maxStatements, maxFunctions });
|
233
|
+
|
234
|
+
let result = 0; // pass
|
235
|
+
let error = null;
|
236
|
+
let stage = 0;
|
237
|
+
|
238
|
+
try {
|
239
|
+
const out = compile(code, false, {});
|
240
|
+
|
241
|
+
try {
|
242
|
+
out.exports.main();
|
243
|
+
stage = 2;
|
244
|
+
result = 0; // pass
|
245
|
+
} catch (runtimeError) {
|
246
|
+
stage = 1;
|
247
|
+
error = runtimeError;
|
248
|
+
result = 6; // runtime error
|
249
|
+
}
|
250
|
+
} catch (compileError) {
|
251
|
+
stage = 0;
|
252
|
+
error = compileError;
|
253
|
+
|
254
|
+
// Classify compile errors same as test262
|
255
|
+
if (compileError.name === 'CompileError') {
|
256
|
+
result = 2; // wasm compile error
|
257
|
+
} else {
|
258
|
+
result = 3; // compile error
|
259
|
+
}
|
260
|
+
}
|
261
|
+
|
262
|
+
process.send({
|
263
|
+
result,
|
264
|
+
error: error ? { name: error.name, message: error.message } : null,
|
265
|
+
code: verbose || saveFailures ? code : null
|
266
|
+
});
|
267
|
+
});
|
268
|
+
|
269
|
+
process.send(null);
|
270
|
+
}
|
package/package.json
CHANGED
package/runtime/index.js
CHANGED
package/AGENT.md
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
you are an assistant coder for Porffor - a WIP js/ts -> wasm/native ahead-of-time compiler. the codebase is written in js and ts.
|
2
|
-
|
3
|
-
IMPORTANT:
|
4
|
-
- built-ins apis (Date, String.prototype, etc) are written in ts inside `compiler/builtins`
|
5
|
-
- once you update a file inside that directory, you MUST run `./porf precompile` to compile to make your changes effective
|
6
|
-
|
7
|
-
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' instead of 'test262/test/built-ins/RegExp').
|
8
|
-
|
9
|
-
- always use single quotes instead of double quotes (unless needed)
|
10
|
-
- after finishing, check if your work/diff could be simplified
|
11
|
-
- to just evaluate code in the engine, use the command: `./porf -p "..."`
|
12
|
-
- to get an overview of the most failing directories, use the command: `node test262/fails.cjs`
|
13
|
-
- when working in `compiler/builtins`, inline code instead of using utility/helper functions
|
package/foo.js
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
// (() => {
|
2
|
-
// let y = Math.random();
|
3
|
-
// let x = 0;
|
4
|
-
// if (x === 0) {
|
5
|
-
// x = 1337;
|
6
|
-
// } else {
|
7
|
-
// x = 42;
|
8
|
-
// }
|
9
|
-
// Porffor.log(x);
|
10
|
-
// })()
|
11
|
-
|
12
|
-
const fn = function() {}
|
13
|
-
|
14
|
-
class C {
|
15
|
-
async *m() { return 42; } a; b = 42;
|
16
|
-
c = fn;
|
17
|
-
|
18
|
-
}
|
19
|
-
|
20
|
-
new C();
|
21
|
-
|
22
|
-
console.log(Object.prototype.hasOwnProperty.call(C, "a"))
|