Skip to content

Commit 535e648

Browse files
feat: optimize string printing
Signed-off-by: salaheldinsoliman <[email protected]>
1 parent 1b8aba0 commit 535e648

File tree

6 files changed

+107
-41
lines changed

6 files changed

+107
-41
lines changed

src/codegen/dispatch/soroban.rs

-6
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,8 @@ pub fn function_dispatch(
102102

103103
wrapper_cfg.add(&mut vartab, placeholder);
104104

105-
<<<<<<< HEAD
106105

107106
if value.len() == 1 {
108-
=======
109-
>>>>>>> 06798cdeac6fd62ee98f5ae7da38f3af4933dc0f
110107
// set the msb 8 bits of the return value to 6, the return value is 64 bits.
111108
// FIXME: this assumes that the solidity function always returns one value.
112109
let shifted = Expression::ShiftLeft {
@@ -136,7 +133,6 @@ pub fn function_dispatch(
136133
};
137134

138135
wrapper_cfg.add(&mut vartab, Instr::Return { value: vec![added] });
139-
<<<<<<< HEAD
140136
} else {
141137

142138
// return 2 as numberliteral
@@ -149,8 +145,6 @@ pub fn function_dispatch(
149145
wrapper_cfg.add(&mut vartab, Instr::Return { value: vec![two] });
150146
}
151147

152-
=======
153-
>>>>>>> 06798cdeac6fd62ee98f5ae7da38f3af4933dc0f
154148

155149
vartab.finalize(ns, &mut wrapper_cfg);
156150
cfg.public = false;

src/emit/expression.rs

+33-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use inkwell::{AddressSpace, IntPredicate};
1717
use num_bigint::Sign;
1818
use num_traits::ToPrimitive;
1919
use std::collections::HashMap;
20+
use std::ops::Deref;
2021

2122
/// The expression function recursively emits code for expressions. The BasicEnumValue it
2223
/// returns depends on the context; if it is simple integer, bool or bytes32 expression, the value
@@ -1198,6 +1199,7 @@ pub(super) fn expression<'a, T: TargetRuntime<'a> + ?Sized>(
11981199
expr,
11991200
..
12001201
} => {
1202+
println!("bytes cast");
12011203
let e = expression(target, bin, expr, vartab, function, ns).into_int_value();
12021204

12031205
let size = e.get_type().get_bit_width() / 8;
@@ -1538,6 +1540,10 @@ pub(super) fn expression<'a, T: TargetRuntime<'a> + ?Sized>(
15381540
initializer,
15391541
..
15401542
} => {
1543+
1544+
println!("alloc dynamic bytes");
1545+
println!("TYYY {:?}", ty);
1546+
println!("SIZE {:?}", size);
15411547
if matches!(ty, Type::Slice(_)) {
15421548
let init = initializer.as_ref().unwrap();
15431549

@@ -1553,7 +1559,33 @@ pub(super) fn expression<'a, T: TargetRuntime<'a> + ?Sized>(
15531559
.into(),
15541560
])
15551561
.into()
1556-
} else {
1562+
} else if matches!(size.clone().deref(), Expression::NumberLiteral{loc, ty, value}) {
1563+
1564+
println!("size is number literal");
1565+
let size = expression(target, bin, size, vartab, function, ns).into_int_value();
1566+
1567+
println!("size {:?}", size);
1568+
1569+
// convert size to i64
1570+
1571+
let size = size.const_cast(bin.context.i64_type(), false);
1572+
1573+
//let elem_size = bin.context.i32_type().const_int(1, false);
1574+
1575+
// elem_size.into()
1576+
1577+
//bin.vector_new(size, elem_size, initializer.as_ref()).into()
1578+
1579+
size.into()
1580+
}
1581+
1582+
1583+
1584+
1585+
else
1586+
1587+
1588+
{
15571589
let elem = match ty {
15581590
Type::Slice(_) | Type::String | Type::DynamicBytes => Type::Bytes(1),
15591591
_ => ty.array_elem(),

src/emit/instructions.rs

+2
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,8 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
446446
Instr::Print { expr } => {
447447
let expr = expression(target, bin, expr, &w.vars, function, ns);
448448

449+
println!("PRINTING {:?}", expr);
450+
449451
target.print(bin, bin.vector_bytes(expr), bin.vector_len(expr));
450452
}
451453
Instr::Call {

src/emit/soroban/mod.rs

-9
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,7 @@ use std::sync;
2222
const SOROBAN_ENV_INTERFACE_VERSION: u64 = 90194313216;
2323
pub const PUT_CONTRACT_DATA: &str = "l._";
2424
pub const GET_CONTRACT_DATA: &str = "l.1";
25-
<<<<<<< HEAD
2625
pub const LOG_FROM_LINEAR_MEMORY: &str = "x._";
27-
=======
28-
>>>>>>> 06798cdeac6fd62ee98f5ae7da38f3af4933dc0f
2926

3027
pub struct SorobanTarget;
3128

@@ -235,27 +232,21 @@ impl SorobanTarget {
235232
.i64_type()
236233
.fn_type(&[ty.into(), ty.into()], false);
237234

238-
<<<<<<< HEAD
239235
let log_function_ty = binary
240236
.context
241237
.i64_type()
242238
.fn_type(&[ty.into(), ty.into(), ty.into(), ty.into()], false);
243239

244-
=======
245-
>>>>>>> 06798cdeac6fd62ee98f5ae7da38f3af4933dc0f
246240
binary
247241
.module
248242
.add_function(PUT_CONTRACT_DATA, function_ty_1, Some(Linkage::External));
249243
binary
250244
.module
251245
.add_function(GET_CONTRACT_DATA, function_ty, Some(Linkage::External));
252-
<<<<<<< HEAD
253246

254247
binary
255248
.module
256249
.add_function(LOG_FROM_LINEAR_MEMORY, log_function_ty, Some(Linkage::External));
257-
=======
258-
>>>>>>> 06798cdeac6fd62ee98f5ae7da38f3af4933dc0f
259250
}
260251

261252
fn emit_initializer(binary: &mut Binary, _ns: &ast::Namespace) {

src/emit/soroban/target.rs

+68-25
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,8 @@
22

33
use crate::codegen::cfg::HashTy;
44
use crate::codegen::Expression;
5-
<<<<<<< HEAD
65
use crate::emit::binary::{self, Binary};
76
use crate::emit::soroban::{SorobanTarget, GET_CONTRACT_DATA, LOG_FROM_LINEAR_MEMORY, PUT_CONTRACT_DATA};
8-
=======
9-
use crate::emit::binary::Binary;
10-
use crate::emit::soroban::{SorobanTarget, GET_CONTRACT_DATA, PUT_CONTRACT_DATA};
11-
>>>>>>> 06798cdeac6fd62ee98f5ae7da38f3af4933dc0f
127
use crate::emit::ContractArgs;
138
use crate::emit::{TargetRuntime, Variable};
149
use crate::emit_context;
@@ -18,17 +13,10 @@ use crate::sema::ast::{Function, Namespace, Type};
1813

1914
use inkwell::types::{BasicTypeEnum, IntType};
2015
use inkwell::values::{
21-
<<<<<<< HEAD
2216
AnyValue, ArrayValue, AsValueRef, BasicMetadataValueEnum, BasicValue, BasicValueEnum, FunctionValue, IntValue, PointerValue
2317
};
2418

2519
use inkwell::AddressSpace;
26-
=======
27-
ArrayValue, BasicMetadataValueEnum, BasicValue, BasicValueEnum, FunctionValue, IntValue,
28-
PointerValue,
29-
};
30-
31-
>>>>>>> 06798cdeac6fd62ee98f5ae7da38f3af4933dc0f
3220
use solang_parser::pt::Loc;
3321

3422
use std::collections::HashMap;
@@ -248,35 +236,76 @@ impl<'a> TargetRuntime<'a> for SorobanTarget {
248236

249237
/// Prints a string
250238
/// TODO: Implement this function, with a call to the `log` function in the Soroban runtime.
251-
<<<<<<< HEAD
252239
fn print(&self, bin: &Binary, string: PointerValue, length: IntValue) {
253240

254241

242+
if string.is_const() {
255243

256-
let mut toprint;
257-
unsafe {
258-
toprint = string.as_value_ref().offset(0);
259-
println!( "TO PRINT! {:?}", toprint);
260-
}
261-
//println!("print called with string: {:?} ", string.as_value_ref());
262244
println!("msg_pos: {:?}", string);
263245
println!("length: {:?}", length);
264246

265247
let msg_pos = bin.builder.build_ptr_to_int(string, bin.context.i64_type(), "msg_pos").unwrap();
266-
267248
let msg_pos = msg_pos.const_cast(bin.context.i64_type(), false);
268249

269250

270251

271252
println!("msg_pos extracted: {:?}", msg_pos);
272253
println!("=============================================================");
273254

255+
let length = length.const_cast(bin.context.i64_type(), false);
256+
257+
258+
let eight = bin.context.i64_type().const_int(8, false);
259+
let four = bin.context.i64_type().const_int(4, false);
260+
let zero = bin.context.i64_type().const_int(0, false);
261+
let thirty_two = bin.context.i64_type().const_int(32, false);
262+
263+
// encode msg_pos and length
264+
let msg_pos_encoded = bin.builder.build_left_shift(msg_pos, thirty_two, "temp").unwrap();
265+
let msg_pos_encoded = bin.builder.build_int_add(msg_pos_encoded, four, "msg_pos_encoded").unwrap();
266+
274267

268+
269+
let length_encoded = bin.builder.build_left_shift(length, thirty_two, "temp").unwrap();
270+
let length_encoded = bin.builder.build_int_add(length_encoded, four, "length_encoded").unwrap();
271+
272+
273+
let zero_encoded = bin.builder.build_left_shift(zero, eight, "temp").unwrap();
275274

276275

277-
//let length = bin.context.i64_type().const_int(1024, false);
276+
let eight_encoded = bin.builder.build_left_shift(eight, eight, "temp").unwrap();
277+
let eight_encoded = bin.builder.build_int_add(eight_encoded, four, "eight_encoded").unwrap();
278+
278279

279-
let length = length.const_cast(bin.context.i64_type(), false);
280+
281+
282+
let call_res = bin.builder.build_call(
283+
bin.module.get_function(LOG_FROM_LINEAR_MEMORY).unwrap(),
284+
&[
285+
msg_pos_encoded.into(),
286+
length_encoded.into(),
287+
msg_pos_encoded.into(),
288+
four.into(),
289+
],
290+
"log",
291+
).unwrap();
292+
}
293+
294+
else {
295+
296+
297+
/*println!("msg_pos: {:?}", string);
298+
println!("length: {:?}", length);
299+
300+
let msg_pos = bin.builder.build_ptr_to_int(string, bin.context.i64_type(), "msg_pos").unwrap();
301+
//let msg_pos = msg_pos.const_cast(bin.context.i64_type(), false);
302+
303+
304+
305+
println!("msg_pos extracted: {:?}", msg_pos);
306+
println!("=============================================================");
307+
308+
//let length = length.const_cast(bin.context.i64_type(), false);
280309
281310
282311
let eight = bin.context.i64_type().const_int(8, false);
@@ -288,11 +317,24 @@ impl<'a> TargetRuntime<'a> for SorobanTarget {
288317
let msg_pos_encoded = bin.builder.build_left_shift(msg_pos, thirty_two, "temp").unwrap();
289318
let msg_pos_encoded = bin.builder.build_int_add(msg_pos_encoded, four, "msg_pos_encoded").unwrap();
290319
320+
println!("CAN MSG ENCODE");
321+
322+
291323
324+
//let length = bin.builder.build_int_z_extend(length, bin.context.i64_type(), "extended").unwrap();
325+
326+
327+
let length_type = length.get_type();
328+
println!("LENGTH TYPE: {:?}", length_type);
329+
330+
//let length = bin.builder.build_int_z_extend(length, bin.context.i64_type(), "extended").unwrap();
331+
//let length = bin.builder.build_int_cast(length, bin.context.i64_type(), "extended").unwrap();
292332
293333
let length_encoded = bin.builder.build_left_shift(length, thirty_two, "temp").unwrap();
294334
let length_encoded = bin.builder.build_int_add(length_encoded, four, "length_encoded").unwrap();
295335
336+
println!("CAN LENGTH ENCODE");
337+
296338
297339
let zero_encoded = bin.builder.build_left_shift(zero, eight, "temp").unwrap();
298340
@@ -313,11 +355,12 @@ impl<'a> TargetRuntime<'a> for SorobanTarget {
313355
],
314356
"log",
315357
).unwrap();
358+
*/
359+
360+
361+
}
316362

317363
}
318-
=======
319-
fn print(&self, bin: &Binary, string: PointerValue, length: IntValue) {}
320-
>>>>>>> 06798cdeac6fd62ee98f5ae7da38f3af4933dc0f
321364

322365
/// Return success without any result
323366
fn return_empty_abi(&self, bin: &Binary) {

src/emit/strings.rs

+4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ pub(super) fn format_string<'a, T: TargetRuntime<'a> + ?Sized>(
1919
function: FunctionValue<'a>,
2020
ns: &Namespace,
2121
) -> BasicValueEnum<'a> {
22+
23+
24+
println!("IN format_string");
25+
2226
// first we need to calculate the space we need
2327
let mut length = bin.context.i32_type().const_zero();
2428

0 commit comments

Comments
 (0)