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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,6 @@ kvtut*

# tutorial bench 空产物
/tutorial/benchmark.csv

# runtime-rs 测试 shm 产物
kvlangtest*
39 changes: 31 additions & 8 deletions layout/src/code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,21 +395,31 @@ pub fn write_func(kv: &mut Kv, pkg: &str, fn_: &mut Func) {
let mut pairs: Vec<(String, Vec<u8>)> = Vec::new();
pairs.push((
format!("{func_dir}/[0,0]"),
kvkind::new_rwfunc(seq.len() as i32, nr, nw, fn_.sig.dynamic(), &param_types),
kvkind::new_rwfunc(seq.len() as i32, nr, nw, fn_.sig.dynamic()),
));
pairs.push((
keytree::lib_src(pkg, &fn_.sig.name),
ffi::new_char_byte(fn_.full_text().as_bytes()),
));
// 签名行:每个参数的类型定义落 [0,x] 槽(def langtype),x<0 读参、x>0 写参。
// 运行期 call 会用实参绑定覆盖同坐标的帧槽,静态类型定义仅供 layout 类型检查/dump。
for (i, p) in fn_.sig.params.iter().enumerate() {
let slot = format!("[0,-{}]", i + 1);
pairs.push((
format!("{func_dir}/{slot}"),
kvkind::new_def_langtype(&param_types[i]),
));
pairs.push((
format!("{func_dir}/{}", p.name),
ffi::new_ptr(kvkind::KIND_CHAR, &slot),
));
}
for (i, r) in fn_.sig.returns.iter().enumerate() {
let slot = format!("[0,{}]", i + 1);
pairs.push((
format!("{func_dir}/{slot}"),
kvkind::new_def_langtype(&param_types[nr as usize + i]),
));
pairs.push((
format!("{func_dir}/{}", r.name),
ffi::new_ptr(kvkind::KIND_CHAR, &slot),
Expand Down Expand Up @@ -498,13 +508,26 @@ pub fn write_rwir_decl(kv: &mut Kv, decl: &RwirDecl) {
if !decl.pkg.is_empty() {
opcode = format!("{}{}{opcode}", decl.pkg, keytree::MEMBER_SEP);
}
let v = kvkind::new_defrwir(
decl.sig.num_reads(),
decl.sig.num_writes(),
decl.sig.dynamic(),
&decl.sig.langtype_list().join("\n"),
);
let _ = kv.set(&[(keytree::rwir(&opcode), v)]);
let nr = decl.sig.num_reads();
let nw = decl.sig.num_writes();
let param_types = decl.sig.langtype_list();
let base = keytree::rwir(&opcode);
// 路由头:仅计数头(无参数载荷);各参数类型落 [0,x] 签名行槽(def langtype)。
let mut pairs: Vec<(String, Vec<u8>)> =
vec![(base.clone(), kvkind::new_defrwir(nr, nw, decl.sig.dynamic()))];
for i in 0..nr as usize {
pairs.push((
format!("{base}/[0,-{}]", i + 1),
kvkind::new_def_langtype(&param_types[i]),
));
}
for i in 0..nw as usize {
pairs.push((
format!("{base}/[0,{}]", i + 1),
kvkind::new_def_langtype(&param_types[nr as usize + i]),
));
}
let _ = kv.set(&pairs);
}

/// Flatten body into seq; ScopeStmt records label → irseq (1-based; [0,0] is the signature).
Expand Down
73 changes: 36 additions & 37 deletions layout/src/kvkind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ pub const KIND_STRUCT: &str = "struct";
// kvlang 自有 kind
pub const KIND_RWIR: &str = "rwir";
pub const KIND_RWFUNC: &str = "rwfunc";
pub const KIND_DEF_RWIR: &str = "defrwir";
pub const KIND_DEF_RWIR: &str = "def rwir";
pub const KIND_DEF_LANGTYPE: &str = "def langtype";
pub const KIND_RWIR_OR_RWFUNC: &str = "rwir|rwfunc";
pub const KIND_SCOPE: &str = "scope";

Expand Down Expand Up @@ -188,7 +189,7 @@ fn plain_value(k: &str, b: &[u8]) -> String {
.collect(),
"index" => format!("({})", count_names(b)),
// kvlang 自有 kind:body = [2B nr][2B nw][1B dynamic][sig];槽值/调用目标 nr=nw=0,取 sig 即可。
"rwir" | "rwir|rwfunc" | "rwfunc" | "defrwir" => {
"rwir" | "rwir|rwfunc" | "rwfunc" | "def rwir" => {
let (nr, nw, dynamic) = if b.len() >= 5 {
(
u16::from_le_bytes([b[0], b[1]]),
Expand All @@ -214,32 +215,50 @@ pub fn is_char_kind(k: &str) -> bool {
k.starts_with("char/")
}

// ── kvlang 自有 kind:rwir / defrwir ────────────────────────────────
// ── kvlang 自有 kind:rwir / def rwir / def langtype ─────────────────
//
// body = [2B nr LE][2B nw LE][1B dynamic][sig],array_len=1。
// rwir=槽值(引用串/opcode),defrwir=定义(签名)。dynamic=末读参变参(arity,非 langtype)。

fn rwir_body(nr: i32, nw: i32, dynamic: bool, sig: &str) -> Vec<u8> {
let mut raw = Vec::with_capacity(5 + sig.len());
// 铁律:任何 rwir/rwfunc 值的 body 只记计数头 [2B nr LE][2B nw LE][1B dynamic],
// 禁止携带具体参数。指令槽 [n,x] 的引用串(opcode/操作数名)是「每坐标一个值」,
// 落于 rwir 槽值 body 的尾部载荷;定义(rwfunc/def rwir)的各参数类型分散落在
// 签名行 [0,x] 槽(各为一个 def langtype 值,body=该参数 langtype 串)。
// dynamic=末读参变参(arity,非 langtype)。

/// 计数头 [nr:u16 LE][nw:u16 LE][dynamic:u8](定义体,无参数载荷)。
fn counts_body(nr: i32, nw: i32, dynamic: bool) -> Vec<u8> {
let mut raw = Vec::with_capacity(5);
raw.extend_from_slice(&(nr as u16).to_le_bytes());
raw.extend_from_slice(&(nw as u16).to_le_bytes());
raw.push(dynamic as u8);
raw
}

/// 指令槽值:计数头 + 单个引用串载荷(opcode/操作数名,每坐标一个值)。
fn rwir_slot_body(sig: &str) -> Vec<u8> {
let mut raw = counts_body(0, 0, false);
raw.extend_from_slice(sig.as_bytes());
raw
}

pub fn new_rwir(nr: i32, nw: i32, sig: &str) -> Vec<u8> {
ffi::tlv_encode(KIND_RWIR, &rwir_body(nr, nw, false, sig), 1)
let mut raw = counts_body(nr, nw, false);
raw.extend_from_slice(sig.as_bytes());
ffi::tlv_encode(KIND_RWIR, &raw, 1)
}

/// 调用目标(看起来像函数调用的 opcode)→ langtype `rwir|rwfunc` 并列。
/// 静态无法判定是扩展 rwir 还是用户 rwfunc,交 runtime 查 /lib/<op> 的 XValue kind 分派。
pub fn new_rwir_union(sig: &str) -> Vec<u8> {
ffi::tlv_encode(KIND_RWIR_OR_RWFUNC, &rwir_body(0, 0, false, sig), 1)
ffi::tlv_encode(KIND_RWIR_OR_RWFUNC, &rwir_slot_body(sig), 1)
}

/// def rwir 路由头:仅计数头,无参数载荷。各参数落 [0,x] 签名行槽(def langtype)。
pub fn new_defrwir(nr: i32, nw: i32, dynamic: bool) -> Vec<u8> {
ffi::tlv_encode(KIND_DEF_RWIR, &counts_body(nr, nw, dynamic), 1)
}

pub fn new_defrwir(nr: i32, nw: i32, dynamic: bool, sig: &str) -> Vec<u8> {
ffi::tlv_encode(KIND_DEF_RWIR, &rwir_body(nr, nw, dynamic, sig), 1)
/// 签名行 [0,x] 槽:一个参数的类型定义,body=该参数完整 langtype 串。
pub fn new_def_langtype(langtype: &str) -> Vec<u8> {
ffi::tlv_encode(KIND_DEF_LANGTYPE, langtype.as_bytes(), 1)
}

// ── struct 原型(对齐 runtime kvlangBuiltinMemindex)─────────────────
Expand All @@ -264,21 +283,11 @@ pub fn new_memindex(names: &[String]) -> Vec<u8> {

// ── kvlang 自有 kind:rwfunc ────────────────────────────────────────
//
// body = [2B nr LE][2B nw LE][1B dynamic][param_types 以 \n 连接],array_len=num_insts。

pub fn new_rwfunc(
num_insts: i32,
nr: i32,
nw: i32,
dynamic: bool,
param_types: &[String],
) -> Vec<u8> {
let mut raw = Vec::with_capacity(5 + param_types.iter().map(|s| s.len()).sum::<usize>());
raw.extend_from_slice(&(nr as u16).to_le_bytes());
raw.extend_from_slice(&(nw as u16).to_le_bytes());
raw.push(dynamic as u8);
raw.extend_from_slice(param_types.join("\n").as_bytes());
ffi::tlv_encode(KIND_RWFUNC, &raw, num_insts)
// body = 计数头 [2B nr LE][2B nw LE][1B dynamic],array_len=num_insts。
// 各参数类型落签名行 [0,x] 槽(def langtype),不入 body(见上「铁律」)。

pub fn new_rwfunc(num_insts: i32, nr: i32, nw: i32, dynamic: bool) -> Vec<u8> {
ffi::tlv_encode(KIND_RWFUNC, &counts_body(nr, nw, dynamic), num_insts)
}

/// rwfunc body 访问器(layout 读回签名时用)。
Expand All @@ -295,13 +304,3 @@ pub fn rwfunc_num_writes(body: &[u8]) -> i32 {
}
u16::from_le_bytes([body[2], body[3]]) as i32
}

pub fn rwfunc_param_types(body: &[u8]) -> Vec<String> {
if body.len() <= 5 {
return Vec::new();
}
String::from_utf8_lossy(&body[5..])
.split('\n')
.map(|s| s.to_string())
.collect()
}
1 change: 1 addition & 0 deletions runtime-rs/src/rwir/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ mod tests {
rt: std::ptr::null_mut(),
kv,
dsn: dsn.to_string(),
ext: None,
};
let src = r#"
lib http {
Expand Down
1 change: 1 addition & 0 deletions runtime-rs/src/rwir/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ mod tests {
rt: std::ptr::null_mut(),
kv,
dsn: dsn.to_string(),
ext: None,
}
}

Expand Down
11 changes: 10 additions & 1 deletion runtime-rs/src/rwir/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! rwir —— 注册进 kvlang runtime 的 stdlib,文件/模块按 kvlang lib 嵌套关系组织
//! (lib 用 `/` 嵌套、成员用 `·`,文件树与之 1:1):
//! term : print / println / cerr / input 行输出 + 读 stdin(裸 rwir)
//! term : print / println / cerr / printf / input 行输出 + C 风格格式化 + 读 stdin(裸 rwir)
//! json : json·to / json·from KV 子树 ↔ JSON 文本
//! http : http·call 网络抓取(ureq 原生)
//! kvlanglayout : kvlanglayout·vet/format/layout/dump 自造 kv 代码入库(layout C ABI)
Expand Down Expand Up @@ -54,6 +54,13 @@ pub const MYRWIRCAPS: &[(&str, Rwir)] = &[
wp: &[],
},
),
(
"printf",
Rwir {
rp: &["[]char/utf8|[]char/utf32", "any..."],
wp: &[],
},
),
(
"json·to",
Rwir {
Expand Down Expand Up @@ -206,6 +213,7 @@ pub fn is_inproc(op: &str) -> bool {
"print"
| "println"
| "cerr"
| "printf"
| "input"
| "json·to"
| "json·from"
Expand Down Expand Up @@ -235,6 +243,7 @@ pub fn in_myrwircaps(op: &str) -> bool {
pub fn dispatch(eng: &Engine, op: &str, pc: &str) {
match op {
"print" | "println" | "cerr" => term::print_line(eng, pc),
"printf" => term::printf(eng, pc),
"input" => term::input(eng, pc),
"json·to" => json::to(eng, pc),
"json·from" => json::from(eng, pc),
Expand Down
Loading
Loading