Skip to content

Commit

Permalink
Success adding support to uint32 type for soroban language.
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmadsamehh committed Jan 14, 2025
1 parent 2536c08 commit c1bd908
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 42 deletions.
Binary file added .DS_Store
Binary file not shown.
1 change: 1 addition & 0 deletions incrementer.abi
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"type":"constructor","inputs":[{"name":"initvalue","type":"uint32","internalType":"uint32"}],"stateMutability":"nonpayable"},{"name":"inc","type":"function","inputs":[{"name":"by","type":"uint32","internalType":"uint32"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"add","type":"function","inputs":[{"name":"a","type":"uint32","internalType":"uint32"},{"name":"b","type":"uint32","internalType":"uint32"}],"outputs":[{"name":"","type":"uint32","internalType":"uint32"}],"stateMutability":"view"},{"name":"get","type":"function","inputs":[],"outputs":[{"name":"","type":"uint32","internalType":"uint32"}],"stateMutability":"view"}]
Binary file added incrementer.wasm
Binary file not shown.
1 change: 1 addition & 0 deletions integration/anchor/target/.rustc_info.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"rustc_fingerprint":13881514899064403785,"outputs":{"15729799797837862367":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.dylib\nlib___.dylib\nlib___.a\nlib___.dylib\n/Users/ahmadsameh/.rustup/toolchains/stable-x86_64-apple-darwin\noff\npacked\nunpacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"\"\ntarget_family=\"unix\"\ntarget_feature=\"cmpxchg16b\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_feature=\"sse3\"\ntarget_feature=\"sse4.1\"\ntarget_feature=\"ssse3\"\ntarget_has_atomic=\"128\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"macos\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"apple\"\nunix\n","stderr":""},"4614504638168534921":{"success":true,"status":"","code":0,"stdout":"rustc 1.83.0 (90b35a623 2024-11-26)\nbinary: rustc\ncommit-hash: 90b35a6239c3d8bdabc530a6a0816f7ff89a0aaf\ncommit-date: 2024-11-26\nhost: x86_64-apple-darwin\nrelease: 1.83.0\nLLVM version: 19.1.1\n","stderr":""}},"successes":{}}
Binary file added src/codegen/.DS_Store
Binary file not shown.
144 changes: 105 additions & 39 deletions src/codegen/dispatch/soroban.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// SPDX-License-Identifier: Apache-2.0

use anchor_syn::Ty;
use num_bigint::BigInt;
use solang_parser::pt::{self};

