stage0 新增内存复制指令 重构vm交互
This commit is contained in:
1 parent
0b8f649818
commit
40cffa9cb5
22 files changed
+626
-158
No files matched your search
@@ -0,0 +1,155 @@
|
||||
// Expect retcode = 0
|
||||
|
||||
type Pair = struct {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
|
||||
type Option = enum {
|
||||
None,
|
||||
Some: i32,
|
||||
}
|
||||
|
||||
type Nested = struct {
|
||||
inner: Pair,
|
||||
tag: i32,
|
||||
}
|
||||
|
||||
// 对照:无 & 的值绑定是拷贝,写回不作用于源。
|
||||
fn test_value_binding_is_copy() {
|
||||
var p: Pair = .{ .x = 1, .y = 2 };
|
||||
var .{ .x = a, .y = b } = p;
|
||||
a = 10;
|
||||
b = 20;
|
||||
@assert(a == 10, "value binding a is local copy");
|
||||
@assert(p.x == 1, "value binding does not write back x");
|
||||
@assert(p.y == 2, "value binding does not write back y");
|
||||
}
|
||||
|
||||
// 普通结构体解构:& 引用绑定。
|
||||
fn test_struct_ref_binding() {
|
||||
var p: Pair = .{ .x = 1, .y = 2 };
|
||||
var .{ .x = &a, .y = &b } = p;
|
||||
@assert(a.* == 1, "struct ref reads x");
|
||||
@assert(b.* == 2, "struct ref reads y");
|
||||
a.* = 10;
|
||||
b.* = 20;
|
||||
@assert(p.x == 10, "struct ref writes back x");
|
||||
@assert(p.y == 20, "struct ref writes back y");
|
||||
}
|
||||
|
||||
// 混合:值绑定 + 引用绑定。
|
||||
fn test_struct_mixed_binding() {
|
||||
var p: Pair = .{ .x = 1, .y = 2 };
|
||||
var .{ .x = val, .y = &ref } = p;
|
||||
@assert(val == 1, "mixed value reads x");
|
||||
val = 100;
|
||||
ref.* = 200;
|
||||
@assert(p.x == 1, "mixed value does not write back");
|
||||
@assert(p.y == 200, "mixed ref writes back");
|
||||
}
|
||||
|
||||
// 部分字段 & 引用绑定。
|
||||
fn test_struct_partial_ref() {
|
||||
var p: Pair = .{ .x = 1, .y = 2 };
|
||||
var .{ .y = &b } = p;
|
||||
b.* = 99;
|
||||
@assert(p.y == 99, "partial ref writes back y");
|
||||
@assert(p.x == 1, "partial ref leaves x untouched");
|
||||
}
|
||||
|
||||
// 嵌套结构体解构:& 引用绑定。
|
||||
fn test_nested_ref() {
|
||||
var n: Nested = .{ .inner = .{ .x = 1, .y = 2 }, .tag = 3 };
|
||||
var .{ .inner = .{ .x = &a, .y = &b }, .tag = &t } = n;
|
||||
a.* = 7;
|
||||
b.* = 8;
|
||||
t.* = 9;
|
||||
@assert(n.inner.x == 7, "nested ref writes back inner.x");
|
||||
@assert(n.inner.y == 8, "nested ref writes back inner.y");
|
||||
@assert(n.tag == 9, "nested ref writes back tag");
|
||||
}
|
||||
|
||||
// 源本身是左值子表达式(字段):& 引用绑定。
|
||||
fn test_field_source_ref() {
|
||||
var n: Nested = .{ .inner = .{ .x = 1, .y = 2 }, .tag = 3 };
|
||||
var .{ .x = &a, .y = &b } = n.inner;
|
||||
a.* = 11;
|
||||
b.* = 12;
|
||||
@assert(n.inner.x == 11, "field source ref writes back x");
|
||||
@assert(n.inner.y == 12, "field source ref writes back y");
|
||||
}
|
||||
|
||||
// 枚举解构:& 引用绑定。
|
||||
fn test_enum_ref() {
|
||||
var o: Option = .Some(1);
|
||||
var .Some(&n) = o;
|
||||
@assert(n.* == 1, "enum ref reads payload");
|
||||
n.* = 42;
|
||||
match o {
|
||||
.None => { @assert(false, "enum ref: expected Some"); },
|
||||
.Some(m) => { @assert(m == 42, "enum ref writes back payload"); },
|
||||
}
|
||||
}
|
||||
|
||||
// 元组解构:& 引用绑定。
|
||||
fn test_tuple_ref() {
|
||||
var t: (i32, i32) = (1, 2);
|
||||
var (&a, &b) = t;
|
||||
@assert(a.* == 1, "tuple ref reads [0]");
|
||||
@assert(b.* == 2, "tuple ref reads [1]");
|
||||
a.* = 10;
|
||||
b.* = 20;
|
||||
@assert(t[0] == 10, "tuple ref writes back [0]");
|
||||
@assert(t[1] == 20, "tuple ref writes back [1]");
|
||||
}
|
||||
|
||||
// if var:& 引用绑定(枚举)。
|
||||
fn test_ifvar_enum_ref() {
|
||||
var o: Option = .Some(1);
|
||||
if var .Some(&n) = o {
|
||||
n.* = 77;
|
||||
}
|
||||
match o {
|
||||
.None => { @assert(false, "if var ref: expected Some"); },
|
||||
.Some(m) => { @assert(m == 77, "if var ref writes back payload"); },
|
||||
}
|
||||
}
|
||||
|
||||
// if var:& 引用绑定(元组)。
|
||||
fn test_ifvar_tuple_ref() {
|
||||
var t: (i32, i32) = (1, 2);
|
||||
if var (&a, &b) = t {
|
||||
a.* = 5;
|
||||
b.* = 6;
|
||||
}
|
||||
@assert(t[0] == 5, "if var tuple ref writes back [0]");
|
||||
@assert(t[1] == 6, "if var tuple ref writes back [1]");
|
||||
}
|
||||
|
||||
// match arm:& 引用绑定。
|
||||
fn test_match_enum_ref() {
|
||||
var o: Option = .Some(1);
|
||||
match o {
|
||||
.None => { @assert(false, "match ref: expected Some"); },
|
||||
.Some(&n) => { n.* = 55; },
|
||||
}
|
||||
match o {
|
||||
.None => { @assert(false, "match ref: expected Some after"); },
|
||||
.Some(m) => { @assert(m == 55, "match arm ref writes back payload"); },
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
test_value_binding_is_copy();
|
||||
test_struct_ref_binding();
|
||||
test_struct_mixed_binding();
|
||||
test_struct_partial_ref();
|
||||
test_nested_ref();
|
||||
test_field_source_ref();
|
||||
test_enum_ref();
|
||||
test_tuple_ref();
|
||||
test_ifvar_enum_ref();
|
||||
test_ifvar_tuple_ref();
|
||||
test_match_enum_ref();
|
||||
}
|
||||
Reference in new issue
Block a user