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
5 changes: 3 additions & 2 deletions runtime-rs/src/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
21 changes: 11 additions & 10 deletions runtime-rs/src/rwir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 列表(逐槽一型,不假设同型)。
Expand Down Expand Up @@ -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::<Vec<_>>()
.join("\n");
let rp: Vec<CString> = r.rp.iter().map(|s| cs(s)).collect();
let wp: Vec<CString> = 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,
)
};
}
Expand Down
9 changes: 6 additions & 3 deletions runtime/include/kvlang_rwirext.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@
* *)传进下列带句柄的函数即可。 本 ABI 只暴露 kvspace 不提供的 runtime
* 语义:rwir 解码 + resolve + display + PC 推进 + 类型判定。 */

/* 写 /lib/<opcode> = rwir 签名(幂等) */
int kvlangRwirextRegister(void *kvspace, const char *opcode, int32_t nr,
int32_t nw, const char *sig);
/* 注册一条 rwir(幂等):/lib/<opcode> 路由头(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/<opcode>/.todo<vid> 并阻塞 watch .done<vid>(30s
* 超时)。RETURN 模式下 term 遇非己方 ext rwir(如 json.to/numpy)时调用,把
Expand Down
50 changes: 41 additions & 9 deletions runtime/src/kvcpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}

Expand Down Expand Up @@ -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;
Expand Down
6 changes: 3 additions & 3 deletions runtime/src/rwirext.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ static void write_sig_slot(kvlangKv_t *k, const char *base, int x, const char *l
/* 注册一条 rwir:/lib/<op> 路由头(仅计数头)+ 各参数落 [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];
Expand Down
2 changes: 1 addition & 1 deletion runtime/src/xvalue.c
Original file line number Diff line number Diff line change
Expand Up @@ -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/<op>/[0,x] 签名行槽(def langtype)。 */
* 各参数类型由 kvlangDefRwir 落 /lib/<op>/[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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 具体解析。

Expand Down Expand Up @@ -303,7 +303,7 @@ kvspaceNewPtr / NewChar / NewBool / NewInt64 / NewFloat64
kvlangRwirextHandoff
kvlangRwirextNextPc
kvlangRwirextParams
kvlangRwirextRegister
kvlangDefRwir
kvlangRwirextResolveRead
kvlangRwirextResolveReadPath
kvlangRwirextResolveWrite
Expand Down
Loading