@@ -591,15 +591,17 @@ AlignedStorageStore: "(offs, val) {
591
591
// TODO: this function needs more testing
592
592
// Copies size bytes from memory to memory.
593
593
CopyMemory : "(src, dst, size) {
594
+ let num_words, overflow_bytes := $ToWordOffs(size)
594
595
let i := 0
595
- for { } lt(i, size ) { i := add(i, 32) } {
596
+ for { } lt(i, mul(num_words, 32) ) { i := add(i, 32) } {
596
597
mstore(add(dst, i), mload(add(src, i)))
597
598
}
598
- if lt(i, size) {
599
- let mask := sub(shl(shl(3, i), 1), 1)
600
- let dst_word := and(mload(add(dst, i)), not(mask))
601
- let src_word := and(mload(add(src, i)), mask)
602
- mstore(add(dst, i), or(dst_word, src_word))
599
+ if overflow_bytes {
600
+ let mask := $MaskForSize(sub(32, overflow_bytes))
601
+ let overflow_offs := mul(num_words, 32)
602
+ let dst_word := and(mload(add(dst, overflow_offs)), mask)
603
+ let src_word := and(mload(add(src, overflow_offs)), not(mask))
604
+ mstore(add(dst, overflow_offs), or(dst_word, src_word))
603
605
}
604
606
}" ,
605
607
@@ -739,7 +741,7 @@ EqVector: "(x, y, elem_size) -> r {
739
741
let data_size_bytes := mul(elem_size, len_x)
740
742
let num_words, overflow_bytes := $ToWordOffs(data_size_bytes)
741
743
let i := 0
742
- for { } lt(i, data_size_bytes ) { i := add(i, 32) } {
744
+ for { } lt(i, mul(num_words, 32) ) { i := add(i, 32) } {
743
745
if $Neq(mload(add(x, add(i, 32))), mload(add(y, add(i, 32)))) {
744
746
r := false
745
747
leave
@@ -850,5 +852,48 @@ TryDecodeErrMsg: "() -> data {
850
852
$MemoryStoreU64(data, length)
851
853
$MemoryStoreU64(add(data, 8), length)
852
854
returndatacopy(add(data, 0x20), add(offset, 0x24), length)
853
- }" dep Malloc dep MemoryStoreU64
855
+ }" dep Malloc dep MemoryStoreU64 ,
856
+ NumToString : "(x) -> s {
857
+ if iszero(x) {
858
+ s := $Malloc(add(${VECTOR_METADATA_SIZE}, 2))
859
+ $MemoryStoreU64(s, 1)
860
+ $MemoryStoreU64(add(s, 8), 2)
861
+ $MemoryStoreU8(add(s, ${VECTOR_METADATA_SIZE}), 48) // string \" 0\"
862
+ leave
863
+ }
864
+ let temp := x
865
+ let num_digits := 0
866
+ for { } temp { num_digits := add(num_digits, 1) } {
867
+ temp := div(temp, 10)
868
+ }
869
+ let digits_space := $ClosestGreaterPowerOfTwo(num_digits)
870
+ s := $Malloc(add(${VECTOR_METADATA_SIZE}, digits_space))
871
+ $MemoryStoreU64(s, num_digits)
872
+ $MemoryStoreU64(add(s, 8), digits_space)
873
+ let digit
874
+ for { } x { } {
875
+ digit := add(48, mod(x, 10))
876
+ num_digits := sub(num_digits, 1)
877
+ $MemoryStoreU8(add(add(s, ${VECTOR_METADATA_SIZE}), num_digits), digit)
878
+ x := div(x, 10)
879
+ }
880
+ }" dep Malloc dep MemoryStoreU64 dep MemoryStoreU8 dep ClosestGreaterPowerOfTwo ,
881
+ ExtendVector : "(v1, v2, elem_size) -> new_v1 {
882
+ let v1_len := $MemoryLoadU64(v1)
883
+ let v2_len := $MemoryLoadU64(v2)
884
+ let new_len := add(v1_len, v2_len)
885
+ let v1_cap := $MemoryLoadU64(add(v1, 8))
886
+ new_v1 := v1
887
+ if iszero(gt(v1_cap, new_len)){
888
+ let new_cap := $ClosestGreaterPowerOfTwo(new_len)
889
+ new_v1 := $Malloc(add(mul(new_cap, elem_size), ${VECTOR_METADATA_SIZE}))
890
+ $CopyMemory(v1, new_v1, add(mul(v1_len, elem_size), ${VECTOR_METADATA_SIZE}))
891
+ $MemoryStoreU64(add(new_v1, 8), new_cap)
892
+ $Free(v1, add(mul(v1_len, elem_size), ${VECTOR_METADATA_SIZE}))
893
+ }
894
+ let src := add(v2, ${VECTOR_METADATA_SIZE})
895
+ let dst := add(add(new_v1, ${VECTOR_METADATA_SIZE}), mul(elem_size, v1_len))
896
+ $CopyMemory(src, dst, mul(v2_len, elem_size))
897
+ $MemoryStoreU64(new_v1, new_len)
898
+ }" dep Malloc dep MemoryLoadU64 dep MemoryStoreU64 dep ClosestGreaterPowerOfTwo dep CopyMemory dep Free ,
854
899
}
0 commit comments