### Install Porffor CLI Source: https://github.com/canadahonk/porffor/blob/main/README.md Install the Porffor command-line interface globally using npm. Ensure you have Node.js and npm installed. ```bash npm install -g porffor@latest ``` -------------------------------- ### Install and Execute JavaScript File with Porffor CLI Source: https://context7.com/canadahonk/porffor/llms.txt Install Porffor globally and execute a JavaScript file. Supports TypeScript parsing, disabling optimizations, and module execution. ```bash # Install globally npm install -g porffor@latest # Execute a JS file porf path/to/script.js # Execute with TypeScript parsing enabled porf -t path/to/script.ts # Execute with optimizations disabled porf -O0 path/to/script.js # Execute a module (ESM) porf --module path/to/module.js # Execute with timing output porf -t path/to/script.js # Evaluate an inline expression and print result porf -p -e "1 + 2 + 3" # Output: 6 # Print Wasm binary size after compilation porf -b path/to/script.js # Show version porf --version # Output: 0.61.13 ``` -------------------------------- ### Start Porffor Interactive REPL Source: https://context7.com/canadahonk/porffor/llms.txt Launch the Porffor interactive REPL for line-by-line compilation and execution. The REPL maintains context and offers dot-commands for inspection. ```bash # Start the REPL porf # Example REPL session: # Welcome to Porffor (0.61.13) running on Node 20.x # > let x = 40 # undefined # > x + 2 # 42 # > [1,2,3].map(n => n * n) # [ 1, 4, 9 ] # > .memory # Show Wasm memory layout # > .asm # Show disassembled Wasm for current session # > .js # Show accumulated JS source being compiled ``` -------------------------------- ### Example Commit Messages Source: https://github.com/canadahonk/porffor/blob/main/CONTRIBUTING.md Follow the `${file}: ${description}` format for commit messages. Use detailed descriptions for clarity and consider adding humor. ```text builtins/date: impl toJSON ``` ```text builtins/date: fix ToIntegerOrInfinity returning -0 ``` ```text codegen: fix inline wasm for unreachable ``` ```text builtins/array: wip toReversed ``` ```text builtins/tostring_number: impl radix ``` -------------------------------- ### Run Porffor REPL Source: https://github.com/canadahonk/porffor/blob/main/README.md Start an interactive Read-Eval-Print Loop (REPL) for Porffor by running the `porf` command without any arguments. This is useful for quick testing. ```bash porf ``` -------------------------------- ### Compile JS to Wasm and Execute Source: https://context7.com/canadahonk/porffor/llms.txt Use the default export of `compiler/wrap.js` to compile JS source to Wasm, instantiate it, and get callable exports. Wasm return values are automatically deserialized. ```javascript import compile from 'porffor'; // resolves to compiler/wrap.js via package "main" // Basic execution const { exports } = compile(` function add(a, b) { return a + b; } const result = add(10, 32); result; "); const value = exports.main(); console.log(value); // 42 // Custom print handler (captures console.log output) const lines = []; const { exports: ex } = compile( `console.log('hello'); console.log('world');`, false, str => lines.push(str) ); ex.main(); console.log(lines); // ['hello\n', 'world\n'] // Compile a module (ESM source) const { exports: mod } = compile( `export const PI = 3.14159;`, true // isModule = true ); // Inspect raw Wasm bytes and timing const { wasm, times } = compile(`1 + 1`); console.log(`Wasm binary: ${wasm.byteLength} bytes`); console.log(`Compile time: ${times[0].toFixed(2)}ms`); console.log(`Instantiate time: ${times[1].toFixed(2)}ms`); // Error handling try { compile(`null.foo`); } catch (e) { console.error(e.name, e.message); // TypeError: Cannot read properties of null } ``` -------------------------------- ### Get Memory Pointers Source: https://github.com/canadahonk/porffor/blob/main/CONTRIBUTING.md Retrieves the memory pointers for the input string (`_this`) and the output buffer (`out`) as 32-bit integers. ```typescript let i: i32 = Porffor.wasm`local.get ${_this}`, j: i32 = Porffor.wasm`local.get ${out}`; ``` -------------------------------- ### Porffor Global API: Object Operations Source: https://context7.com/canadahonk/porffor/llms.txt Provides low-level object manipulation functions such as preventing extensions, checking extensibility, looking up keys, getting values, setting values, and defining properties with flags. ```typescript // Object operations Porffor.object.preventExtensions(obj); const locked: boolean = Porffor.object.isInextensible(obj); const entryPtr: i32 = Porffor.object.lookup(obj, 'key'); const val: any = Porffor.object.get(obj, 'key'); Porffor.object.set(obj, 'key', 42); Porffor.object.define(obj, 'key', 42, 0b1110); ``` -------------------------------- ### Get Pointer to Variable Source: https://github.com/canadahonk/porffor/blob/main/CONTRIBUTING.md Retrieves the memory pointer for a given variable. This is a fundamental operation for accessing and manipulating object data in Wasm. ```javascript Porffor.wasm`local.get ${foobar}` ``` -------------------------------- ### Running Test262 Tests with Porffor Source: https://context7.com/canadahonk/porffor/llms.txt Clone the test262 repository first. These commands demonstrate how to run all tests, specific subsets, limit thread count, and show error or assertion details. ```bash # Clone test262 first (one time) cd test262 && git clone https://github.com/tc39/test262.git ``` ```bash # Run all tests (uses all available threads) node test262 ``` ```bash # Run a specific subset node test262 built-ins/Array ``` ```bash node test262 built-ins/String/prototype/trim ``` ```bash # Limit thread count node test262 --threads=4 ``` ```bash # Show per-test error messages node test262 --log-errors ``` ```bash # Show assertion failure details node test262 --debug-asserts ``` -------------------------------- ### Initialize Output Buffer Source: https://github.com/canadahonk/porffor/blob/main/CONTRIBUTING.md Sets up the output buffer (`out`) by allocating space and storing its length. This is necessary because Wasm intrinsics do not automatically update string lengths. ```typescript const len: i32 = _this.length; let out: bytestring = ''; Porffor.wasm.i32.store(out, len, 0, 0); ``` -------------------------------- ### Run a JavaScript file with Porffor Source: https://github.com/canadahonk/porffor/blob/main/README.md Execute a JavaScript file using Porffor by providing the file path as an argument to the `porf` command. ```bash porf path/to/script.js ``` -------------------------------- ### Run All Test262 Tests Source: https://github.com/canadahonk/porffor/blob/main/CONTRIBUTING.md Execute all test262 tests and view the overall summary. This command can consume significant system resources and take 1-30 minutes to complete. ```bash node test262 ``` -------------------------------- ### Enable Basic Optimizations Source: https://github.com/canadahonk/porffor/blob/main/README.md Enable basic optimizations, such as simplifying instructions and tree-shaking Wasm imports. This is the default optimization level. ```bash -O1 ``` -------------------------------- ### Specify C Compiler for Native Compilation Source: https://github.com/canadahonk/porffor/blob/main/README.md When compiling to native binaries, specify the C compiler to use. Supported options are 'clang' (default), 'gcc', and 'zig'. ```bash --compiler=clang|gcc|zig ``` -------------------------------- ### Specify C Optimization Level for Native Compilation Source: https://github.com/canadahonk/porffor/blob/main/README.md When compiling to native binaries, specify the optimization level for the C compiler. Options range from 'Ofast' (default) down to 'O0'. ```bash --cO=Ofast|O3|O2|O1|O0 ``` -------------------------------- ### Compile JavaScript to Native Binary Source: https://context7.com/canadahonk/porffor/llms.txt Compile JS/TS to a native executable by transpiling to C and then using a C compiler. Supports clang, gcc, and zig back-ends. ```bash # Compile to native binary (uses clang + O3 by default) porf native path/to/script.js out # Specify compiler and optimization level porf native --compiler=gcc --cO=Ofast path/to/script.js out # Compile and immediately run (--native flag) porf --native path/to/script.js # Cross-check Wasm size porf native -b path/to/script.js out ``` -------------------------------- ### Compile JavaScript to Native Binary Source: https://github.com/canadahonk/porffor/blob/main/README.md Compile a JavaScript file to a native executable. This process uses Porffor's experimental Wasm to C compiler (2c). You can specify the C compiler (clang, gcc, zig) and optimization level. ```bash porf native path/to/script.js out(.exe) ``` -------------------------------- ### Compiler Flags: Experimental Features Source: https://context7.com/canadahonk/porffor/llms.txt Enable experimental features like the Cyclone optimizer (`--cyclone`), profile-guided optimization (`--pgo`), Wasm tail call proposal (`--tail-call`), or the oneshot allocator (`--allocator=oneshot`). ```bash # Experimental porf --cyclone script.js # Force enable Cyclone optimizer porf --pgo script.js # Enable profile-guided optimization porf --tail-call script.js # Enable Wasm tail call proposal porf --allocator=oneshot script.js # Use oneshot allocator (faster for Lambda) ``` -------------------------------- ### Initialize Monaco Editor and Load Script Source: https://github.com/canadahonk/porffor/blob/main/index.html This snippet initializes the Monaco editor and loads necessary scripts for its functionality. It ensures the editor is ready before proceeding. ```javascript (async () => { const loadScript = async (x) => { const el = document.createElement('script'); el.src = x; document.head.append(el); await new Promise((res) => (el.onload = res)); }; if (!window.monaco) { await loadScript('https://cdn.openasar.dev/monaco-editor/min/vs/loader.js'); require.config({ paths: { vs: 'https://cdn.openasar.dev/monaco-editor/min/vs' } }); await new Promise((res) => require(['vs/editor/editor.main'], res)); } const monacoContainer = document.createElement('div'); split.appendChild(monacoContainer); const jsSize = document.createElement('div'); jsSize.id = 'js-size'; monacoContainer.append(jsSize); const wasmView = document.createElement('div'); split.appendChild(wasmView); const status = document.getElementById('status'); let code = ` console.log(\`Hello from ${navigator.userAgent}! Did you know:\\n\`); const rows = [ ['Engine', 'Execution model'], ['Porffor', 'Compiles ahead-of-time (Wasm + native)'], ['V8', 'Compiles just-in-time'], ['SpiderMonkey', 'Compiles just-in-time'], ['JavaScriptCore', 'Compiles just-in-time'], ['QuickJS', 'Interprets'], ['Hermes', 'Interprets (ahead-of-time bytecode)'] ]; const widths = [0, 0]; for (const r of rows) { if (r[0].length > widths[0]) widths[0] = r[0].length; if (r[1].length > widths[1]) widths[1] = r[1].length; } const border = '+' + '-'.repeat(widths[0] + 2) + '+' + '-'.repeat(widths[1] + 2) + '+'; console.log(border); for (let i = 0; i < rows.length; i++) { const r = rows[i]; console.log('| ' + r[0].padEnd(widths[0], ' ') + ' | ' + r[1].padEnd(widths[1], ' ') + ' |'); if (i === 0) console.log(border); } console.log(border); `.trim(); const addOptions = (container, options, def) => { for (const x of options) { const el = document.createElement('option'); el.textContent = x; el.selected = x === def; container.appendChild(el); } }; window.editor = monaco.editor.create(monacoContainer, { value: code, codeLens: false, language: 'typescript', theme: 'vs-dark', minimap: { enabled: false, }, }); const debounce = (handler, timeout) => { let timer; return (...args) => { clearTimeout(timer); timer = setTimeout(() => handler(...args), timeout); }; }; const setProcess = () => { globalThis.process = { argv: ['', '', '--disassemble'], }; }; setProcess(); globalThis.version = (await (await fetch('../runtime/index.js')).text()).split("'"`)[3]; const compile = (await import('../compiler/wrap.js')).default; const comp = async () => { setProcess(); globalThis.argvChanged?.(); location.hash = '#' + btoa(code); jsSize.textContent = `${new Blob([code]).size} bytes`; const ansi = x => x.replaceAll('\x1B[0m', '').replace(/\x1B\[([0-9]{1,2})m/g, (_, esc) => ``); let cache = ''; const print = (str) => { cache += str; }; output.textContent = ''; wasmView.innerHTML = ''; status.textContent = 'Compiling...'; let wasm, exports, times, disasms, c; try { ({ wasm, exports, times, disasms, c } = compile(code, true, print)); } catch (e) { console.error(e); status.textContent = `${e.constructor.name}: ${e.message}`; return; } wasmView.innerHTML = `
${wasm.byteLength} bytes
` + ansi(disasms.join('\n')); status.textContent = `Compiled in ${times[0].toFixed(0)}ms`; await new Promise((res) => setTimeout(res, 10)); const t2 = performance.now(); try { exports.main(); } catch (e) { console.error(e); status.textContent = `${e.constructor.name}: ${e.message}`; return; } print('\n'); const execTime = performance.now() - t2; status.textContent += `. Executed in ${execTime.toFixed(0)}ms`; output.innerHTML = ansi(cache); }; const compDebounce = debounce(comp, 500); editor.getModel().onDidChangeContent((e) => { code = editor.getValue(); compDebounce(); }); ``` -------------------------------- ### Profile JavaScript file execution Source: https://github.com/canadahonk/porffor/blob/main/README.md Profile the execution of a JavaScript file using Porffor. This is an experimental feature and may be unstable. ```bash porf profile path/to/script.js ``` -------------------------------- ### Run Specific Test262 Directories/Files Source: https://github.com/canadahonk/porffor/blob/main/CONTRIBUTING.md To debug or focus on a particular area, specify the path to the test directory or file. This helps in isolating issues. ```bash node test262 path/to/tests ``` -------------------------------- ### compile(source) - Primary Programmatic Entry Point Source: https://context7.com/canadahonk/porffor/llms.txt The default export of `compiler/wrap.js` compiles JS source to Wasm, instantiates it, and returns callable exports. Wasm return values are deserialized to JS types. ```APIDOC ## compile(source) ### Description Compiles JavaScript source code into a WebAssembly module, instantiates it, and returns an object with callable exports. Values returned from Wasm are automatically deserialized back to native JavaScript types. ### Parameters - **source** (string) - Required - The JavaScript source code to compile. - **isModule** (boolean) - Optional - Whether the source code is an ES Module. Defaults to `false`. - **printHandler** (function) - Optional - A callback function to handle `console.log` output from the Wasm module. ### Returns An object containing: - **exports**: An object with the callable exports of the instantiated Wasm module. - **wasm**: The raw Wasm binary as a `Uint8Array`. - **times**: An array containing compile and instantiate times in milliseconds. ### Request Example ```javascript import compile from 'porffor'; // Basic execution const { exports } = compile(` function add(a, b) { return a + b; } const result = add(10, 32); result; `); const value = exports.main(); console.log(value); // 42 // Custom print handler const lines = []; const { exports: ex } = compile( `console.log('hello'); console.log('world');`, false, str => lines.push(str) ); ex.main(); console.log(lines); // ['hello\n', 'world\n'] // Compile a module (ESM source) const { exports: mod } = compile( `export const PI = 3.14159;`, true // isModule = true ); // Inspect raw Wasm bytes and timing const { wasm, times } = compile(`1 + 1`); console.log(`Wasm binary: ${wasm.byteLength} bytes`); console.log(`Compile time: ${times[0].toFixed(2)}ms`); console.log(`Instantiate time: ${times[1].toFixed(2)}ms`); ``` ### Error Handling ```javascript try { compile(`null.foo`); } catch (e) { console.error(e.name, e.message); // TypeError: Cannot read properties of null } ``` ``` -------------------------------- ### Precompile Built-in TypeScript Files Source: https://context7.com/canadahonk/porffor/llms.txt Compiles all built-in TypeScript files (`compiler/builtins/*.ts`) into Wasm bytecode using Porffor itself. This script must be run after any modifications to the built-in files. ```bash # After editing any file in compiler/builtins/ ./porf precompile # Or via the runtime directly node runtime/index.js precompile ``` -------------------------------- ### Compile JavaScript to WebAssembly Binary Source: https://context7.com/canadahonk/porffor/llms.txt Compile a JS/TS source file into a standalone `.wasm` binary. The output has minimal I/O imports and is suitable for embedding in a host environment. ```bash # Compile to Wasm porf wasm path/to/script.js out.wasm # With optimization level 2 (enables Cyclone partial evaluator) porf -O2 wasm path/to/script.js out.wasm # Check output size ls -lh out.wasm ``` -------------------------------- ### Compile JavaScript to C Source: https://github.com/canadahonk/porffor/blob/main/README.md Compile a JavaScript file to C source code using Porffor's experimental Wasm to C compiler (2c). If no output file is specified, the C code will be printed to standard output. ```bash porf c path/to/script.js (out.c) ``` -------------------------------- ### Compile JavaScript to C Source Code Source: https://context7.com/canadahonk/porffor/llms.txt Use Porffor's 2c transpiler to convert JS/TS code into C source files. The generated C code is self-contained with minimal boilerplate. ```bash # Compile to C file porf c path/to/script.js out.c # Print C output to stdout instead porf c path/to/script.js # With specific optimization level porf -O2 c path/to/script.js out.c ``` -------------------------------- ### Debug JavaScript file execution Source: https://github.com/canadahonk/porffor/blob/main/README.md Debug a JavaScript file using Porffor. This is a highly experimental feature and may be unstable. ```bash porf debug path/to/script.js ``` -------------------------------- ### Porffor Global API: Logical Helpers Source: https://context7.com/canadahonk/porffor/llms.txt Provides non-short-circuiting logical OR (`Porffor.fastOr`) and AND (`Porffor.fastAnd`) operations. All conditions are evaluated regardless of intermediate results. ```typescript // Logical helpers (non-short-circuiting) const result: boolean = Porffor.fastOr(a == 1, b == 2, c == 3); const all: boolean = Porffor.fastAnd(x > 0, y > 0, z > 0); ``` -------------------------------- ### Compile JavaScript to Wasm Source: https://github.com/canadahonk/porffor/blob/main/README.md Compile a JavaScript file to a WebAssembly binary (`.wasm`). Note that the output is not directly usable with standard runtimes like WASI without additional handling. ```bash porf wasm path/to/script.js out.wasm ``` -------------------------------- ### Porffor Global API: Direct Printing Source: https://context7.com/canadahonk/porffor/llms.txt Prints values directly using `Porffor.print` or `Porffor.printStatic` for literal strings, bypassing standard JavaScript console overhead for potentially faster output. ```typescript // Print directly (bypasses JS console.log overhead) Porffor.print(someValue); Porffor.printStatic('literal string'); ``` -------------------------------- ### Package JavaScript Handler for AWS Lambda Source: https://context7.com/canadahonk/porffor/llms.txt Compile a JS/TS handler function into a native Lambda binary and package it into a deployable `.zip` archive. The handler must export a `handler` function. ```javascript # handler.js const handler = () => { return { statusCode: 200, body: 'Hello from Porffor Lambda!' }; }; ``` ```bash # Package it porf lambda handler.js function.zip # Output: Lambda function packaged to function.zip # Use a specific C compiler CC=musl-gcc porf lambda handler.js function.zip ``` -------------------------------- ### Lower-Level Compiler Pipeline Source: https://context7.com/canadahonk/porffor/llms.txt Utilize `compiler/index.js` for direct access to the compiler pipeline, returning raw intermediate representations including Wasm bytes and metadata. This is used internally by `wrap.js`. ```javascript import compile from './compiler/index.js'; const result = compile(` const arr = [1, 2, 3]; arr.reduce((a, b) => a + b, 0); `); // result contains: // - result.wasm : Uint8Array — final Wasm binary // - result.funcs : array of compiled function descriptors // - result.globals : global variable map // - result.tags : Wasm exception tags // - result.exceptions: exception table // - result.pages : memory page allocation map // - result.data : Wasm data segments // - result.c : C source string (only when target='c') console.log(`Functions compiled: ${result.funcs.length}`); console.log(`Memory pages: ${result.pages.size}`); console.log([...result.pages.keys()]); // e.g. ['Array: arr', 'number: reduce result'] ``` -------------------------------- ### Iterate Through String Source: https://github.com/canadahonk/porffor/blob/main/CONTRIBUTING.md Sets up a loop to iterate through the entire input string by calculating the end pointer and looping until the current pointer reaches it. ```typescript const endPtr: i32 = i + len; while (i < endPtr) { ``` -------------------------------- ### Specify Test Threads Source: https://github.com/canadahonk/porffor/blob/main/CONTRIBUTING.md Control the number of threads used for running tests with the `--threads=N` option. Adjusting this can impact execution time and resource consumption. ```bash node test262 --threads=N ``` -------------------------------- ### Set Porffor Parser Option Source: https://github.com/canadahonk/porffor/blob/main/README.md Specify the JavaScript parser to be used by Porffor. Options include 'acorn', '@babel/parser', 'meriyah', and 'hermes-parser'. 'acorn' is the default. ```bash --parser=acorn|@babel/parser|meriyah|hermes-parser ``` -------------------------------- ### Wasm Type Conversion Source: https://github.com/canadahonk/porffor/blob/main/CONTRIBUTING.md Use custom Porffor instructions like `i32.from` to convert between Wasm's valtype and specific types (e.g., `i32`). `type.to` is used for the reverse conversion. ```wasm local.get ${a} i32.from local.set aCasted ``` ```wasm local.get ${b} i32.from local.set bCasted ``` -------------------------------- ### Compiler Flags / Prefs System Source: https://context7.com/canadahonk/porffor/llms.txt Controls compiler behavior via `process.argv` flags. Flags use `--name=value`, `--name` (boolean true), or `--no-name` (boolean false) syntax. Several options are enabled by default. ```APIDOC ## Compiler Flags Compiler behavior is controlled via command-line flags parsed into the global `Prefs` object. ### Optimization Levels - `-O0`: Disable all optimization. - `-O1`: Default: basic Wasm instruction simplification + import treeshaking. - `-O2`: Advanced: enable Cyclone partial evaluator (unstable). ### Parser Selection - `--parser=acorn`: Default parser. - `--parser=@babel/parser`: Use Babel parser. - `--parser=meriyah`: Use Meriyah parser. - `--parser=hermes-parser`: Use Hermes parser. - `--parser=oxc-parser`: Use OXC parser. ### TypeScript Support - `--parse-types` or `-t`: Parse TypeScript syntax (no type checking). - `--opt-types`: Use TS type annotations as compiler hints. ### Value Type - `--valtype=i32`: Use `i32` instead of the default `f64` for values (rarely needed). ### Debug / Introspection - `-d`: Debug mode: includes names in Wasm and enables verbose logs. - `-f`: Print disassembled Wasm for user functions. - `--profile-compiler`: Log compile and instantiate timing. ### Experimental Flags - `--cyclone`: Force enable Cyclone optimizer. - `--pgo`: Enable profile-guided optimization. - `--tail-call`: Enable Wasm tail call proposal. - `--allocator=oneshot`: Use oneshot allocator (faster for Lambda). ### Example Usage ```bash # Optimize with default settings porf -O1 script.js # Use Babel parser and enable debug mode porf --parser=@babel/parser -d script.js # Compile TypeScript with type hints porf --opt-types script.ts ``` ``` -------------------------------- ### Enable Advanced Optimizations Source: https://github.com/canadahonk/porffor/blob/main/README.md Enable advanced optimizations, including partial evaluation. This level is considered unstable. ```bash -O2 ``` -------------------------------- ### Compiler Flags: TypeScript Support Source: https://context7.com/canadahonk/porffor/llms.txt Enable TypeScript parsing with `--parse-types` or `-t`. Use `--opt-types` to leverage TS type annotations as compiler hints. ```bash # TypeScript support (parse only, no type checking) porf --parse-types script.ts porf -t script.ts # Shorthand # Use TS type annotations as compiler hints porf --opt-types script.ts ``` -------------------------------- ### Set Wasm Value Type Source: https://github.com/canadahonk/porffor/blob/main/README.md Set the WebAssembly value type to be used, either 'i32' (32-bit integer) or 'f64' (64-bit float). 'f64' is the default. ```bash --valtype=i32|f64 ``` -------------------------------- ### compile(code) - Lower-Level Compiler Pipeline Source: https://context7.com/canadahonk/porffor/llms.txt Exposes the lower-level compiler pipeline from `compiler/index.js`. It accepts JS source and returns the raw intermediate representation, including Wasm bytes, function metadata, and memory allocations. ```APIDOC ## compile(code) ### Description Provides access to the lower-level compiler pipeline. Accepts JavaScript source code and returns a detailed intermediate representation of the compilation process, including Wasm bytes, function metadata, globals, tags, exceptions, and memory page allocations. This is used internally by `wrap.js`. ### Parameters - **code** (string) - Required - The JavaScript source code to compile. ### Returns An object containing: - **wasm**: `Uint8Array` - The final Wasm binary. - **funcs**: `array` - An array of compiled function descriptors. - **globals**: `map` - A map of global variables. - **tags**: `array` - Wasm exception tags. - **exceptions**: `array` - The exception table. - **pages**: `map` - A map of memory page allocations. - **data**: `array` - Wasm data segments. - **c**: `string` - The C source string (only when `target='c'`). ### Request Example ```javascript import compile from './compiler/index.js'; const result = compile(` const arr = [1, 2, 3]; arr.reduce((a, b) => a + b, 0); `); console.log(`Functions compiled: ${result.funcs.length}`); console.log(`Memory pages: ${result.pages.size}`); console.log([...result.pages.keys()]); // e.g. ['Array: arr', 'number: reduce result'] ``` ``` -------------------------------- ### Enable Type-Optimizations Source: https://github.com/canadahonk/porffor/blob/main/README.md Perform optimizations using TypeScript type annotations as compiler hints. This option does not perform type checking. ```bash --opt-types ``` -------------------------------- ### Log Assertion Failures Source: https://github.com/canadahonk/porffor/blob/main/CONTRIBUTING.md Enable `--debug-asserts` to log the expected and actual values for assertion failures. This feature is experimental. ```bash node test262 --debug-asserts ``` -------------------------------- ### Memory Allocation with Porffor.malloc Source: https://context7.com/canadahonk/porffor/llms.txt Allocates a buffer of a specified size using `Porffor.malloc`. The returned pointer can be used for direct memory manipulation. ```typescript // Memory allocation export const allocBuffer = (size: i32): any => { const ptr: any = Porffor.malloc(size); return ptr; }; ``` -------------------------------- ### Wasm Comments Source: https://github.com/canadahonk/porffor/blob/main/CONTRIBUTING.md Use `;;` for single-line comments within Wasm bytecode, similar to `//` in other languages. ```wasm ;; if both types are number ``` -------------------------------- ### Inline WAT for i32 Addition with Type Checking Source: https://context7.com/canadahonk/porffor/llms.txt Performs i32 addition using inline WAT within Porffor.wasm, including type checking for inputs. Returns 0, 0 if types are not i32. ```typescript // Direct i32/f64 operations with inline WAT export const add_i32 = (a: any, b: any) => { Porffor.wasm` local aCasted i32 local bCasted i32 returns i32 i32 local.get ${a+1} i32.const 1 i32.eq local.get ${b+1} i32.const 1 i32.eq i32.and if local.get ${a} i32.from local.set aCasted local.get ${b} i32.from local.set bCasted local.get aCasted local.get bCasted i32.add i32.const 1 return end i32.const 0 i32.const 0 return`; }; ``` -------------------------------- ### Porffor Global API: Memory Information Source: https://context7.com/canadahonk/porffor/llms.txt Retrieves the pointer to allocated memory using `Porffor.malloc` and the total memory size in pages using `Porffor.memorySize`. ```typescript // Memory const ptr: any = Porffor.malloc(64); const memSize: i32 = Porffor.memorySize(); ``` -------------------------------- ### Porffor Version Numbering Scheme Source: https://context7.com/canadahonk/porffor/llms.txt The minor version in Porffor's semver indicates the Test262 pass rate, rounded half-down. The micro version represents the build number for that pass rate. ```text Version: 0.61.13 0 → major, always 0 (not production-ready) 61 → Test262 pass rate: ~61% 13 → 13th build push at this pass rate ``` -------------------------------- ### Porffor Global API: Fast Array Operations Source: https://context7.com/canadahonk/porffor/llms.txt Performs fast array operations without bounds checking, including `fastPush`, `fastIndexOf`, and `fastRemove`. Use with caution as these bypass safety checks. ```typescript // Fast array operations (no bounds checking) const arr: any[] = [1, 2, 3]; Porffor.array.fastPush(arr, 4); const idx: i32 = Porffor.array.fastIndexOf(arr, 2); Porffor.array.fastRemove(arr, 1); ``` -------------------------------- ### Compiler Flags: Parser Selection Source: https://context7.com/canadahonk/porffor/llms.txt Choose the JavaScript parser using the `--parser` flag. Options include `acorn` (default), `@babel/parser`, `meriyah`, `hermes-parser`, and `oxc-parser`. ```bash # Parser selection porf --parser=acorn script.js # Default porf --parser=@babel/parser script.js porf --parser=meriyah script.js porf --parser=hermes-parser script.js porf --parser=oxc-parser script.js ``` -------------------------------- ### Compiler Flags: Debug and Introspection Source: https://context7.com/canadahonk/porffor/llms.txt Enable debug mode with `-d` for Wasm names and verbose logs, or use `-f` to print disassembled Wasm for user functions. `--profile-compiler` logs timing information. ```bash # Debug / introspection porf -d script.js # Debug mode: names in Wasm, verbose logs porf -f script.js # Print disassembled Wasm for user functions porf --profile-compiler script.js # Log compile/instantiate timing ``` -------------------------------- ### Generate SVG Graph Source: https://github.com/canadahonk/porffor/blob/main/index.html Creates an SVG graph visualizing test result history. It calculates dimensions based on window size and draws gridlines and data lines for different result types. ```javascript const makeGraph = () => { const oldest = new Date(history.at(-1).time); const now = new Date(); // const months = // now.getMonth() - // oldest.getMonth() + // 12 * (now.getFullYear() - oldest.getFullYear()); // graph_time.textContent = `All-time (${months} months)`; const newest = history[0].time; const dateRange = newest - oldest; const availableWidth = Math.min(window.innerWidth, 2000) - 400 - 24; const availableHeight = 800; const aspectRatio = availableWidth / availableHeight; const width = 1000 * aspectRatio; const height = 1000; const leftAxisWidth = 70; const paddingX = 0; const paddingY = 10; svg.setAttribute( 'viewBox', `0 0 ${width + leftAxisWidth + paddingX * 2} ${height + paddingY * 2}`, ); svg.innerHTML = ''; // left axis line // const leftAxisLine = document.createElementNS( // 'http://www.w3.org/2000/svg', // 'line', // ); // leftAxisLine.setAttribute('x1', padding + leftAxisWidth); // leftAxisLine.setAttribute('x2', padding + leftAxisWidth); // leftAxisLine.setAttribute('y1', padding); // leftAxisLine.setAttribute('y2', height + padding); // leftAxisLine.setAttribute('stroke', '#909498'); // svg.appendChild(leftAxisLine); const gridlinesEvery = 10; // for (let i = lowerBound; i <= upperBound; i += gridlinesEvery) { for (let i = 0; i <= 100; i += gridlinesEvery) { const line = document.createElementNS( 'http://www.w3.org/2000/svg', 'line', ); line.setAttribute('x1', (leftAxisWidth + paddingX).toFixed()); line.setAttribute('x2', (width + leftAxisWidth + paddingX).toFixed()); // const y = (padding + (1 - ((i - lowerBound) / (upperBound - lowerBound))) * height).toFixed(); const y = (paddingY + (1 - i / 100) * height).toFixed(); line.setAttribute('y1', y); line.setAttribute('y2', y); line.setAttribute('stroke', '#505458'); svg.appendChild(line); const text = document.createElementNS( 'http://www.w3.org/2000/svg', 'text', ); text.setAttribute('x', paddingX + leftAxisWidth - 12); // text.setAttribute('y', +y + ((i - lowerBound) / (upperBound - lowerBound)) * 10); text.setAttribute('y', +y + 7); text.setAttribute('text-anchor', 'end'); text.textContent = `${i}%`; svg.appendChild(text); } const points = { pass: [], fail: [], runtimeError: [], compileError: [], }; for (let i = 0; i < history.length; i++) { const [ percent, total, pass, fail, runtimeError, wasmError, compileError, timeout ] = history[i].results; const when = (history[i].time - oldest) / dateRange; const x = (paddingX + leftAxisWidth + when * width).toFixed(); const run = (n, type) => { const y = (paddingY + (1 - n / total) * height).toFixed(); points[type].push(`${x},${y}`); }; run(pass, 'pass'); run(fail, 'fail'); run(runtimeError + timeout, 'runtimeError'); run(compileError + wasmError, 'compileError'); } const addLine = (points, color) => { const polyline = document.createElementNS( 'http://www.w3.org/2000/svg', 'polyline', ); polyline.setAttribute('fill', 'none'); polyline.setAttribute('stroke', color); polyline.setAttribute('stroke-width', 3); polyline.setAttribute('points', points.join(' ')); svg.appendChild(polyline); }; for (const x in points) { addLine(points[x], colors[x]); } }; makeGraph(); window.addEventListener('resize', makeGraph); })(); ``` -------------------------------- ### Compiler Flags: Optimization Levels Source: https://context7.com/canadahonk/porffor/llms.txt Control optimization levels using flags like `-O0`, `-O1`, or `-O2`. `-O1` is the default, enabling basic Wasm instruction simplification and import treeshaking. ```bash # Optimization levels porf -O0 script.js # Disable all optimization porf -O1 script.js # Default: basic Wasm instruction simplification + import treeshaking porf -O2 script.js # Advanced: enable Cyclone partial evaluator (unstable) ``` -------------------------------- ### Log Errors for Individual Tests Source: https://github.com/canadahonk/porffor/blob/main/CONTRIBUTING.md Use the `--log-errors` flag to see the specific errors encountered by individual tests. This is useful for detailed debugging. ```bash node test262 --log-errors ``` -------------------------------- ### Wasm Arithmetic and Return Source: https://github.com/canadahonk/porffor/blob/main/CONTRIBUTING.md Perform arithmetic operations like addition (`i32.add`) on local variables and return the result along with a status code using the `return` instruction. End conditional blocks with `end`. ```wasm local.get aCasted local.get bCasted i32.add i32.const 1 return end ``` -------------------------------- ### Create Graph Legend Source: https://github.com/canadahonk/porffor/blob/main/index.html Generates legend items for a graph based on a color map. Each item's text is capitalized and its corresponding CSS variable is set. ```javascript const colors = { pass: '#57f287', fail: '#fee75c', runtimeError: '#ed4245', compileError: '#6f0b0c', }; for (const x in colors) { const name = x.replace( /[a-z][A-Z]/, (_) => `${_[0]} ${_[1].toLowerCase()}`, ); const el = document.createElement('div'); el.textContent = name[0].toUpperCase() + name.slice(1); el.style = `--color: ${colors[x]}`; graph_legend.appendChild(el); } ``` -------------------------------- ### Porffor Global API: String Building Source: https://context7.com/canadahonk/porffor/llms.txt Appends strings and characters to a bytestring using `Porffor.bytestring.appendStr` and `Porffor.bytestring.appendChar`. Note that bytestrings are mutable and operations modify the string in place. ```typescript // String building (bytestring) let s: bytestring = ''; Porffor.bytestring.appendStr(s, 'hello'); Porffor.bytestring.appendChar(s, 33); ``` -------------------------------- ### Inline Wasm i32 Memory Load/Store Source: https://context7.com/canadahonk/porffor/llms.txt Implements a `toUpperCase` function for bytestrings using direct i32 memory load/store operations within Porffor.wasm. Ensure correct pointer arithmetic and memory access. ```typescript // compiler/builtins/example.ts // Direct i32 memory load/store (ByteString — 1 byte per char) export const __ByteString_prototype_toUpperCase = (_this: bytestring) => { const len: i32 = _this.length; let out: bytestring = ''; Porffor.wasm.i32.store(out, len, 0, 0); // set output length let i: i32 = Porffor.wasm`local.get ${_this}`; let j: i32 = Porffor.wasm`local.get ${out}`; const endPtr: i32 = i + len; while (i < endPtr) { let chr: i32 = Porffor.wasm.i32.load8_u(i++, 0, 4); if (chr >= 97) if (chr <= 122) chr -= 32; // a-z → A-Z Porffor.wasm.i32.store8(j++, chr, 0, 4); } return out; }; ``` -------------------------------- ### Enable TypeScript Parsing Source: https://github.com/canadahonk/porffor/blob/main/README.md Enable parsing of TypeScript type annotations. If no parser is explicitly set, this option defaults to '@babel/parser'. Note that this does not perform type checking. ```bash --parse-types ``` -------------------------------- ### Implement ByteString.prototype.toUpperCase Source: https://github.com/canadahonk/porffor/blob/main/CONTRIBUTING.md This function converts a bytestring to its uppercase equivalent. It manually manipulates memory using Wasm intrinsics for performance. Ensure explicit type annotations and avoid `this`. ```typescript export const __ByteString_prototype_toUpperCase = (_this: bytestring) => { const len: i32 = _this.length; let out: bytestring = ''; Porffor.wasm.i32.store(out, len, 0, 0); let i: i32 = Porffor.wasm`local.get ${_this}`, j: i32 = Porffor.wasm`local.get ${out}`; const endPtr: i32 = i + len; while (i < endPtr) { let chr: i32 = Porffor.wasm.i32.load8_u(i++, 0, 4); if (chr >= 97) if (chr <= 122) chr -= 32; Porffor.wasm.i32.store8(j++, chr, 0, 4); } return out; }; ``` -------------------------------- ### Disassemble Wasm Function to WAT-like Format Source: https://context7.com/canadahonk/porffor/llms.txt Uses the `disassemble` function from `compiler/disassemble.js` to convert compiled Wasm bytecode into a human-readable WAT-like format. This is useful for debugging and analysis. ```javascript import compile from './compiler/index.js'; import disassemble from './compiler/disassemble.js'; const { funcs, globals, exceptions } = compile(` function square(n) { return n * n; } square(7); `); // Disassemble the user-defined 'square' function const userFunc = funcs.find(f => f.name === 'square'); if (userFunc) { const asm = disassemble( userFunc.wasm, userFunc.name, userFunc.index, userFunc.locals, userFunc.params, userFunc.returns, funcs, globals, exceptions ); console.log(asm); } // Example output: square(5) (n(0): f64) -> (f64, i32) ;; local #last_type(1): i32 local.get n local.get n f64.mul i32.const 1 return ``` -------------------------------- ### Wasm Default Return Source: https://github.com/canadahonk/porffor/blob/main/CONTRIBUTING.md Provide a default return value, such as `(0, 0)`, when a condition is not met. This is achieved using `i32.const` followed by `return`. ```wasm i32.const 0 i32.const 0 return ``` -------------------------------- ### Disable Optimizations Source: https://github.com/canadahonk/porffor/blob/main/README.md Disable all optimizations during the compilation process. ```bash -O0 ``` -------------------------------- ### Load Character from String Source: https://github.com/canadahonk/porffor/blob/main/CONTRIBUTING.md Loads a single character's code from a UTF-16 encoded String at a specified memory location. This is used for retrieving characters that occupy two bytes. ```javascript Porffor.wasm.i32.load16_u(pointer, 0, 4) ``` -------------------------------- ### Compiler Flags: Value Type Source: https://context7.com/canadahonk/porffor/llms.txt Specify the Wasm value type using `--valtype`. The default is `f64`, but `i32` can be used for specific cases. ```bash # Value type (rarely needed) porf --valtype=i32 script.js # Use i32 instead of default f64 ``` -------------------------------- ### Load Character from ByteString Source: https://github.com/canadahonk/porffor/blob/main/CONTRIBUTING.md Loads a single character's code from a ByteString at a specified memory location. This operation is optimized for single-byte character encodings. ```javascript Porffor.wasm.i32.load8_u(pointer, 0, 4) ``` -------------------------------- ### Specify Wasm Function Return Type Source: https://github.com/canadahonk/porffor/blob/main/CONTRIBUTING.md Define the expected return type of a Wasm function. Be cautious as Porffor typically expects a `(valtype, i32)` return type. ```wasm returns i32 i32 ``` -------------------------------- ### Define Porffor Built-in Function Source: https://github.com/canadahonk/porffor/blob/main/CONTRIBUTING.md Defines a built-in function for Porffor using a specific naming convention (`__FunctionName`) and an `_this` argument. Arrow functions are used, and return types are omitted for prototype methods. ```typescript export const __ByteString_prototype_toUpperCase = (_this: bytestring) => { ``` -------------------------------- ### Update Test Results Percentage Source: https://github.com/canadahonk/porffor/blob/main/index.html Updates the displayed percentage of test results and visualizes progress with a bar. Fetches history data from '/test262/history.json'. ```javascript const niceDate = (x) => { return x.toLocaleString('default', { month: 'long', day: 'numeric' }); }; const history = await (await fetch('/test262/history.json')).json(); const percent = history[0].results[0]; test262_percent.innerHTML = `${percent.toFixed(2)}% ${'█'.repeat(Math.floor(percent / 4))}${'░'.repeat(Math.ceil((100 - percent) / 4))}`; ``` -------------------------------- ### Inline Wasm Bytecode with Porffor.wasm Source: https://github.com/canadahonk/porffor/blob/main/CONTRIBUTING.md Use this macro to embed Wasm bytecode directly within TypeScript. It supports defining local variables, specifying return types, and performing type checks and conversions. ```typescript export const add_i32 = (a: any, b: any) => { Porffor.wasm` local aCasted i32 local bCasted i32 returns i32 i32 ;; if both types are number local.get ${a+1} i32.const 1 i32.eq local.get ${b+1} i32.const 1 i32.eq i32.and if local.get ${a} i32.from local.set aCasted local.get ${b} i32.from local.set bCasted local.get aCasted local.get bCasted i32.add i32.const 1 return end ;; return (0, 0) otherwise i32.const 0 i32.const 0 return`; } ``` -------------------------------- ### Convert to Uppercase Source: https://github.com/canadahonk/porffor/blob/main/CONTRIBUTING.md Converts a lowercase ASCII character to its uppercase equivalent by subtracting 32 from its character code if it falls within the 'a' to 'z' range. ```typescript if (chr >= 97) if (chr <= 122) chr -= 32; ``` -------------------------------- ### Store Character in ByteString Source: https://github.com/canadahonk/porffor/blob/main/CONTRIBUTING.md Stores a single character's code into a ByteString at a specified memory location. Use this for ASCII/LATIN-1 characters to optimize memory usage. ```javascript Porffor.wasm.i32.store8(pointer, characterCode, 0, 4) ```