Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 31 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

[中文](README.zh.md) | English

FakeLua is an embeddable Lua-subset compilation engine: it compiles Lua scripts into C code and dynamically compiles them into native machine code via the GCC backend for execution. It provides a C++23 interface with high-performance interop between scripts and native code.
FakeLua is an embeddable Lua-subset runtime for high-performance hosts: it compiles scripts to a bytecode VM and optionally to native code via GCC/TCC JIT, ships a large C++ native standard library (net/http/db/crypto/…), and uses an arena allocator with frame reset so there is no GC pause.

## Design Philosophy & Memory Model

Expand All @@ -28,18 +28,19 @@ This design allows FakeLua to fully eliminate GC pause impact on frame rates whi

## Core Features

### Dual JIT Backends
### Three Execution Backends

Supports two JIT modes with a seamless API switch:
The same `Call` API can target any registered backend:

- **JIT_GCC**: Invokes system GCC (`-O3`) to generate high-quality native code. This is the primary backend for production use.
- **JIT_TCC**: Embeds TinyCC for extremely fast compilation. Primarily used for development, debugging, and testing (TCC source is automatically fetched during CMake configuration — no system installation needed).
- **JIT_GCC**: Invokes system GCC (`-O3`) to generate high-quality native code. Primary backend for production.
- **JIT_TCC**: Embeds TinyCC for extremely fast compilation. Best for development, debugging, and tests (TCC is fetched automatically by CMake).
- **JIT_INTERP**: Compiles to FakeLua bytecode and runs on the built-in interpreter (`src/interp/`). No external C compiler required; useful for portability, tooling, and mixed JIT↔interp closures.

```cpp
int ret = 0;
// Same Call API, switching between JIT_GCC and JIT_TCC on demand
Call(s, JIT_GCC, "add", ret, 10, 20); // Production: GCC backend (-O3 high performance)
Call(s, JIT_TCC, "add", ret, 10, 20); // Development: TCC backend (ultra-fast compilation)
Call(s, JIT_GCC, "add", ret, 10, 20); // Production: GCC (-O3)
Call(s, JIT_TCC, "add", ret, 10, 20); // Dev/test: TCC (fast compile)
Call(s, JIT_INTERP, "add", ret, 10, 20); // Bytecode VM (no host C compiler)
```

