Skip to content

Commit 59f0a94

Browse files
fix lifetime constraints
Signed-off-by: salaheldinsoliman <salaheldin_sameh@aucegypt.edu>
1 parent acb296d commit 59f0a94

File tree

7 files changed

+295
-9
lines changed

7 files changed

+295
-9
lines changed

src/codegen/dispatch/soroban.rs

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ pub fn function_dispatch(
8181
res: call_returns,
8282
call: InternalCallTy::Static { cfg_no },
8383
return_tys,
84-
args: decode_args(function, ns),
84+
args: decode_args(function, ns, &mut vartab, &mut wrapper_cfg),
8585
};
8686

8787
wrapper_cfg.add(&mut vartab, placeholder);
@@ -116,6 +116,16 @@ pub fn function_dispatch(
116116
right: tag.into(),
117117
};
118118

119+
/*let ret = vartab.temp_anonymous(&Type::Uint(64));
120+
let ret_expr = Expression::Variable {
121+
loc: pt::Loc::Codegen,
122+
ty: Type::Uint(64),
123+
var_no: ret,
124+
};
125+
126+
let instr = Instr::Call { res: vec![ret], return_tys: vec![Type::Uint(64)], call: InternalCallTy::HostFunction { name: "i._".to_owned() }, args: vec![value[0].clone()] };
127+
wrapper_cfg.add(&mut vartab, instr);*/
128+
119129
wrapper_cfg.add(&mut vartab, Instr::Return { value: vec![added] });
120130
} else {
121131
// Return 2 as numberliteral. 2 is the soroban Void type encoded.
@@ -136,14 +146,33 @@ pub fn function_dispatch(
136146
wrapper_cfgs
137147
}
138148

139-
fn decode_args(function: &Function, ns: &Namespace) -> Vec<Expression> {
149+
fn decode_args(function: &Function, ns: &Namespace, vartab: &mut Vartable, cfg: &mut ControlFlowGraph) -> Vec<Expression> {
140150
let mut args = Vec::new();
141151

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

145155
let arg = match arg.ty {
146-
Type::Uint(64) => Expression::ShiftRight {
156+
Type::Uint(64) => {
157+
/* let ret = vartab.temp_anonymous(&Type::Uint(64));
158+
let ret_expr = Expression::Variable {
159+
loc: pt::Loc::Codegen,
160+
ty: Type::Uint(64),
161+
var_no: ret,
162+
};
163+
164+
let instr = Instr::Call { res: vec![ret], return_tys: vec![Type::Uint(64)], call: InternalCallTy::HostFunction { name: "i.0".to_owned() }, args: vec![Expression::FunctionArg {
165+
loc: arg.loc,
166+
ty: arg.ty.clone(),
167+
arg_no: i,
168+
}] };
169+
cfg.add(vartab, instr);
170+
171+
172+
ret_expr*/
173+
174+
175+
Expression::ShiftRight {
147176
loc: arg.loc,
148177
ty: Type::Uint(64),
149178
left: Box::new(Expression::FunctionArg {
@@ -157,7 +186,12 @@ fn decode_args(function: &Function, ns: &Namespace) -> Vec<Expression> {
157186
value: BigInt::from(8_u64),
158187
}),
159188
signed: false,
160-
},
189+
190+
191+
}
192+
}
193+
/* */
194+
,
161195
Type::Address(_) => Expression::FunctionArg {
162196
loc: arg.loc,
163197
ty: arg.ty.clone(),

src/codegen/encoding/mod.rs

Lines changed: 126 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,14 +157,55 @@ pub(super) fn soroban_encode(
157157
args: vec![encoded, len],
158158
}
159159
}
160-
Type::Uint(64) => Instr::Call {
160+
Type::Uint(64) => {
161+
162+
163+
/*Instr::Call {
161164
res: vec![obj],
162165
return_tys: vec![Type::Uint(64)],
163166
call: super::cfg::InternalCallTy::HostFunction {
164167
name: "i._".to_string(),
165168
},
166169
args: vec![item.clone()],
170+
}*/
171+
172+
let shift_left = Expression::ShiftLeft {
173+
loc: *loc,
174+
ty: Type::Uint(64),
175+
left: Box::new(item.clone()),
176+
right: Box::new(Expression::NumberLiteral {
177+
loc: *loc,
178+
ty: Type::Uint(64),
179+
value: BigInt::from(8),
180+
}),
181+
};
182+
183+
let added = Expression::Add {
184+
loc: *loc,
185+
ty: Type::Uint(64),
186+
left: Box::new(shift_left),
187+
right: Box::new(Expression::NumberLiteral {
188+
loc: *loc,
189+
ty: Type::Uint(64),
190+
value: BigInt::from(6),
191+
}),
192+
overflowing: false,
193+
};
194+
195+
let set = Instr::Set {
196+
loc: *loc,
197+
res: obj,
198+
expr: added,
199+
};
200+
201+
set
202+
203+
204+
167205
},
206+
207+
208+
168209
_ => todo!("type not yet supported"),
169210
};
170211

@@ -254,6 +295,11 @@ pub(super) fn abi_decode(
254295
cfg: &mut ControlFlowGraph,
255296
buffer_size_expr: Option<Expression>,
256297
) -> Vec<Expression> {
298+
299+
if ns.target == Target::Soroban {
300+
return soroban_decode(loc, buffer, types, ns, vartab, cfg, buffer_size_expr);
301+
}
302+
257303
let buffer_size = vartab.temp_anonymous(&Uint(32));
258304
if let Some(length_expression) = buffer_size_expr {
259305
cfg.add(
@@ -312,6 +358,85 @@ pub(super) fn abi_decode(
312358
read_items
313359
}
314360

361+
fn soroban_decode( loc: &Loc,
362+
buffer: &Expression,
363+
types: &[Type],
364+
ns: &Namespace,
365+
vartab: &mut Vartable,
366+
cfg: &mut ControlFlowGraph,
367+
buffer_size_expr: Option<Expression>) -> Vec<Expression> {
368+
369+
let mut returns = Vec::new();
370+
371+
372+
let loaded_val = Expression::Load { loc: Loc::Codegen, ty: Type::Uint(64), expr: Box::new(buffer.clone()) };
373+
374+
let decoded_val = Expression::ShiftRight { loc: *loc, ty: Type::Uint(64), left: Box::new(loaded_val.clone()), right: Box::new(Expression::NumberLiteral { loc: *loc, ty: Type::Uint(64), value: BigInt::from(8) }), signed: false };
375+
376+
/*let obj = vartab.temp_name("obj", &Type::Uint(64));
377+
378+
let var = Expression::Variable { loc: Loc::Codegen, ty: Uint(64), var_no: obj };
379+
380+
let convert_from_obj = Instr::Call {
381+
res: vec![obj],
382+
return_tys: vec![Type::Uint(64)],
383+
call: super::cfg::InternalCallTy::HostFunction {
384+
name: "i.0".to_string(),
385+
},
386+
args: vec![loaded_val.clone()],
387+
};*/
388+
389+
390+
391+
//cfg.add(vartab, decoded_val);
392+
393+
394+
395+
//let set_casted_buffer = Instr::Set { loc: *loc, res: new_casted_buffer, expr: shifted_vec.clone() };
396+
397+
//cfg.add(vartab, set_casted_buffer);
398+
399+
400+
401+
returns.push(decoded_val);
402+
403+
//println!( "new casted {:?}", new_casted_buffer);
404+
405+
406+
407+
/*for (index,ty) in types.iter().rev().enumerate() {
408+
409+
410+
let val_temp = vartab.temp_name("val ", ty);
411+
412+
let vec_back_var = Expression::Variable { loc: *loc, ty: Type::Uint(64), var_no: val_temp };
413+
414+
let vec_back = Instr::Call { res: vec![val_temp], return_tys: vec![Uint(64)], call: InternalCallTy::HostFunction { name: "v.9".to_string() } , args: vec![loaded_vec.clone()] };
415+
416+
returns.push(vec_back_var);
417+
cfg.add(vartab, vec_back);
418+
419+
// let obj = Expression::Variable { loc: *loc, ty: Uint(64), var_no: val_temp };
420+
421+
// let shifted = Expression::ShiftLeft { loc: *loc, ty: Uint(64), left: Box::new(obj), right: Box::new(Expression::NumberLiteral { loc: *loc, ty: Uint(64), value: BigInt::from(8) }) };
422+
423+
// cfg.add(vartab, vec_back);
424+
425+
// let vec_pop_back = Instr::Call { res: vec![buffer_var_no], return_tys: vec![Uint(64)], call: InternalCallTy::HostFunction { name: "v.7".to_string() }, args: vec![loaded_vec.clone()] };
426+
427+
// cfg.add(vartab, vec_pop_back);
428+
429+
// returns.push(shifted);
430+
431+
}*/
432+
433+
434+
//returns.reverse();
435+
436+
returns
437+
438+
}
439+
315440
/// Calculate the size of a set of arguments to encoding functions
316441
fn calculate_size_args(
317442
encoder: &mut Box<dyn AbiEncoding>,

src/emit/binary.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,8 @@ pub struct Binary<'a> {
166166
/// No initializer for vector_new
167167
pub(crate) vector_init_empty: PointerValue<'a>,
168168
global_constant_strings: RefCell<HashMap<Vec<u8>, PointerValue<'a>>>,
169+
170+
pub return_data : RefCell<Option<PointerValue<'a>>>,
169171
}
170172

171173
impl<'a> Binary<'a> {
@@ -435,6 +437,7 @@ impl<'a> Binary<'a> {
435437
.ptr_type(AddressSpace::default())
436438
.const_null(),
437439
global_constant_strings: RefCell::new(HashMap::new()),
440+
return_data: RefCell::new(None),
438441
}
439442
}
440443

src/emit/soroban/target.rs

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,47 @@ impl<'a> TargetRuntime<'a> for SorobanTarget {
558558
&[address.unwrap().into(), symbol.into(), vec_object.into()],
559559
"call",
560560
)
561+
.unwrap().try_as_basic_value().left().unwrap().into_int_value();
562+
563+
564+
565+
let allocate_i64 = bin
566+
.builder
567+
.build_alloca(bin.context.i64_type(), "allocate_i64")
568+
.unwrap();
569+
570+
bin.builder.build_store(allocate_i64, call_res).unwrap();
571+
572+
*bin.return_data.borrow_mut() = Some(allocate_i64);
573+
574+
575+
let zero_encoded = bin.builder.build_left_shift(zero, thirty_two, "temp").unwrap();
576+
let zero_encoded = bin.builder.build_int_add(zero_encoded, four, "zero_encoded").unwrap();
577+
578+
let res_pos = bin
579+
.builder
580+
.build_ptr_to_int(allocate_i64, bin.context.i64_type(), "res_pos")
561581
.unwrap();
582+
let res_pos_encoded = bin
583+
.builder
584+
.build_left_shift(res_pos, thirty_two, "temp")
585+
.unwrap();
586+
587+
let res_pos_encoded = bin.builder.build_int_add(res_pos_encoded, four, "res_pos_encoded").unwrap();
588+
589+
let one = bin.context.i64_type().const_int(1, false);
590+
let one_encoded = bin.builder.build_left_shift(one, thirty_two, "temp").unwrap();
591+
let one_encoded = bin.builder.build_int_add(one_encoded, four, "one_encoded").unwrap();
592+
593+
let logger = bin
594+
.builder
595+
.build_call(
596+
bin.module.get_function(LOG_FROM_LINEAR_MEMORY).unwrap(),
597+
&[zero_encoded.into(), zero_encoded.into(), res_pos_encoded.into(), one_encoded.into()],
598+
"log",
599+
)
600+
.unwrap();
601+
562602

563603
//
564604
}
@@ -592,10 +632,9 @@ impl<'a> TargetRuntime<'a> for SorobanTarget {
592632
/// Return the return data from an external call (either revert error or return values)
593633
fn return_data<'b>(&self, bin: &Binary<'b>, function: FunctionValue<'b>) -> PointerValue<'b> {
594634
println!("Return data!!!!");
595-
bin.context
596-
.i8_type()
597-
.ptr_type(inkwell::AddressSpace::default())
598-
.const_null()
635+
636+
let ret = bin.return_data.borrow().unwrap();
637+
ret
599638
//unimplemented!()
600639
}
601640

tests/soroban.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,38 @@ impl SorobanEnv {
106106

107107
self.env.logs().all()
108108
}
109+
110+
pub fn deploy_contract(&mut self, src: &str) -> Address {
111+
112+
let tmp_file = OsStr::new("test.sol");
113+
let mut cache = FileResolver::default();
114+
cache.set_file_contents(tmp_file.to_str().unwrap(), src.to_string());
115+
let opt = inkwell::OptimizationLevel::Default;
116+
let target = Target::Soroban;
117+
let (wasm, _ns) = compile(
118+
tmp_file,
119+
&mut cache,
120+
target,
121+
&Options {
122+
opt_level: opt.into(),
123+
log_runtime_errors: true,
124+
log_prints: true,
125+
#[cfg(feature = "wasm_opt")]
126+
wasm_opt: Some(contract_build::OptimizationPasses::Z),
127+
soroban_version: None,
128+
..Default::default()
129+
},
130+
std::vec!["unknown".to_string()],
131+
"0.0.1",
132+
);
133+
134+
let addr = self.register_contract(wasm[0].0.clone());
135+
136+
self.contracts.push(addr.clone());
137+
138+
addr
139+
140+
}
109141
}
110142

111143
impl Default for SorobanEnv {

0 commit comments

Comments
 (0)