From 953c63cb2af13ee13984c4e6a134528a73df1b68 Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Sat, 12 Aug 2023 14:54:06 +0100 Subject: [PATCH 1/9] str as_bytes --- .../tests/execution_success/str_as_bytes/Nargo.toml | 7 +++++++ .../tests/execution_success/str_as_bytes/src/main.nr | 7 +++++++ crates/noirc_evaluator/src/ssa/ir/instruction.rs | 3 +++ crates/noirc_evaluator/src/ssa/ir/instruction/call.rs | 9 +++++++++ noir_stdlib/Nargo.toml | 1 + noir_stdlib/src/lib.nr | 1 + noir_stdlib/src/string.nr | 4 ++++ 7 files changed, 32 insertions(+) create mode 100644 crates/nargo_cli/tests/execution_success/str_as_bytes/Nargo.toml create mode 100644 crates/nargo_cli/tests/execution_success/str_as_bytes/src/main.nr create mode 100644 noir_stdlib/src/string.nr diff --git a/crates/nargo_cli/tests/execution_success/str_as_bytes/Nargo.toml b/crates/nargo_cli/tests/execution_success/str_as_bytes/Nargo.toml new file mode 100644 index 00000000000..31f7ab5d9b4 --- /dev/null +++ b/crates/nargo_cli/tests/execution_success/str_as_bytes/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "str_as_bytes" +type = "bin" +authors = [""] +compiler_version = "0.9.0" + +[dependencies] \ No newline at end of file diff --git a/crates/nargo_cli/tests/execution_success/str_as_bytes/src/main.nr b/crates/nargo_cli/tests/execution_success/str_as_bytes/src/main.nr new file mode 100644 index 00000000000..45cae8d1e48 --- /dev/null +++ b/crates/nargo_cli/tests/execution_success/str_as_bytes/src/main.nr @@ -0,0 +1,7 @@ +use dep::std; +fn main() { + let a: str<2> = "ab"; + let b = a.as_bytes(); + assert(b[0]==97); + assert(b[1]==98); +} diff --git a/crates/noirc_evaluator/src/ssa/ir/instruction.rs b/crates/noirc_evaluator/src/ssa/ir/instruction.rs index 31521def27f..e09e21f158f 100644 --- a/crates/noirc_evaluator/src/ssa/ir/instruction.rs +++ b/crates/noirc_evaluator/src/ssa/ir/instruction.rs @@ -41,6 +41,7 @@ pub(crate) enum Intrinsic { SlicePopFront, SliceInsert, SliceRemove, + StrAsBytes, Println, ToBits(Endian), ToRadix(Endian), @@ -60,6 +61,7 @@ impl std::fmt::Display for Intrinsic { Intrinsic::SlicePopFront => write!(f, "slice_pop_front"), Intrinsic::SliceInsert => write!(f, "slice_insert"), Intrinsic::SliceRemove => write!(f, "slice_remove"), + Intrinsic::StrAsBytes => write!(f, "str_as_bytes"), Intrinsic::ToBits(Endian::Big) => write!(f, "to_be_bits"), Intrinsic::ToBits(Endian::Little) => write!(f, "to_le_bits"), Intrinsic::ToRadix(Endian::Big) => write!(f, "to_be_radix"), @@ -84,6 +86,7 @@ impl Intrinsic { "slice_pop_front" => Some(Intrinsic::SlicePopFront), "slice_insert" => Some(Intrinsic::SliceInsert), "slice_remove" => Some(Intrinsic::SliceRemove), + "str_as_bytes" => Some(Intrinsic::StrAsBytes), "to_le_radix" => Some(Intrinsic::ToRadix(Endian::Little)), "to_be_radix" => Some(Intrinsic::ToRadix(Endian::Big)), "to_le_bits" => Some(Intrinsic::ToBits(Endian::Little)), diff --git a/crates/noirc_evaluator/src/ssa/ir/instruction/call.rs b/crates/noirc_evaluator/src/ssa/ir/instruction/call.rs index 648bffd093a..ddf9b9984e3 100644 --- a/crates/noirc_evaluator/src/ssa/ir/instruction/call.rs +++ b/crates/noirc_evaluator/src/ssa/ir/instruction/call.rs @@ -165,6 +165,15 @@ pub(super) fn simplify_call( SimplifyResult::None } } + Intrinsic::StrAsBytes => { + let str = dfg.get_array_constant(arguments[0]); + if let Some((str, typ)) = str { + let result = dfg.make_array(str, typ); + SimplifyResult::SimplifiedTo(result) + } else { + SimplifyResult::None + } + } Intrinsic::AssertConstant => { if arguments.iter().all(|argument| dfg.is_constant(*argument)) { SimplifyResult::Remove diff --git a/noir_stdlib/Nargo.toml b/noir_stdlib/Nargo.toml index 29392dcc38a..9b7a79ad2a6 100644 --- a/noir_stdlib/Nargo.toml +++ b/noir_stdlib/Nargo.toml @@ -1,5 +1,6 @@ [package] name = "std" +type = "lib" authors = [""] compiler_version = "0.1" diff --git a/noir_stdlib/src/lib.nr b/noir_stdlib/src/lib.nr index d552ca44a29..f033334c140 100644 --- a/noir_stdlib/src/lib.nr +++ b/noir_stdlib/src/lib.nr @@ -15,6 +15,7 @@ mod unsafe; mod collections; mod compat; mod option; +mod string; // Oracle calls are required to be wrapped in an unconstrained function // Thus, the only argument to the `println` oracle is expected to always be an ident diff --git a/noir_stdlib/src/string.nr b/noir_stdlib/src/string.nr new file mode 100644 index 00000000000..6dd5c5a28af --- /dev/null +++ b/noir_stdlib/src/string.nr @@ -0,0 +1,4 @@ +impl str { + #[builtin(str_as_bytes)] + fn as_bytes(_self: Self) -> [u8] { } +} \ No newline at end of file From fc78f75b695b313addfc5e7966d1843f704f3c75 Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Sat, 12 Aug 2023 14:57:03 +0100 Subject: [PATCH 2/9] . --- noir_stdlib/src/string.nr | 1 + 1 file changed, 1 insertion(+) diff --git a/noir_stdlib/src/string.nr b/noir_stdlib/src/string.nr index 6dd5c5a28af..82517876586 100644 --- a/noir_stdlib/src/string.nr +++ b/noir_stdlib/src/string.nr @@ -1,4 +1,5 @@ impl str { + /// return a byte slice of string #[builtin(str_as_bytes)] fn as_bytes(_self: Self) -> [u8] { } } \ No newline at end of file From 390da8c616a4618587a56f45715ead82b8801fc5 Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Sat, 12 Aug 2023 15:02:16 +0100 Subject: [PATCH 3/9] . --- .../tests/execution_success/str_as_bytes/src/main.nr | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/crates/nargo_cli/tests/execution_success/str_as_bytes/src/main.nr b/crates/nargo_cli/tests/execution_success/str_as_bytes/src/main.nr index 45cae8d1e48..4b32edbcb91 100644 --- a/crates/nargo_cli/tests/execution_success/str_as_bytes/src/main.nr +++ b/crates/nargo_cli/tests/execution_success/str_as_bytes/src/main.nr @@ -1,7 +1,10 @@ use dep::std; fn main() { - let a: str<2> = "ab"; + let a = "hello"; let b = a.as_bytes(); - assert(b[0]==97); - assert(b[1]==98); + assert(b[0]==104); + assert(b[1]==101); + assert(b[2]==108); + assert(b[3]==108); + assert(b[4]==111); } From f1943370cefd72432f4ac0771a44f3160cefb4ca Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Sat, 12 Aug 2023 15:25:06 +0100 Subject: [PATCH 4/9] . --- .../tests/execution_success/str_as_bytes/src/main.nr | 6 ++++++ noir_stdlib/src/string.nr | 8 +++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/crates/nargo_cli/tests/execution_success/str_as_bytes/src/main.nr b/crates/nargo_cli/tests/execution_success/str_as_bytes/src/main.nr index 4b32edbcb91..c0b47072858 100644 --- a/crates/nargo_cli/tests/execution_success/str_as_bytes/src/main.nr +++ b/crates/nargo_cli/tests/execution_success/str_as_bytes/src/main.nr @@ -7,4 +7,10 @@ fn main() { assert(b[2]==108); assert(b[3]==108); assert(b[4]==111); + let mut c = a.into_bytes(); + assert(c.get(0)==104); + assert(c.get(1)==101); + assert(c.get(2)==108); + assert(c.get(3)==108); + assert(c.get(4)==111); } diff --git a/noir_stdlib/src/string.nr b/noir_stdlib/src/string.nr index 82517876586..4fac284b287 100644 --- a/noir_stdlib/src/string.nr +++ b/noir_stdlib/src/string.nr @@ -1,5 +1,11 @@ +use crate::collections::vec::Vec; impl str { - /// return a byte slice of string + /// return a byte slice of the str content #[builtin(str_as_bytes)] fn as_bytes(_self: Self) -> [u8] { } + + /// return a byte vector of the str content + fn into_bytes(self: Self) -> Vec { + Vec::from_slice(self.as_bytes()) + } } \ No newline at end of file From 50f430cfefbf33ad97107f109dac1b39a80b5839 Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Mon, 14 Aug 2023 20:50:44 +0100 Subject: [PATCH 5/9] . --- .../nargo_cli/tests/execution_success/str_as_bytes/src/main.nr | 2 +- noir_stdlib/src/string.nr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/nargo_cli/tests/execution_success/str_as_bytes/src/main.nr b/crates/nargo_cli/tests/execution_success/str_as_bytes/src/main.nr index c0b47072858..7f3026db694 100644 --- a/crates/nargo_cli/tests/execution_success/str_as_bytes/src/main.nr +++ b/crates/nargo_cli/tests/execution_success/str_as_bytes/src/main.nr @@ -7,7 +7,7 @@ fn main() { assert(b[2]==108); assert(b[3]==108); assert(b[4]==111); - let mut c = a.into_bytes(); + let mut c = a.as_bytes_vec(); assert(c.get(0)==104); assert(c.get(1)==101); assert(c.get(2)==108); diff --git a/noir_stdlib/src/string.nr b/noir_stdlib/src/string.nr index 4fac284b287..875e5078559 100644 --- a/noir_stdlib/src/string.nr +++ b/noir_stdlib/src/string.nr @@ -5,7 +5,7 @@ impl str { fn as_bytes(_self: Self) -> [u8] { } /// return a byte vector of the str content - fn into_bytes(self: Self) -> Vec { + fn as_bytes_vec(self: Self) -> Vec { Vec::from_slice(self.as_bytes()) } } \ No newline at end of file From e95cc81b580ab4fb7d9ea03afa6815d1b8978441 Mon Sep 17 00:00:00 2001 From: ethan-000 Date: Mon, 14 Aug 2023 20:54:41 +0100 Subject: [PATCH 6/9] . --- .../nargo_cli/tests/execution_success/str_as_bytes/src/main.nr | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/nargo_cli/tests/execution_success/str_as_bytes/src/main.nr b/crates/nargo_cli/tests/execution_success/str_as_bytes/src/main.nr index 7f3026db694..6890b156b15 100644 --- a/crates/nargo_cli/tests/execution_success/str_as_bytes/src/main.nr +++ b/crates/nargo_cli/tests/execution_success/str_as_bytes/src/main.nr @@ -7,10 +7,12 @@ fn main() { assert(b[2]==108); assert(b[3]==108); assert(b[4]==111); + assert(b.len()==5); let mut c = a.as_bytes_vec(); assert(c.get(0)==104); assert(c.get(1)==101); assert(c.get(2)==108); assert(c.get(3)==108); assert(c.get(4)==111); + assert(c.len()==5); } From 49e6623883238b668626482d742736a74d02cb32 Mon Sep 17 00:00:00 2001 From: Ethan-000 Date: Mon, 14 Aug 2023 20:55:40 +0100 Subject: [PATCH 7/9] Update crates/noirc_evaluator/src/ssa/ir/instruction/call.rs Co-authored-by: jfecher --- crates/noirc_evaluator/src/ssa/ir/instruction/call.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/crates/noirc_evaluator/src/ssa/ir/instruction/call.rs b/crates/noirc_evaluator/src/ssa/ir/instruction/call.rs index ddf9b9984e3..e73ff02ba08 100644 --- a/crates/noirc_evaluator/src/ssa/ir/instruction/call.rs +++ b/crates/noirc_evaluator/src/ssa/ir/instruction/call.rs @@ -166,13 +166,8 @@ pub(super) fn simplify_call( } } Intrinsic::StrAsBytes => { - let str = dfg.get_array_constant(arguments[0]); - if let Some((str, typ)) = str { - let result = dfg.make_array(str, typ); - SimplifyResult::SimplifiedTo(result) - } else { - SimplifyResult::None - } + // Strings are already represented as bytes internally + SimplifyResult::SimplifiedTo(arguments[0]) } Intrinsic::AssertConstant => { if arguments.iter().all(|argument| dfg.is_constant(*argument)) { From b4f87d151b5938cdadecee6646865256cec81d87 Mon Sep 17 00:00:00 2001 From: Ethan-000 Date: Tue, 15 Aug 2023 16:09:27 +0100 Subject: [PATCH 8/9] Update noir_stdlib/src/string.nr Co-authored-by: jfecher --- noir_stdlib/src/string.nr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/noir_stdlib/src/string.nr b/noir_stdlib/src/string.nr index 875e5078559..e41ae3cf854 100644 --- a/noir_stdlib/src/string.nr +++ b/noir_stdlib/src/string.nr @@ -1,8 +1,8 @@ use crate::collections::vec::Vec; impl str { - /// return a byte slice of the str content + /// Converts the given string into a byte array #[builtin(str_as_bytes)] - fn as_bytes(_self: Self) -> [u8] { } + fn as_bytes(_self: Self) -> [u8; N] { } /// return a byte vector of the str content fn as_bytes_vec(self: Self) -> Vec { From a0056f10477eca290b3481db1560e154c2a7a81b Mon Sep 17 00:00:00 2001 From: Ethan-000 Date: Tue, 15 Aug 2023 16:09:36 +0100 Subject: [PATCH 9/9] Update noir_stdlib/src/string.nr Co-authored-by: jfecher --- noir_stdlib/src/string.nr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noir_stdlib/src/string.nr b/noir_stdlib/src/string.nr index e41ae3cf854..e24bb567681 100644 --- a/noir_stdlib/src/string.nr +++ b/noir_stdlib/src/string.nr @@ -6,6 +6,6 @@ impl str { /// return a byte vector of the str content fn as_bytes_vec(self: Self) -> Vec { - Vec::from_slice(self.as_bytes()) + Vec::from_slice(self.as_bytes().as_slice()) } } \ No newline at end of file