From 8796ab35da2cf6cd55578a08b7094649a41004c9 Mon Sep 17 00:00:00 2001 From: esrrhs Date: Wed, 17 Jun 2026 10:15:16 +0800 Subject: [PATCH 1/2] Update root README.md to fix obsolete CVar definition, API formatting, and source links --- README.md | 83 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 46 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 7ecc8167..42a4b162 100644 --- a/README.md +++ b/README.md @@ -21,9 +21,9 @@ FakeLua 是一个可嵌入的 Lua 子集编译引擎:将 Lua 脚本编译为 C 编译器对函数的数学参数自动做类型推断与特化: -1. **TypeInferencer** 对每个顶层函数运行迭代不动点推断(leave-one-out),识别出真正参与算术运算的参数(math params)。 -2. **CGen** 为每个含数学参数的函数生成 `2^k` 个特化版本(`int64_t` / `double` 组合),以及一个运行时入口分发器,根据实际参数类型路由到对应特化体。 -3. 特化体内的算术运算直接用原生 C 类型(`int64_t`/`double`)计算,比较表达式也生成原生 C `bool` 而非走 `CVar` 装箱路径,彻底消除热路径上的类型判断开销。 +1. [TypeInferencer](file:///home/project/fakelua/src/compile/type_inferencer.h) 对每个顶层函数运行迭代不动点推断(leave-one-out),识别出真正参与算术运算的参数(math params)。 +2. [CGen](file:///home/project/fakelua/src/compile/c_gen.h) 为每个含数学参数的函数生成 `2^k` 个特化版本(`int64_t` / `double` 组合),以及一个运行时入口分发器,根据实际参数类型路由到对应特化体。 +3. 特化体内的算术运算直接用原生 C 类型(`int64_t`/`double`)计算,比较表达式也生成原生 C `bool` 而非走 [CVar](file:///home/project/fakelua/include/fakelua.h#L198) 装箱路径,彻底消除热路径上的类型判断开销。 以递归 Fibonacci(n=32)为例,GCC 后端比 Lua 5.4 快 **43.7x**,TCC 后端快 **10.4x**(详见 [benchmark/README.md](benchmark/README.md))。 @@ -33,23 +33,31 @@ FakeLua 是一个可嵌入的 Lua 子集编译引擎:将 Lua 脚本编译为 C - 生成高效的类型化 C 代码,消除动态类型装箱开销 - 支持根据调用上下文自动生成 int64/double 专特化版本 -### CVar:ABI 安全的跨边界值类型 +### [CVar](file:///home/project/fakelua/include/fakelua.h#L198):ABI 安全的跨边界值类型 ```cpp struct CVar { - int type_; - int flag_; - union { bool b; int64_t i; double f; VarString *s; VarTable *t; } data_; + int type_ = 0; + int flag_ = 0; + union cvar_data { + bool b; + int64_t i; + double f; + VarString *s; + VarTable *t; + VarMulti *m; + }; + cvar_data data_{}; }; static_assert(std::is_standard_layout_v); static_assert(std::is_trivially_copyable_v); ``` -`CVar` 是 JIT 代码与 C++ 宿主之间传递值的唯一载体,强制为标准布局(POD),保证 arm64 等平台的 ABI 兼容性。 +[CVar](file:///home/project/fakelua/include/fakelua.h#L198) 是 JIT 代码与 C++ 宿主之间传递值的唯一载体,强制为标准布局(POD),保证 arm64 等平台的 ABI 兼容性。 -### VarInterface:可扩展的复杂类型桥接 +### [VarInterface](file:///home/project/fakelua/include/fakelua.h#L17):可扩展的复杂类型桥接 -`VarInterface` 是 Lua table 等复杂类型与宿主之间的抽象接口,宿主可按需实现自己的版本接入原有对象系统。库内附带 `SimpleVarImpl` 开箱即用。 +[VarInterface](file:///home/project/fakelua/include/fakelua.h#L17) 是 Lua table 等复杂类型与宿主之间的抽象接口,宿主可按需实现自己的版本接入原有对象系统。库内附带 [SimpleVarImpl](file:///home/project/fakelua/include/fakelua.h#L61) 开箱即用。 ### 多返回值与参数展开(Multi-Return & Parameter Expansion) @@ -81,7 +89,7 @@ static_assert(std::is_trivially_copyable_v); - 类型推导基于静态分析,复杂的动态类型操作无法优化 - 函数 specialization 基于调用点的 math 参数发现 - 函数参数上限 32 个(通过常量 `kMaxFunctionInputParams` 统一配置) -- 数学特化参数上限 8 个(通过常量 `kMaxMathSpecializedParams` 统一配置,超过此限制的数学参数不进行特化,作为普通动态参数处理) +- 数学特化参数上限 8 个(通过常量 [kMaxMathSpecializedParams](file:///home/project/fakelua/include/fakelua.h#L14) 统一配置,超过此限制的数学参数不进行特化,作为普通动态参数处理) ## 快速上手 @@ -138,6 +146,7 @@ ctest --test-dir build -V - `--entry`:入口函数名(默认 `main`) - `--jit_type`:`0`=TCC,`1`=GCC - `--repeat`:重复调用次数(用于性能测量) +- `--debug`:是否启用调试模式(默认 `false`,若为 `true` 则输出生成的 C 源码) ### C++ 嵌入示例 @@ -156,7 +165,7 @@ int main() { } ``` -`Call()` 支持最多 32 个参数,参数与返回值在原生 C++ 类型与 `CVar` 之间自动转换。 +[Call()](file:///home/project/fakelua/include/fakelua.h#L318) 支持最多 32 个参数(受到 [kMaxFunctionInputParams](file:///home/project/fakelua/include/fakelua.h#L13) 的统一限制),参数与返回值在原生 C++ 类型与 [CVar](file:///home/project/fakelua/include/fakelua.h#L198) 之间自动转换。 ## 性能基准 @@ -178,12 +187,12 @@ int main() { ```cpp // 手动管理(不推荐,容易泄漏) -State* s = FakeluaNewState(StateConfig{}); +State* s = [FakeluaNewState](file:///home/project/fakelua/include/fakelua.h#L262)([StateConfig](file:///home/project/fakelua/include/fakelua.h#L252){}); // ... 使用 s ... -FakeluaDeleteState(s); +[FakeluaDeleteState](file:///home/project/fakelua/include/fakelua.h#L265)(s); // 或使用 RAII 风格(推荐) -FakeluaStateGuard guard(StateConfig{}); +[FakeluaStateGuard](file:///home/project/fakelua/include/fakelua.h#L268) guard([StateConfig](file:///home/project/fakelua/include/fakelua.h#L252){}); State* s = guard.GetState(); // ... 使用 s ... // 自动释放 @@ -193,18 +202,18 @@ State* s = guard.GetState(); | 函数 | 功能 | |------|------| -| `FakeluaNewState()` | 创建 FakeLua 状态 | -| `FakeluaDeleteState()` | 释放 FakeLua 状态 | -| `CompileFile()` | 编译 Lua 文件 | -| `CompileString()` | 编译 Lua 代码字符串 | -| `Call()` | 调用编译后的函数 | -| `GetLastRecordedCCode()` | 获取最近编译的 C 代码 | -| `SetVarInterfaceNewFunc()` | 设置自定义 VarInterface 工厂 | -| `SetDebugLogLevel()` | 设置全局调试日志级别 | +| [`FakeluaNewState()`](file:///home/project/fakelua/include/fakelua.h#L262) | 创建 FakeLua 状态 | +| [`FakeluaDeleteState()`](file:///home/project/fakelua/include/fakelua.h#L265) | 释放 FakeLua 状态 | +| [`CompileFile()`](file:///home/project/fakelua/include/fakelua.h#L308) | 编译 Lua 文件 | +| [`CompileString()`](file:///home/project/fakelua/include/fakelua.h#L311) | 编译 Lua 代码字符串 | +| [`Call()`](file:///home/project/fakelua/include/fakelua.h#L318) | 调用编译后的函数 | +| [`GetLastRecordedCCode()`](file:///home/project/fakelua/include/fakelua.h#L315) | 获取最近编译的 C 代码 | +| [`SetVarInterfaceNewFunc()`](file:///home/project/fakelua/include/fakelua.h#L322) | 设置自定义 VarInterface 工厂 | +| [`SetDebugLogLevel()`](file:///home/project/fakelua/include/fakelua.h#L329) | 设置全局调试日志级别 | ### 类型转换 -FakeLua 提供 `inter::NativeToFakelua()` 和 `FakeluaToNative()` 自动推导型转换: +FakeLua 提供 [`inter::NativeToFakelua()`](file:///home/project/fakelua/include/fakelua.h#L355) 和 [`FakeluaToNative()`](file:///home/project/fakelua/include/fakelua.h#L458) 自动推导型转换: ```cpp // 原生 → FakeLua @@ -219,7 +228,7 @@ std::string native_str = inter::FakeluaToNative(v_str); ### Table 与对象互转 -通过实现 `VarInterface` 可实现 Lua table 与原生对象的双向映射: +通过实现 [`VarInterface`](file:///home/project/fakelua/include/fakelua.h#L17) 可实现 Lua table 与原生对象的双向映射: ```cpp class CustomVar : public VarInterface { @@ -258,15 +267,15 @@ Lua 源码 | 模块 | 职责 | |------|------| -| `lexer/parser` | Lua 词法和语法解析 | -| `syntax_tree` | AST 表示和遍历 | -| `preprocessor` | Lua 语法规范化(如 functiondef 提升) | -| `type_inferencer` | 静态类型推导和 specialization 决策 | -| `c_gen` | C 代码生成和类型驱动优化 | -| `compile_common` | 公共类型推导和代码生成工具 | -| `jit/*` | TCC 和 GCC 后端集成 | -| `state` | FakeLua 运行时状态管理 | -| `var` | 动态值 CVar 和转换工具 | +| [`lexer/parser`](file:///home/project/fakelua/src/compile/bison/) | Lua 词法和语法解析 | +| [`syntax_tree`](file:///home/project/fakelua/src/compile/syntax_tree.h) | AST 表示和遍历 | +| [`preprocessor`](file:///home/project/fakelua/src/compile/preprocessor.h) | Lua 语法规范化(如 functiondef 提升) | +| [`type_inferencer`](file:///home/project/fakelua/src/compile/type_inferencer.h) | 静态类型推导和 specialization 决策 | +| [`c_gen`](file:///home/project/fakelua/src/compile/c_gen.h) | C 代码生成和类型驱动优化 | +| [`compile_common`](file:///home/project/fakelua/src/compile/compile_common.h) | 公共类型推导和代码生成工具 | +| [`jit/*`](file:///home/project/fakelua/src/jit/) | TCC 和 GCC 后端集成 | +| [`state`](file:///home/project/fakelua/src/state/) | FakeLua 运行时状态管理 | +| [`var`](file:///home/project/fakelua/src/var/) | 动态值 CVar 和转换工具 | ## 项目结构 @@ -298,7 +307,7 @@ fakelua/ ## 常见问题 ### Q: 为什么选择 Lua 子集而不是完整 Lua? -A: 完整 Lua 的动态特性(如 metatable、varargs、多返回值)很难高效编译。子集实现聚焦于可静态分析的常见模式,通过类型推导和 JIT 编译获得接近 C 的性能。 +A: 完整 Lua 的某些动态特性(如 metatable、varargs)很难高效编译。子集实现聚焦于可静态分析的常见模式,通过类型推导和 JIT 编译获得接近 C 的性能。目前也支持了受限的多返回值和参数展开,但更复杂的元表(metatable)或协程等特性尚不支持。 ### Q: TCC 和 GCC 后端如何选择? A: **TCC** 快速编译(适合脚本小、编译频繁);**GCC** 优化充分(适合脚本大、运行次数多)。在同一 API 下可根据场景动态选择。 @@ -307,7 +316,7 @@ A: **TCC** 快速编译(适合脚本小、编译频繁);**GCC** 优化充 A: 可以,TCC 后端体积小,编译速度快,适合嵌入式。核心库依赖极少(仅 C++ 标准库),可交叉编译。 ### Q: 如何调试生成的 C 代码? -A: 启用 `CompileConfig::debug_mode`,查看日志和 C 代码;使用 `GetLastRecordedCCode()` 导出 C 代码进行分析。 +A: 启用 [`CompileConfig::debug_mode`](file:///home/project/fakelua/include/fakelua.h#L232),查看日志和 C 代码;使用 [`GetLastRecordedCCode()`](file:///home/project/fakelua/include/fakelua.h#L315) 导出 C 代码进行分析。 ### Q: 支持多线程吗? -A: 每个 `State` 当前为线程本地对象,多线程环境中应为每个线程创建独立的 `State`。 +A: 每个 [`State`](file:///home/project/fakelua/include/fakelua.h#L259) 当前为线程本地对象,多线程环境中应为每个线程创建独立的 [`State`](file:///home/project/fakelua/include/fakelua.h#L259)。 From 0fa5e9cdfbaf3966012de38fd6e309d87f0a067c Mon Sep 17 00:00:00 2001 From: esrrhs Date: Wed, 17 Jun 2026 10:24:52 +0800 Subject: [PATCH 2/2] Update README.md compiler flowchart and components list to include semantic analysis --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 42a4b162..453d89b7 100644 --- a/README.md +++ b/README.md @@ -254,6 +254,8 @@ Lua 源码 ↓ [预处理] → normalized AST (preprocessor) ↓ +[语义分析] → analysis result (semantic_analysis) + ↓ [类型推导] → type hints (type_inferencer) ↓ [C 代码生成] → C 源码 (c_gen) @@ -270,6 +272,7 @@ Lua 源码 | [`lexer/parser`](file:///home/project/fakelua/src/compile/bison/) | Lua 词法和语法解析 | | [`syntax_tree`](file:///home/project/fakelua/src/compile/syntax_tree.h) | AST 表示和遍历 | | [`preprocessor`](file:///home/project/fakelua/src/compile/preprocessor.h) | Lua 语法规范化(如 functiondef 提升) | +| [`semantic_analysis`](file:///home/project/fakelua/src/compile/semantic_analysis.h) | 语义和控制流分析(如未定义符号分析等) | | [`type_inferencer`](file:///home/project/fakelua/src/compile/type_inferencer.h) | 静态类型推导和 specialization 决策 | | [`c_gen`](file:///home/project/fakelua/src/compile/c_gen.h) | C 代码生成和类型驱动优化 | | [`compile_common`](file:///home/project/fakelua/src/compile/compile_common.h) | 公共类型推导和代码生成工具 |