# 数据流设计

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

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

## 简介
本文件面向 ts-native 的数据流设计，系统性阐述从 TypeScript 源码到 AST、再到 HIR（高层中间表示）、最终生成机器码的完整数据转换路径。文档重点覆盖以下方面：
- 编译管线中的数据流转与格式转换
- 关键数据结构的设计理念与演进（ModuleNode、HirExpr、RawModuleData 等）
- 缓存策略、内存布局与序列化机制
- 数据一致性与并发访问控制的设计考量
- 多入口项目编译与独立可执行文件生成的工程化实践

## 项目结构
ts-native 采用模块化组织，核心模块如下：
- 编译器前端：负责 TypeScript 解析与 HIR 构建
- 编译器后端：负责 HIR 到目标码（COFF）的生成
- 项目管理：模块发现、依赖图构建与编译顺序确定
- 独立可执行文件生成：合并模块、重命名符号、序列化为 .tsnobj
- 运行时插件：提供 NaN-boxing 值模型与 JS 运行时函数
- 加载器：支持直接加载 COFF 或通过 DLL 编译并执行

```mermaid
graph TB
subgraph "编译器前端"
SWC["SWC 解析器<br/>生成 HIR"]
HIR["HirExpr<br/>高层中间表示"]
end
subgraph "编译器后端"
CG["CodeGen<br/>Cranelift IR 生成"]
COFF["COFF 对象文件"]
RAW["RawModuleData<br/>原始模块数据"]
end
subgraph "项目管理"
PRJ["Project<br/>项目发现与模块管理"]
DG["DepGraph<br/>依赖图与拓扑排序"]
PC["ProjectCompiler<br/>多模块编译协调"]
end
subgraph "独立可执行文件"
SG["StandaloneGen<br/>合并与序列化"]
TSNOBJ[".tsnobj<br/>序列化二进制"]
end
subgraph "运行时"
RT["tsn_runtime.dll<br/>NaN-boxing 值模型"]
LOADER["tsn-loader<br/>动态加载与执行"]
end
SRC["TypeScript 源码"] --> SWC --> HIR --> CG --> COFF --> RAW
PRJ --> DG --> PC --> SG --> TSNOBJ
RAW --> LOADER --> RT
TSNOBJ --> LOADER --> RT
```

