Skip to content

Latest commit

 

History

History
102 lines (81 loc) · 3.95 KB

File metadata and controls

102 lines (81 loc) · 3.95 KB

Architecture

This is a brief overview for contributors. For detailed implementation notes, see the project's CLAUDE.md.

Compilation Pipeline

TypeScript (.ts)
    ↓ Parse (SWC)
    ↓ AST
    ↓ Lower (perry-hir)
    ↓ HIR (High-level IR)
    ↓ Transform (inline, closure conversion, async lowering)
    ↓ Codegen (LLVM)
    ↓ Object file (.o)
    ↓ Link (system cc)
    ↓
Native Executable

Crate Map

Crate Purpose
perry CLI driver, command parsing, compilation orchestration
perry-parser SWC wrapper for TypeScript parsing
perry-types Type system definitions
perry-hir HIR data structures (ir.rs) and AST→HIR lowering (lower.rs)
perry-transform IR passes: function inlining, closure conversion, async lowering
perry-codegen-llvm LLVM-based native code generation
perry-codegen-wasm WebAssembly code generation for --target web / --target wasm (HIR → WASM bytecode + JS bridge)
perry-codegen-js Legacy JavaScript code generator (still present for the JS minifier; the JS-emit --target web path was consolidated into perry-codegen-wasm)
perry-codegen-swiftui SwiftUI code generation for WidgetKit extensions
perry-runtime Runtime library: NaN-boxed values, GC, arena allocator, objects, arrays, strings
perry-stdlib Node.js API implementations: mysql2, redis, fastify, bcrypt, etc.
perry-ui Shared UI types
perry-ui-macos macOS UI (AppKit)
perry-ui-ios iOS UI (UIKit)
perry-jsruntime JavaScript interop via QuickJS

Key Concepts

NaN-Boxing

All JavaScript values are represented as 64-bit NaN-boxed values. The upper 16 bits encode the type tag:

Tag Type
0x7FFF String (lower 48 bits = pointer)
0x7FFD Pointer/Object (lower 48 bits = pointer)
0x7FFE Int32 (lower 32 bits = integer)
0x7FFA BigInt (lower 48 bits = pointer)
Special constants undefined, null, true, false
Any other Float64 (the full 64 bits)

Garbage Collection

Generational mark-sweep GC, per-thread arena split into nursery + old-gen. Roots come from a precise shadow stack (emitted by codegen), a conservative native-stack scan, and 9 registered runtime scanners. Two-bit aging tenures objects after surviving 2 minor cycles; a write barrier maintains a remembered set for old → young pointers.

See Internals → Memory Model for the full picture (NaN-boxing, heap layout, root discovery, generational behaviour, env-var escape hatches).

Handle-Based UI

UI widgets are represented as small integer handles NaN-boxed with POINTER_TAG. Each handle maps to a native platform widget (NSButton, UILabel, GtkButton, etc.). Two dispatch tables route method calls and property accesses to the correct FFI function.

Source Code Organization

The codegen crate is organized into focused modules:

perry-codegen-llvm/src/
  codegen.rs       # Main entry, module compilation
  types.rs         # Type definitions, context structs
  util.rs          # Helper functions
  stubs.rs         # Stub generation for unresolved deps
  runtime_decls.rs # Runtime function declarations
  classes.rs       # Class compilation
  functions.rs     # Function compilation
  closures.rs      # Closure compilation
  module_init.rs   # Module initialization
  stmt.rs          # Statement compilation
  expr.rs          # Expression compilation

The HIR lowering was split into 8 modules:

perry-hir/src/
  lower.rs           # Main lowering entry
  analysis.rs        # Code analysis passes
  enums.rs           # Enum lowering
  jsx.rs             # JSX lowering
  lower_types.rs     # Type lowering
  lower_patterns.rs  # Pattern lowering
  destructuring.rs   # Destructuring lowering
  lower_decl.rs      # Declaration lowering

Next Steps