Unify heap objects with typed headers and bootstrap Type
Verify databases and deploy Aster VM / verify-and-deploy (push) Successful in 14m16s

This commit is contained in:
2026-10-18 13:38:00 +08:00
parent afcaf5cff8
commit d394f07fc2
9 changed files with 235 additions and 62 deletions
+18 -6
View File
@@ -2,15 +2,27 @@
## 内核
`Vm` 拥有私有 `Heap`。`Vm::new` 分配一个 `Object::Class(Class)`,其描述为名称 Object、父类 None,然后保存 `ClassRef`。不存在可观察的“半初始化 VM”;`bootstrap` 只返回已建立的根类句柄。因此根类不依赖数据库、全局命名空间、元类、网络或异步运行时。
`Vm` 拥有私有 `Heap`。堆中每个条目都是统一的 Rust `Object`:公共 `ObjectHeader` 保存类型句柄,`ObjectData` 保存类元数据或实例字段。`Class` 只是类载荷,不是独立于公共对象头的语言对象。实例不再重复保存类型,统一通过 `vm.type_of(ObjectRef)` 查询对象头;`vm.class`/`vm.instance` 读取相应载荷。
`create_class(name, parent)` 校验已有父类后创建不可变描述,父类不可事后改写,不能形成继承环;只有内核启动路径可以创建没有父类的类。`create_instance` 校验类句柄再创建独立字段表。没有复制原型或隐式字段继承。未实现方法与实例字段查找的语言规则。
`Vm::new` 通过私有 `Heap::bootstrap` 一次性建立 Object 和 Type。Object 无父类,类型为 Type;Type 的父类为 Object,类型为自身。初始化器在独占的空堆中计算两个槽位的私有句柄并填入完整对象,不使用裸指针或可空的临时类型引用;完整堆建立后才返回。不存在可观察的“半初始化 VM”,`bootstrap` 只返回已有根类句柄。此过程不依赖数据库、全局命名空间、网络或异步运行时。
```text
堆条目:Object { header: ObjectHeader { class }, data: ObjectData }
对象 对象头中的类型 类载荷中的父类
Object Type 无
Type Type Object
用户类 C Type 创建时指定的父类
C 的实例 C 不适用
```
`create_class(name, parent)` 校验已有父类后创建不可变描述,并在公共对象头中设置类型为 Type。父类不可事后改写,不能形成继承环;只有内核启动路径可以创建没有父类的类。精确名称 Object 和 Type 保留。`create_instance` 校验类句柄,再创建以该类为类型的对象头和独立字段表。当前禁止直接实例化 Type 或继承 Type,返回 `UnsupportedMetaclass` 且不分配对象,避免把类工厂与普通实例工厂混用;尚未实现自定义元类、类型调用、描述符、方法与继承属性查找。
句柄结构是私有 VM 身份加 `usize` 槽位。VM 身份用原子计数器分配,耗尽时返回错误,不回绕复用。`Vec` 扩容会移动 Rust 对象,但外部不保存它们的地址,旧句柄继续通过索引访问。当前绝不删除槽位,所以无代际号。VM 不实现 Clone,复制句柄不能复制 VM 身份。
检查顺序是归属、范围、种类。外部没有从整数构造句柄的 API;低层无效槽位与伪造类型用私有单元测试覆盖。通用句柄可通过 `as_class/as_instance` 做校验后的转换。不同 VM 的引用、已经销毁 VM 的引用,在新 VM 中都报 `ForeignHandle`。同一 VM 中不在有效槽位的引用报 `InvalidHandle`。写字段前检查目标和引用值,失败不会覆盖原字段。
`Value` 中标量和字符串不强制堆分配,引用目前仅指类或实例。当前字符串值是按 Rust 所有权复制的文本,并非具有对象身份的字符串实例。`Float` 使用 Rust f64/PartialEq 行为,尚未作为最终语言语义承诺。类不是自身或其他类的实例,根类也没有隐式元类。
`Value` 中标量和字符串不强制堆分配,引用目前仅指类或实例。当前字符串值是按 Rust 所有权复制的文本,并非具有对象身份的字符串实例。`Float` 使用 Rust f64/PartialEq 行为,尚未作为最终语言语义承诺。统一对象头适用于堆对象,不表示所有标量都已对象化,也不复制 CPython 的引用计数或内存布局。Type 的自身类型引用是对象图中的环,继承关系仍然无环。
没有 GC,循环引用不形成 Rust 引用计数环,因为边只是句柄;所有内存随 VM 释放。长期运行时分配只增不减,尚无资源限额或内存不足的可恢复错误处理。宿主必须控制使用范围。
@@ -22,12 +34,12 @@ SQLite 文件模式自动创建父目录、开启 WAL,连接池最多 5 条连
PostgreSQL 最多 5 条连接,获取/建立连接超时 5 秒,启动真实连接而非惰性连接。其配置失败或初始化失败均上抛,不进入 SQLite 分支。SQLite 的缺省只发生在**未配置** DATABASE_URL 时。
元数据仅供宿主管理,不代表类、实例、句柄或整堆快照。重启宿主会创建新的 VM、新的 Object 和新句柄,只保留文件/数据库内的元数据。服务仅写入 `host.version`,不会把句柄调试值写入数据库。
元数据仅供宿主管理,不代表类、实例、句柄或整堆快照。重启宿主会创建新的 VM、新的 Object/Type 和新句柄,只保留文件/数据库内的元数据。服务仅写入 `host.version`,不会把句柄调试值写入数据库。
`aster-server` 保存只读 VM 和共享 Storage。GET /bootstrap 只读根类;GET /health 探测数据库可用性。没有对象操作 API、语言执行 API 或鉴权协议。HTTP/Tokio/SQLx 都不进入内核。后续浏览器宿主应通过明确的能力接口桥接,不能把浏览器类型塞进核心对象工厂。
## 已决定与未决定
已决定:唯一无父类 Object、类和实例分离、实例引用类、句柄由 VM 校验、存储属于宿主。
已决定:唯一无父类 Object、基础元类 Type、堆对象统一对象头、类与实例使用不同载荷、类型与父类分开、句柄由 VM 校验、存储属于宿主。
未决定:字节码格式、调用栈、方法解析、语言异常、外部对象协议、线程间共享 VM、GC/根集、堆序列化、浏览器通信、完整字符串对象/数值对象语义。不得在后续交接中把这些当成已实现契约。
未决定:自定义元类、字节码格式、调用栈、方法解析、语言异常、外部对象协议、线程间共享 VM、GC/根集、堆序列化、浏览器通信、完整字符串对象/数值对象语义。不得在后续交接中把这些当成已实现契约。
+2
View File
@@ -6,6 +6,8 @@
核心 API 示例在 `aster-core/src/lib.rs`,由 rustdoc 实际编译执行。公开语义测试在 `aster-core/tests/runtime.rs`;伪造句柄仅在私有堆单元测试中构造,禁止为测试添加公开非法构造器。
堆对象通过 `ObjectHeader` 统一保存类型,`Class`/`Instance` 仅为不同载荷。旧的 `vm.instance(handle)?.class()` 改为 `vm.type_of(handle.into())`,类对象也使用同一接口。启动分配两个基础对象:Object 与 Type;CLI 示例另建一个类和两个实例后共 5 个对象,HTTP `/bootstrap` 的初始对象数为 2。新增测试覆盖 Type 自身类型、类型与父类分离、跨 VM 类型查询、扩容后类型引用稳定,以及拒绝通过普通工厂创建自定义元类。
存储测试用 `tempfile` 隔离文件,关闭池后重开,验证独立连接生命周期中的持久化。内存测试验证克隆共享、独立 store 隔离、特殊字符参数绑定、更新/缺失键。PostgreSQL 失败测试用只监听但不处理协议的本地 TCP socket,检验真实连接超时和不降级;成功测试显式 ignore,需要用户提供专用测试库。
尚未运行的冒烟脚本用于跨进程调用 CLI、启动 HTTP 宿主、探测真实 TCP 端点、发送 SIGTERM 并确认正常退出。它只创建临时目录,不改 `.env`,不操作外部服务器。端口通过临时绑定选择,释放后启动间存在很小的端口竞争窗口;在指定验证环境中若冲突,可重试整个脚本。
+6
View File
@@ -48,3 +48,9 @@
准备阶段只读检查:Docker 29.1.3、Compose 2.40.3、x86_64、约 1.7 GiB 内存/4 GiB swap、73 GiB 可用磁盘;没有主机 Rust 或 buildx,已缓存 PostgreSQL 17 镜像。选用单任务 Rust 构建、legacy Docker builder,默认生产端口 18081(服务器回环地址),PostgreSQL 数据目录独立。
此处不预先宣称远端 CI 或部署已成功;最终结果以 Gitea Actions 对应运行与服务器状态核验为准。
## 统一对象头变更(2026-10-18)
本次把堆条目改为 `ObjectHeader` 加载荷,所有类与实例通过同一对象头引用类型;启动同时建立 Object 和 Type。新增或更新类型引导、类型查询、无效句柄、跨 VM 隔离、工厂边界、扩容稳定性及文档示例的检查,并同步远端 CLI/HTTP 冒烟的对象数预期。
本次未在本地运行 Rust 构建、测试、格式化脚本或冒烟脚本,也未下载依赖。本记录提交时尚未取得新版本远端结果,实际通过与否以本次提交对应的 Gitea CI 记录为准;之前已成功的 #160/#161 仅验证旧版对象模型,不代表本次修改已通过。