Skip to content

Commit 323c289

Browse files
committed
Success adding support to uint32 type for soroban language.
Signed-off-by: Ahmad Sameh <[email protected]>
1 parent 2536c08 commit 323c289

File tree

8 files changed

+121
-42
lines changed

8 files changed

+121
-42
lines changed

.DS_Store

8 KB
Binary file not shown.

incrementer.abi

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
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"}]

incrementer.wasm

1.01 KB
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
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":{}}

src/codegen/.DS_Store

6 KB
Binary file not shown.

src/codegen/dispatch/soroban.rs

+105-39
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
// SPDX-License-Identifier: Apache-2.0
22

3+
use anchor_syn::Ty;
34
use num_bigint::BigInt;
45
use solang_parser::pt::{self};
56

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

5556
wrapper_cfg.returns = vec![return_type].into();
5657
wrapper_cfg.public = true;
58+
wrapper_cfg.function_no = cfg.function_no.clone();
5759

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

@@ -80,41 +82,88 @@ pub fn function_dispatch(
8082
res: call_returns,
8183
call: InternalCallTy::Static { cfg_no },
8284
return_tys,
83-
args: function
84-
.params
85-
.iter()
86-
.enumerate()
87-
.map(|(i, p)| Expression::ShiftRight {
88-
loc: pt::Loc::Codegen,
89-
ty: Type::Uint(64),
90-
left: Expression::FunctionArg {
91-
loc: p.loc,
92-
ty: p.ty.clone(),
93-
arg_no: i,
94-
}
95-
.into(),
96-
right: Expression::NumberLiteral {
97-
loc: pt::Loc::Codegen,
98-
ty: Type::Uint(64),
99-
value: BigInt::from(8_u64),
100-
}
101-
.into(),
102-
103-
signed: false,
104-
})
105-
.collect(),
85+
args: decode_args(function, ns),
10686
};
10787

10888
wrapper_cfg.add(&mut vartab, placeholder);
10989

