Skip to content

Commit

Permalink
feat: optimize string printing
Browse files Browse the repository at this point in the history
Signed-off-by: salaheldinsoliman <salaheldin_sameh@aucegypt.edu>
  • Loading branch information
salaheldinsoliman committed Jul 24, 2024
1 parent 1b8aba0 commit 535e648
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 41 deletions.
6 changes: 0 additions & 6 deletions src/codegen/dispatch/soroban.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,8 @@ pub fn function_dispatch(

wrapper_cfg.add(&mut vartab, placeholder);

<<<<<<< HEAD

if value.len() == 1 {
=======
>>>>>>> 06798cdeac6fd62ee98f5ae7da38f3af4933dc0f
// 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 shifted = Expression::ShiftLeft {
Expand Down Expand Up @@ -136,7 +133,6 @@ pub fn function_dispatch(
};

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

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

=======
>>>>>>> 06798cdeac6fd62ee98f5ae7da38f3af4933dc0f

vartab.finalize(ns, &mut wrapper_cfg);
cfg.public = false;
Expand Down
34 changes: 33 additions & 1 deletion src/emit/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use inkwell::{AddressSpace, IntPredicate};
use num_bigint::Sign;
use num_traits::ToPrimitive;
use std::collections::HashMap;
use std::ops::Deref;

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

let size = e.get_type().get_bit_width() / 8;
Expand Down Expand Up @@ -1538,6 +1540,10 @@ pub(super) fn expression<'a, T: TargetRuntime<'a> + ?Sized>(
initializer,
..
} => {

println!("alloc dynamic bytes");
println!("TYYY {:?}", ty);
println!("SIZE {:?}", size);
if matches!(ty, Type::Slice(_)) {
let init = initializer.as_ref().unwrap();

Expand All @@ -1553,7 +1559,33 @@ pub(super) fn expression<'a, T: TargetRuntime<'a> + ?Sized>(
.into(),
])
.into()
} else {
} else if matches!(size.clone().deref(), Expression::NumberLiteral{loc, ty, value}) {

println!("size is number literal");
let size = expression(target, bin, size, vartab, function, ns).into_int_value();

println!("size {:?}", size);

// convert size to i64

let size = size.const_cast(bin.context.i64_type(), false);

//let elem_size = bin.context.i32_type().const_int(1, false);

// elem_size.into()

//bin.vector_new(size, elem_size, initializer.as_ref()).into()

size.into()
}




else


{
let elem = match ty {
Type::Slice(_) | Type::String | Type::DynamicBytes => Type::Bytes(1),
_ => ty.array_elem(),
Expand Down
2 changes: 2 additions & 0 deletions src/emit/instructions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,8 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
Instr::Print { expr } => {
let expr = expression(target, bin, expr, &w.vars, function, ns);

println!("PRINTING {:?}", expr);

target.print(bin, bin.vector_bytes(expr), bin.vector_len(expr));
}
Instr::Call {
Expand Down
9 changes: 0 additions & 9 deletions src/emit/soroban/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@ use std::sync;
const SOROBAN_ENV_INTERFACE_VERSION: u64 = 90194313216;
pub const PUT_CONTRACT_DATA: &str = "l._";
pub const GET_CONTRACT_DATA: &str = "l.1";
<<<<<<< HEAD
pub const LOG_FROM_LINEAR_MEMORY: &str = "x._";
=======
>>>>>>> 06798cdeac6fd62ee98f5ae7da38f3af4933dc0f

pub struct SorobanTarget;

Expand Down Expand Up @@ -235,27 +232,21 @@ impl SorobanTarget {
.i64_type()
.fn_type(&[ty.into(), ty.into()], false);

<<<<<<< HEAD
let log_function_ty = binary
.context
.i64_type()
.fn_type(&[ty.into(), ty.into(), ty.into(), ty.into()], false);

=======
>>>>>>> 06798cdeac6fd62ee98f5ae7da38f3af4933dc0f
binary
.module
.add_function(PUT_CONTRACT_DATA, function_ty_1, Some(Linkage::External));
binary
.module
.add_function(GET_CONTRACT_DATA, function_ty, Some(Linkage::External));
<<<<<<< HEAD

binary
.module
.add_function(LOG_FROM_LINEAR_MEMORY, log_function_ty, Some(Linkage::External));
=======
>>>>>>> 06798cdeac6fd62ee98f5ae7da38f3af4933dc0f
}

fn emit_initializer(binary: &mut Binary, _ns: &ast::Namespace) {
Expand Down
93 changes: 68 additions & 25 deletions src/emit/soroban/target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,8 @@

use crate::codegen::cfg::HashTy;
use crate::codegen::Expression;
<<<<<<< HEAD
use crate::emit::binary::{self, Binary};
use crate::emit::soroban::{SorobanTarget, GET_CONTRACT_DATA, LOG_FROM_LINEAR_MEMORY, PUT_CONTRACT_DATA};
=======
use crate::emit::binary::Binary;
use crate::emit::soroban::{SorobanTarget, GET_CONTRACT_DATA, PUT_CONTRACT_DATA};
>>>>>>> 06798cdeac6fd62ee98f5ae7da38f3af4933dc0f
use crate::emit::ContractArgs;
use crate::emit::{TargetRuntime, Variable};
use crate::emit_context;
Expand All @@ -18,17 +13,10 @@ use crate::sema::ast::{Function, Namespace, Type};

use inkwell::types::{BasicTypeEnum, IntType};
use inkwell::values::{
<<<<<<< HEAD
AnyValue, ArrayValue, AsValueRef, BasicMetadataValueEnum, BasicValue, BasicValueEnum, FunctionValue, IntValue, PointerValue
};

use inkwell::AddressSpace;
=======
ArrayValue, BasicMetadataValueEnum, BasicValue, BasicValueEnum, FunctionValue, IntValue,
PointerValue,
};

>>>>>>> 06798cdeac6fd62ee98f5ae7da38f3af4933dc0f
use solang_parser::pt::Loc;

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

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


if string.is_const() {

let mut toprint;
unsafe {
toprint = string.as_value_ref().offset(0);
println!( "TO PRINT! {:?}", toprint);
}
//println!("print called with string: {:?} ", string.as_value_ref());
println!("msg_pos: {:?}", string);
println!("length: {:?}", length);

let msg_pos = bin.builder.build_ptr_to_int(string, bin.context.i64_type(), "msg_pos").unwrap();

let msg_pos = msg_pos.const_cast(bin.context.i64_type(), false);



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

let length = length.const_cast(bin.context.i64_type(), false);


let eight = bin.context.i64_type().const_int(8, false);
let four = bin.context.i64_type().const_int(4, false);
let zero = bin.context.i64_type().const_int(0, false);
let thirty_two = bin.context.i64_type().const_int(32, false);

// encode msg_pos and length
let msg_pos_encoded = bin.builder.build_left_shift(msg_pos, thirty_two, "temp").unwrap();
let msg_pos_encoded = bin.builder.build_int_add(msg_pos_encoded, four, "msg_pos_encoded").unwrap();



let length_encoded = bin.builder.build_left_shift(length, thirty_two, "temp").unwrap();
let length_encoded = bin.builder.build_int_add(length_encoded, four, "length_encoded").unwrap();


let zero_encoded = bin.builder.build_left_shift(zero, eight, "temp").unwrap();


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


let length = length.const_cast(bin.context.i64_type(), false);


let call_res = bin.builder.build_call(
bin.module.get_function(LOG_FROM_LINEAR_MEMORY).unwrap(),
&[
msg_pos_encoded.into(),
length_encoded.into(),
msg_pos_encoded.into(),
four.into(),
],
"log",
).unwrap();
}

else {


/*println!("msg_pos: {:?}", string);
println!("length: {:?}", length);
let msg_pos = bin.builder.build_ptr_to_int(string, bin.context.i64_type(), "msg_pos").unwrap();
//let msg_pos = msg_pos.const_cast(bin.context.i64_type(), false);
println!("msg_pos extracted: {:?}", msg_pos);
println!("=============================================================");
//let length = length.const_cast(bin.context.i64_type(), false);
let eight = bin.context.i64_type().const_int(8, false);
Expand All @@ -288,11 +317,24 @@ impl<'a> TargetRuntime<'a> for SorobanTarget {
let msg_pos_encoded = bin.builder.build_left_shift(msg_pos, thirty_two, "temp").unwrap();
let msg_pos_encoded = bin.builder.build_int_add(msg_pos_encoded, four, "msg_pos_encoded").unwrap();
println!("CAN MSG ENCODE");
//let length = bin.builder.build_int_z_extend(length, bin.context.i64_type(), "extended").unwrap();
let length_type = length.get_type();
println!("LENGTH TYPE: {:?}", length_type);
//let length = bin.builder.build_int_z_extend(length, bin.context.i64_type(), "extended").unwrap();
//let length = bin.builder.build_int_cast(length, bin.context.i64_type(), "extended").unwrap();
let length_encoded = bin.builder.build_left_shift(length, thirty_two, "temp").unwrap();
let length_encoded = bin.builder.build_int_add(length_encoded, four, "length_encoded").unwrap();
println!("CAN LENGTH ENCODE");
let zero_encoded = bin.builder.build_left_shift(zero, eight, "temp").unwrap();
Expand All @@ -313,11 +355,12 @@ impl<'a> TargetRuntime<'a> for SorobanTarget {
],
"log",
).unwrap();
*/


}

}
=======
fn print(&self, bin: &Binary, string: PointerValue, length: IntValue) {}
>>>>>>> 06798cdeac6fd62ee98f5ae7da38f3af4933dc0f

/// Return success without any result
fn return_empty_abi(&self, bin: &Binary) {
Expand Down
4 changes: 4 additions & 0 deletions src/emit/strings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ pub(super) fn format_string<'a, T: TargetRuntime<'a> + ?Sized>(
function: FunctionValue<'a>,
ns: &Namespace,
) -> BasicValueEnum<'a> {


println!("IN format_string");

// first we need to calculate the space we need
let mut length = bin.context.i32_type().const_zero();

Expand Down

0 comments on commit 535e648

Please sign in to comment.