Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 16 additions & 6 deletions src/codegen/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::codegen::array_boundary::handle_array_assign;
use crate::codegen::constructor::call_constructor;
use crate::codegen::interface::TargetCodegen;
use crate::codegen::targets::polkadot::return_code as polkadot;
use crate::codegen::targets::soroban::{soroban_bytes_length, soroban_strings_length};
use crate::codegen::unused_variable::should_remove_assignment;
use crate::codegen::{Builtin, Expression};
use crate::sema::ast::ExternalCallAccounts;
Expand Down Expand Up @@ -754,6 +755,10 @@ pub fn expression(
array,
elem_ty,
} => {
// TODO-refactor : a good change to move the implementation of storage array length
// to CFG instead of llvm-ir.
// right now for bytes and strings we simply use a host function
// to get the length.
let array_ty = array.ty().deref_into();
let array = expression(array, cfg, contract_no, func, ns, vartab, opt, target);

Expand All @@ -770,12 +775,8 @@ pub fn expression(
.unwrap();
expression(&ast_expr, cfg, contract_no, func, ns, vartab, opt, target)
}
Type::DynamicBytes | Type::String => Expression::StorageArrayLength {
loc: *loc,
ty: ty.clone(),
array: Box::new(array),
elem_ty: elem_ty.clone(),
},
Type::DynamicBytes => soroban_bytes_length(loc, array, cfg, vartab, ns),
Type::String => soroban_strings_length(loc, array, cfg, vartab, ns),
Type::Array(_, dim) => match dim.last().unwrap() {
ArrayLength::Dynamic => {
target.lower_storage_array_length(loc, ty, array, elem_ty, cfg, vartab, ns)
Expand Down Expand Up @@ -1183,6 +1184,8 @@ pub fn expression(
kind: ast::Builtin::ArrayPush,
args,
} => {
// TODO: since array push is builtin i suggest to movt it to
// targets/target/mod.rs
if args[0].ty().is_contract_storage() {
target.storage_array_push(loc, args, cfg, contract_no, func, ns, vartab, opt)
} else {
Expand Down Expand Up @@ -1212,6 +1215,8 @@ pub fn expression(
kind: ast::Builtin::ArrayPop,
args,
} => {
// TODO: since array pop is builtin i suggest moving it to
// targets/target/mod.rs in lower_builtin
if args[0].ty().is_contract_storage() {
target.storage_array_pop(loc, args, &ty[0], cfg, contract_no, func, ns, vartab, opt)
} else {
Expand Down Expand Up @@ -3589,6 +3594,11 @@ fn array_subscript(
opt: &Options,
target: &dyn TargetCodegen,
) -> Expression {
// TODO: the function handling many subscript
// e.g array - bytes - map - ...
// i prefer to split it and dispatch to separte functions
// TODO: for bytes storage subscript we can write it in CFG
// instead of llvm-ir.
if array_ty.is_storage_bytes() {
return Expression::Subscript {
loc: *loc,
Expand Down
14 changes: 14 additions & 0 deletions src/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ pub enum HostFunctions {
LogFromLinearMemory,
SymbolNewFromLinearMemory,
VectorNew,
BytesNew,
VectorNewFromLinearMemory,
VecUnpackToLinearMemory,
VecLen,
Expand Down Expand Up @@ -139,6 +140,12 @@ pub enum HostFunctions {
BytesNewFromLinearMemory,
BytesLen,
BytesCopyToLinearMemory,
BytesGet,
BytesPut,
BytesPush,
BytesPop,
StringLen,
StringCopyToLinearMemory,
ContractEvent,
}

Expand All @@ -154,6 +161,7 @@ impl HostFunctions {
HostFunctions::LogFromLinearMemory => "x._",
HostFunctions::SymbolNewFromLinearMemory => "b.j",
HostFunctions::VectorNew => "v._",
HostFunctions::BytesNew => "b.4",
HostFunctions::VectorNewFromLinearMemory => "v.g",
HostFunctions::VecUnpackToLinearMemory => "v.h",
HostFunctions::Call => "d._",
Expand Down Expand Up @@ -188,6 +196,12 @@ impl HostFunctions {
HostFunctions::BytesNewFromLinearMemory => "b.3",
HostFunctions::BytesLen => "b.8",
HostFunctions::BytesCopyToLinearMemory => "b.1",
HostFunctions::BytesGet => "b.6",
HostFunctions::BytesPut => "b.5",
HostFunctions::BytesPush => "b.9",
HostFunctions::BytesPop => "b.a",
HostFunctions::StringLen => "b.k",
HostFunctions::StringCopyToLinearMemory => "b.g",
HostFunctions::ContractEvent => "x.1",
HostFunctions::VecLen => "v.3",
HostFunctions::VecPopBack => "v.7",
Expand Down
20 changes: 19 additions & 1 deletion src/codegen/optimize/constant_folding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,20 @@ fn bigint_to_expression(
value
}
}
Type::Bytes(n) => {
let bits = *n as usize * 8;
if value.sign() == Sign::Minus {
let mut bs = value.to_signed_bytes_le();
bs.resize(bits / 8, 0xff);
BigInt::from_bytes_le(Sign::Plus, &bs)
} else if value.bits() > bits as u64 {
let (_, mut bs) = value.to_bytes_le();
bs.truncate(bits / 8);
BigInt::from_bytes_le(Sign::Plus, &bs)
} else {
value
}
}
Type::StorageRef(..) => value,
_ => unreachable!(),
};
Expand Down Expand Up @@ -1328,7 +1342,11 @@ fn reference_variable(
// There must be at least one definition, and all should evaluate to the same value
let mut v = None;

for def in defs.keys() {
for (def, modified) in defs {
if *modified {
v = None;
break;
}
if let Some(expr) = get_definition(def, cfg) {
let expr = expression(expr, None, cfg, ns);

Expand Down
Loading
Loading