# 编译器管道架构

<cite>
**本文引用的文件**
- [src/main.rs](file://src/main.rs)
- [src/lib.rs](file://src/lib.rs)
- [src/project_compiler.rs](file://src/project_compiler.rs)
- [src/swc_transform.rs](file://src/swc_transform.rs)
- [src/codegen.rs](file://src/codegen.rs)
- [src/coff.rs](file://src/coff.rs)
- [src/standalone_gen.rs](file://src/standalone_gen.rs)
- [src/dep_graph.rs](file://src/dep_graph.rs)
- [src/project.rs](file://src/project.rs)
- [src/standalone_loader.rs](file://src/standalone_loader.rs)
- [Cargo.toml](file://Cargo.toml)
- [loader/src/main.rs](file://loader/src/main.rs)
</cite>

## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)

## 简介
本文件系统性阐述 ts-native 编译器管道的架构与实现，覆盖从 TypeScript 源码到机器码的完整流程：前端解析（SWC AST 生成 HIR）、中间表示转换（HIR 到 Cranelift IR）、后端代码生成（Cranelift IR 到 COFF/EXE）。文档重点说明各阶段职责、输入输出格式、数据转换过程、设计模式（流水线、并行化、错误传播）、性能优化与内存管理策略，并提供流程图与阶段间数据流示例，帮助读者快速理解与扩展编译器。

## 项目结构
仓库采用模块化组织，核心编译逻辑集中在 src 目录，包含命令行入口、库导出、项目编译器、前端转换、代码生成、COFF 解析与独立可执行生成等模块；loader 目录提供运行时加载器；runtime 目录提供运行时 DLL。

```mermaid
graph TB
subgraph "命令行与库"
CLI["src/main.rs<br/>命令行入口"]
LIB["src/lib.rs<br/>库导出"]
end
subgraph "编译器核心"
PC["src/project_compiler.rs<br/>项目编译器"]
DG["src/dep_graph.rs<br/>依赖图"]
PJ["src/project.rs<br/>项目发现与管理"]
SWC["src/swc_transform.rs<br/>前端解析/转换"]
CG["src/codegen.rs<br/>代码生成(Cranelift)"]
COFF["src/coff.rs<br/>COFF解析"]
SG["src/standalone_gen.rs<br/>独立可执行生成"]
end
subgraph "运行时与加载器"
LDR["loader/src/main.rs<br/>tsn-loader"]
SLDR["src/standalone_loader.rs<br/>独立加载器"]
RT["runtime/<br/>tsn_runtime.dll"]
end
CLI --> SWC
CLI --> CG
PC --> PJ
PC --> DG
PC --> SWC
PC --> CG
PC --> SG
SWC --> CG
CG --> COFF
SG --> SLDR
LDR --> RT
SLDR --> RT
```

图表来源
- [src/main.rs:1-79](file://src/main.rs#L1-L79)
- [src/lib.rs:1-17](file://src/lib.rs#L1-L17)
- [src/project_compiler.rs:1-728](file://src/project_compiler.rs#L1-L728)
- [src/dep_graph.rs:1-257](file://src/dep_graph.rs#L1-L257)
- [src/project.rs:1-461](file://src/project.rs#L1-L461)
- [src/swc_transform.rs:1-800](file://src/swc_transform.rs#L1-L800)
- [src/codegen.rs:1-800](file://src/codegen.rs#L1-L800)
- [src/coff.rs:1-388](file://src/coff.rs#L1-L388)
- [src/standalone_gen.rs:1-637](file://src/standalone_gen.rs#L1-L637)
- [loader/src/main.rs:1-800](file://loader/src/main.rs#L1-L800)
- [src/standalone_loader.rs:1-339](file://src/standalone_loader.rs#L1-L339)

章节来源
- [src/main.rs:1-79](file://src/main.rs#L1-L79)
- [src/lib.rs:1-17](file://src/lib.rs#L1-L17)
- [Cargo.toml:1-57](file://Cargo.toml#L1-L57)

## 核心组件
- 命令行入口与主流程：负责参数解析、输入输出文件推断、调用前端解析与代码生成，最终写出 COFF 对象文件。
- 项目编译器：协调多模块项目，构建依赖图、按拓扑顺序编译模块、为每个入口生成独立可执行文件（内嵌 loader）。
- 依赖图：解析 import/export，构建 DAG，支持拓扑排序与依赖闭包计算。
- 项目发现与管理：扫描目录、识别入口、解析模块路径与导入。
- 前端解析与转换（SWC）：使用 SWC 解析 TypeScript，生成 HIR（高层中间表示）。
- 代码生成（Cranelift）：将 HIR 转换为 Cranelift IR，再生成 COFF 对象文件。
- COFF 解析：解析标准 COFF 文件，提取节区、符号、重定位。
- 独立可执行生成：将模块数据序列化为 .tsnobj，配合独立加载器运行。
- 运行时加载器：支持直接加载 COFF 或通过 DLL 编译并执行；独立加载器从 .tsnobj 文件加载并执行。

章节来源
- [src/main.rs:1-79](file://src/main.rs#L1-L79)
- [src/project_compiler.rs:1-728](file://src/project_compiler.rs#L1-L728)
- [src/dep_graph.rs:1-257](file://src/dep_graph.rs#L1-L257)
- [src/project.rs:1-461](file://src/project.rs#L1-L461)
- [src/swc_transform.rs:1-800](file://src/swc_transform.rs#L1-L800)
- [src/codegen.rs:1-800](file://src/codegen.rs#L1-L800)
- [src/coff.rs:1-388](file://src/coff.rs#L1-L388)
- [src/standalone_gen.rs:1-637](file://src/standalone_gen.rs#L1-L637)
- [loader/src/main.rs:1-800](file://loader/src/main.rs#L1-L800)
- [src/standalone_loader.rs:1-339](file://src/standalone_loader.rs#L1-L339)

## 架构总览
编译器管道采用“前端解析 → 中间转换 → 后端生成”的经典三段式架构，结合项目级依赖管理与独立可执行生成，形成完整的端到端流水线。

```mermaid
sequenceDiagram
participant User as "用户"
participant CLI as "命令行入口(main.rs)"
participant SWC as "前端解析(SWC)"
participant CG as "代码生成(Cranelift)"
participant COFF as "COFF输出"
participant Loader as "运行时加载器(loader/src/main.rs)"
User->>CLI : "ts-native <input.ts> [-o output]"
CLI->>SWC : "parse(source)"
SWC-->>CLI : "HIR 列表"
CLI->>CG : "compile_coff(HIR)"
CG-->>CLI : "COFF 字节流"
CLI->>COFF : "写入 .obj 文件"
CLI-->>User : "输出完成提示"
Note over Loader,COFF : "运行时加载器可直接加载 COFF 或通过 DLL 编译并执行"
```

图表来源
- [src/main.rs:55-76](file://src/main.rs#L55-L76)
- [src/swc_transform.rs:10-34](file://src/swc_transform.rs#L10-L34)
- [src/codegen.rs:521-604](file://src/codegen.rs#L521-L604)

## 详细组件分析

### 前端解析与 HIR 生成（SWC）
- 职责：解析 TypeScript 源码，构建 SWC AST，再转换为内部 HIR（函数、表达式、语句、导入绑定等）。
- 输入：TypeScript 源码字符串。
- 输出：HIR 表达式列表（Vec<HirExpr>）。
- 关键点：
  - 使用 SWC 的 Lexer/Parser 解析 TS。
  - 将模块级导入转换为 ImportBinding 节点，便于后续依赖分析。
  - 自动注入 main 函数（若缺失）以保证可执行入口。
  - 支持多种控制流与表达式（if/while/for/try/catch/throw 等）。
- 错误传播：解析失败时返回错误，上层捕获并终止流程。

```mermaid
flowchart TD
Start(["开始: 输入 TypeScript 源码"]) --> Lex["词法分析(SWC Lexer)"]
Lex --> Parse["语法分析(SWC Parser)"]
Parse --> Transform["模块转换为 HIR"]
Transform --> InjectMain{"是否包含 main 函数?"}
InjectMain --> |否| AddMain["添加默认 main 函数"]
InjectMain --> |是| Keep["保留已有 main"]
AddMain --> Out["输出 HIR 列表"]
Keep --> Out
```

图表来源
- [src/swc_transform.rs:10-34](file://src/swc_transform.rs#L10-L34)
- [src/swc_transform.rs:36-176](file://src/swc_transform.rs#L36-L176)

章节来源
- [src/swc_transform.rs:1-800](file://src/swc_transform.rs#L1-L800)

### 中间表示转换（HIR → Cranelift IR）
- 职责：将 HIR 转换为 Cranelift IR，建立函数签名、收集字符串常量、生成数据段。
- 输入：HIR 列表。
- 输出：COFF 对象文件字节流。
- 关键点：
  - 第一遍：收集函数签名与字符串常量，声明导出函数与本地数据。
  - 第二遍：编译函数体，生成 IR 指令，应用数据与符号。
  - 支持字符串池、符号表、重定位表的生成与提取。
- 性能：两遍扫描，避免重复分配；字符串池去重，减少数据冗余。

```mermaid
flowchart TD
HIR["输入: HIR 列表"] --> Pass1["第一遍: 收集函数签名/字符串常量"]
Pass1 --> Declare["声明导出函数/数据"]
Declare --> Pass2["第二遍: 编译函数体(IR)"]
Pass2 --> Emit["生成 COFF 节区/符号/重定位"]
Emit --> Bytes["输出: COFF 字节流"]
```

图表来源
- [src/codegen.rs:521-604](file://src/codegen.rs#L521-L604)
- [src/codegen.rs:539-586](file://src/codegen.rs#L539-L586)

章节来源
- [src/codegen.rs:1-800](file://src/codegen.rs#L1-L800)

### 后端代码生成（COFF/EXE）
- 职责：将 Cranelift IR 输出为 COFF 对象文件，支持从 COFF 提取原始模块数据，供独立可执行生成与运行时加载。
- 输入：COFF 字节流或 HIR 列表。
- 输出：COFF 对象文件或 .tsnobj 独立可执行数据。
- 关键点：
  - COFF 解析：支持节区、符号、重定位的读取与验证。
  - 独立可执行：将模块数据序列化为 .tsnobj，配合独立加载器运行。
  - 运行时加载器：支持直接加载 COFF 或通过 DLL 编译并执行，动态解析外部符号。

```mermaid
sequenceDiagram
participant CG as "代码生成(Cranelift)"
participant COFF as "COFF 输出"
participant SG as "独立可执行生成"
participant SL as "独立加载器"
CG-->>COFF : "生成 COFF 对象文件"
CG-->>SG : "提取模块数据(RawModuleData)"
SG-->>SL : "序列化 .tsnobj"
SL-->>SL : "加载 tsn_runtime.dll 并应用重定位"
SL-->>SL : "查找入口 main 并执行"
```

图表来源
- [src/codegen.rs:607-707](file://src/codegen.rs#L607-L707)
- [src/standalone_gen.rs:390-487](file://src/standalone_gen.rs#L390-L487)
- [src/standalone_loader.rs:127-302](file://src/standalone_loader.rs#L127-L302)

章节来源
- [src/coff.rs:1-388](file://src/coff.rs#L1-L388)
- [src/standalone_gen.rs:1-637](file://src/standalone_gen.rs#L1-L637)
- [src/standalone_loader.rs:1-339](file://src/standalone_loader.rs#L1-L339)

### 项目编译器与流水线
- 职责：协调多模块项目，构建依赖图，按拓扑顺序编译模块，为每个入口生成独立可执行文件。
- 设计模式：
  - 流水线：分阶段执行（模块编译、可执行生成、报告生成）。
  - 并行化：模块编译阶段可并行（当前实现为顺序，具备扩展空间）。
  - 错误传播：任一模块失败即终止，记录失败模块与错误信息。
- 关键点：
  - 依赖图构建：解析 import/export，计算编译层级与入口闭包。
  - 模块符号表：跨模块调用时声明外部符号。
  - 独立可执行：合并模块、重命名符号、对齐节区、应用重定位。

```mermaid
flowchart TD
Proj["项目发现与配置"] --> BuildDG["构建依赖图(DAG)"]
BuildDG --> Topo["拓扑排序(编译顺序)"]
Topo --> CompileMods["按序编译模块(.obj)"]
CompileMods --> Merge["合并模块(入口闭包)"]
Merge --> Rename["重命名符号(避免冲突)"]
Rename --> Align["节区对齐/重定位应用"]
Align --> GenExe["生成独立可执行(.exe/.tsnobj)"]
GenExe --> Report["生成编译报告"]
```

图表来源
- [src/project_compiler.rs:248-332](file://src/project_compiler.rs#L248-L332)
- [src/dep_graph.rs:43-132](file://src/dep_graph.rs#L43-L132)
- [src/project_compiler.rs:334-382](file://src/project_compiler.rs#L334-L382)
- [src/project_compiler.rs:384-567](file://src/project_compiler.rs#L384-L567)

章节来源
- [src/project_compiler.rs:1-728](file://src/project_compiler.rs#L1-L728)
- [src/dep_graph.rs:1-257](file://src/dep_graph.rs#L1-L257)
- [src/project.rs:1-461](file://src/project.rs#L1-L461)

### 运行时加载器与独立可执行
- 职责：加载 tsn_runtime.dll，分配可执行/数据内存，应用重定位，查找入口并执行。
- 支持两种模式：
  - 直接加载 COFF：解析标准 COFF，应用重定位，执行入口。
  - DLL 编译模式：调用 ts-native DLL 编译并执行。
- 独立加载器：从 .tsnobj 文件读取模块数据，应用重定位，执行入口。

```mermaid
sequenceDiagram
participant L as "tsn-loader"
participant RT as "tsn_runtime.dll"
participant VM as "虚拟内存"
participant EXE as "独立可执行"
L->>RT : "加载运行时 DLL"
L->>VM : "分配可执行/数据内存"
L->>L : "应用重定位(REL32/ADDR64)"
L->>EXE : "查找入口 main 并调用"
EXE-->>L : "返回执行结果"
```

图表来源
- [loader/src/main.rs:537-743](file://loader/src/main.rs#L537-L743)
- [src/standalone_loader.rs:127-302](file://src/standalone_loader.rs#L127-L302)

章节来源
- [loader/src/main.rs:1-800](file://loader/src/main.rs#L1-L800)
- [src/standalone_loader.rs:1-339](file://src/standalone_loader.rs#L1-L339)

## 依赖关系分析
- 外部依赖：
  - SWC 生态：解析 TypeScript（swc_common, swc_ecma_parser, swc_ecma_ast）。
  - Cranelift：生成目标代码（cranelift-frontend, cranelift-module, cranelift-object, clcodegen）。
  - object：解析/写入 COFF 文件。
  - log/env_logger：日志与调试。
- 内部模块耦合：
  - project_compiler 依赖 project/dep_graph/swo_transform/codegen/standalone_gen。
  - codegen 依赖 Cranelift 与 object。
  - standalone_gen 与 standalone_loader 形成独立可执行闭环。

```mermaid
graph TB
SWC["SWC 解析"] --> HIR["HIR"]
HIR --> CG["Cranelift 代码生成"]
CG --> OBJ["COFF 对象文件"]
OBJ --> COFF["COFF 解析"]
OBJ --> SG["独立可执行生成"]
SG --> SL["独立加载器"]
CG --> RT["tsn_runtime.dll"]
SL --> RT
```

图表来源
- [Cargo.toml:22-47](file://Cargo.toml#L22-L47)
- [src/codegen.rs:521-604](file://src/codegen.rs#L521-L604)
- [src/standalone_gen.rs:390-487](file://src/standalone_gen.rs#L390-L487)

章节来源
- [Cargo.toml:1-57](file://Cargo.toml#L1-L57)

## 性能考量
- 时间复杂度：
  - 前端解析：O(n)，n 为源码字符数。
  - 代码生成：O(n + m)，n 为 HIR 节点数，m 为重定位条目数。
  - 依赖图构建：O(V+E)，V 为模块数，E 为导入边数。
- 内存管理：
  - 字符串池：去重字符串常量，减少数据段大小。
  - 两遍扫描：先收集后生成，避免重复分配。
  - 节区对齐：align_up 对齐，减少重定位复杂度。
  - 进程内存估算：项目编译器提供内存使用估算与格式化输出，便于监控。
- 并行化策略：
  - 模块编译阶段可并行（当前顺序实现，具备扩展为并行任务队列的空间）。
  - 重定位应用可在 CPU 核心间拆分（按重定位条目切片）。
- I/O 优化：
  - COFF 解析与序列化采用零拷贝切片操作，减少内存复制。
  - 独立可执行生成将数据序列化为紧凑二进制，便于快速加载。

章节来源
- [src/project_compiler.rs:27-52](file://src/project_compiler.rs#L27-L52)
- [src/codegen.rs:709-800](file://src/codegen.rs#L709-L800)
- [src/standalone_gen.rs:489-605](file://src/standalone_gen.rs#L489-L605)

## 故障排查指南
- 常见问题与定位：
  - 前端解析失败：检查 TypeScript 语法与 SWC 版本兼容性；查看解析错误信息。
  - 代码生成失败：确认 HIR 正确性与 Cranelift 配置；检查字符串池与符号表。
  - COFF 解析失败：确认对象文件完整性与节区/符号/重定位一致性。
  - 独立可执行重定位失败：检查外部符号（js_*）是否在 tsn_runtime.dll 中导出；内部符号是否存在于模块数据。
  - 运行时加载器找不到 DLL：确认 tsn_runtime.dll 位于可执行同目录或 target/release/deps。
- 错误传播机制：
  - 项目编译器在模块编译失败时立即终止并记录错误。
  - 命令行入口在缺少输入或输出文件时给出明确提示。
  - 运行时加载器在重定位失败时输出警告并继续处理，便于诊断。
- 调试建议：
  - 启用详细日志（RUST_LOG），观察阶段耗时与内存使用。
  - 使用编译报告查看模块统计与覆盖率。
  - 逐步验证 HIR、COFF、重定位表的正确性。

章节来源
- [src/project_compiler.rs:273-279](file://src/project_compiler.rs#L273-L279)
- [src/main.rs:10-40](file://src/main.rs#L10-L40)
- [loader/src/main.rs:632-711](file://loader/src/main.rs#L632-L711)

## 结论
ts-native 采用清晰的三段式编译架构，结合项目级依赖管理与独立可执行生成，实现了从 TypeScript 到机器码的高效转换。前端解析稳定可靠，中间转换与后端生成紧密协作，运行时加载器提供灵活的执行方式。通过两遍扫描、字符串池、对齐与重定位优化，整体性能与内存占用得到良好平衡。未来可在模块编译阶段引入并行化与增量编译，进一步提升大规模项目的构建效率。

## 附录
- API 与数据模型概览（简化）
  - HIR 表达式：函数、变量、表达式、控制流、类、装饰器等。
  - 模块数据：代码、数据、只读数据、符号、重定位。
  - 编译统计：解析时间、代码生成时间、COFF 生成时间、提取时间、函数数、字符串数、代码/数据大小。
- 使用建议
  - 大型项目建议使用项目编译器进行批量编译与独立可执行生成。
  - 开发调试阶段可直接使用 tsn-loader 进行即时编译与执行。
  - 产物部署建议使用独立可执行（.exe/.tsnobj）以降低运行时依赖。