This makes several changes: - It adds an index_type to heap declarations, allowing heaps to specify the type for indexing. This also anticipates 64-bit heap support. - It adds a memory_type to deref global values, allowing deref globals to have types other than pointers. This is used to allow the bound variable in dynamic heaps to have type i32, to match the index type in heaps with i32 index type. - And, it fixes heap legalization to do the bounds check in the heap's index type.
81 lines
2.1 KiB
Plaintext
81 lines
2.1 KiB
Plaintext
test cat
|
|
test verifier
|
|
|
|
function %vmglobal(i64 vmctx) -> i32 {
|
|
gv3 = vmctx+16
|
|
; check: gv3 = vmctx+16
|
|
gv4 = vmctx+0
|
|
; check: gv4 = vmctx
|
|
; not: +0
|
|
gv5 = vmctx -256
|
|
; check: gv5 = vmctx-256
|
|
ebb0(v0: i64):
|
|
v1 = global_value.i32 gv3
|
|
; check: v1 = global_value.i32 gv3
|
|
return v1
|
|
}
|
|
|
|
function %deref(i64 vmctx) -> i32 {
|
|
gv3 = vmctx+16
|
|
gv4 = deref(gv3)-32: i32
|
|
; check: gv4 = deref(gv3)-32
|
|
ebb0(v0: i64):
|
|
v1 = global_value.i32 gv4
|
|
; check: v1 = global_value.i32 gv4
|
|
return v1
|
|
}
|
|
|
|
; Refer to a global value before it's been declared.
|
|
function %backref(i64 vmctx) -> i32 {
|
|
gv1 = deref(gv2)-32: i32
|
|
; check: gv1 = deref(gv2)-32
|
|
gv2 = vmctx+16
|
|
; check: gv2 = vmctx+16
|
|
ebb0(v0: i64):
|
|
v1 = global_value.i32 gv1
|
|
return v1
|
|
}
|
|
|
|
function %sym() -> i32 {
|
|
gv0 = globalsym %something
|
|
; check: gv0 = globalsym %something
|
|
gv1 = globalsym u8:9
|
|
; check: gv1 = globalsym u8:9
|
|
ebb0:
|
|
v0 = global_value.i32 gv0
|
|
; check: v0 = global_value.i32 gv0
|
|
v1 = global_value.i32 gv1
|
|
; check: v1 = global_value.i32 gv1
|
|
v2 = bxor v0, v1
|
|
return v2
|
|
}
|
|
|
|
; Declare static heaps.
|
|
function %sheap(i32, i64 vmctx) -> i64 {
|
|
heap1 = static gv5, min 0x1_0000, bound 0x1_0000_0000, guard 0x8000_0000
|
|
heap2 = static gv5, guard 0x1000, bound 0x1_0000
|
|
gv5 = vmctx+64
|
|
|
|
; check: heap1 = static gv5, min 0x0001_0000, bound 0x0001_0000_0000, guard 0x8000_0000
|
|
; check: heap2 = static gv5, min 0, bound 0x0001_0000, guard 4096
|
|
ebb0(v1: i32, v2: i64):
|
|
v3 = heap_addr.i64 heap1, v1, 0
|
|
; check: v3 = heap_addr.i64 heap1, v1, 0
|
|
return v3
|
|
}
|
|
|
|
; Declare dynamic heaps.
|
|
function %dheap(i32, i64 vmctx) -> i64 {
|
|
heap1 = dynamic gv5, min 0x1_0000, bound gv6, guard 0x8000_0000
|
|
heap2 = dynamic gv5, bound gv6, guard 0x1000
|
|
gv5 = vmctx+64
|
|
gv6 = vmctx+72
|
|
|
|
; check: heap1 = dynamic gv5, min 0x0001_0000, bound gv6, guard 0x8000_0000
|
|
; check: heap2 = dynamic gv5, min 0, bound gv6, guard 4096
|
|
ebb0(v1: i32, v2: i64):
|
|
v3 = heap_addr.i64 heap2, v1, 0
|
|
; check: v3 = heap_addr.i64 heap2, v1, 0
|
|
return v3
|
|
}
|