11090
// TODO: support multiple returns
11191
if value.len() == 1 {
112-
// set the msb 8 bits of the return value to 6, the return value is 64 bits.
113-
// FIXME: this assumes that the solidity function always returns one value.
92+
let added = encode_return(function, value[0].clone());
93+
wrapper_cfg.add(&mut vartab, Instr::Return { value: vec![added] });
94+
} else {
95+
// Return 2 as numberliteral. 2 is the soroban Void type encoded.
96+
let two = Expression::NumberLiteral {
97+
loc: pt::Loc::Codegen,
98+
ty: Type::Uint(64),
99+
value: BigInt::from(2_u64),
100+
};
101+
102+
wrapper_cfg.add(&mut vartab, Instr::Return { value: vec![two] });
103+
}
104+
105+
vartab.finalize(ns, &mut wrapper_cfg);
106+
cfg.public = false;
107+
wrapper_cfgs.push(wrapper_cfg);
108+
}
109+
110+
wrapper_cfgs
111+
}
112+
113+
fn decode_args(function: &Function, ns: &Namespace) -> Vec<Expression> {
114+
let mut args = Vec::new();
115+
116+
for (i, arg) in function.params.iter().enumerate() {
117+
println!("ARGUMENTS {:?}", arg);
118+
119+
let arg = match arg.ty {
120+
Type::Uint(64) | Type::Uint(32) => Expression::ShiftRight {
121+
loc: arg.loc,
122+
ty: Type::Uint(64),
123+
left: Box::new(Expression::FunctionArg {
124+
loc: arg.loc,
125+
ty: arg.ty.clone(),
126+
arg_no: i,
127+
}),
128+
right: Box::new(Expression::NumberLiteral {
129+
loc: arg.loc,
130+
ty: Type::Uint(64),
131+
value: BigInt::from(8_u64),
132+
}),
133+
signed: false,
134+
},
135+
Type::Address(_) => Expression::FunctionArg {
136+
loc: arg.loc,
137+
ty: arg.ty.clone(),
138+
arg_no: i,
139+
}
140+
.cast(&Type::Address(false), ns),
141+
142+
// FIXME: Should properly decode the value instead of just passing it
143+
Type::Uint(128) | Type::Int(128) => Expression::FunctionArg {
144+
loc: arg.loc,
145+
ty: arg.ty.clone(),
146+
arg_no: i,
147+
},
148+
149+
_ => unimplemented!(),
150+
};
151+
152+
args.push(arg);
153+
}
154+
155+
args
156+
}
157+
158+
// TODO: Implement for UINT32
159+
fn encode_return(function: &Function, value: Expression) -> Expression {
160+
let returned = function.returns[0].clone();
161+
match returned.ty {
162+
Type::Uint(64) => {
114163
let shifted = Expression::ShiftLeft {
115164
loc: pt::Loc::Codegen,
116165
ty: Type::Uint(64),
117-
left: value[0].clone().into(),
166+
left: value.clone().into(),
118167
right: Expression::NumberLiteral {
119168
loc: pt::Loc::Codegen,
120169
ty: Type::Uint(64),
@@ -137,22 +186,39 @@ pub fn function_dispatch(
137186
right: tag.into(),
138187
};
139188

140-
wrapper_cfg.add(&mut vartab, Instr::Return { value: vec![added] });
141-
} else {
142-
// Return 2 as numberliteral. 2 is the soroban Void type encoded.
143-
let two = Expression::NumberLiteral {
189+
added
190+
}
191+
192+
// TODO: support UINT32 here
193+
Type::Uint(32) => {
194+
let shifted = Expression::ShiftLeft {
144195
loc: pt::Loc::Codegen,
145196
ty: Type::Uint(64),
146-
value: BigInt::from(2_u64),
197+
left: value.clone().into(),
198+
right: Expression::NumberLiteral {
199+
loc: pt::Loc::Codegen,
200+
ty: Type::Uint(64),
201+
value: BigInt::from(8_u64),
202+
}
203+
.into(),
147204
};
148205

149-
wrapper_cfg.add(&mut vartab, Instr::Return { value: vec![two] });
150-
}
206+
let tag = Expression::NumberLiteral {
207+
loc: pt::Loc::Codegen,
208+
ty: Type::Uint(64),
209+
value: BigInt::from(4_u64),
210+
};
151211

152-
vartab.finalize(ns, &mut wrapper_cfg);
153-
cfg.public = false;
154-
wrapper_cfgs.push(wrapper_cfg);
155-
}
212+
let added = Expression::Add {
213+
loc: pt::Loc::Codegen,
214+
ty: Type::Uint(64),
215+
overflowing: true,
216+
left: shifted.into(),
217+
right: tag.into(),
218+
};
156219

157-
wrapper_cfgs
220+
added
221+
}
222+
_ => unimplemented!(),
223+
}
158224
}

src/emit/binary.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use std::cell::RefCell;
88
use std::path::Path;
99
use std::str;
1010

11+
use libc::uint32_t;
1112
use num_bigint::BigInt;
1213
use num_traits::ToPrimitive;
1314
use std::collections::HashMap;
@@ -930,8 +931,14 @@ impl<'a> Binary<'a> {
930931
match ty {
931932
Type::Bool => BasicTypeEnum::IntType(self.context.bool_type()),
932933
Type::Int(n) | Type::Uint(n) => {
933-
BasicTypeEnum::IntType(self.context.custom_width_int_type(*n as u32))
934+
if ns.target == Target::Soroban {
935+
//ahmads edit testing if this work....
936+
BasicTypeEnum::IntType(self.context.i64_type())
937+
} else {
938+
BasicTypeEnum::IntType(self.context.custom_width_int_type(*n as u32))
939+
}
934940
}
941+
935942
Type::Value => BasicTypeEnum::IntType(
936943
self.context
937944
.custom_width_int_type(ns.value_length as u32 * 8),

src/emit/soroban/mod.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,12 @@ impl SorobanTarget {
174174
.unwrap_or_else(|| i.to_string())
175175
.try_into()
176176
.expect("function input name exceeds limit"),
177-
type_: ScSpecTypeDef::U64, // TODO: Map type.
178-
doc: StringM::default(), // TODO: Add doc.
177+
type_: match p.ty {
178+
ast::Type::Uint(64) => ScSpecTypeDef::U64,
179+
ast::Type::Uint(32) => ScSpecTypeDef::U32,
180+
_ => panic!("unsupported input type"),
181+
}, // TODO: Map type.
182+
doc: StringM::default(), // TODO: Add doc.
179183
})
180184
.collect::<Vec<_>>()
181185
.try_into()

0 commit comments

Comments
 (0)