Skip to content

Commit

Permalink
impl encode for arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
xunilrj committed Dec 13, 2023
1 parent 8b3c4bb commit 55a2da1
Show file tree
Hide file tree
Showing 6 changed files with 242 additions and 19 deletions.
165 changes: 165 additions & 0 deletions sway-lib-core/src/codec.sw
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ impl AbiEncode for b256 {
}
}

impl AbiEncode for bool {
fn abi_encode(self, ref mut buffer: Buffer) {
buffer.push(self);
}
}

impl AbiEncode for u256 {
fn abi_encode(self, ref mut buffer: Buffer) {
let (a, b, c, d): (u64, u64, u64, u64) = asm(r1: self) {r1: (u64, u64, u64, u64)};
Expand Down Expand Up @@ -141,6 +147,163 @@ impl AbiEncode for str {
}
}

// str arrays

impl AbiEncode for str[0] {
fn abi_encode(self, ref mut buffer: Buffer) {
}
}

impl AbiEncode for str[1] {
fn abi_encode(self, ref mut buffer: Buffer) {
use ::str::*;
let s = from_str_array(self);

let len = s.len();
let ptr = s.as_ptr();

let mut i = 0;
while i < len {
let byte = ptr.add::<u8>(i).read::<u8>();
buffer.push(byte);
i += 1;
}
}
}

impl AbiEncode for str[2] {
fn abi_encode(self, ref mut buffer: Buffer) {
use ::str::*;
let s = from_str_array(self);

let len = s.len();
let ptr = s.as_ptr();

let mut i = 0;
while i < len {
let byte = ptr.add::<u8>(i).read::<u8>();
buffer.push(byte);
i += 1;
}
}
}

impl AbiEncode for str[3] {
fn abi_encode(self, ref mut buffer: Buffer) {
use ::str::*;
let s = from_str_array(self);

let len = s.len();
let ptr = s.as_ptr();

let mut i = 0;
while i < len {
let byte = ptr.add::<u8>(i).read::<u8>();
buffer.push(byte);
i += 1;
}
}
}

impl AbiEncode for str[4] {
fn abi_encode(self, ref mut buffer: Buffer) {
use ::str::*;
let s = from_str_array(self);

let len = s.len();
let ptr = s.as_ptr();

let mut i = 0;
while i < len {
let byte = ptr.add::<u8>(i).read::<u8>();
buffer.push(byte);
i += 1;
}
}
}

impl AbiEncode for str[5] {
fn abi_encode(self, ref mut buffer: Buffer) {
use ::str::*;
let s = from_str_array(self);

let len = s.len();
let ptr = s.as_ptr();

let mut i = 0;
while i < len {
let byte = ptr.add::<u8>(i).read::<u8>();
buffer.push(byte);
i += 1;
}
}
}

// arrays

impl<T> AbiEncode for [T;0]
where
T: AbiEncode
{
fn abi_encode(self, ref mut buffer: Buffer) {
}
}

impl<T> AbiEncode for [T;1]
where
T: AbiEncode
{
fn abi_encode(self, ref mut buffer: Buffer) {
self[0].abi_encode(buffer);
}
}

impl<T> AbiEncode for [T;2]
where
T: AbiEncode
{
fn abi_encode(self, ref mut buffer: Buffer) {
self[0].abi_encode(buffer);
self[1].abi_encode(buffer);
}
}

impl<T> AbiEncode for [T;3]
where
T: AbiEncode
{
fn abi_encode(self, ref mut buffer: Buffer) {
self[0].abi_encode(buffer);
self[1].abi_encode(buffer);
self[2].abi_encode(buffer);
}
}

impl<T> AbiEncode for [T;4]
where
T: AbiEncode
{
fn abi_encode(self, ref mut buffer: Buffer) {
self[0].abi_encode(buffer);
self[1].abi_encode(buffer);
self[2].abi_encode(buffer);
self[3].abi_encode(buffer);
}
}

impl<T> AbiEncode for [T;5]
where
T: AbiEncode
{
fn abi_encode(self, ref mut buffer: Buffer) {
self[0].abi_encode(buffer);
self[1].abi_encode(buffer);
self[2].abi_encode(buffer);
self[3].abi_encode(buffer);
self[4].abi_encode(buffer);
}
}

pub fn encode<T>(item: T) -> raw_slice
where
T: AbiEncode
Expand All @@ -152,6 +315,8 @@ where

#[test]
fn ok_encode() {
encode(true);

encode(0u8);
encode(0u16);
encode(0u32);
Expand Down
30 changes: 11 additions & 19 deletions test/src/ir_generation/tests/logging.sw
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
script;

use core::codec::*;

struct TestStruct {
field_1: bool,
field_2: b256,
Expand All @@ -22,29 +24,19 @@ fn main() {
};

let test_enum = TestEnum::VariantTwo;
__log(k);
__log(42);
__log(42u32);
__log(42u16);
__log(42u8);
__log(a);
__log(b);
__log(test_struct);
__log(test_enum);
//__log(k);
//__log(42);
//__log(42u32);
//__log(42u16);
//__log(42u8);
//__log(a);
//__log(b);
//__log(test_struct);
//__log(test_enum);
}

// ::check-ir::

// check: script {
// check: fn main() -> ()
// check: entry():

// check: log b256 $VAL, $VAL
// check: log u64 $VAL, $VAL
// check: log u64 $VAL, $VAL
// check: log u64 $VAL, $VAL
// check: log u8 $VAL, $VAL
// check: log string<4> $VAL, $VAL
// check: log [u8; 3] $VAL, $VAL
// check: log { bool, b256, u64 } $VAL, $VAL
// check: log { u64 } $VAL, $VAL
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
contract;

use methods_abi::MethodsContract;
use core::codec::*;

fn bogus() -> Identity {
let sender = msg_sender();
Expand Down
11 changes: 11 additions & 0 deletions test/src/sdk-harness/test_projects/logging/src/main.sw
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
script;

use core::codec::*;

struct TestStruct {
field_1: bool,
field_2: b256,
Expand All @@ -11,6 +13,15 @@ enum TestEnum {
VariantTwo: (),
}

impl AbiEncode for TestEnum {
fn abi_encode(self, ref mut buffer: Buffer) {
match self {
TestEnum::VariantOne => {}
TestEnum::VariantTwo => {}
}
}
}

fn main() {
let k: b256 = 0xef86afa9696cf0dc6385e2c407a6e159a1103cefb7e2ae0636fb33d3cb2a9e4a;
let a: str[4] = __to_str_array("Fuel");
Expand Down
53 changes: 53 additions & 0 deletions test/src/sdk-harness/test_projects/parsing_logs/src/main.sw
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
contract;

use core::codec::*;

struct TestStruct {
field_1: bool,
field_2: b256,
Expand All @@ -11,26 +13,77 @@ enum TestEnum {
VariantTwo: (),
}

impl AbiEncode for TestEnum {
fn abi_encode(self, ref mut buffer: Buffer) {
match self {
TestEnum::VariantOne => {}
TestEnum::VariantTwo => {}
}
}
}

struct StructWithGeneric<D> {
field_1: D,
field_2: u64,
}

impl<D> AbiEncode for StructWithGeneric<D>
where
D: AbiEncode
{
fn abi_encode(self, ref mut buffer: Buffer) {
self.field_1.abi_encode(buffer);
self.field_2.abi_encode(buffer);
}
}

enum EnumWithGeneric<D> {
VariantOne: D,
VariantTwo: (),
}

impl<D> AbiEncode for EnumWithGeneric<D>
where
D: AbiEncode
{
fn abi_encode(self, ref mut buffer: Buffer) {
match self {
EnumWithGeneric::VariantOne(x) => x.abi_encode(buffer),
EnumWithGeneric::VariantTwo => {}
}
}
}

struct StructWithNestedGeneric<D> {
field_1: D,
field_2: u64,
}

impl<D> AbiEncode for StructWithNestedGeneric<D>
where
D: AbiEncode
{
fn abi_encode(self, ref mut buffer: Buffer) {
self.field_1.abi_encode(buffer);
self.field_2.abi_encode(buffer);
}
}

struct StructDeeplyNestedGeneric<D> {
field_1: D,
field_2: u64,
}

impl<D> AbiEncode for StructDeeplyNestedGeneric<D>
where
D: AbiEncode
{
fn abi_encode(self, ref mut buffer: Buffer) {
self.field_1.abi_encode(buffer);
self.field_2.abi_encode(buffer);
}
}

abi TestContract {
fn produce_logs_values() -> ();
fn produce_logs_variables() -> ();
Expand Down
1 change: 1 addition & 0 deletions test/src/sdk-harness/test_projects/script_data/src/main.sw
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
script;

use std::tx::tx_script_data;
use core::codec::*;

fn main() {
// Reference type
Expand Down

0 comments on commit 55a2da1

Please sign in to comment.