From 082a986ecfea71f227b1849f3a0e37fd54e3ec50 Mon Sep 17 00:00:00 2001 From: "peng.li24" <734991033@qq.com> Date: Wed, 9 Sep 2026 14:05:42 +0800 Subject: [PATCH] =?UTF-8?q?runtime:=20kvlangRwirextRegister=20=E2=86=92=20?= =?UTF-8?q?kvlangDefRwir=EF=BC=88def=20langtype=20=E6=B3=A8=E5=86=8C?= =?UTF-8?q?=EF=BC=89+=20spec=20=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 注册函数改名反映语义(经 def langtype 签名行落 /lib/);消费方 ffi/rwir 适配; spec 09 附录 + 散文 9 符号表同步。nm 实测导出仍 203(7 myrwir 符号含 kvlangDefRwir)。 --- runtime-rs/src/ffi.rs | 5 +- runtime-rs/src/rwir/mod.rs | 21 ++++---- runtime/include/kvlang_rwirext.h | 9 ++-- runtime/src/kvcpu.c | 50 +++++++++++++++---- runtime/src/rwirext.c | 6 +-- runtime/src/xvalue.c | 2 +- ...344\270\216\345\220\216\347\253\257abi.kv" | 4 +- 7 files changed, 67 insertions(+), 30 deletions(-) diff --git a/runtime-rs/src/ffi.rs b/runtime-rs/src/ffi.rs index e049aaab..a2c89b79 100644 --- a/runtime-rs/src/ffi.rs +++ b/runtime-rs/src/ffi.rs @@ -167,12 +167,13 @@ unsafe extern "C" { // ── kvlang runtime:rwirext 宿主 ABI(均传 kvspace 句柄)───────── // C 头 kvlang_rwirext.h 导出 9 符号;此处声明 7:故意省略 LangtypeValid/LangtypeMatch // ——langtype 校验属 layout 期、匹配属 C dispatch 内部,Rust term 侧不调用(非缺陷)。 - pub fn kvlangRwirextRegister( + pub fn kvlangDefRwir( kvspace: *mut c_void, opcode: *const c_char, + rp: *const *const c_char, nr: c_int, + wp: *const *const c_char, nw: c_int, - sig: *const c_char, ) -> c_int; pub fn kvlangRwirextParams(kvspace: *mut c_void, pc: *const c_char) -> *mut c_char; pub fn kvlangRwirextResolveRead( diff --git a/runtime-rs/src/rwir/mod.rs b/runtime-rs/src/rwir/mod.rs index 7be869c3..6a2ec157 100644 --- a/runtime-rs/src/rwir/mod.rs +++ b/runtime-rs/src/rwir/mod.rs @@ -16,6 +16,8 @@ pub mod term; use crate::engine::Engine; use crate::ffi::*; use std::collections::HashMap; +use std::ffi::CString; +use std::os::raw::c_char; use std::sync::OnceLock; /// 单个 rwir 的签名:读参 / 写参各自独立的 langtype 列表(逐槽一型,不假设同型)。 @@ -188,19 +190,18 @@ pub fn rwirmap() -> &'static HashMap<&'static str, &'static Rwir> { pub fn register(eng: &Engine) { for (op, r) in MYRWIRCAPS { - let sig = - r.rp.iter() - .chain(r.wp.iter()) - .copied() - .collect::>() - .join("\n"); + let rp: Vec = r.rp.iter().map(|s| cs(s)).collect(); + let wp: Vec = r.wp.iter().map(|s| cs(s)).collect(); + let rpp: Vec<*const c_char> = rp.iter().map(|c| c.as_ptr()).collect(); + let wpp: Vec<*const c_char> = wp.iter().map(|c| c.as_ptr()).collect(); unsafe { - kvlangRwirextRegister( + kvlangDefRwir( eng.kv, cs(op).as_ptr(), - r.rp.len() as i32, - r.wp.len() as i32, - cs(&sig).as_ptr(), + rpp.as_ptr(), + rpp.len() as i32, + wpp.as_ptr(), + wpp.len() as i32, ) }; } diff --git a/runtime/include/kvlang_rwirext.h b/runtime/include/kvlang_rwirext.h index 78c71ff9..a5250514 100644 --- a/runtime/include/kvlang_rwirext.h +++ b/runtime/include/kvlang_rwirext.h @@ -10,9 +10,12 @@ * *)传进下列带句柄的函数即可。 本 ABI 只暴露 kvspace 不提供的 runtime * 语义:rwir 解码 + resolve + display + PC 推进 + 类型判定。 */ -/* 写 /lib/ = rwir 签名(幂等) */ -int kvlangRwirextRegister(void *kvspace, const char *opcode, int32_t nr, - int32_t nw, const char *sig); +/* 注册一条 rwir(幂等):/lib/ 路由头(body 仅计数头 [nr][nw][dynamic])+ + * 各参数类型落签名行 [0,x] 槽(def langtype)。读参类型逐条 rp[0..nr]、写参 wp[0..nw], + * 不拼签名串——避免其它 runtime 把「拼接 sig」误当注册标准。末读参尾缀 "..." → 变参。 */ +int kvlangDefRwir(void *kvspace, const char *opcode, + const char *const *rp, int32_t nr, + const char *const *wp, int32_t nw); /* 外部扩展 handoff:写 /lib//.todo 并阻塞 watch .done(30s * 超时)。RETURN 模式下 term 遇非己方 ext rwir(如 json.to/numpy)时调用,把 diff --git a/runtime/src/kvcpu.c b/runtime/src/kvcpu.c index eb967501..cfb88a8e 100644 --- a/runtime/src/kvcpu.c +++ b/runtime/src/kvcpu.c @@ -186,8 +186,40 @@ static int check_read_types(kvlangKv_t *kv, const char *vtid, const char *pc, return rc; } -/* 读取 rwir/rwfunc 定义体的 kindexp-list(nr/nw 前缀后的 \n 分隔串)。 - * 返回 malloc 串(调用方 free)并置 *out_nr;无定义返回 NULL。 */ +/* 读签名行 [0,x] 槽(def langtype)的 body 为 langtype 串(malloc;无槽返 NULL)。 + * dir 带尾 /;x<0 读参、x>0 写参。 */ +static char *read_sig_slot(kvlangKv_t *kv, const char *dir, int x) { + kvlangStrbuf_t sk; kvlangStrbufInit(&sk); + kvlangStrbufPrintf(&sk, "%s[0,%d]", dir, x); + kvlangXvalue_t v; kvlangXvalueZero(&v); + kvlangKvGetOne(kv, sk.p, &v); + kvlangStrbufFree(&sk); + char *s = NULL; + if (!kvlangXvalueNone(&v)) { + kvspaceHead_t h; kvlangXvalueHead(&v, &h); + int32_t bl; const uint8_t *b = kvlangXvalueBody(&v, &h, &bl); + s = malloc((size_t)bl + 1); + memcpy(s, b, (size_t)bl); s[bl] = 0; + } + kvlangXvalueFree(&v); + return s; +} + +/* 拼读参签名(\n 连接 [0,-1..-nr] 各 def langtype 槽)。dir 带尾 /。malloc 返回。 */ +static char *join_read_sig(kvlangKv_t *kv, const char *dir, int nr) { + kvlangStrbuf_t b; kvlangStrbufInit(&b); + for (int i = 1; i <= nr; i++) { + if (i > 1) kvlangStrbufPutc(&b, '\n'); + char *s = read_sig_slot(kv, dir, -i); + kvlangStrbufPuts(&b, s ? s : ""); + free(s); + } + return kvlangStrbufDetach(&b); +} + +/* 读取 rwir/rwfunc 定义的读参签名:从主槽计数头取 nr/dynamic,读参 langtype 逐条 + * 落在签名行 [0,-i] 槽(def langtype)。返回 \n 连接的 kindexp-list(调用方 free) + * 并置 *out_nr;无定义返回 NULL。 */ static char *load_def_reads(kvlangKv_t *kv, const char *key, int *out_nr, int *out_dyn) { *out_nr = 0; *out_dyn = 0; @@ -199,10 +231,11 @@ static char *load_def_reads(kvlangKv_t *kv, const char *key, int *out_nr, int *o if (bl < 5) { kvlangXvalueFree(&v); return NULL; } *out_nr = b[0] | (b[1] << 8); *out_dyn = b[4]; - size_t sl = (size_t)(bl - 5); - char *sig = malloc(sl + 1); - memcpy(sig, b + 5, sl); sig[sl] = 0; kvlangXvalueFree(&v); + kvlangStrbuf_t dir; kvlangStrbufInit(&dir); + kvlangStrbufPrintf(&dir, "%s/", key); + char *sig = join_read_sig(kv, dir.p, *out_nr); + kvlangStrbufFree(&dir); return sig; } @@ -372,10 +405,9 @@ static char *handle_call(kvlangKv_t *kv, const char *pc, kvlangRwirInst_t *inst) int nw = sbody[2] | (sbody[3] << 8); int dyn = h.body_len >= 5 ? sbody[4] : 0; - { /* 读参类型校验:reads[0]=函数名,实参从 reads[1] 起 */ - size_t sl = h.body_len >= 5 ? (size_t)(h.body_len - 5) : 0; - char *ds = malloc(sl + 1); - memcpy(ds, sbody + 5, sl); ds[sl] = 0; + { /* 读参类型校验:reads[0]=函数名,实参从 reads[1] 起。 + * 读参 langtype 逐条落签名行 [0,-i] 槽(def langtype),主槽 body 仅计数头。 */ + char *ds = join_read_sig(kv, func_dir.p, nr); int crc = check_read_types(kv, vtid, pc, fn, ds, nr, dyn, inst->reads + 1, inst->nr - 1); free(ds); if (crc != 0) goto fail; diff --git a/runtime/src/rwirext.c b/runtime/src/rwirext.c index 761e9eb1..61f89090 100644 --- a/runtime/src/rwirext.c +++ b/runtime/src/rwirext.c @@ -65,9 +65,9 @@ static void write_sig_slot(kvlangKv_t *k, const char *base, int x, const char *l /* 注册一条 rwir:/lib/ 路由头(仅计数头)+ 各参数落 [0,x] 签名行槽(def langtype)。 * 参数类型逐条传入(读参 rp[0..nr]、写参 wp[0..nw]),不再拼签名串——避免其它 runtime * 把「拼接 sig 串」误当注册标准。末读参尾缀 "..." → 变参 arity(落 dynamic 字节)。 */ -int kvlangRwirextRegister(void *kvspace, const char *opcode, - const char *const *rp, int32_t nr, - const char *const *wp, int32_t nw) { +int kvlangDefRwir(void *kvspace, const char *opcode, + const char *const *rp, int32_t nr, + const char *const *wp, int32_t nw) { kvlangKv_t k = {kvspace}; char *base = kvlangKeytreeRwir(opcode); char err[256]; diff --git a/runtime/src/xvalue.c b/runtime/src/xvalue.c index d8f0303c..b5614ce7 100644 --- a/runtime/src/xvalue.c +++ b/runtime/src/xvalue.c @@ -557,7 +557,7 @@ void kvlangXvalueNewPtr(kvlangXvalue_t *v, const char *target_langtype, const ch v->borrowed = 0; } /* def rwir 路由头:body 仅计数头 [nr:u16 LE][nw:u16 LE][dynamic:u8],无参数载荷。 - * 各参数类型由 kvlangRwirextRegister 落 /lib//[0,x] 签名行槽(def langtype)。 */ + * 各参数类型由 kvlangDefRwir 落 /lib//[0,x] 签名行槽(def langtype)。 */ void kvlangXvalueNewDefRwir(kvlangXvalue_t *v, int32_t nr, int32_t nw, int dynamic) { uint8_t raw[5] = { nr & 0xFF, (nr >> 8) & 0xFF, nw & 0xFF, (nw >> 8) & 0xFF, dynamic ? 1 : 0 }; kvlangXvalueNewTlv(v, KVSPACE_KIND_DEF_RWIR, raw, 5, 1); diff --git "a/stdlib/kvlang/spec/05-runtime\350\257\255\344\271\211/09-cruntime\344\270\216\345\220\216\347\253\257abi.kv" "b/stdlib/kvlang/spec/05-runtime\350\257\255\344\271\211/09-cruntime\344\270\216\345\220\216\347\253\257abi.kv" index 8daa4cc1..979d16d8 100644 --- "a/stdlib/kvlang/spec/05-runtime\350\257\255\344\271\211/09-cruntime\344\270\216\345\220\216\347\253\257abi.kv" +++ "b/stdlib/kvlang/spec/05-runtime\350\257\255\344\271\211/09-cruntime\344\270\216\345\220\216\347\253\257abi.kv" @@ -24,7 +24,7 @@ lib kvlang/spec/runtime语义/cruntime与后端abi { `kvlang/runtime/` 是通用嵌入式执行器(纯 C + `extern "C"`),可嵌入 myrwir 项目(op-gpu、agent、livebyte)。两组对外 C ABI: - `kvlang_runtime.h`:核心执行器(`kvlangRuntimeConnect`/`Disconnect`/`Bootstrap`/`ExecuteVthread`/`KvspaceHandle` …)。 -- `kvlang_myrwir.h`:扩展 runtime 语义,**只暴露 kvspace 不提供的部分**。现有 9 个符号:`Register`、`Handoff`、`NextPc`、`Params`、`ResolveRead`、`ResolveReadPath`、`ResolveWrite`、`LangtypeValid`、`LangtypeMatch`。KV 存取(connect/get/write/del/list/tlv)**不在此**——扩展宿主自连 kvspace ABI,把句柄(`void *`)传进带句柄的 myrwir 函数。 +- `kvlang_myrwir.h`:扩展 runtime 语义,**只暴露 kvspace 不提供的部分**。现有 9 个符号:`DefRwir`、`Handoff`、`NextPc`、`Params`、`ResolveRead`、`ResolveReadPath`、`ResolveWrite`、`LangtypeValid`、`LangtypeMatch`。KV 存取(connect/get/write/del/list/tlv)**不在此**——扩展宿主自连 kvspace ABI,把句柄(`void *`)传进带句柄的 myrwir 函数。 其中 `LangtypeValid`/`LangtypeMatch` 与正典 codec 的 head 解码,正是 langtype **两型**对外的两条 ABI(两型 def/value 与 kindexpr 简写见 [[langtype签名类型表达式]]):前者服务 **def langtype**(模式侧——校验签名 kindexpr、把一个值的 `(kind,ndim,dims)` 匹配进签名),后者服务 **value langtype**(具体侧——把 head 里一条 kindexpr 解析为 `(kind,ndim,dims,元素字节宽)`,事实源为 `kvspaceDecodeHead` 与 layout 的 `kvlangLangtypeParse`)。两者同吃一条 kindexpr 串、共用唯一文法与 codec,差别只在模式匹配 vs 具体解析。 @@ -303,7 +303,7 @@ kvspaceNewPtr / NewChar / NewBool / NewInt64 / NewFloat64 kvlangRwirextHandoff kvlangRwirextNextPc kvlangRwirextParams - kvlangRwirextRegister + kvlangDefRwir kvlangRwirextResolveRead kvlangRwirextResolveReadPath kvlangRwirextResolveWrite