# Rust 运行时库

<cite>
**本文引用的文件列表**
- [runtime/src/lib.rs](file://runtime/src/lib.rs)
- [ARCHITECTURE.md](file://ARCHITECTURE.md)
- [src/tsn_ffi.rs](file://src/tsn_ffi.rs)
- [loader/src/main.rs](file://loader/src/main.rs)
- [src/main.rs](file://src/main.rs)
- [runtime/Cargo.toml](file://runtime/Cargo.toml)
- [Cargo.toml](file://Cargo.toml)
- [docs/README.md](file://docs/README.md)
- [test_multi_entry/src/main.ts](file://test_multi_entry/src/main.ts)
</cite>

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

## 简介
本文件面向 ts-native 的 Rust 运行时库（runtime crate），系统化阐述其值表示体系（NaN-boxing）、池化管理（字符串池、数组池、对象池）、核心运行时函数族（算术、数组、对象、数学、JSON、文件系统、路径、OS、进程、定时器、加密、压缩、日期、工具等）以及静态变量与生命周期管理，并提供使用示例与性能优化建议，帮助开发者高效使用该运行时库。

## 项目结构
- 运行时库位于 runtime 子目录，导出一组以 js_ 前缀命名的 C ABI 函数，供编译产物通过符号重定位调用。
- 编译器侧通过 FFI 模块导出编译接口，供 loader 或 CLI 工具调用。
- loader 负责加载 COFF 或调用 DLL 编译并执行，完成重定位与内存映射后调用入口函数。
- 顶层 Cargo.toml 定义了二进制与库目标，runtime/Cargo.toml 定义了运行时依赖。

```mermaid
graph TB
subgraph "编译器侧"
A["tsn_ffi.rs<br/>导出 tsn_* 接口"]
B["src/main.rs<br/>CLI 编译入口"]
L["loader/src/main.rs<br/>加载器/执行器"]
end
subgraph "运行时库"
R["runtime/src/lib.rs<br/>js_* 运行时函数"]
end
A --> R
B --> L
L --> R
```

图表来源
- [src/tsn_ffi.rs:60-113](file://src/tsn_ffi.rs#L60-L113)
- [src/main.rs:7-78](file://src/main.rs#L7-L78)
- [loader/src/main.rs:42-127](file://loader/src/main.rs#L42-L127)
- [runtime/src/lib.rs:135-1532](file://runtime/src/lib.rs#L135-L1532)

章节来源
- [runtime/src/lib.rs:1-1532](file://runtime/src/lib.rs#L1-L1532)
- [src/tsn_ffi.rs:1-341](file://src/tsn_ffi.rs#L1-L341)
- [loader/src/main.rs:1-1260](file://loader/src/main.rs#L1-L1260)
- [src/main.rs:1-79](file://src/main.rs#L1-L79)
- [runtime/Cargo.toml:1-28](file://runtime/Cargo.toml#L1-L28)
- [Cargo.toml:1-57](file://Cargo.toml#L1-L57)

## 核心组件
- NaN-boxing 值表示：使用 IEEE 754 双精度浮点的高位作为标签，低 48 位承载指针或数值，实现统一的 64 位值表示。
- 池化管理：字符串池、数组池、对象池分别维护堆上资源，通过标签与索引进行寻址。
- 运行时函数族：涵盖算术、数组、对象、数学、JSON、文件系统、路径、OS、进程、定时器、加密、压缩、日期、工具等。
- 静态变量与生命周期：全局池使用静态可变变量，配合线程局部存储与原子计数器管理并发安全与生命周期。

章节来源
- [runtime/src/lib.rs:7-24](file://runtime/src/lib.rs#L7-L24)
- [runtime/src/lib.rs:37-121](file://runtime/src/lib.rs#L37-L121)
- [runtime/src/lib.rs:135-1532](file://runtime/src/lib.rs#L135-L1532)
- [ARCHITECTURE.md:90-115](file://ARCHITECTURE.md#L90-L115)

## 架构总览
运行时与编译器通过符号重定位连接，运行时函数以 js_ 前缀暴露，供编译产物直接调用。编译器通过 FFI 暴露 tsn_* 接口，loader 可直接调用 DLL 或加载 COFF 执行。

```mermaid
sequenceDiagram
participant CLI as "CLI/Loader"
participant FFI as "tsn_ffi.rs"
participant RT as "runtime/src/lib.rs"
participant Exec as "执行引擎"
CLI->>FFI : 调用 tsn_compile(source)
FFI-->>CLI : 返回 TsnCompileResult(含 code/rdata/symbols/relocs)
CLI->>Exec : 分配可执行/数据内存并复制
Exec->>Exec : 应用重定位(外部符号解析为 js_* 函数)
Exec->>RT : 调用入口函数(main)
RT-->>Exec : 返回 f64 结果
Exec-->>CLI : 输出结果
```

图表来源
- [src/tsn_ffi.rs:60-113](file://src/tsn_ffi.rs#L60-L113)
- [loader/src/main.rs:387-502](file://loader/src/main.rs#L387-L502)
- [loader/src/main.rs:537-743](file://loader/src/main.rs#L537-L743)
- [runtime/src/lib.rs:135-1532](file://runtime/src/lib.rs#L135-L1532)

## 详细组件分析

### NaN-boxing 值表示系统
- 标签编码：使用高 4 位作为类型标签，payload 的低 48 位承载指针或数值。
- 类型分类与标签：
  - 数字：非 NaN 值；NaN 且 tag=0 也视为数字。
  - 字符串：tag=1，payload 为字符串池索引。
  - 对象：tag=2，payload 为对象池索引。
  - 布尔：tag=3，payload 为 0/1。
  - undefined：tag=4。
  - null：tag=5。
  - 函数：tag=6。
  - 数组：tag=7，payload 为数组池索引。
- 内存布局：IEEE 754 双精度 64 位，标签与 payload 共享同一存储单元，避免额外内存开销。

```mermaid
flowchart TD
Start(["输入 f64"]) --> CheckNaN{"是否为 NaN?"}
CheckNaN --> |否| IsNum["标记为 number"]
CheckNaN --> |是| ExtractTag["提取高 4 位标签"]
ExtractTag --> Tag0{"tag==0 ?"}
Tag0 --> |是| IsNum
Tag0 --> |否| Branch["根据标签分支"]
Branch --> S["字符串池索引"]
Branch --> O["对象池索引"]
Branch --> A["数组池索引"]
Branch --> B["布尔值(0/1)"]
Branch --> U["undefined/null/function"]
IsNum --> End(["输出类型判断"])
S --> End
O --> End
A --> End
B --> End
U --> End
```

图表来源
- [runtime/src/lib.rs:21-35](file://runtime/src/lib.rs#L21-L35)
- [runtime/src/lib.rs:7-19](file://runtime/src/lib.rs#L7-L19)

章节来源
- [runtime/src/lib.rs:7-35](file://runtime/src/lib.rs#L7-L35)
- [ARCHITECTURE.md:90-115](file://ARCHITECTURE.md#L90-L115)

### 字符串池、数组池与对象池
- 字符串池：Vec<String>，store_string 返回带标签的 f64，get_string 通过标签与索引还原字符串。
- 数组池：Vec<JsArray>，JsArray 含 elements: Vec<f64> 与 length: usize，支持 push、索引读写、length 属性。
- 对象池：Vec<JsObject>，JsObject 含 HashMap<u64, f64>，键为字符串哈希（NaN-tagged）。

```mermaid
classDiagram
class JsArray {
+elements : Vec<f64>
+length : usize
}
class JsObject {
+properties : HashMap<u64, f64>
}
class Runtime {
+store_string(s) : f64
+get_string(bits) : Option<String>
+store_array(arr) : f64
+get_array(bits) : Option<&JsArray>
+get_array_mut(bits) : Option<&mut JsArray>
+store_object(obj) : f64
+get_object_mut(bits) : Option<&mut JsObject>
}
Runtime --> JsArray : "管理数组池"
Runtime --> JsObject : "管理对象池"
```

图表来源
- [runtime/src/lib.rs:65-68](file://runtime/src/lib.rs#L65-L68)
- [runtime/src/lib.rs:108-110](file://runtime/src/lib.rs#L108-L110)
- [runtime/src/lib.rs:39-60](file://runtime/src/lib.rs#L39-L60)
- [runtime/src/lib.rs:70-103](file://runtime/src/lib.rs#L70-L103)
- [runtime/src/lib.rs:112-133](file://runtime/src/lib.rs#L112-L133)

章节来源
- [runtime/src/lib.rs:37-121](file://runtime/src/lib.rs#L37-L121)

### 核心运行时函数族

#### 算术与比较
- js_add/js_sub/js_mul/js_div：基础四则运算。
- js_fmod：取模运算，除零返回 NaN。
- js_strict_equals：严格相等（===），字符串内容比较，其他类型按位比较。

章节来源
- [runtime/src/lib.rs:201-221](file://runtime/src/lib.rs#L201-L221)
- [runtime/src/lib.rs:147-167](file://runtime/src/lib.rs#L147-L167)

#### 数组操作
- js_array_new：创建数组，传入初始容量。
- js_array_push：向数组末尾追加元素，必要时扩容。
- js_index_get/js_array_set：数组索引读取/设置，支持扩展稀疏数组。
- js_property_length：返回数组/字符串长度。

章节来源
- [runtime/src/lib.rs:222-317](file://runtime/src/lib.rs#L222-L317)

#### 对象属性访问
- js_object_new：创建对象。
- js_object_get/js_object_set：属性读取/设置，键为 NaN-tagged 字符串哈希。
- js_object_keys/js_object_values/js_object_entries/js_object_has_own/js_object_assign：对象工具函数。

章节来源
- [runtime/src/lib.rs:325-572](file://runtime/src/lib.rs#L325-L572)

#### 数学函数
- js_math_sin/js_math_cos/js_math_sqrt/js_math_abs/js_math_floor/js_math_ceil/js_math_pow/js_math_random：标准数学函数与伪随机数生成。

章节来源
- [runtime/src/lib.rs:366-402](file://runtime/src/lib.rs#L366-L402)

#### JSON 工具
- js_string_from_char_code：Unicode 码点转字符串。
- js_json_stringify/js_json_parse：简单 JSON 序列化/反序列化。

章节来源
- [runtime/src/lib.rs:460-506](file://runtime/src/lib.rs#L460-L506)

#### 类型检测与日志
- js_typeof：返回类型字符串（字符串化）。
- js_set_log_callback：设置日志回调，启用/禁用日志。

章节来源
- [runtime/src/lib.rs:404-455](file://runtime/src/lib.rs#L404-L455)

#### DOM/正则/占位
- js_regex_test/js_regex_exec/js_string_match/js_dom_create_element/js_dom_append_child/js_await：占位实现，便于桥接前端生态。

章节来源
- [runtime/src/lib.rs:597-644](file://runtime/src/lib.rs#L597-L644)

#### 文件系统(fs)模块
- js_fs_read_file_sync/js_fs_read_file/js_fs_write_file_sync/js_fs_write_file/js_fs_append_file_sync/js_fs_exists_sync/js_fs_exists/js_fs_mkdir_sync/js_fs_mkdir/js_fs_unlink_sync/js_fs_unlink/js_fs_rmdir_sync/js_fs_rmdir/js_fs_readdir_sync/js_fs_readdir/js_fs_stat_sync/js_fs_stat/js_fs_copy_file_sync/js_fs_copy_file/js_fs_rename_sync/js_fs_rename/js_fs_realpath_sync/js_fs_realpath：文件系统操作，返回 undefined/null/布尔/字符串/数组/对象等。

章节来源
- [runtime/src/lib.rs:646-851](file://runtime/src/lib.rs#L646-L851)

#### 路径(path)模块
- js_path_join/js_path_resolve/js_path_dirname/js_path_basename/js_path_extname/js_path_is_absolute/js_path_normalize/js_path_sep/js_path_delimiter：路径工具函数。

章节来源
- [runtime/src/lib.rs:853-950](file://runtime/src/lib.rs#L853-L950)

#### OS 模块
- js_os_platform/js_os_type/js_os_arch/js_os_hostname/js_os_homedir/js_os_tmpdir/js_os_totalmem/js_os_freemem/js_os_uptime/js_os_eol/js_os_endianness/js_os_release/js_os_version/js_os_machine/js_os_network_interfaces/js_os_user_info/js_os_constants/js_os_dev_null/js_os_loadavg/js_os_cpus：系统信息查询。

章节来源
- [runtime/src/lib.rs:965-1149](file://runtime/src/lib.rs#L965-L1149)

#### 进程(process)模块
- js_process_cwd/js_process_chdir/js_process_exit/js_process_pid/js_process_ppid/js_process_platform/js_process_arch/js_process_version/js_process_env/js_process_env_get/js_process_argv/js_process_exec_path/js_process_hrtime/js_process_memory_usage/js_process_uptime/js_process_title/js_process_next_tick：进程与环境信息。

章节来源
- [runtime/src/lib.rs:1151-1287](file://runtime/src/lib.rs#L1151-L1287)

#### 定时器(timers)模块
- js_set_timeout/js_set_interval/js_clear_timeout/js_clear_interval/js_set_immediate/js_clear_immediate：定时器占位实现。

章节来源
- [runtime/src/lib.rs:1289-1324](file://runtime/src/lib.rs#L1289-L1324)

#### 加密(crypto)模块
- js_crypto_random_bytes/js_crypto_random_uuid/js_crypto_create_hash/js_crypto_hash_update/js_crypto_hash_digest/js_crypto_hash/js_crypto_get_hashes/js_crypto_get_ciphers/js_crypto_timing_safe_equal/js_crypto_pbkdf2：哈希、随机、PBKDF2 等。

章节来源
- [runtime/src/lib.rs:1326-1449](file://runtime/src/lib.rs#L1326-L1449)

#### 压缩(zlib)模块
- js_zlib_deflate_sync/js_zlib_inflate_sync/js_zlib_gzip_sync/js_zlib_gunzip_sync：Gzip 压缩/解压。

章节来源
- [runtime/src/lib.rs:1451-1496](file://runtime/src/lib.rs#L1451-L1496)

#### 日期(Date)模块
- js_date_now/js_date_parse/js_date_utc：时间戳与占位。

章节来源
- [runtime/src/lib.rs:1498-1519](file://runtime/src/lib.rs#L1498-L1519)

#### 工具(util)模块
- js_util_format/js_util_inspect：占位。

章节来源
- [runtime/src/lib.rs:1521-1531](file://runtime/src/lib.rs#L1521-L1531)

### 静态变量与生命周期管理
- 全局池：STRING_POOL、ARRAY_POOL、OBJECT_POOL 使用静态可变变量，通过 unsafe 访问，注意并发安全。
- 日志回调：LOG_CALLBACK 与 LOG_ENABLED 使用静态可变变量控制日志开关与回调。
- 定时器计数器：TIMER_ID_COUNTER 使用原子计数器保证多线程安全。
- 线程局部存储：Math.random 使用 thread_local 保存种子，避免全局锁竞争。

章节来源
- [runtime/src/lib.rs:39-48](file://runtime/src/lib.rs#L39-L48)
- [runtime/src/lib.rs:70-79](file://runtime/src/lib.rs#L70-L79)
- [runtime/src/lib.rs:112-121](file://runtime/src/lib.rs#L112-L121)
- [runtime/src/lib.rs:427-455](file://runtime/src/lib.rs#L427-L455)
- [runtime/src/lib.rs:1291-1292](file://runtime/src/lib.rs#L1291-L1292)
- [runtime/src/lib.rs:392-402](file://runtime/src/lib.rs#L392-L402)

### 使用示例与最佳实践
- 示例一：数组与对象的基本使用
  - 创建数组：调用 js_array_new，随后多次调用 js_array_push 或 js_array_set。
  - 读取长度：调用 js_property_length。
  - 对象属性：调用 js_object_new，然后 js_object_set 设置键值，js_object_get 读取。
  - 参考路径：[runtime/src/lib.rs:222-317](file://runtime/src/lib.rs#L222-L317)，[runtime/src/lib.rs:325-364](file://runtime/src/lib.rs#L325-L364)
- 示例二：字符串与 JSON
  - 从静态字符串创建 JS 字符串：js_string_from_static。
  - JSON 序列化/反序列化：js_json_stringify/js_json_parse。
  - 参考路径：[runtime/src/lib.rs:137-145](file://runtime/src/lib.rs#L137-L145)，[runtime/src/lib.rs:460-506](file://runtime/src/lib.rs#L460-L506)
- 示例三：文件系统与路径
  - 读取文件：js_fs_read_file_sync。
  - 路径拼接：js_path_join。
  - 参考路径：[runtime/src/lib.rs:646-657](file://runtime/src/lib.rs#L646-L657)，[runtime/src/lib.rs:853-868](file://runtime/src/lib.rs#L853-L868)
- 示例四：日志与类型检测
  - 设置日志回调：js_set_log_callback。
  - 类型检测：js_typeof。
  - 参考路径：[runtime/src/lib.rs:425-455](file://runtime/src/lib.rs#L425-L455)，[runtime/src/lib.rs:404-421](file://runtime/src/lib.rs#L404-L421)

章节来源
- [runtime/src/lib.rs:135-1532](file://runtime/src/lib.rs#L135-L1532)

## 依赖关系分析
- 运行时依赖：sha2、sha1、md-5、hmac、rand、flate2、hex 等第三方库，用于加密、压缩、随机数与十六进制编码。
- 编译器依赖：SWC 生态、Cranelift、object 等，负责解析、生成与目标文件输出。
- 加载器：通过 Win32 API 分配可执行内存、应用重定位、调用入口函数。

```mermaid
graph LR
RT["runtime/src/lib.rs"] --> SHA2["sha2"]
RT --> SHA1["sha1"]
RT --> MD5["md-5"]
RT --> HMAC["hmac"]
RT --> RAND["rand"]
RT --> FLATE2["flate2"]
RT --> HEX["hex"]
COMP["src/tsn_ffi.rs"] --> SWC["swc_*"]
COMP --> CL["cranelift-*"]
COMP --> OBJ["object"]
LOAD["loader/src/main.rs"] --> RT
LOAD --> COMP
```

图表来源
- [runtime/Cargo.toml:21-27](file://runtime/Cargo.toml#L21-L27)
- [Cargo.toml:22-47](file://Cargo.toml#L22-L47)
- [loader/src/main.rs:537-743](file://loader/src/main.rs#L537-L743)

章节来源
- [runtime/Cargo.toml:1-28](file://runtime/Cargo.toml#L1-L28)
- [Cargo.toml:1-57](file://Cargo.toml#L1-L57)
- [loader/src/main.rs:1-1260](file://loader/src/main.rs#L1-L1260)

## 性能考量
- NaN-boxing 优势：统一 64 位存储，减少分支与包装成本，适合高频调用的运行时函数。
- 池化策略：字符串/数组/对象池避免频繁分配，但需注意池增长与并发访问的代价。
- 线程局部存储：Math.random 使用 thread_local，降低全局锁竞争。
- 压缩与哈希：使用 flate2 与 sha2 等成熟库，注意输入大小与缓冲区复用。
- 重定位与内存映射：加载器一次性分配可执行/数据内存并复制，减少多次映射开销。

[本节为通用性能讨论，不直接分析具体文件]

## 故障排查指南
- 编译错误：tsn_ffi::create_error_result 会提取行号与上下文，结合日志级别定位问题。
- 符号未解析：加载器在应用重定位时若遇到未知符号或空符号名，会记录警告并跳过。
- 空指针与越界：运行时函数对空指针与越界访问进行保护，返回 undefined/null，避免崩溃。
- 日志开关：通过 js_set_log_callback 控制日志回调与开关，便于调试。

章节来源
- [src/tsn_ffi.rs:294-340](file://src/tsn_ffi.rs#L294-L340)
- [loader/src/main.rs:632-711](file://loader/src/main.rs#L632-L711)
- [runtime/src/lib.rs:137-145](file://runtime/src/lib.rs#L137-L145)

## 结论
ts-native 的 Rust 运行时库以 NaN-boxing 为核心，结合池化管理与丰富的运行时函数族，为编译产物提供了高性能、可移植的运行时支撑。通过清晰的 C ABI 接口与完善的加载器/编译器链路，开发者可以便捷地编写、编译与执行 TypeScript 程序，并按需扩展运行时能力。

[本节为总结性内容，不直接分析具体文件]

## 附录
- 相关文档入口：[docs/README.md:1-9](file://docs/README.md#L1-L9)
- 架构设计：[ARCHITECTURE.md:1-184](file://ARCHITECTURE.md#L1-L184)
- 示例入口：[test_multi_entry/src/main.ts:1-15](file://test_multi_entry/src/main.ts#L1-L15)