现象
被调用 rwfunc 的写参(return 参数)在 durable 后端(fs:// / redis://)无法回传给调用者,而 shm 后端(kvspace-c)正常。等价于所有"函数返回值"在 durable 上丢失。
最小复现
lib m {
rwfunc f() -> (out:[]char/utf32) {
"hello" -> out
println("f sees out:", out)
}
}
rwfunc test() -> () {
m·f() -> e
println("caller sees:", e)
}
运行(同一 /usr/bin/kvlang 与 /usr/lib/libkvlang_runtime.so,仅切换后端):
| 后端 |
f sees out |
caller sees |
shm://…(kvspace-c) |
hello |
hello |
fs://…(durable) |
hello |
(空) |
callee 读得到自己的 out,但 caller 的 e 为空。
根因定位
写参机制(runtime 侧 runtime/src/builtin.c:143 kvlangBuiltinResolveWriteSlot):handle_call 把调用者的目标槽路径以 plain-char 写进 callee 帧的写槽 [0,i];callee 写 out 时应先解析 out 的 memindex ptr → [0,i] → 读回其中的调用者槽路径,从而"顺指针"写到调用者槽。
- callee 能看到
hello 说明写发生了,但 caller 看不到 → 说明 ResolveWriteSlot 在 durable 上退回了 callee 本地槽,没有跟随指针到调用者槽。
- runtime
.so 后端无关(两后端共用同一份),故分歧必在 kvspace-durable 对该写槽值的 set/get 编码上:要么 memindex ptr 的 ref 标志(*,ref==1)未正确保留导致 kvlangXvalueIsPtr 判否,要么写入 [0,i] 的 plain-char 路径读回为 NONE,二者都会让 ResolveWriteSlot 落到 fallback 的本地槽(builtin.c:180)。
- 局部变量的 memindex ptr 在 durable 上是正常的(
"x" -> a; println(a) 得到 x),所以不是 ptr 标志被全量丢弃,而是写参槽这一特定路径。
影响
- 全量回归固定跑 shm,从未覆盖 durable 的函数返回路径,此 bug 长期潜伏。
- byteseek 走 durable,其
llm·call(...) -> entry 等所有带返回值的调用均失效,LLM→run 主链路不通。
排查建议
对照 shm/kvspace-c 与 durable 在以下点的行为:写入含 * ref 标志的 head(memindex ptr)后 get 的 ref 保留;写入并立即 get 帧槽 …/[0,i] 的 plain-char 值;两后端 head codec 的 ref/kind 编解码对齐。
现象
被调用 rwfunc 的写参(return 参数)在 durable 后端(
fs:///redis://)无法回传给调用者,而 shm 后端(kvspace-c)正常。等价于所有"函数返回值"在 durable 上丢失。最小复现
lib m { rwfunc f() -> (out:[]char/utf32) { "hello" -> out println("f sees out:", out) } } rwfunc test() -> () { m·f() -> e println("caller sees:", e) }运行(同一
/usr/bin/kvlang与/usr/lib/libkvlang_runtime.so,仅切换后端):f sees outcaller seesshm://…(kvspace-c)fs://…(durable)callee 读得到自己的
out,但 caller 的e为空。根因定位
写参机制(runtime 侧
runtime/src/builtin.c:143kvlangBuiltinResolveWriteSlot):handle_call把调用者的目标槽路径以 plain-char 写进 callee 帧的写槽[0,i];callee 写out时应先解析out的 memindex ptr →[0,i]→ 读回其中的调用者槽路径,从而"顺指针"写到调用者槽。hello说明写发生了,但 caller 看不到 → 说明ResolveWriteSlot在 durable 上退回了 callee 本地槽,没有跟随指针到调用者槽。.so后端无关(两后端共用同一份),故分歧必在 kvspace-durable 对该写槽值的 set/get 编码上:要么 memindex ptr 的 ref 标志(*,ref==1)未正确保留导致kvlangXvalueIsPtr判否,要么写入[0,i]的 plain-char 路径读回为 NONE,二者都会让ResolveWriteSlot落到 fallback 的本地槽(builtin.c:180)。"x" -> a; println(a)得到x),所以不是 ptr 标志被全量丢弃,而是写参槽这一特定路径。影响
llm·call(...) -> entry等所有带返回值的调用均失效,LLM→run 主链路不通。排查建议
对照 shm/kvspace-c 与 durable 在以下点的行为:写入含
*ref 标志的 head(memindex ptr)后get的 ref 保留;写入并立即get帧槽…/[0,i]的 plain-char 值;两后端 head codec 的 ref/kind 编解码对齐。