Description
Hello all,
We are looking to implement a verification-friendly stubs for modules in the Rust standard library for rmc. Specifically, the first module we are targeting is Vector.
Currently, the way we envision implementing support for dynamic data structures such as the vector is to allocate memory and then resizing the allocation per requirement. For instance, below is the piece of code we are using to model the Vector in C right now:
typedef struct {
uint32_t* mem;
size_t len;
size_t capacity;
} vec;
void grow(vec* v) {
// Expensive operation
uint32_t* new_mem = (uint32_t *) realloc(v->mem, v->capacity * 2 * sizeof(uint32_t));
v->mem = new_mem;
v->capacity = v->capacity * 2;
}
void push(vec* v, uint32_t elem) {
if (v->len == v->capacity) {
grow(v);
}
v->mem[v->len] = elem;
v->len += 1;
}
The grow()
operation here is fairly expensive as it allocates a new chunk of memory and copies over all the elements of the previous allocation creating complex solver queries.
We could avoid this (while remaining sound) by treating memory allocations as regions of memory which can be tracked using their start
and end
pointers. For instance, a "verification-friendly" realloc would only change the end
pointer being tracked for this specific memory region.
Ofcourse, this might not be true for an generic allocator which chooses to model memory differently but for abstractions which dont care about the underlying allocator, we believe that such an optimization would lead to significant benefits when considering dynamically resizeable data structures.
I had a talk with Michael Tautschnig about this in his office hours with the RMC dev team and he suggested that this might be a worthwhile idea to look at. I am creating this issue on recommendation of DSN, please let me know if any other information is required.
I have created a gist containing c_vec.c
which implements a rudimentary Vector implementation in C which acts as a library for c_vec.rs
(which treats these as extern functions). Gist here : https://gist.github.com/chinmaydd/7ccd66273c162906f037905ed1ac8e2b
I also looked at the abstraction implemented in regression/cbmc-cpp/Vector1/lib
which uses the idea of an infinite array to implement a Vector (apart from the abstraction which does not use a backing-store). If that is recommended way to go about implementing dynamic data structures, please let me know. I think this would require supporting the infinite array type in rmc in codegen but I would be happy to discuss further.
Thanks !