Skip to content

Instantly share code, notes, and snippets.

@ulan
Last active August 28, 2021 18:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ulan/8cc37022c72fe20dc1d57fdfd0aaf1fd to your computer and use it in GitHub Desktop.
Save ulan/8cc37022c72fe20dc1d57fdfd0aaf1fd to your computer and use it in GitHub Desktop.
Internet Computer spec changes to support the proposed 64-bit stable memory API
diff --git a/spec/index.adoc b/spec/index.adoc
index f76111f..e5976bd 100644
--- a/spec/index.adoc
+++ b/spec/index.adoc
@@ -956,6 +956,10 @@ ic0.stable_size : () -> (page_count : i32); // *
ic0.stable_grow : (new_pages : i32) -> (old_page_count : i32); // *
ic0.stable_write : (offset : i32, src : i32, size : i32) -> (); // *
ic0.stable_read : (dst : i32, offset : i32, size : i32) -> (); // *
+ic0.stable_size64 : () -> (page_count : i64); // *
+ic0.stable_grow64 : (new_pages : i64) -> (old_page_count : i64); // *
+ic0.stable_write64 : (offset : i64, src : i64, size : i64) -> (); // *
+ic0.stable_read64 : (dst : i64, offset : i64, size : i64) -> (); // *
ic0.certified_data_set : (src: i32, size: i32) -> () // I G U Ry Rt H
ic0.data_certificate_present : () -> i32 // *
@@ -1238,25 +1242,65 @@ The stable memory is initially empty.
* `ic0.stable_size : () -> (page_count : i32)`
+
-returns the current size of the stable memory in WebAssembly pages. (One WebAssembly page is 64Ki bytes.)
+returns the current size of the stable memory in WebAssembly pages. (One WebAssembly page is 64KiB)
++
+This system call traps if the size of the stable memory exceeds 2^32 bytes.
* `ic0.stable_grow : (new_pages : i32) -> (old_page_count : i32)`
+
tries to grow the memory by `new_pages` many pages containing zeroes.
+
-If successful, returns the _previous_ size of the memory (in pages). Otherwise, returns `-1`.
+This system call traps if the _previous_ size of the memory exceeds 2^32 bytes.
++
+If the _new_ size of the memory exceeds 2^32 bytes or growing is unsuccessful, then it returns `-1`.
++
+Otherwise, it grows the memory and returns the _previous_ size of the memory in pages.
* `ic0.stable_write : (offset : i32, src : i32, size : i32) -> ()`
+
copies the data referred to by `src`/`size` out of the canister and replaces the corresponding segment starting at `offset` in the stable memory.
+
-This system call traps if `src+size` exceeds the size of the WebAssembly memory or `offset+size` exceeds the size of the stable memory.
+This system call traps if the size of the stable memory exceeds 2^32 bytes.
++
+It also traps if `src+size` exceeds the size of the WebAssembly memory or `offset+size` exceeds the size of the stable memory.
* `ic0.stable_read : (dst : i32, offset : i32, size : i32) -> ()`
+
copies the data referred to by `offset`/`size` out of the stable memory and replaces the corresponding bytes starting at `dest` in the canister memory.
+
+This system call traps if the size of the stable memory exceeds 2^32 bytes.
++
+It also traps if `dst+size` exceeds the size of the WebAssembly memory or `offset+size` exceeds the size of the stable memory
+
+* `ic0.stable_size64 : () -> (page_count : i64)`
++
+returns the current size of the stable memory in WebAssembly pages. (One WebAssembly page is 64KiB)
++
+This system call is experimental. It may be changed or removed in the future. Canisters using it may stop working.
+
+* `ic0.stable_grow64 : (new_pages : i64) -> (old_page_count : i64)`
++
+tries to grow the memory by `new_pages` many pages containing zeroes.
++
+If successful, returns the _previous_ size of the memory (in pages). Otherwise, returns `-1`.
++
+This system call is experimental. It may be changed or removed in the future. Canisters using it may stop working.
+
+* `ic0.stable_write64 : (offset : i64, src : i64, size : i64) -> ()`
++
+Copies the data from location [src, src+size) of the canister memory to location [offset, offset+size) in the stable memory.
++
+This system call traps if `src+size` exceeds the size of the WebAssembly memory or `offset+size` exceeds the size of the stable memory.
++
+This system call is experimental. It may be changed or removed in the future. Canisters using it may stop working.
+
+* `ic0.stable_read64 : (dst : i64, offset : i64, size : i64) -> ()`
++
+Copies the data from location [offset, offset+size) of the stable memory to the location [dst, dst+size) in the canister memory.
++
This system call traps if `dst+size` exceeds the size of the WebAssembly memory or `offset+size` exceeds the size of the stable memory.
++
+This system call is experimental. It may be changed or removed in the future. Canisters using it may stop working.
[#system-api-time]
=== System time
@@ -3851,24 +3895,53 @@ discard_pending_call<es>() =
es.pending_call := NoPendingCall
ic0.stable_size<es>() : (page_count : i32) =
- return |es.wasm_state.stable_mem| / 64k
+ if |es.wasm_state.store.mem| > 2^32 then Trap
+ page_count := |es.wasm_state.stable_mem| / 64k
+ return page_count
ic0.stable_grow<es>(new_pages : i32) : (old_page_count : i32) =
- if arbitrary()
- then return -1
+ if |es.wasm_state.store.mem| > 2^32 then Trap
+ if arbitrary() then return -1
else
old_size := |es.wasm_state.stable_mem| / 64k
+ if old_size + new_pages > 2^16 then return -1
es.wasm_state.stable_mem :=
es.wasm_state.stable_mem · repeat(0x00, new_pages * 64k)
return old_size
ic0.stable_write<es>(offset : i32, src : i32, size : i32)
+ if |es.wasm_state.store.mem| > 2^32 then Trap
if src+size > |es.wasm_state.store.mem| then Trap
if offset+size > |es.wasm_state.stable_mem| then Trap
es.wasm_state.stable_mem[offset..offset+size] := es.wasm_state.store.mem[src..src+size]
ic0.stable_read<es>(dst : i32, offset : i32, size : i32)
+ if |es.wasm_state.store.mem| > 2^32 then Trap
+ if offset+size > |es.wasm_state.stable_mem| then Trap
+ if dst+size > |es.wasm_state.store.mem| then Trap
+
+ es.wasm_state.store.mem[offset..offset+size] := es.wasm_state.stable.mem[src..src+size]
+
+ic0.stable_size64<es>() : (page_count : i64) =
+ return |es.wasm_state.stable_mem| / 64k
+
+ic0.stable_grow64<es>(new_pages : i64) : (old_page_count : i64) =
+ if arbitrary()
+ then return -1
+ else
+ old_size := |es.wasm_state.stable_mem| / 64k
+ es.wasm_state.stable_mem :=
+ es.wasm_state.stable_mem · repeat(0x00, new_pages * 64k)
+ return old_size
+
+ic0.stable_write64<es>(offset : i64, src : i64, size : i64)
+ if src+size > |es.wasm_state.store.mem| then Trap
+ if offset+size > |es.wasm_state.stable_mem| then Trap
+
+ es.wasm_state.stable_mem[offset..offset+size] := es.wasm_state.store.mem[src..src+size]
+
+ic0.stable_read64<es>(dst : i64, offset : i64, size : i64)
if offset+size > |es.wasm_state.stable_mem| then Trap
if dst+size > |es.wasm_state.store.mem| then Trap
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment