# 架构与语义 ## 内核 `Vm` 拥有私有 `Heap`。堆中每个条目都是统一的 Rust `Object`:公共 `ObjectHeader` 保存类型句柄,`ObjectData` 保存类元数据或实例字段。`Class` 只是类载荷,不是独立于公共对象头的语言对象。实例不再重复保存类型,统一通过 `vm.type_of(ObjectRef)` 查询对象头;`vm.class`/`vm.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 行为,尚未作为最终语言语义承诺。统一对象头适用于堆对象,不表示所有标量都已对象化,也不复制 CPython 的引用计数或内存布局。Type 的自身类型引用是对象图中的环,继承关系仍然无环。 没有 GC,循环引用不形成 Rust 引用计数环,因为边只是句柄;所有内存随 VM 释放。长期运行时分配只增不减,尚无资源限额或内存不足的可恢复错误处理。宿主必须控制使用范围。 ## 宿主与持久化 `aster-storage` 不引用任何内核类型。它连接一个确定的后端,初始化 `aster_metadata(key TEXT PRIMARY KEY NOT NULL, value TEXT NOT NULL)`,通过参数绑定完成幂等更新及读取。当前 schema 是单条幂等 DDL;修改 schema 时再引入版本化迁移,禁止把 CREATE IF NOT EXISTS 当作升级已有列结构的工具。 SQLite 文件模式自动创建父目录、开启 WAL,连接池最多 5 条连接,busy timeout 为 5 秒。内存模式单连接,关闭空闲回收和最大存活时间,防止池正常轮换导致数据库消失;独立 Storage 实例的内存数据库相互隔离。`Storage` 克隆共享连接池,`close` 关闭全部克隆的池。 PostgreSQL 最多 5 条连接,获取/建立连接超时 5 秒,启动真实连接而非惰性连接。其配置失败或初始化失败均上抛,不进入 SQLite 分支。SQLite 的缺省只发生在**未配置** DATABASE_URL 时。 元数据仅供宿主管理,不代表类、实例、句柄或整堆快照。重启宿主会创建新的 VM、新的 Object/Type 和新句柄,只保留文件/数据库内的元数据。服务仅写入 `host.version`,不会把句柄调试值写入数据库。 `aster-server` 保存只读 VM 和共享 Storage。GET /bootstrap 只读根类;GET /health 探测数据库可用性。没有对象操作 API、语言执行 API 或鉴权协议。HTTP/Tokio/SQLx 都不进入内核。后续浏览器宿主应通过明确的能力接口桥接,不能把浏览器类型塞进核心对象工厂。 ## 已决定与未决定 已决定:唯一无父类 Object、基础元类 Type、堆对象统一对象头、类与实例使用不同载荷、类型与父类分开、句柄由 VM 校验、存储属于宿主。 未决定:自定义元类、字节码格式、调用栈、方法解析、语言异常、外部对象协议、线程间共享 VM、GC/根集、堆序列化、浏览器通信、完整字符串对象/数值对象语义。不得在后续交接中把这些当成已实现契约。