图表来源
- [src/swc_transform.rs:10-34](file://src/swc_transform.rs#L10-L34)
- [src/codegen.rs:520-604](file://src/codegen.rs#L520-L604)
- [src/project.rs:58-153](file://src/project.rs#L58-L153)
- [src/dep_graph.rs:43-132](file://src/dep_graph.rs#L43-L132)
- [src/project_compiler.rs:205-332](file://src/project_compiler.rs#L205-L332)
- [src/standalone_gen.rs:390-487](file://src/standalone_gen.rs#L390-L487)
- [loader/src/main.rs:537-743](file://loader/src/main.rs#L537-L743)
- [runtime/src/lib.rs:1-800](file://runtime/src/lib.rs#L1-L800)

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

## 核心组件
- SWC 解析器：将 TypeScript 源码解析为 HIR（HirExpr）树，涵盖函数、表达式、控制流、类、装饰器、异步/生成器等语法。
- CodeGen：基于 Cranelift 将 HIR 转换为目标码（COFF），同时收集字符串常量、符号与重定位信息，并可提取 RawModuleData 以供 JIT/FFI 使用。
- Project 与 DepGraph：扫描项目、解析 import/export、构建依赖图、拓扑排序与入口闭包计算，支撑多模块编译与独立可执行文件生成。
- ProjectCompiler：协调多模块编译、对象文件合并、符号重命名、.tsnobj 序列化与独立可执行文件生成。
- StandaloneGen：将多个模块数据合并为单一模块，应用符号重命名与重定位，序列化为 .tsnobj。
- 运行时（tsn_runtime.dll）：提供 NaN-boxing 值模型与 JS 运行时函数（如字符串、数组、对象、Math、fs 等），供加载器在运行时解析外部符号。

章节来源
- [src/swc_transform.rs:36-176](file://src/swc_transform.rs#L36-L176)
- [src/codegen.rs:80-196](file://src/codegen.rs#L80-L196)
- [src/project.rs:44-153](file://src/project.rs#L44-L153)
- [src/dep_graph.rs:11-132](file://src/dep_graph.rs#L11-L132)
- [src/project_compiler.rs:190-332](file://src/project_compiler.rs#L190-L332)
- [src/standalone_gen.rs:11-34](file://src/standalone_gen.rs#L11-L34)
- [runtime/src/lib.rs:1-800](file://runtime/src/lib.rs#L1-L800)

## 架构概览
下图展示从源码到可执行文件的关键数据流与转换：

```mermaid
sequenceDiagram
participant TS as "TypeScript 源码"
participant SWC as "SWC 解析器"
participant HIR as "HIR 树 (HirExpr)"
participant CG as "CodeGen"
participant COFF as "COFF 对象"
participant RAW as "RawModuleData"
participant PC as "ProjectCompiler"
participant SG as "StandaloneGen"
participant OBJ as ".tsnobj"
TS->>SWC : "读取并解析"
SWC-->>HIR : "生成 HIR 节点"
HIR->>CG : "遍历函数与表达式"
CG-->>COFF : "生成 COFF 字节流"
COFF->>RAW : "解析节区/符号/重定位"
PC->>COFF : "多模块编译与合并"
COFF->>SG : "合并模块数据"
SG-->>OBJ : "序列化为 .tsnobj"
```

图表来源
- [src/swc_transform.rs:10-34](file://src/swc_transform.rs#L10-L34)
- [src/codegen.rs:520-707](file://src/codegen.rs#L520-L707)
- [src/project_compiler.rs:334-382](file://src/project_compiler.rs#L334-L382)
- [src/standalone_gen.rs:390-605](file://src/standalone_gen.rs#L390-L605)

## 详细组件分析

### HIR 数据结构与设计理念
- 设计目标：以统一的 HirExpr 表达 TypeScript 的语法结构，便于后续编译器优化与目标码生成。
- 关键类型：
  - 基础表达式：Number、Boolean、String、Null、Undefined、Identifier
  - 控制流：Binary、Unary、Typeof、Call、Ternary、Return、Var、If、While、For、Block、Break、Continue、Assign、Seq
  - 数组与对象：Array、Index、Object、Property
  - 异常与语句：TryCatch、Throw、ExprStmt
  - 正则：Regex、RegexTest、RegexExec、RegexMatch
  - 类与继承：Class、New、This、SuperMethod
  - 生成器：Generator、Yield、YieldFrom
  - 异步：AsyncFunction、Await
  - 装饰器：Decorator、DecoratedClass、DecoratedMethod
- 设计权衡：
  - 通过 ImportBinding 记录模块导入绑定，便于跨模块编译时声明外部符号
  - 通过 SourceMapEntry 记录源码位置，便于调试与性能分析
  - 通过 CompileStats 统计编译性能指标，辅助优化

```mermaid
classDiagram
class HirExpr {
+Number(f64)
+Boolean(bool)
+String(String)
+Null
+Undefined
+Identifier(String)
+Binary(op, left, right)
+Unary(op, operand)
+Typeof(expr)
+Call(callee, args)
+Ternary(cond, then_expr, else_expr)
+Function(name, params, body)
+Return(option)
+Var(name, init, is_mut)
+If(cond, then_body, else_body)
+While(cond, body)
+For(init, cond, update, body)
+Block(stmts)
+Break
+Continue
+Assign(target, value)
+Array(elements)
+Index(object, index)
+Object(props)
+Property(object, name)
+TryCatch(try_body, catch_param, catch_body, finally_body)
+Throw(option)
+ExprStmt(expr)
+Seq(stmts)
+Regex(pattern, flags)
+RegexTest(regex, text)
+RegexExec(regex, text)
+RegexMatch(regex, text)
+Class(name, parent, constructor, methods, properties)
+New(class_name, args)
+This
+SuperMethod(method_name, args)
+Generator(name, params, body)
+Yield(expr)
+YieldFrom(expr)
+AsyncFunction(name, params, body)
+Await(expr)
+Decorator(target, target_type, name, args)
+DecoratedClass(name, parent, constructor, methods, properties, decorators)
+DecoratedMethod(name, params, body, is_static, decorators)
}
```

图表来源
- [src/codegen.rs:80-196](file://src/codegen.rs#L80-L196)

章节来源
- [src/codegen.rs:80-196](file://src/codegen.rs#L80-L196)
- [src/codegen.rs:231-238](file://src/codegen.rs#L231-L238)
- [src/codegen.rs:241-252](file://src/codegen.rs#L241-L252)

### 项目发现与依赖图（Project 与 DepGraph）
- Project：扫描目录、识别入口与模块、解析 import 路径、规范化模块名、延迟加载文件内容。
- DepGraph：解析每个模块的导出与导入，构建有向无环图（DAG），进行拓扑排序与层级计算，计算每个入口的依赖闭包。
- 关键流程：
  - 从项目根目录扫描 .ts 文件，构建 SourceFile 映射
  - 解析每个文件的 import/export，建立模块间依赖关系
  - 拓扑排序得到编译顺序
  - 计算入口闭包，用于独立可执行文件生成

```mermaid
flowchart TD
Start(["开始"]) --> Scan["扫描 .ts 文件<br/>构建 SourceFile 映射"]
Scan --> ParseImpExp["解析 import/export<br/>收集模块依赖"]
ParseImpExp --> BuildDAG["构建依赖图 (DAG)"]
BuildDAG --> TopoSort["拓扑排序"]
TopoSort --> Levels["计算编译层级"]
Levels --> Closures["计算入口闭包"]
Closures --> End(["完成"])
```

图表来源
- [src/project.rs:58-153](file://src/project.rs#L58-L153)
- [src/dep_graph.rs:43-132](file://src/dep_graph.rs#L43-L132)
- [src/dep_graph.rs:167-210](file://src/dep_graph.rs#L167-L210)
- [src/dep_graph.rs:212-232](file://src/dep_graph.rs#L212-L232)

章节来源
- [src/project.rs:58-153](file://src/project.rs#L58-L153)
- [src/dep_graph.rs:43-132](file://src/dep_graph.rs#L43-L132)
- [src/dep_graph.rs:167-210](file://src/dep_graph.rs#L167-L210)
- [src/dep_graph.rs:212-232](file://src/dep_graph.rs#L212-L232)

### 多模块编译与独立可执行文件生成（ProjectCompiler 与 StandaloneGen）
- ProjectCompiler：
  - 按拓扑顺序编译所有模块为 .obj
  - 为每个入口生成独立可执行文件（预编译 loader + .tsnobj）
  - 合并对象文件、重命名非入口模块符号、应用重定位
- StandaloneGen：
  - 将多个模块数据合并为单一模块（对齐节区、复制节数据）
  - 应用符号重命名与重定位（内部/跨模块）
  - 序列化为 .tsnobj，包含头部、节数据、符号表与重定位表

```mermaid
sequenceDiagram
participant PC as "ProjectCompiler"
participant MOD as "模块 (.obj)"
participant SG as "StandaloneGen"
participant TSN as ".tsnobj"
PC->>MOD : "编译模块 (COFF)"
PC->>PC : "收集模块符号表"
PC->>SG : "合并模块数据"
SG->>SG : "重命名符号 (非入口模块)"
SG->>SG : "应用重定位"
SG-->>TSN : "序列化为 .tsnobj"
```

图表来源
- [src/project_compiler.rs:205-332](file://src/project_compiler.rs#L205-L332)
- [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/standalone_gen.rs:390-487](file://src/standalone_gen.rs#L390-L487)
- [src/standalone_gen.rs:524-605](file://src/standalone_gen.rs#L524-L605)

章节来源
- [src/project_compiler.rs:205-332](file://src/project_compiler.rs#L205-L332)
- [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/standalone_gen.rs:390-487](file://src/standalone_gen.rs#L390-L487)
- [src/standalone_gen.rs:524-605](file://src/standalone_gen.rs#L524-L605)

### 运行时加载与执行（Loader 与 tsn_runtime.dll）
- tsn-loader 支持两种模式：
  - 直接加载 COFF：使用 object crate 解析标准 COFF，分配可执行/数据内存，应用重定位，调用入口函数
  - DLL 模式：调用 ts-native.dll 编译 TypeScript，返回 RawModuleData 或 COFF 字节流
- tsn_runtime.dll 提供：
  - NaN-boxing 值模型（number/string/object/boolean/undefined/function/array）
  - JS 运行时函数（字符串、数组、对象、Math、fs 等）
  - 外部符号解析（js_* 前缀函数）

```mermaid
sequenceDiagram
participant LDR as "tsn-loader"
participant RT as "tsn_runtime.dll"
participant MEM as "内存分配"
participant REL as "重定位应用"
participant MAIN as "入口函数 main"
LDR->>RT : "加载运行时 DLL"
LDR->>MEM : "分配可执行/数据内存"
LDR->>REL : "应用重定位 (REL32/ADDR64)"
REL-->>LDR : "重定位结果统计"
LDR->>MAIN : "调用入口函数 main()"
MAIN-->>LDR : "返回结果"
```

图表来源
- [loader/src/main.rs:537-743](file://loader/src/main.rs#L537-L743)
- [runtime/src/lib.rs:1-800](file://runtime/src/lib.rs#L1-L800)

章节来源
- [loader/src/main.rs:537-743](file://loader/src/main.rs#L537-L743)
- [runtime/src/lib.rs:1-800](file://runtime/src/lib.rs#L1-L800)

### 数据结构关系图
- ModuleNode：描述单个模块的导出、导入、依赖、层级与是否为入口
- HirExpr：描述 TypeScript 语法结构的统一中间表示
- RawModuleData：从 COFF 提取的原始模块数据（函数、数据项、符号、重定位）
- ModuleData：StandaloneGen 合并后的模块数据（代码、数据、只读数据、符号、重定位）

```mermaid
classDiagram
class ModuleNode {
+path : PathBuf
+module_name : String
+exports : HashSet~String~
+imports : HashMap~PathBuf, Vec~String~~
+deps : Vec~PathBuf~
+reverse_deps : Vec~PathBuf~
+level : usize
+is_entry : bool
}
class HirExpr {
<<enumeration>>
+... (见上文)
}
class RawModuleData {
+functions : HashMap~String, Vec~u8~~
+data_items : HashMap~String, Vec~u8~~
+symbols : Vec~RawSymbol~
+relocations : Vec~RawRelocation~
}
class RawSymbol {
+name : String
+section : u8
+offset : u32
+is_global : bool
}
class RawRelocation {
+section : u8
+offset : u32
+reloc_type : u8
+target_symbol : String
}
class ModuleData {
+code : Vec~u8~
+data : Vec~u8~
+rdata : Vec~u8~
+symbols : Vec~ModuleSymbol~
+relocations : Vec~ModuleRelocation~
}
ModuleNode --> ModuleData : "依赖"
HirExpr --> RawModuleData : "编译生成"
RawModuleData --> ModuleData : "合并/重命名"
```

图表来源
- [src/dep_graph.rs:11-30](file://src/dep_graph.rs#L11-L30)
- [src/codegen.rs:21-43](file://src/codegen.rs#L21-L43)
- [src/standalone_gen.rs:11-34](file://src/standalone_gen.rs#L11-L34)

章节来源
- [src/dep_graph.rs:11-30](file://src/dep_graph.rs#L11-L30)
- [src/codegen.rs:21-43](file://src/codegen.rs#L21-L43)
- [src/standalone_gen.rs:11-34](file://src/standalone_gen.rs#L11-L34)

## 依赖关系分析
- 外部依赖：
  - SWC 生态：解析 TypeScript 语法
  - Cranelift：生成目标码（IR、ObjectModule、ObjectProduct）
  - object crate：解析 COFF 文件（节区、符号、重定位）
- 内部模块耦合：
  - swc_transform 与 codegen：前端解析与后端编译紧密协作
  - project 与 dep_graph：项目发现与依赖分析
  - project_compiler 协调多模块编译与独立可执行文件生成
  - standalone_gen 与 loader：.tsnobj 序列化与运行时加载

```mermaid
graph TB
SWC["swc_transform.rs"] --> CG["codegen.rs"]
PRJ["project.rs"] --> DG["dep_graph.rs"]
DG --> PC["project_compiler.rs"]
PC --> SG["standalone_gen.rs"]
CG --> COFF["COFF 对象文件"]
COFF --> RAW["RawModuleData"]
RAW --> LOADER["loader/src/main.rs"]
SG --> TSNOBJ[".tsnobj"]
TSNOBJ --> LOADER
LOADER --> RT["runtime/src/lib.rs"]
```

图表来源
- [Cargo.toml:22-47](file://Cargo.toml#L22-L47)
- [src/swc_transform.rs:3-8](file://src/swc_transform.rs#L3-L8)
- [src/codegen.rs:1-18](file://src/codegen.rs#L1-L18)
- [src/project.rs:5-6](file://src/project.rs#L5-L6)
- [src/dep_graph.rs:5-8](file://src/dep_graph.rs#L5-L8)
- [src/project_compiler.rs:11-25](file://src/project_compiler.rs#L11-L25)
- [src/standalone_gen.rs:6-9](file://src/standalone_gen.rs#L6-L9)
- [loader/src/main.rs:1-16](file://loader/src/main.rs#L1-L16)
- [runtime/src/lib.rs:1-6](file://runtime/src/lib.rs#L1-L6)

章节来源
- [Cargo.toml:22-47](file://Cargo.toml#L22-L47)

## 性能考量
- 编译阶段计时与内存估算：
  - CompilePhase 记录阶段耗时与内存使用（Windows 使用 GetProcessMemoryInfo，其他平台读取 /proc/self/status）
  - CompileStats 统计编译耗时、函数数量、字符串数量与代码/数据大小
- 字符串池与符号去重：
  - CodeGen 维护 string_pool，避免重复字符串常量
  - 模块符号重命名（非入口模块符号加前缀），减少符号冲突
- 对齐与内存布局：
  - 合并模块时按 16 字节对齐节区，降低运行时内存碎片
- 重定位类型：
  - REL32 与 ADDR64 两类重定位，分别用于相对寻址与绝对地址，确保跨模块调用正确

章节来源
- [src/project_compiler.rs:28-52](file://src/project_compiler.rs#L28-L52)
- [src/project_compiler.rs:54-121](file://src/project_compiler.rs#L54-L121)
- [src/codegen.rs:241-252](file://src/codegen.rs#L241-L252)
- [src/project_compiler.rs:418-419](file://src/project_compiler.rs#L418-L419)
- [src/project_compiler.rs:498-534](file://src/project_compiler.rs#L498-L534)

## 故障排查指南
- COFF 解析失败：
  - 检查 object crate 的 SectionKind 与重定位类型解析
  - 确认符号名称解析（短名与长名）与字符串表偏移
- 重定位失败：
  - 核对符号表与重定位目标名称
  - 确认内部/外部符号解析路径
- 运行时符号未解析：
  - 确认 tsn_runtime.dll 是否存在且可加载
  - 检查 js_* 前缀函数是否在运行时导出
- 多模块符号冲突：
  - 使用模块符号重命名（非入口模块符号加前缀）
  - 确保入口模块符号不被重命名

章节来源
- [src/coff.rs:72-231](file://src/coff.rs#L72-L231)
- [src/standalone_gen.rs:390-487](file://src/standalone_gen.rs#L390-L487)
- [loader/src/main.rs:632-711](file://loader/src/main.rs#L632-L711)
- [src/project_compiler.rs:418-449](file://src/project_compiler.rs#L418-L449)

## 结论
ts-native 的数据流设计围绕“从 TypeScript 到 HIR 再到目标码”的清晰路径展开，结合项目级依赖分析与独立可执行文件生成，形成完整的工程化编译链路。通过 RawModuleData、ModuleData 等关键数据结构，实现了从编译期到运行时的无缝衔接；借助 NaN-boxing 值模型与丰富的运行时函数，提供了高效的 JS 运行时能力。性能与可靠性方面，通过计时统计、内存估算、符号重命名与对齐策略，有效提升了编译效率与运行稳定性。

## 附录
- 术语说明：
  - HIR：高层中间表示（High-Level Intermediate Representation）
  - COFF：Common Object File Format
  - NaN-boxing：使用 NaN 的位域承载不同类型的值标签
- 相关文件：
  - [src/main.rs:7-78](file://src/main.rs#L7-L78)：命令行入口与基本编译流程
  - [src/bin/native_linker_main.rs:24-162](file://src/bin/native_linker_main.rs#L24-L162)：原生链接器（COFF 链接）
  - [runtime/src/lib.rs:1-800](file://runtime/src/lib.rs#L1-L800)：运行时插件实现