elephc Documentation

repository·main·Indexed 19 days ago

https://github.com/illegalstudio/elephc

elephc is a PHP-to-native AOT compiler (version 0.26.2) that transforms a subset of PHP into standalone, high-performance native binaries for macOS and Linux without the Zend Engine. It provides systems programming features including pointers, buffers, packed classes, FFI, and the ability to emit C-ABI compatible shared libraries via --emit cdylib. The toolset includes a native dependency manager (elephc native) and an experimental eval() bridge via elephc-magician.

Tokens
485.4K
Snippets
1.5K
Records
2.5K
Agent score
65%

What's inside elephc

  1. What is Elephc?

    main

    Elephc is a PHP-to-native compiler that compiles a subset of PHP directly to native assembly. It produces standalone binaries for macOS ARM64, Linux ARM64, and Linux x86_64 without requiring the Zend Engine, an external PHP runtime, or PHP-FPM.

    Key characteristics:

    • AOT Compilation: Ordinary source is Ahead-of-Time compiled with no opcode fallback.
    • Standalone Binaries: The output is a single executable containing only the necessary runtime routines.
    • Experimental eval(): Can embed an optional interpreter bridge (Magician) when runtime parsing is required.
    • Native Extensions: Provides tools like packed class, buffer<T>, ptr, and extern (FFI) for systems and performance-critical work.
  2. Overview of supported SPL components in elephc

    main

    elephc provides a comprehensive set of Standard PHP Library (SPL) components required for modern PHP code. These include interfaces for iteration, counting, and array access; the standard SPL exception hierarchy; container classes; and various iterators (filesystem, recursive, and decorators).

    Key characteristics:

    • Namespace: All SPL names live in the global namespace, matching standard PHP behavior.
    • Availability: They are available without requiring manual imports or additional runtime extensions.
  3. Understand the elephc module map and project structure

    main

    The elephc project is organized into a core compiler/runtime engine and several specialized crates that provide high-performance bridges to PHP functionality.

    Core Compiler (src/) components:

    • Frontend: Lexer, Parser (AST), and Type Checker.
    • Middle-end: IR (Intermediate Representation), Optimization passes, and Type-checking.
    • Backend: Codegen (EIR to Assembly), Link-planning, and Linker integration.
    • Runtime Support: codegen_support provides the heavy lifting for ABI, platform-specific transforms, and the extensive PHP runtime routines (strings, arrays, IO, etc.).
    • Preludes: Specialized injection points for features like PDO, Timezones, Images, and Web superglobals.

    Specialized Crates (crates/) for PHP functionality:

    These crates are typically compiled as staticlibs to provide high-performance implementations of PHP core functions:

    • elephc-crypto: Hashing/HMAC bridge for hash() and hash_hmac().
    • elephc-image: Image processing bridge (GD, Exif, Imagick, Gmagick, Cairo).
    • elephc-magician: Optional EvalIR parser/interpreter for dynamic eval() support.
    • elephc-pdo: Multi-driver database bridge.
    • elephc-phar: PHAR/tar/zip archive bridge for phar:// paths.
    • elephc-tls: TLS bridge for https:// stream wrappers.
    • elephc-tz: IANA timezone-introspection bridge.
    • elephc-web: Prefork HTTP server bridge for --web binaries.
  4. Supported PHP-compatible language features in elephc

    main

    elephc is a PHP-compatible compiler and runtime. As of the current roadmap, it supports a wide range of PHP language features including:

    Control Structures

    • Loops: if, elseif, else, while, for, do...while.
    • Loop Control: break N and continue N (multi-level).
    • Branching: switch (with fall-through) and match expressions (PHP 8 style, no fall-through).

    Variables and Types

    • Types: Integers, Strings, Booleans (true/false), and Floats.
    • Type Casting: (int), (string), (float), (bool), (array).
    • Null: Proper null support with is_null() and null coercion.
    • Constants: define(), const, and predefined constants like PHP_INT_MAX, M_PI.
    • Scope: global $var, static variables, and local function scope.
    • Parameter Handling: Pass by reference (&$x), default values, and variadic functions (...$args).
    • Closures: Anonymous functions with use captures and Arrow functions (fn($x) => ...).

    Operators

    • Arithmetic: +, -, *, /, %, ** (exponentiation).
    • Assignment: Standard =, compound assignments (+=, -=, etc.), and null coalescing (??, ??=).
    • Comparison: ==, !=, <, >, <=, >=, and strict comparison ===, !==.
    • Logical: &&, ||, and, or, xor, !.
    • Bitwise: &, |, ^, ~, <<, >> and compound versions.
    • Other: Ternary (? :), Spaceship (<=>), and Spread operator (...).

    Data Structures

    • Indexed Arrays: $arr = [1, 2, 3]; with push, pop, count, etc.
    • Associative Arrays: $map = ["key" => "value"]; with hash table runtime support.
    • Multi-dimensional Arrays: [[1,2],[3,4]].
    • Unpacking: List unpacking [$a, $b] = $array; and spread [...$a, ...$b].

    Built-in Functions

    • String: strlen, str_replace, explode, implode, sprintf, hash family, etc.
    • Array: array_map, array_filter, array_merge, array_column, etc.
    • File System: fopen, file_get_contents, mkdir, unlink, etc.
    • Math: abs, min, max, round, rand, etc.
  5. Core runtime features in v0.22.x

    main

    The v0.22.x release cycle focused on core parity and runtime correctness, specifically addressing dispatching, subscript syntax, and memory helpers for low-level operations.

    Key features included:

    • Subscript syntax for ArrayAccess: Support for $obj[$k] syntax, covering read, write, isset, and unset paths, including Mixed-boxing for offsets and values.
    • Raw pointer memory helpers: Low-level helpers for FFI and socket implementations, such as ptr_read16(), ptr_write16(), ptr_read_string(), and ptr_write_string().
    • Throwable dispatch fix: Corrected the behavior where catching by Throwable and calling getMessage() on a typed binding returned incorrect data.
    • IntrinsicCall foundation: A mechanism for runtime-managed SPL/core objects to allow for clean method interception.
  6. Compile PHP to native binaries

    main

    elephc is an Ahead-of-Time (AOT) compiler that transforms a static subset of PHP into standalone native binaries. It does not require the PHP Zend Engine or an external VM to run the resulting binaries.

    Supported targets include:

    • macOS ARM64
    • Linux ARM64
    • Linux x86_64

    For code requiring runtime parsing, an experimental eval() feature can embed an optional interpreter bridge.

  7. Benefits of compiling PHP with elephc

    main

    Compiling PHP with elephc provides several advantages over traditional interpreted PHP:

    1. Standalone Binaries: You ship a single executable that has no dependency on PHP or an external VM.
    2. Performance: PHP code is converted into native machine code, allowing it to run as fast as compiled languages like C or Rust.
    3. Transparency: Because the output is real assembly, you can trace exactly how PHP constructs (like echo 1 + 2) translate into data moves, arithmetic, and system calls.
    4. Hybrid Dynamic Support: For programs using experimental eval(), elephc can embed an optional Magician interpreter bridge inside the executable, allowing dynamic fragments to run while the rest of the program remains native.
  8. What is a generator in elephc?

    main

    A generator is a function that uses the yield keyword. Instead of executing the body immediately, calling a generator function returns a Generator object. This object implements the built-in Iterator interface. When you iterate over it (e.g., using foreach), the function body runs up to the next yield, hands the value back, and suspends execution until the next iteration.

    <?php
    function counter(int $from) {
        $i = $from;
        while ($i < $from + 3) {
            yield $i;
            $i++;
        }
    }
    
    foreach (counter(10) as $v) {
        echo $v;
        echo " ";
    }
    // Prints: 10 11 12
  9. Check ptr() availability and compatibility modes

    main

    The ptr() builtin's availability depends on how your Elephc code is being executed:

    • Compiled (AOT): Fully supported by the Elephc code generator.
    • eval() (magician interpreter): Supported via the declarative interpreter builtin.
    • Strict PHP mode: Not supported. Because ptr() is an Elephc extension with no PHP equivalent, programs compiled with the --strict-php flag will treat ptr() as a nonexistent name in both compiled and eval'd code.
  10. Constant folding in elephc

    main

    The fold_constants() pass recursively walks the AST and rewrites expressions whose results are statically decidable from their children. This allows the compiler to emit constants directly instead of calling runtime helpers like pow, __rt_concat, or numeric string conversion paths.

    Supported folding operations include:

    • Arithmetic: +, -, *, /, %, ** (scalar arithmetic).
    • Bitwise/Shift: Integer bitwise and shift operations.
    • Unary: -, !, and ~.
    • Strings: Concatenation using the . operator.
    • Comparisons: Strict, numeric, and spaceship <=> operators.
    • Logical: && and || when both sides are scalar constants.
    • Control Structures: ??, ternary, and match when the result is known.
    • Arrays: Scalar indexed and associative array-literal reads (e.g., [2, 9][0]).
    • Casts: Unambiguous scalar casts like (int)"42" or (bool)"0".

    Folding is applied recursively inside function/method bodies, closures, arrow functions, default parameter values, property defaults, and constant declarations.

    <?php
    $x = (2 < 3) ? (2 ** 3) : (3 ** 4);
    echo $x . "\n";

    // After folding, the AST is effectively:

    <?php
    $x = 8;
    echo $x . "\n";
  11. How the HashContext object works for incremental hashing

    main

    The hash_init() function returns a HashContext object, which is used for incremental hashing. This object allows you to feed data into a hashing context in chunks using hash_update() and then finalize the digest with hash_final().

    Key behaviors:

    • Lifecycle: The context is freed automatically when the object goes out of scope. Using a context after hash_final() will raise a TypeError.
    • Cloning: hash_copy() returns an independent object. Feeding the original after copying does not affect the copy, and finalizing the original leaves the copy usable.
    • Security: hash_equals() should be used for timing-safe string comparison.
    • Limitations:
      • serialize() is not supported and will raise an Exception.
      • HMAC streaming via hash_init($algo, HASH_HMAC, $key) is not supported; use hash_hmac() instead.
      • print_r() and var_export() do not render HashContext objects.
    • Implementation: The class is injected by the compiler only when hashing functions are referenced. It is a real object, not a resource.
    $c = hash_init('md5');
    var_dump(is_object($c));            // bool(true)
    var_dump(gettype($c));              // string(6) "object"
    var_dump(get_class($c));            // string(11) "HashContext"
    var_dump($c instanceof HashContext) // bool(true)
    var_dump($c);                       // object(HashContext)#1 (1) { ["algo"]=> string(3) "md5" }
  12. Understand the differences between ini_get() and opcache_get_configuration()

    main

    When inspecting OPcache settings, be aware that ini_get() and opcache_get_configuration() return different data formats:

    • ini_get('opcache.*'): Returns the raw INI string. Booleans are rendered as "1" or "0".
    • opcache_get_configuration(): Returns normalized values. For example, opcache.memory_consumption returns a large integer (bytes) instead of a string like "128", and opcache.max_wasted_percentage returns a float (e.g., 0.05) instead of a string (e.g., "5").
    Directiveini_get() (Raw)opcache_get_configuration() (Normalized)
    opcache.memory_consumption"128"134217728
    opcache.max_wasted_percentage"5"0.05
    opcache.optimization_level"0x7FFEBFFF"2147401727
    opcache.jit_buffer_size"64M"67108864