### Numeric Specialization
Expand Down Expand Up @@ -140,20 +141,20 @@ FL_SPEC(Table_Spec_1, point, x) = NativeAdd(FL_SPEC(Table_Spec_1, point, x), (CV

## Built-in Standard Libraries

FakeLua provides 29 independent C++ native modules under `src/native/`, covering math, string, table, IO, networking, timers, events, random, containers, compression, encryption, serialization, databases, protobuf, config formats, logging, and subprocesses.
FakeLua provides 30+ independent C++ native modules under `src/native/` (registered automatically on each `State`), covering math, string, table, IO, networking, timers, events, random, containers, compression, cryptography, serialization, databases, protobuf, config formats, logging, and subprocesses.

> **Full API reference:** [src/native/README.md](src/native/README.md) / [中文](src/native/README.zh.md)

| Category | Modules |
|----------|---------|
| Core Lua | `math`, `table`, `string`, `os`, `utf8`, `io`, `random` |
| Networking | `net` (TCP/UDP server/client), `http` (Beast HTTP/1.1), `url`, `timer`, `event` |
| Core Lua | `basic`, `math`, `table`, `string`, `os`, `utf8`, `io`, `random` |
| Runtime / I/O | `runtime` (`runtime.tick()`), `net` (TCP/UDP), `http` (HTTP/1.1), `url`, `timer`, `event` |
| Data | `json`, `csv`, `serialize`, `protobuf`, `container` (Boost.Container deque/vector/list/map/set) |
| Config | `yaml`, `toml`, `xml`, `ini` |
| Database | `mysql` (async + pool), `redis` (async), `sqlite` (synchronous) |
| Crypto | `compress` (LZ4/zlib/gzip/Zstd), `crypto` (MD5/SHA/AES/RC4/Blowfish/DES, UUID, CRC-32, xxHash) |
| Crypto / compress | `compress` (LZ4/zlib/gzip/Zstd), `crypto` (OpenSSL digests/ciphers, UUID, CRC-32, xxHash) |
| Process | `process` (`process.run`; does not replace `os.execute`) |
| Logging | `log` (7 levels, tagged output, file rotation) |
| Logging | `log` (levels, tagged output, file rotation) |
| Object | `object` (NativeObject Lua-side API) |

**Regex note:** `string.find`/`match`/`gmatch`/`gsub` use **ECMAScript regex** (`boost::regex::ECMAScript`), not Lua patterns. See [Regex Guide](#regex-matching-ecmascript-syntax-not-lua-patterns) below for migration tips.
Expand Down Expand Up @@ -230,13 +231,13 @@ ctest --test-dir build -V
### CLI Tool `flua`

```bash
./build/bin/flua <script.lua> --entry=<func> --jit_type=<0|1> --repeat=<N>
./build/bin/flua <script.lua> --entry=<func> --jit_type=<0|1|2> --repeat=<N>
```

- `--entry`: Entry function name (default `main`)
- `--jit_type`: `0`=TCC, `1`=GCC
- `--jit_type`: `0`=TCC, `1`=GCC, `2`=INTERP (bytecode VM)
- `--repeat`: Repeat call count (for performance measurement)
- `--debug`: Enable debug mode (default `false`; when `true`, outputs generated C source)
- `--debug`: Enable debug mode (default `false`; when `true`, outputs generated C source / richer diagnostics)

## Performance Benchmarks

Expand Down Expand Up @@ -333,11 +334,14 @@ Lua source
↓
[Type inference] → type hints (type_inferencer)
↓
[C code generation] → C source (c_gen)
↓
[JIT compilation] → machine code (tcc_jit / gcc_jit)
↓
[Load & execute] → result
┌─────────────────────────────┬──────────────────────────────┐
↓ ↓ ↓
[C code generation] [Bytecode codegen] (shared AST)
(c_gen) (interp/codegen)
↓ ↓
[JIT TCC / GCC] [Interpreter VM]
native code (interp/interpreter)
└───────────── Call(s, JIT_*, …) ─────────────┘
```

### Key Components
Expand All @@ -350,8 +354,10 @@ Lua source
| `semantic_analysis` | Semantic and control flow analysis |
| `type_inferencer` | Static type inference and specialization decisions |
| `c_gen` | C code generation and type-driven optimization |
| `interp/*` | Bytecode codegen, opcodes, and interpreter VM |
| `compile_common` | Common type inference and codegen utilities |
| `jit/*` | TCC and GCC backend integration |
| `jit/*` | TCC/GCC backends plus `Vm` function registry |
| `native/*` | Built-in standard libraries (net, http, db, crypto, …) |
| `state` | FakeLua runtime state management |
| `var` | Dynamic value CVar and conversion utilities |

Expand All @@ -360,11 +366,11 @@ Lua source
### Q: Why choose a Lua subset over full Lua?
A: Certain dynamic features of full Lua (e.g., metatables) are difficult to compile efficiently. The subset focuses on statically analyzable common patterns, achieving near-C performance through type inference and JIT compilation.

### Q: How to choose between TCC and GCC backends?
A: **GCC** is the primary backend for production (with `-O3` optimization); **TCC** compiles extremely fast, primarily for development and testing.
### Q: How to choose among TCC, GCC, and INTERP?
A: **GCC** is the primary production backend (`-O3`). **TCC** compiles extremely fast for development and CI. **INTERP** runs bytecode without a host C compiler — good for constrained environments, tooling, and validating script semantics; hot paths can still call JIT closures when mixed.

### Q: Can it be used in embedded or constrained environments?
A: Yes — the TCC backend is small and fast. The core library has minimal dependencies (C++ standard library only) and is cross-compilable.
A: Yes — use **JIT_INTERP** (no GCC/TCC required at runtime) or the small **TCC** backend. Native modules that need OpenSSL/MySQL/etc. are optional at the dependency level for your build.

### Q: How to debug generated C code?
A: Enable `CompileConfig::debug_mode` to inspect logs and C code; use `GetLastRecordedCCode()` to export C code for analysis.
Expand Down
56 changes: 31 additions & 25 deletions README.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

中文 | [English](README.md)

FakeLua 是一个可嵌入的 Lua 子集编译引擎:将 Lua 脚本编译为 C 代码,通过 GCC 后端动态编译为原生机器码执行。提供 C++23 接口,支持脚本与原生代码高效互操作。
FakeLua 是面向高性能宿主的可嵌入 Lua 子集运行时:脚本可编译为字节码由内置虚拟机执行,也可经 GCC/TCC JIT 生成原生机器码;并内置大量 C++ native 标准库(网络/HTTP/数据库/加密等),采用 Arena 内存池 + 帧重置,无 GC 停顿。

## 设计初衷与内存设计哲学

Expand All @@ -28,18 +28,19 @@ FakeLua 的设计初衷是为了在**高性能游戏服务器**或类似的实

## 核心特性

### 双 JIT 后端
### 三种执行后端

支持两种 JIT 模式,同一套 API 无缝切换:
同一套 `Call` API 可切换任意已注册后端:

- **JIT_GCC**:调用系统 GCC(`-O3`),生成高质量原生代码。这是 FakeLua 实际运行和生产环境采用的主力后端。
- **JIT_TCC**:内嵌 TinyCC,编译速度极快。主要用于开发调试和测试验证(TCC 源码在 CMake 配置阶段自动拉取,无需系统预装)。
- **JIT_GCC**:调用系统 GCC(`-O3`)生成高质量原生代码,生产环境主力。
- **JIT_TCC**:内嵌 TinyCC,编译极快,适合开发调试与测试(CMake 自动拉取 TCC,无需系统预装)。
- **JIT_INTERP**:编译为 FakeLua 字节码,由内置解释器执行(`src/interp/`)。无需宿主 C 编译器,便于移植、工具链以及 JIT↔解释器混合闭包。

```cpp
int ret = 0;
// 同一套 Call API,可按需指定 JIT_GCC 或 JIT_TCC 后端
Call(s, JIT_GCC, "add", ret, 10, 20); // 生产环境推荐:GCC 后端 (-O3 高性能)
Call(s, JIT_TCC, "add", ret, 10, 20); // 开发调试推荐:TCC 后端 (极速编译)
Call(s, JIT_GCC, "add", ret, 10, 20); // 生产:GCC (-O3)
Call(s, JIT_TCC, "add", ret, 10, 20); // 开发/测试:TCC(极速编译)
Call(s, JIT_INTERP, "add", ret, 10, 20); // 字节码虚拟机(无需宿主 C 编译器)
```

### 数值参数特化(Numeric Specialization)
Expand Down Expand Up @@ -140,20 +141,20 @@ FL_SPEC(Table_Spec_1, point, x) = NativeAdd(FL_SPEC(Table_Spec_1, point, x), (CV

## 标准内置扩展库

FakeLua 在 `src/native/` 下提供 29 个独立 C++ 原生模块,覆盖数学、字符串、表、IO、网络、定时器、事件、随机数、容器、压缩、加密、序列化、数据库、Protobuf、配置解析、日志、子进程等领域。
FakeLua 在 `src/native/` 下提供 30+ 个独立 C++ 原生模块(每个 `State` 创建时自动注册),覆盖数学、字符串、表、IO、网络、定时器、事件、随机数、容器、压缩、加密、序列化、数据库、Protobuf、配置解析、日志、子进程等领域。

> **完整 API 文档:** [src/native/README.zh.md](src/native/README.zh.md) / [English](src/native/README.md)

| 分类 | 模块 |
|------|------|
| 核心 Lua | `math`、`table`、`string`、`os`、`utf8`、`io`、`random` |
| 网络 | `net`(TCP/UDP 服务端/客户端)、`http`(Beast HTTP/1.1)、`url`、`timer`、`event` |
| 核心 Lua | `basic`、`math`、`table`、`string`、`os`、`utf8`、`io`、`random` |
| 运行时 / IO | `runtime`(`runtime.tick()`)、`net`(TCP/UDP)、`http`(HTTP/1.1)、`url`、`timer`、`event` |
| 数据 | `json`、`csv`、`serialize`、`protobuf`、`container`(Boost.Container deque/vector/list/map/set) |
| 配置解析 | `yaml`、`toml`、`xml`、`ini` |
| 数据库 | `mysql`(异步 + 连接池)、`redis`(异步)、`sqlite`(同步) |
| 加解密 | `compress`(LZ4/zlib/gzip/Zstd)、`crypto`(MD5/SHA/AES/RC4/Blowfish/DES、UUID、CRC-32、xxHash) |
| 加解密 / 压缩 | `compress`(LZ4/zlib/gzip/Zstd)、`crypto`(OpenSSL 摘要/对称加密、UUID、CRC-32、xxHash) |
| 进程 | `process`(`process.run`;不替换 `os.execute`) |
| 日志 | `log`(7 级别,分类标签输出,文件滚动) |
| 日志 | `log`(级别、分类标签输出、文件滚动) |
| 对象 | `object`(NativeObject Lua 侧 API) |

> ⚠️ `string.find`/`match`/`gmatch`/`gsub` 底层使用 **ECMAScript 正则**(`boost::regex::ECMAScript`),而非 Lua pattern。从标准 Lua 迁移时需改写模式串。
Expand Down Expand Up @@ -229,13 +230,13 @@ ctest --test-dir build -V
### 命令行工具 `flua`

```bash
./build/bin/flua <script.lua> --entry=<func> --jit_type=<0|1> --repeat=<N>
./build/bin/flua <script.lua> --entry=<func> --jit_type=<0|1|2> --repeat=<N>
```

- `--entry`:入口函数名(默认 `main`)
- `--jit_type`:`0`=TCC,`1`=GCC
- `--jit_type`:`0`=TCC,`1`=GCC,`2`=INTERP(字节码虚拟机)
- `--repeat`:重复调用次数(用于性能测量)
- `--debug`:是否启用调试模式(默认 `false`,若为 `true` 则输出生成的 C 源码)
- `--debug`:是否启用调试模式(默认 `false`,若为 `true` 则输出生成的 C 源码 / 更详细诊断)

## 性能基准

Expand Down Expand Up @@ -332,11 +333,14 @@ Lua 源码
↓
[类型推导] → type hints (type_inferencer)
↓
[C 代码生成] → C 源码 (c_gen)
↓
[JIT 编译] → 机器码 (tcc_jit / gcc_jit)
↓
[加载执行] → 结果
┌─────────────────────────────┬──────────────────────────────┐
↓ ↓ ↓
[C 代码生成] [字节码生成] (共享 AST)
(c_gen) (interp/codegen)
↓ ↓
[JIT TCC / GCC] [解释器虚拟机]
原生机器码 (interp/interpreter)
└───────────── Call(s, JIT_*, …) ─────────────┘
```

### 关键组件
Expand All @@ -349,8 +353,10 @@ Lua 源码
| `semantic_analysis` | 语义和控制流分析 |
| `type_inferencer` | 静态类型推导和 specialization 决策 |
| `c_gen` | C 代码生成和类型驱动优化 |
| `interp/*` | 字节码生成、指令集与解释器虚拟机 |
| `compile_common` | 公共类型推导和代码生成工具 |
| `jit/*` | TCC 和 GCC 后端集成 |
| `jit/*` | TCC/GCC 后端与 `Vm` 函数注册表 |
| `native/*` | 内置标准库(net、http、db、crypto 等) |
| `state` | FakeLua 运行时状态管理 |
| `var` | 动态值 CVar 和转换工具 |

Expand All @@ -359,11 +365,11 @@ Lua 源码
### Q: 为什么选择 Lua 子集而不是完整 Lua?
A: 完整 Lua 的某些动态特性(如 metatable)很难高效编译。子集实现聚焦于可静态分析的常见模式,通过类型推导和 JIT 编译获得接近 C 的性能。

### Q: TCC 和 GCC 后端如何选择?
A: **GCC** 是生产环境主力后端(`-O3` 生成高质量原生代码);**TCC** 编译极快,主要用于开发调试和测试。
### Q: TCC、GCC 与 INTERP 如何选择?
A: **GCC** 是生产环境主力(`-O3`)。**TCC** 编译极快,适合开发与 CI。**INTERP** 跑字节码、无需宿主 C 编译器,适合受限环境、工具链与语义校验;热路径仍可与 JIT 闭包混合调用。

### Q: 可以在嵌入式环境中使用吗?
A: 可以,TCC 后端体积小、编译速度快。核心库依赖极少(仅 C++ 标准库),可交叉编译。
A: 可以——用 **JIT_INTERP**(运行时不依赖 GCC/TCC)或体积很小的 **TCC** 后端。OpenSSL/MySQL 等 native 依赖可按构建需求裁剪。

### Q: 如何调试生成的 C 代码?
A: 启用 `CompileConfig::debug_mode` 查看日志和 C 代码;使用 `GetLastRecordedCCode()` 导出 C 代码进行分析。
Expand Down
2 changes: 1 addition & 1 deletion cmd/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ using namespace fakelua;
DEFINE_bool(debug, false, "enable debug mode");
DEFINE_string(entry, "main", "entry function name, entry must return code(int) and has no parameter");
DEFINE_int32(repeat, 1, "the repeat run main function times");
DEFINE_int32(jit_type, 0, "jit type, 0 for tcc, 1 for gcc");
DEFINE_int32(jit_type, 0, "jit type: 0=tcc, 1=gcc, 2=interp");

int main(int argc, char **argv) {
gflags::SetUsageMessage("usage: ./flua --help\n"
Expand Down
Loading