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
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ lib kvlang/spec/导言/规范用语与阅读约定 {

- 文法元记法与本规范其余用语约定见 [[文法]]。
- 完整权威文法汇总于 [[文法]](附录);正文各章只引用其片段,不各自另立文法。
- 章节间引用以 `[[章节名]]` 链接
- 章节间引用用双方括号括住章节名(如 `[[文法]]`
"#### -> /lib/kvlang/spec/导言/规范用语与阅读约定
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ lib kvlang/spec/词法/逻辑位运算与优先级 {
分别为按位与、按位或、按位异或、左移、右移。

`&` 一符二用,靠位置区分(同 C):操作数之后为中缀**按位与**;表达式起始或运算符之后为一元前缀
**取址**(见下 [[取址运算符 `&`]])。
**取址**(见下取址运算符 `&`)。

## 取址运算符 `&`

Expand Down
5 changes: 3 additions & 2 deletions stdlib/kvlang/spec/02-kvspace模型/01-地址空间.kv
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ ref=2(@ext,见 [[键系统与数组访问]]),其 body 只记录目标位
| GPU 显存 | 计算张量 |
| 文件系统 / 对象存储 | 模型权重、检查点、数据集、外部进程输出 |

读取一个 ref=2 扩展句柄 value 时,运行时按 body 定位符前缀路由到对应兑现器还原真实字节
(`runtime-rs/src/engine.rs`)。
读取一个 ref=2 扩展句柄 value 时,由**支持 `@` 的 rwir** 按定位串还原真实字节——例如 runtime-rs 的
networld/fs 一族 rwir 直接以 `@` 开头的扩展 key 为输入(`runtime-rs/src/engine.rs` 的 `read_at` /
`resolve_ext`)。核心 runtime-c 不解引用 `@`。

## 后端与前端

Expand Down
7 changes: 4 additions & 3 deletions stdlib/kvlang/spec/02-kvspace模型/03-寻址与命名.kv
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ PC 落在 kvspace、帧根落在 kvspace,故执行现场可观测、可崩溃

## 变量名即指针

kvlang 没有取址运算符——**代码中变量的名字,本身就是该变量的指针**(一条 kvspace 路径)。指令槽里存的
从来不是值,而是指针文本;求值恒经一次指针间接。指针有两种形态:
**代码中变量的名字,本身就是该变量的指针**(一条 kvspace 路径)kvspace/kvlang是路径寻址,而不是64位寻址。指令槽里存的从来不是值,而是指针文
本;求值恒经一次指针间接。`&x`(`≡ kv·abs(x)`)是取址语法糖,取到的是 kvspace 路径串,**不是**私有内
存地址(见 [[运算符基础]])。指针有两种形态:

| 形态 | 写法 | 语义 | 解析 |
|------|------|------|------|
Expand Down Expand Up @@ -55,7 +56,7 @@ kvspace 路径与 XValue 的 langtype 共用一套分隔符语义,每个分隔
| 分隔符 | 码位 | 语义 |
|--------|------|------|
| `/` | U+002F | 层级;目录以尾随 `/` 标记 |
| `·` | U+00B7 | **两种独立含义,正交**(见 [[总体方案]]):①**memindex 标记**——值容器成员索引 `{key}·`(仅 stringkeymap/struct 用),以及成员访问 `obj·field`、`m·[i]`;②**包·函数命名分隔符**——`/lib/{pkg}·{func}` 中路径段名字的一部分,rwfunc 目录成员仍走 `/` 子路径,与 memindex 无关 |
| `·` | U+00B7 | **两种独立含义,正交**(见 [[总体方案]]):①**memindex 标记**——值容器成员索引 `{key}·`(仅 stringkeymap/struct 用),以及成员访问 `base·field`、`m·[i]`;②**包·函数命名分隔符**——`/lib/{pkg}·{func}` 中路径段名字的一部分,rwfunc 目录成员仍走 `/` 子路径,与 memindex 无关 |
| `‥` | U+2025 | 运行时系统变量前缀(`X/‥pc`,见 [[系统变量]]) |
| `…` | U+2026 | extindex 句柄 body 的首元素前缀 |

Expand Down
6 changes: 5 additions & 1 deletion stdlib/kvlang/spec/02-kvspace模型/04-CABI.kv
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ camelCase)——kvspace 层前缀 `kvspace`(`kvspaceGet` / `kvspaceWriteInPl
`kvspaceDelTree` 对**最终组件**不解析 link——写/删 Ptr 键只作用该键本体,不重定向到 target
(`Del`/`DelTree` 为 POSIX rm 式:删指针本身,不删被指向者)。解引用由 runtime 显式 `*` 掌控(见
[[ptr]])。否则「写实参地址 Ptr 到帧槽」会被重定向到 target,导致丢参 / 写坏被指向的值。
## kvspace C ABI 导出符号全集(nm -D 实测,30)
## kvspace C ABI 导出符号(快照)

权威来源是**构建产物**——`nm -D --defined-only /usr/lib/kvspace/libkvspace.so | grep '^kvspace'`(前端
dispatch 静态导出;后端 `kvspace-c` / `kvspace-durable` 各导出同一集合)。下列快照仅作阅读导航,改 ABI 时
不必同步本文:

```
kvspaceClear
Expand Down
20 changes: 9 additions & 11 deletions stdlib/kvlang/spec/02-kvspace模型/05-键系统与数组访问.kv
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,16 @@ kind 常量集中定义于 `kvspace/include/kvspace/const.h`(C)与 `kvspace-

### langtype 文法

langtype 串**全前缀**书写,最左符号为最外层构造器,无优先级歧义(对齐 Go/Rust 的 `[]int`):

```
langtype ::= [ dims ] kind
dims ::= '[' ']' # 变长一维
| '[' INT ( ',' INT )* ']' # 定长 / 多维(compact 连续布局)
```
langtype 串**全前缀**书写,最左符号为最外层构造器,无优先级歧义(对齐 Go/Rust 的 `[]int`)。完整文法
(shape 与轴量词 `.`/`?`/`*`/`+`、并集 `A|B`、通配 `any`、mapexpr `key·value`、structref)**只在附录
[[文法]] 一处定义**,本章与其它卷只引用、不另立。
**`langtype` 与 `def langtype` 是两回事**:值处写的是 `langtype`(值的**真实类型**),定义处(函数参数/返回
值)写的是 `def langtype`(**匹配类型**)——后者是模式,**一个参数定义可匹配多种实际 `langtype`**(见
[[langtype签名类型表达式]] 与 [[匹配语义与变参]])。

维数与各维长度编码进 langtype 串本身;ref(存储位置)已独立为 head 中的 ref u8 字段(见 [[XValueHead
线格式]]),不再是 langtype 前缀——storetype 物理字段携带对应的 ndim/dims 结构。完整签名类型表达式
(并集 `A|B`、通配 `any`、动态维 `?`、map 键值 `key·value`)见 [[文法]] 与类型系统卷。**源码**类型标
注可在最前写 `*`/`@` 前缀表示 ref(如 `*int64`、`@[256,256]uint8`),layout 解析时剥离前缀落成 head
`ref` 独立字节;wire 层 langtype 串不含 `*`/`@` 前缀(见 [[总体方案]])。
线格式]]),不再是 langtype 前缀——storetype 物理字段携带对应的 ndim/dims 结构。**源码**类型标注可在最
前写 `*`/`@` 前缀表示 ref(如 `*int64`、`@[256,256]uint8`),layout 解析时剥离前缀落成 head `ref` 独立
字节;wire 层 langtype 串不含 `*`/`@` 前缀(见 [[总体方案]])。
"#### -> /lib/kvlang/spec/kvspace模型/键系统与数组访问
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,18 @@ body = [body_len B raw]
| `ro` | 1B | 1=只读,0=可写 |
| `vid` | 4B LE | vthread id(默认 0) |
| `body_len` | 4B LE | body 字节数 |
| (storetype 物理字段) | 变 | ARRAYND:ndim u8 + dims[ndim] u32 LE;index/extindex:成员名 m×n 对齐字符串数组 dims=[len,cap,M]len=成员数、M align8、cap 预留容量);主槽 body 恒空 |
| (storetype 物理字段) | 变 | ARRAYND:ndim u8 + dims[ndim] u32 LE;index/extindex:**成员枚举载体**(shm 载体为成员名 m×n 对齐字符串数组dims=[len,cap,M]len=成员数、M align8、cap 预留容量;fs 载体把成员落成 `{key}·/` 子目录);值容器主槽 body 恒空、dims 空 |
| `langtype` | 变长 | 类型表达式串,占至 `headlen`(长度 = headlen − 当前偏移,无独立长度字段) |

`langtype` 恒为 head 最后一段,无独立长度字段;body 起始偏移 = `headlen`。ref 与 storetype 各为独立
u8 字节,不再编码进 langtype 串。ARRAYND 的 ndim、dims 直接读自 storetype 物理字段,与 langtype 串内
`[dims]` 保持同步(由 codec 保证)。`char/*` kind 恒为 ARRAYND(ndim=1)。None 编码:
storetype=NONE、langtype=""、body 空。

index/extindex 的**语义是"可枚举成员"**(`kvspaceListLen` / `kvspaceListAt`),物理载体按后端而异:shm 把
成员名收进 head 的 m×n 矩阵,fs 把成员落成 `{key}·/` 子目录——载体差异经对称编解码还原,**不构成 ABI
语义差异**(见 [[地址空间]])。值容器(stringkeymap/struct)主槽只持类型与形状,成员在 `{key}·`。

指针(ref=1)的 head langtype = 目标完整 langtype(langtype,含 `[dims]`),storetype = 目标
storetype,body = 目标 key 路径;由 `kvspaceNewPtr(target_langtype, target)` 构造,Set 时据此单跳类
型检查。
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ lib kvlang/spec/kvspace模型/数组两种物理形态 {
ndim≥1。对齐 C `int[10]`、Go `[10]int`、Rust `[i32;10]`;多维即连续布局的 ndarray/tensor。要求元素
定长同类型——含变长字符串字面量的 `[…]` 在 layout 阶段报错。支持 `arr[i]` 随机访问(下标读经
`xv·at` 在 body 内定位),可零拷贝整块读。
- **stringkeymap**:head kind=`stringkeymap`、ndim≥1,body 只记形状;每个元素是独立子 key,成员名为
**坐标段**。变长、可增长、允许变长元素——字符串数组、可追加数组走此形态。stringkeymap **必须**
ndim≥1(无维度的键值容器应为 `struct`),且成员名**必须**是坐标段(`kvspace-durable/src/const.rs`
的 `ERR_MAP_NDIM`、`ERR_MAP_COORD`)。
- **stringkeymap**:head kind=`stringkeymap`、ndim≥1,body 只记形状;每个元素是独立子 key,成员名即
**memitemkey 值逐字**(逐字铁律见 [[文法与合法性]]):裸标量键落 `b·200`、标量元组键落
`a·[342.124,23.2345]`、字符串键落 `m·a`;由 `scatter` 展开的数组元素落坐标段 `base·[i]`。变长、可
增长、允许变长元素——字符串数组、可追加数组走此形态。stringkeymap **必须** ndim≥1(无维度的键值容器
应为 `struct`)。

## 坐标段

Expand Down Expand Up @@ -57,7 +58,7 @@ stringkeymap 元素的成员名是坐标段,物理 key 形如 `m·[i]`(一

ref=2 表示值本体在扩展世界(SHM/GPU/文件),head 中 langtype 记录形态(如 `[256,256]uint8`),body
记位置描述符。@ext 只表**单个值**存于扩展世界(compact 形态),与 storetype=index/extindex 无关。读
取时按 body 前缀路由兑现(见 [[地址空间]] 扩展存储)。
取时由支持 `@` 的 rwir(如 runtime-rs 的 fs/networld 一族)按定位串兑现(见 [[地址空间]] 扩展存储)。

## memindex:定宽目录矩阵

Expand Down
39 changes: 23 additions & 16 deletions stdlib/kvlang/spec/02-kvspace模型/08-指令布局格式.kv
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,18 @@ lib kvlang/spec/kvspace模型/指令布局格式 {

### 签名行

函数目录 `/lib/{pkg}·{name}/` 自身(主槽):storetype = index、langtype = `rwfunc`(裸种类名,**不含
签名**),body = `[nr:u16 LE][nw:u16 LE][dynamic:u8]`(读参个数 `nr`、写参个数 `nw`、是否变参
`dynamic`)。
函数目录 `/lib/{pkg}·{name}/` 自身是普通**目录节点**:storetype = index、langtype = `index`、**无值**
(body 空)。rwfunc 的**计数头**落签名行锚点 `/lib/{pkg}·{name}/[0,0]`——storetype = index、langtype =
`rwfunc`(裸种类名,**不含签名**),body = `[nr:u16 LE][nw:u16 LE][dynamic:u8]`(读参个数 `nr`、写参
个数 `nw`、是否变参 `dynamic`)。

rwfunc 的各参数类型**不**落 `/[0,x]` 静态槽,而随**参数定义键**承载:`/lib/{pkg}·{name}.[0,-j]`
(读参)/ `.[0,+j]`(写参)——点后缀、与坐标斜杠键 `/[0,±j]` 不同名——langtype `def langtype`,
body = 参数名 + NUL + 该参数完整类型串。参数顺序由键中的 `±j` 显式记录(命名键不保序),故 func 目录
body = 参数名 + NUL + 该参数的 **def langtype**(匹配类型)串——一个参数定义可匹配多种值的 langtype。参
数顺序由键中的 `±j` 显式记录(命名键不保序),故 func 目录
根**不**落 `/[0,x]` 子槽。

`def rwir` 则相反:主槽 langtype = `def rwir`(裸种类名)、body 同计数格式,各参数类型落**位置化**签
`def rwir` 则相反:`/lib/<op>` 节点自身 langtype = `def rwir`(裸种类名)、body 同计数格式,各参数类型落**位置化**签
行 `[0,x]` 子槽(`x<0` 读参、`x>0` 写参,storetype=ATOM、langtype=`def langtype`,body 为该参数
langtype 串),无 `{param}` 命名键、无实现指令行——跨 runtime 队列按位置收参故须有序签名(见 [[总体方
Expand All @@ -42,18 +44,23 @@ langtype 串),无 `{param}` 命名键、无实现指令行——跨 runtime
以 `id_val(x:int64) -> (R:int64) { int64·add(x, 0) -> R }` 为例,`/lib/id_val/` 下:

```
/lib/id_val/ storetype=index langtype=rwfunc body=[nr=1,nw=1,dyn=0] ← 主槽;langtype 裸种类名,不含签名
[0,0] 签名行锚点(s0=0),body=[nr,nw,dyn] 计数头
x ptr(langtype=int64)→"[0,-1]"命名读参:body=坐标、langtype=该参类型
R ptr(langtype=int64)→"[0,1]"命名写参:body=坐标、langtype=该参类型
[1,0] rwir:int64·add ← 指令0 opcode
[1,-1] rwir:x ← 指令0 读槽1
[1,-2] int64:0 ← 指令0 读槽2(内联字面量)
[1,1] rwir:R ← 指令0 写槽1
/lib/id_val/ storetype=index langtype=index ← 普通目录节点(无值)
[0,0] storetype=index langtype=rwfunc body=[nr,nw,dyn] ← 签名行锚点(s0=0),只记计数头
.[0,-1] def langtype:"x\0int64"参数定义键(点后缀):参数名 + NUL + def langtype
.[0,1] def langtype:"R\0int64"参数定义键(写参)
[1,0] storetype=ATOM langtype=rwir|rwfunc body=counts+"int64·add" ← 指令0 opcode
[1,-1] storetype=ATOM langtype=rwir body=counts+"[0,-1]" ← 指令0 读槽1(形参已换成帧坐标)
[1,-2] storetype=ATOM langtype=int64 body=raw(8B) ← 指令0 读槽2(内联字面量,非 rwir、无 counts
[1,1] storetype=ATOM langtype=rwir body=counts+"[0,1]" ← 指令0 写槽1
```

opcode 槽 langtype 为 `rwir`(可为 `rwfunc` 引用),body 记 opcode 名。读/写槽的值有两类:
`rwir:name` 是对变量的引用(存名字文本,即相对指针),或内联字面量(如 `int64:0`、
`char/utf32:"…"`)。opcode 槽永不存变量引用,故值拷贝 `=` 与函数调用 `call` 在 KV 层无歧义。
opcode 槽 langtype 为 `rwir|rwfunc`——这是**派发标记**(layout 不静态判定目标是 runtime 兑现的 rwir 还
是用户 rwfunc,判定推迟到 runtime 查 `/lib/<opcode>`,见 [[指令槽编码]]),非值语言类型。

**`rwir` 值的 body 格式(唯一)**:`counts` = `[nr:u16 LE][nw:u16 LE][dynamic:u8]`(5 字节,指令槽恒
`0,0,0`)+ 槽文本;文本是 opcode 名,或变量引用(相对指针 `[0,±k]`)。**内联字面量不是 `rwir`**——按字
面量自身的 kind 编码(如 `int64` 的 8 字节 raw),**无** `counts`。故读/写槽的值两类:`rwir`(counts +
文本)或内联字面量(如 `int64raw`、`char/utf32` 串)。opcode 槽永不存变量引用,故值拷贝 `=` 与函数调用
`call` 在 KV 层无歧义。
"#### -> /lib/kvlang/spec/kvspace模型/指令布局格式
}
27 changes: 15 additions & 12 deletions stdlib/kvlang/spec/02-kvspace模型/09-调用extindex.kv
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,33 @@ lib kvlang/spec/kvspace模型/调用extindex {
令树的 extindex 叠加层,再把实参 / 结果地址写进帧根下的 `[0,±j]` 槽:

- `/lib/{pkg}·{name}.[0,±j]`(rwfunc 的**参数定义键**,点后缀、与坐标斜杠键 `/[0,±j]` 不同名):
langtype=`def langtype`,body=该参数名字 + NUL + 类型串。此键是**签名元数据**(dump / 类型检查
用),**不参与运行时形参解析**;函数体指令里的形参引用已在 layout 编译期替换为帧坐标的显式解引用
`*[0,-1]`。目录根**无** `/[0,±j]` 静态坐标槽——运行时向 `frameRoot/[0,±j]` 写实参地址 Ptr 时,
langtype=`def langtype`,body=该参数名字 + NUL + **def langtype**(匹配类型)串。此键是**签名元数据**(dump / 类型检查
用),**不参与运行时形参解析**;函数体指令里的形参引用已在 layout 编译期替换为帧坐标(值参 `[0,-1]`
直读,地址参 `*[0,-1]` 解引用,见 [[函数]])。目录根**无** `/[0,±j]` 静态坐标槽——运行时向
`frameRoot/[0,±j]` 写实参槽时,
该坐标在只读 extindex 目标(函数树)中并不存在,extindex 写保护正因**该名在扩展层缺席而放行**帧本
地写,实参内容零拷贝。(反之若 layout 预落 `/[0,±j]` 静态槽,写保护会因扩展层已有同名只读节点而拒
写、丢参——故 rwfunc 目录根不落这些坐标。)
- 所有帧共享 `/lib` 下同一份指令树,零拷贝;帧根下叠加各自的实参槽与局部变量。

崩溃恢复由此自然成立:PC 是路径字符串、帧根落 KV、返回点落 KV——进程重启后可从 kvspace 续跑。

## 参数解析:一层引用(显式解引用)
## 参数解析:值参直读、地址参一层引用

函数体指令里的形参引用,layout 编译期把参数名替换为**对帧槽坐标的显式解引用** `*[0,-1]`。帧槽
`frameRoot/[0,-1]` 由调用点写入实参地址 Ptr(ref=1,langtype=参数类型,body=实参地址),`*` 解引用
一次即得实参真实值:
layout 编译期把形参名替换为**帧槽坐标** `[0,-k]`(值参)或**对帧槽坐标的解引用** `*[0,-k]`(地址参,即
声明带 `*`/`@`;见 [[函数]])。两种帧槽由调用点写入(见 [[函数调用]]):

```
1. frameRoot/[0,-1] → 实参 key 路径 槽 → 实参地址(调用点写入的帧本地 Ptr)
2. *[0,-1] → 值 显式解引用一次
值参 x:T :frameRoot/[0,-k] → 值本体(本帧副本) 体内 [0,-k] 只读(param<0 只读)
地址参 p:*T :frameRoot/[0,-k] → 实参 key 路径 Ptr 体内 *[0,-k] 解引用取实参值
扩展参 h:@T :frameRoot/[0,-k] → 扩展世界定位串(ref=2)由支持 @ 的 rwir 兑现(如 runtime-rs 的 fs/networld 族)
```

读写对称:读参 `*[0,-k]` 读到实参值;写参 `*[0,+k]` 指回调用者写槽,子帧写参直写调用方目标位置。读参
地址可指向调用方值以实现零拷贝重定向(见 [[系统变量]] 的 `‥rparam` / `‥wparam`)。形参类型随帧槽的
Ptr langtype 承载,不在解析链上额外查参数定义键。
**读参(`param<0`)一律只读**:值读参的槽是本帧副本、地址读参 `*[0,-k]` 读到实参值,两者都不得作写槽。
**写参(`param>0`)可读可写**:地址写参 `*[0,+k]` 直写调用方目标位置;值写参按 [[系统变量]] 的 `‥wdst`
表 copy-in / copy-out。`@` 参数的帧槽是扩展定位串——runtime-c 不可直达,读它须按定位串前缀由支持 `@` 的
rwir(在支持它的 runtime 里,如 runtime-rs 的 fs/networld 一族)按 head 的 ref=2 定位串兑现(见
[[ref存储位置]])。形参类型随帧槽的 XValue langtype 承载,不在解析链上额外查参数定义键。

写侧关键约束:kvspace 对 Set/Del **不穿透整键**(Ptr 键的写/删只作用该键本身,不追 target)——自动
穿透会把「写实参地址 Ptr 到帧槽」重定向到 target,导致丢参 / 写坏被指向的值。解引用一律由 runtime 显
Expand Down
Loading
Loading