use crate::sema::ast;
use crate::sema::ast::{self, Function};
use crate::{
codegen::{
cfg::{ASTFunction, ControlFlowGraph, Instr, InternalCallTy},
Expand Down Expand Up @@ -54,6 +55,7 @@ pub fn function_dispatch(

wrapper_cfg.returns = vec![return_type].into();
wrapper_cfg.public = true;
wrapper_cfg.function_no = cfg.function_no.clone();

let mut vartab = Vartable::from_symbol_table(&function.symtable, ns.next_id);

Expand All @@ -80,41 +82,88 @@ pub fn function_dispatch(
res: call_returns,
call: InternalCallTy::Static { cfg_no },
return_tys,
args: function
.params
.iter()
.enumerate()
.map(|(i, p)| Expression::ShiftRight {
loc: pt::Loc::Codegen,
ty: Type::Uint(64),
left: Expression::FunctionArg {
loc: p.loc,
ty: p.ty.clone(),
arg_no: i,
}
.into(),
right: Expression::NumberLiteral {
loc: pt::Loc::Codegen,
ty: Type::Uint(64),
value: BigInt::from(8_u64),
}
.into(),

signed: false,
})
.collect(),
args: decode_args(function, ns),
};

wrapper_cfg.add(&mut vartab, placeholder);

// TODO: support multiple returns
if value.len() == 1 {
// set the msb 8 bits of the return value to 6, the return value is 64 bits.
// FIXME: this assumes that the solidity function always returns one value.
let added = encode_return(function, value[0].clone());
wrapper_cfg.add(&mut vartab, Instr::Return { value: vec![added] });
} else {
// Return 2 as numberliteral. 2 is the soroban Void type encoded.
let two = Expression::NumberLiteral {
loc: pt::Loc::Codegen,
ty: Type::Uint(64),
value: BigInt::from(2_u64),
};

wrapper_cfg.add(&mut vartab, Instr::Return { value: vec![two] });
}

vartab.finalize(ns, &mut wrapper_cfg);
cfg.public = false;
wrapper_cfgs.push(wrapper_cfg);
}

wrapper_cfgs
}

fn decode_args(function: &Function, ns: &Namespace) -> Vec<Expression> {
let mut args = Vec::new();

for (i, arg) in function.params.iter().enumerate() {
println!("ARGUMENTS {:?}", arg);

let arg = match arg.ty {
Type::Uint(64) | Type::Uint(32) => Expression::ShiftRight {
loc: arg.loc,
ty: Type::Uint(64),
left: Box::new(Expression::FunctionArg {
loc: arg.loc,
ty: arg.ty.clone(),
arg_no: i,
}),
right: Box::new(Expression::NumberLiteral {
loc: arg.loc,
ty: Type::Uint(64),
value: BigInt::from(8_u64),
}),
signed: false,
},
Type::Address(_) => Expression::FunctionArg {
loc: arg.loc,
ty: arg.ty.clone(),
arg_no: i,
}
.cast(&Type::Address(false), ns),

// FIXME: Should properly decode the value instead of just passing it
Type::Uint(128) | Type::Int(128) => Expression::FunctionArg {
loc: arg.loc,
ty: arg.ty.clone(),
arg_no: i,
},

_ => unimplemented!(),
};

args.push(arg);
}

args
}

// TODO: Implement for UINT32
fn encode_return(function: &Function, value: Expression) -> Expression {
let returned = function.returns[0].clone();
match returned.ty {
Type::Uint(64) => {
let shifted = Expression::ShiftLeft {
loc: pt::Loc::Codegen,
ty: Type::Uint(64),
left: value[0].clone().into(),
left: value.clone().into(),
right: Expression::NumberLiteral {
loc: pt::Loc::Codegen,
ty: Type::Uint(64),
Expand All @@ -137,22 +186,39 @@ pub fn function_dispatch(
right: tag.into(),
};

wrapper_cfg.add(&mut vartab, Instr::Return { value: vec![added] });
} else {
// Return 2 as numberliteral. 2 is the soroban Void type encoded.
let two = Expression::NumberLiteral {
added
}

// TODO: support UINT32 here
Type::Uint(32) => {
let shifted = Expression::ShiftLeft {
loc: pt::Loc::Codegen,
ty: Type::Uint(64),
value: BigInt::from(2_u64),
left: value.clone().into(),
right: Expression::NumberLiteral {
loc: pt::Loc::Codegen,
ty: Type::Uint(64),
value: BigInt::from(8_u64),
}
.into(),
};

wrapper_cfg.add(&mut vartab, Instr::Return { value: vec![two] });
}
let tag = Expression::NumberLiteral {
loc: pt::Loc::Codegen,
ty: Type::Uint(64),
value: BigInt::from(4_u64),
};

vartab.finalize(ns, &mut wrapper_cfg);
cfg.public = false;
wrapper_cfgs.push(wrapper_cfg);
}
let added = Expression::Add {
loc: pt::Loc::Codegen,
ty: Type::Uint(64),
overflowing: true,
left: shifted.into(),
right: tag.into(),
};

wrapper_cfgs
added
}
_ => unimplemented!(),
}
}
9 changes: 8 additions & 1 deletion src/emit/binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use std::cell::RefCell;
use std::path::Path;
use std::str;

use libc::uint32_t;
use num_bigint::BigInt;
use num_traits::ToPrimitive;
use std::collections::HashMap;
Expand Down Expand Up @@ -930,8 +931,14 @@ impl<'a> Binary<'a> {
match ty {
Type::Bool => BasicTypeEnum::IntType(self.context.bool_type()),
Type::Int(n) | Type::Uint(n) => {
BasicTypeEnum::IntType(self.context.custom_width_int_type(*n as u32))
if ns.target == Target::Soroban {
//ahmads edit testing if this work....
BasicTypeEnum::IntType(self.context.i64_type())
} else {
BasicTypeEnum::IntType(self.context.custom_width_int_type(*n as u32))
}
}

Type::Value => BasicTypeEnum::IntType(
self.context
.custom_width_int_type(ns.value_length as u32 * 8),
Expand Down
8 changes: 6 additions & 2 deletions src/emit/soroban/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,12 @@ impl SorobanTarget {
.unwrap_or_else(|| i.to_string())
.try_into()
.expect("function input name exceeds limit"),
type_: ScSpecTypeDef::U64, // TODO: Map type.
doc: StringM::default(), // TODO: Add doc.
type_: match p.ty {
ast::Type::Uint(64) => ScSpecTypeDef::U64,
ast::Type::Uint(32) => ScSpecTypeDef::U32,
_ => panic!("unsupported input type"),
}, // TODO: Map type.
doc: StringM::default(), // TODO: Add doc.
})
.collect::<Vec<_>>()
.try_into()
Expand Down

0 comments on commit c1bd908

Please sign in to comment.