Skip to content

Commit a164e5c

Browse files
emmazzzbors-diem
authored andcommitted
implement some string operations (#39)
Signed-off-by: sahithiacn <sahithi.kalakonda@accenture.com> Closes: #290
1 parent 7065550 commit a164e5c

File tree

15 files changed

+1203
-265
lines changed

15 files changed

+1203
-265
lines changed

language/evm/move-to-yul/src/functions.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -664,22 +664,21 @@ impl<'a> FunctionGenerator<'a> {
664664
if !val_str.is_empty() {
665665
emitln!(ctx.writer, "{} := {}", dest, val_str);
666666
} else if let Constant::ByteArray(value) = cons {
667-
let str_literal_size = value.len() + 32;
667+
let compute_capacity_str = self.parent.call_builtin_str(
668+
ctx,
669+
YulFunction::ClosestGreaterPowerOfTwo,
670+
std::iter::once(value.len().to_string()),
671+
);
668672
let malloc_str = self.parent.call_builtin_str(
669673
ctx,
670674
YulFunction::Malloc,
671-
std::iter::once(str_literal_size.clone().to_string()),
675+
std::iter::once(format!("add(32, {})", compute_capacity_str)),
672676
);
673677
let store_length_str = self.parent.call_builtin_str(
674678
ctx,
675679
YulFunction::MemoryStoreU64,
676680
vec![dest.clone(), value.len().clone().to_string()].into_iter(),
677681
);
678-
let compute_capacity_str = self.parent.call_builtin_str(
679-
ctx,
680-
YulFunction::ClosestGreaterPowerOfTwo,
681-
std::iter::once(str_literal_size.to_string()),
682-
);
683682
let store_capacity_str = self.parent.call_builtin_str(
684683
ctx,
685684
YulFunction::MemoryStoreU64,

language/evm/move-to-yul/src/native_functions.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,36 @@ impl NativeFunctions {
373373
}"
374374
);
375375
});
376+
377+
self.define(ctx, evm, "to_string", |gen, ctx: &Context, _| {
378+
emitln!(
379+
ctx.writer,
380+
"\
381+
(x) -> result {{
382+
result := {}
383+
}}",
384+
gen.parent.call_builtin_str(
385+
ctx,
386+
YulFunction::NumToString,
387+
std::iter::once("x".to_string())
388+
),
389+
);
390+
});
391+
392+
self.define(ctx, evm, "concat", |gen, ctx: &Context, _| {
393+
emitln!(
394+
ctx.writer,
395+
"\
396+
(s1, s2) -> result {{
397+
result := {}
398+
}}",
399+
gen.parent.call_builtin_str(
400+
ctx,
401+
YulFunction::ExtendVector,
402+
vec!["s1".to_string(), "s2".to_string(), 1.to_string()].into_iter()
403+
),
404+
);
405+
});
376406
}
377407

378408
fn define_move_functions(&mut self, ctx: &Context) {

language/evm/move-to-yul/src/yul_functions.rs

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -591,15 +591,17 @@ AlignedStorageStore: "(offs, val) {
591591
// TODO: this function needs more testing
592592
// Copies size bytes from memory to memory.
593593
CopyMemory: "(src, dst, size) {
594+
let num_words, overflow_bytes := $ToWordOffs(size)
594595
let i := 0
595-
for { } lt(i, size) { i := add(i, 32) } {
596+
for { } lt(i, mul(num_words, 32)) { i := add(i, 32) } {
596597
mstore(add(dst, i), mload(add(src, i)))
597598
}
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))
603605
}
604606
}",
605607

@@ -739,7 +741,7 @@ EqVector: "(x, y, elem_size) -> r {
739741
let data_size_bytes := mul(elem_size, len_x)
740742
let num_words, overflow_bytes := $ToWordOffs(data_size_bytes)
741743
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) } {
743745
if $Neq(mload(add(x, add(i, 32))), mload(add(y, add(i, 32)))) {
744746
r := false
745747
leave
@@ -850,5 +852,48 @@ TryDecodeErrMsg: "() -> data {
850852
$MemoryStoreU64(data, length)
851853
$MemoryStoreU64(add(data, 8), length)
852854
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,
854899
}

0 commit comments

Comments
 (0)