Files
endorphin-aster-vm/docs/runtime/builtins.md
T
codex-bot 0b3a480555
Verify databases and deploy Aster VM / verify-and-deploy (push) Successful in 7m30s
Add token-based PEG frontend and CLI source parsing
2026-10-19 02:48:23 +08:00

137 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Endor 基本对象与统一 Number
这些对象属于虚拟机实现层的数据结构与宿主 API,不定义 Python type、语言根类或解析器;语言函数已接入 [小型字节码执行器](bytecode.md)。它们通过 `ObjectPayload` 接入现有 `EndorObject`,共同使用对象头、稳定 Box、代际句柄、引用计数和循环回收。不是每种对象重新实现一套堆管理。
## 对应关系
| CPython 中的结构 | Endor 对应结构 | 当前实现 |
| --- | --- | --- |
| `PyFunctionObject` | `EndorFunctionObject` | 名称、共享代码对象、全局/内建字典、默认参数和闭包 Cell;由 Vm::call 执行 |
| `PyDictObject` | `EndorDictObject` | 保留插入顺序的键值容器,VM 管理查询、写入、删除和清空 |
| `PyCFunctionObject` | `EndorNativeFunctionObject` | Rust 宿主函数指针、名称与调用入口;旧名 NativeFunction 保留为别名 |
| `PyBaseExceptionObject` | `EndorBaseExceptionObject` | 异常名称、参数、cause、context、上下文抑制、备注与回溯位置 |
| `PyASCIIObject` 等 Unicode 布局 | `EndorStringObject` | 统一 UTF-8 字符串,支持字符数、字符读取、表示、真值、比较与哈希 |
| `PyLongObject`、`PyFloatObject` 等 | `EndorNumberObject` / `EndorNumber` | 一个对外数字接口,内部保留不同数字的无损表示 |
| `PyCellObject` | `EndorCellObject` | 可被多个闭包共享的可变槽;区分空槽与 Nil |
`EndorCode` 保存经过验证的 Endor wordcode 和静态元数据,`EndorCodeObject` 将它放进受管理的堆;函数持有代码对象句柄并可共享同一份代码。指令格式、执行帧与入口见 [字节码 VM](bytecode.md)。不是 CPython 字节码格式。
## Function 与 NativeFunction
Python 代码中的 `def greet(name): ...` 创建的是语言函数。函数需要关联代码,以及代码执行时使用的全局环境、默认参数和闭包。宿主可调用 new_function 工厂,执行中的字节码也可使用 [MakeFunction](bytecode.md#在字节码中创建函数) 创建函数;两条路径使用相同校验。`EndorFunctionObject` 保存这些信息;分配时验证 globals 是字典、closure 中每一项是 Cell,并检查默认参数数量、闭包数量和代码的参数信息一致。
CPython 的 `len`、`print` 等宿主实现的内建函数则通过 C 函数入口调用。Endor 使用 Rust,所以命名为 `EndorNativeFunctionObject`,不把 C 写入名称。
```rust
use endor_core::{EndorNativeFunctionObject, Value, Vm, VmError};
fn echo(arguments: &[Value]) -> Result<Value, VmError> {
match arguments {
[value] => Ok(value.clone()),
_ => Err(VmError::InvalidArgument("expected one value")),
}
}
fn main() -> Result<(), VmError> {
let mut vm = Vm::new()?;
let function = vm.allocate(EndorNativeFunctionObject::new("echo", echo))?;
let value = vm.call(function, &[Value::Text("hello".into())])?;
assert_eq!(value, Value::Text("hello".into()));
vm.release_value(value)?;
vm.release(function)?;
Ok(())
}
```
Native 函数和语言函数均通过 `Vm::call(&mut self, ...)` 调用。语言函数用显式帧绑定位置参数、默认值和闭包,再由取指循环执行。Native 回调仍接收借用参数、返回借用对象值,不能在回调里修改当前 VM;VM 会将对象结果 retain 后返回,因此宿主需对 call/execute 的对象结果配对 release_value。
## Number:优先表示,不先做重计算
数字统一表示为 `Value::Number(EndorNumber)`。宿主仍可直接保存数字值;需要对象身份时才使用 `vm.new_number(number)` 装箱成 `EndorNumberObject`。
| 内部表示 | 适用数据 | 保留的内容 |
| --- | --- | --- |
| Integer | 超大整数、计数、编号 | 任意长度十进制数字和符号;去掉多余前导零,零统一为非负 |
| Decimal | 金额、精确小数、科学计数 | 原始数字、尾随零、正负号和任意长度十进制指数;完全不经过 f64 |
| Rational | 比例、分数 | 任意长度整数分子与非零分母;统一分母为正,不自动约分 |
| BinaryFloat | 宿主已有的 IEEE-754 数值 | 全部 64 位,包括负零、无穷、NaN 及其 payload |
| Complex | 复数记录 | 实部与虚部各自的 Integer、Decimal、Rational 或 BinaryFloat 表示 |
```rust
use endor_core::{EndorNumber, Value};
fn main() -> Result<(), endor_core::VmError> {
let id = EndorNumber::integer("1234567890123456789012345678901234567890")?;
let amount = EndorNumber::decimal("12345678901234567890.000100")?;
let ratio = EndorNumber::rational("1", "3")?;
let tiny = EndorNumber::decimal("1e-999999999999999999999999999999")?;
let host_float = EndorNumber::binary_float(f64::INFINITY);
let value = Value::Number(amount);
Ok(())
}
```
`EndorInteger`、`EndorDecimal`、`EndorRational` 是内部表示结构,不是三种语言数字类。构造器验证输入;分数不能有零分母;十进制指数不转换为机器整数,所以不会因指数很长而溢出。构造任意大整数或精确小数时传文本;已经被宿主转换为 f64 而丢失的精度无法恢复。整数的 `as_i64` 是显式、可失败的窄化读取,不会静默截断。
首版不实现四则运算、排序、跨表示数值相等和数值哈希。Rust 的 PartialEq / Eq 只检查表示是否相同,不能用于解释语言的 `==`:`1.0` 与 `1.00` 保留不同小数位数;`2/6` 与 `1/3` 尚未求数值等价;NaN 位模式也被保留。VM 对两个数字对象的数值比较与哈希显式报不支持。因此数字现在可以作为字典的值,暂不能作为字典键,避免先定义错误的键相等规则。没有用“全部转换 f64”的方式补齐这些操作。
这里的“各类数字”指上述五种可表示形式,不包括符号表达式、无限展开的精确 π、带单位数量、任意位宽二进制浮点等全部数学对象;这些可在未来扩展表示协议。
## Dict 与 Cell 的引用所有权
字典使用 `Vec<(Value, Value)>` 保留插入顺序,查询目前为 O(n),没有假装已经实现 CPython 哈希表性能。键须通过哈希能力检查;支持 Nil、Bool、文本及可哈希的对象。堆字符串与直接文本按内容匹配;覆盖已有键保留首次插入的键对象和位置。可变字典、Cell 与尚未定义数值哈希的数字不能当键。
`dict_items`、`dict_get`、`cell_get` 返回借用内容;这与现在返回持有式结果的 call/execute 不同。宿主需要跨越删除、覆盖或容器释放继续持有一个对象时,应先 `retain`。删除字典条目不返回一个可能已经被回收的借用对象,而是返回是否删除成功。
字典键和值、Cell 内容、函数环境与闭包、异常参数与因果链都作为强引用参与 GC。可变容器不暴露内部可变引用:VM 先构造新载荷,验证并保留所有新边,再替换载荷和引用快照,最后释放旧边。对象自身的 Box、身份、属性和外部引用数不变。非法/跨 VM 句柄使更新失败,原值及引用计数不变。同对象替换不会在中间短暂释放它,自环、字典与 Cell 互相引用、函数与全局字典的环都能由现有循环回收处理。
## Cell 为什么存在
```python
def outer():
x = "first"
def read():
return x
def write(value):
nonlocal x
x = value
return read, write
read, write = outer()
write("updated")
print(read()) # updated
```
`read` 与 `write` 必须引用同一个变量位置。若各自复制一份 `x` 的初始值,write 重新赋值后 read 就看不到变化。Cell 是这个共享位置:函数持有 Cell,Cell 持有当前值。外层函数返回后,Cell 仍被闭包持有。
```rust
use endor_core::{Value, Vm};
fn main() -> Result<(), endor_core::VmError> {
let mut vm = Vm::new()?;
let cell = vm.new_cell(None)?; // 空槽,不是 Nil。
vm.cell_set(cell, Value::Text("first".into()))?;
vm.cell_set(cell, Value::Text("updated".into()))?;
assert_eq!(vm.cell_get(cell)?, Value::Text("updated".into()));
vm.cell_clear(cell)?;
vm.release(cell)?;
Ok(())
}
```
当前已能通过字节码读取、写入和删除共享 Cell,并创建捕获参数的 Cell。LoadClosure 与 MakeFunction 可以在外围函数运行时创建共享这些 Cell 的嵌套函数,外围帧返回后 Cell 仍由闭包保活。上面的 Python 代码说明闭包语义;独立 frontend 已能解析基础函数,但尚无源码闭包语法或字节码编译器,代码对象仍由宿主准备。
## 字符串与异常的准确含义
`PyASCIIObject` 是 CPython Unicode 字符串实现的公共头部,不是 Python 中另外一种 ASCII 字符串类。Endor 不复刻其紧凑布局,统一用 `EndorStringObject` 表示字符串。索引按 Unicode 标量值,不按 UTF-8 字节,也不按人眼字形簇。Rust String 不接受孤立代理码点,所以并非完整复制 Python str 的所有边界行为。repr 用 Rust 的转义文本显示,不承诺 Python repr 的逐字兼容。
Python 语言层所有异常的顶级基类叫 `BaseException`,其下除了普通 `Exception` 分支,还有 `SystemExit`、`KeyboardInterrupt` 等。`PyBaseExceptionObject` 是这些异常的公共 C 实例数据布局,不能把这个结构名直接当成语言类名。
Endor 当前用 `EndorBaseExceptionObject` 保存公共数据,名称只是错误标签;尚无异常继承和按类匹配机制,也没有 raise / try / except 执行流程。异常数据中的回溯保存独立位置记录;执行器另通过 last_traceback 提供已经清理的执行帧位置元信息。宿主 API 的 `VmError` 仍表示操作失败,不会自动分配语言异常或把全部错误强制变成堆对象。
来源:[CPython 函数对象](https://docs.python.org/3.14/c-api/function.html)、[Cell 对象](https://docs.python.org/3.14/c-api/cell.html)、[异常说明](https://docs.python.org/3.14/library/exceptions.html)、[Unicode 对象](https://docs.python.org/3.14/c-api/unicode.html)。实现不承诺 CPython ABI 或默认 Python 兼容性。
## 验证入口
对象行为检查在 [core/tests](../../crates/core/tests/README.md) 的 builtins.rs;执行行为在 execution.rs;验证方式见 [验证](../operations/validation.md)。文档描述当前契约,不代表某次 CI 已通过。CPython 284 项研究表保持为工作区外的研究材料,不纳入项目文档或 Git。