@@ -4,7 +4,6 @@ use super::revert::{
44 assert_failure, expr_assert, log_runtime_error, require, PanicCode , SolidityError ,
55} ;
66use super :: storage:: array_offset;
7- use super :: targets:: soroban:: encoding:: soroban_encode_arg;
87use super :: Options ;
98use super :: {
109 cfg:: { ControlFlowGraph , Instr , InternalCallTy } ,
@@ -14,9 +13,12 @@ use crate::codegen::array_boundary::handle_array_assign;
1413use crate :: codegen:: constructor:: call_constructor;
1514use crate :: codegen:: interface:: TargetCodegen ;
1615use crate :: codegen:: targets:: polkadot:: return_code as polkadot;
16+ use crate :: codegen:: targets:: soroban:: bytes:: {
17+ soroban_bytes_length, soroban_bytes_subscript_read, soroban_strings_length,
18+ } ;
1719use crate :: codegen:: targets:: soroban:: {
18- soroban_bytes_length , soroban_strings_length , soroban_struct_load , soroban_struct_member_load ,
19- soroban_struct_member_store ,
20+ soroban_storage_array_length_ast , soroban_storage_assign , soroban_storage_incdec ,
21+ soroban_storage_load ,
2022} ;
2123use crate :: codegen:: unused_variable:: should_remove_assignment;
2224use crate :: codegen:: { Builtin , Expression } ;
@@ -63,36 +65,19 @@ pub fn expression(
6365 }
6466 ast:: Expression :: StorageLoad { loc, ty, expr } => {
6567 if ns. target == Target :: Soroban {
66- if let ast:: Expression :: StructMember {
67- expr : var, field, ..
68- } = expr. as_ref ( )
69- {
70- return soroban_struct_member_load (
71- loc,
72- var,
73- * field,
74- cfg,
75- contract_no,
76- func,
77- ns,
78- vartab,
79- opt,
80- target,
81- ) ;
82- }
83- if matches ! ( ty, Type :: Struct ( _) ) {
84- return soroban_struct_load (
85- loc,
86- expr,
87- ty,
88- cfg,
89- contract_no,
90- func,
91- ns,
92- vartab,
93- opt,
94- target,
95- ) ;
68+ if let Some ( loaded) = soroban_storage_load (
69+ loc,
70+ expr,
71+ ty,
72+ cfg,
73+ contract_no,
74+ func,
75+ ns,
76+ vartab,
77+ opt,
78+ target,
79+ ) {
80+ return loaded;
9681 }
9782 }
9883
@@ -792,6 +777,22 @@ pub fn expression(
792777 array,
793778 elem_ty,
794779 } => {
780+ if ns. target == Target :: Soroban {
781+ if let Some ( len) = soroban_storage_array_length_ast (
782+ array,
783+ ty,
784+ cfg,
785+ contract_no,
786+ func,
787+ ns,
788+ vartab,
789+ opt,
790+ target,
791+ ) {
792+ return len;
793+ }
794+ }
795+
795796 // TODO-refactor : a good change to move the implementation of storage array length
796797 // to CFG instead of llvm-ir.
797798 // right now for bytes and strings we simply use a host function
@@ -1618,6 +1619,25 @@ fn post_incdec(
16181619 opt : & Options ,
16191620 target : & dyn TargetCodegen ,
16201621) -> Expression {
1622+ if ns. target == Target :: Soroban {
1623+ if let Some ( result) = soroban_storage_incdec (
1624+ loc,
1625+ var,
1626+ ty,
1627+ expr,
1628+ overflowing,
1629+ cfg,
1630+ contract_no,
1631+ func,
1632+ ns,
1633+ vartab,
1634+ opt,
1635+ target,
1636+ ) {
1637+ return result;
1638+ }
1639+ }
1640+
16211641 let res = vartab. temp_anonymous ( ty) ;
16221642 let v = expression ( var, cfg, contract_no, func, ns, vartab, opt, target) ;
16231643
@@ -1763,6 +1783,25 @@ fn pre_incdec(
17631783 opt : & Options ,
17641784 target : & dyn TargetCodegen ,
17651785) -> Expression {
1786+ if ns. target == Target :: Soroban {
1787+ if let Some ( result) = soroban_storage_incdec (
1788+ loc,
1789+ var,
1790+ ty,
1791+ expr,
1792+ overflowing,
1793+ cfg,
1794+ contract_no,
1795+ func,
1796+ ns,
1797+ vartab,
1798+ opt,
1799+ target,
1800+ ) {
1801+ return result;
1802+ }
1803+ }
1804+
17661805 let res = vartab. temp_anonymous ( ty) ;
17671806 let v = expression ( var, cfg, contract_no, func, ns, vartab, opt, target) ;
17681807 let storage_type = storage_type ( var, ns) ;
@@ -2987,30 +3026,18 @@ pub fn assign_single(
29873026 }
29883027 _ => {
29893028 if ns. target == Target :: Soroban {
2990- if let ast:: Expression :: StructMember {
2991- expr : var,
2992- field,
2993- ty : member_ty,
2994- ..
2995- } = left
2996- {
2997- if member_ty. is_contract_storage ( )
2998- && matches ! ( var. ty( ) . deref_any( ) , Type :: Struct ( _) )
2999- {
3000- return soroban_struct_member_store (
3001- & left. loc ( ) ,
3002- var,
3003- * field,
3004- cfg_right,
3005- cfg,
3006- contract_no,
3007- func,
3008- ns,
3009- vartab,
3010- opt,
3011- target,
3012- ) ;
3013- }
3029+ if let Some ( result) = soroban_storage_assign (
3030+ left,
3031+ cfg_right. clone ( ) ,
3032+ cfg,
3033+ contract_no,
3034+ func,
3035+ ns,
3036+ vartab,
3037+ opt,
3038+ target,
3039+ ) {
3040+ return result;
30143041 }
30153042 }
30163043
@@ -3074,17 +3101,12 @@ pub fn assign_single(
30743101 }
30753102 }
30763103 Type :: StorageRef ( ..) => {
3077- let value = target. prepare_storage_value (
3078- Expression :: Variable {
3079- loc : left. loc ( ) ,
3080- ty : ty. clone ( ) ,
3081- var_no : pos,
3082- } ,
3083- & dest,
3084- cfg,
3085- vartab,
3086- ns,
3087- ) ;
3104+ let value = Expression :: Variable {
3105+ loc : left. loc ( ) ,
3106+ ty : ty. clone ( ) ,
3107+ var_no : pos,
3108+ } ;
3109+ let value = target. prepare_storage_value ( value, & dest, cfg, vartab, ns) ;
30883110 cfg. add (
30893111 vartab,
30903112 Instr :: SetStorage {
@@ -3659,12 +3681,23 @@ fn array_subscript(
36593681 opt : & Options ,
36603682 target : & dyn TargetCodegen ,
36613683) -> Expression {
3662- // TODO: the function handling many subscript
3663- // e.g array - bytes - map - ...
3664- // i prefer to split it and dispatch to separte functions
3665- // TODO: for bytes storage subscript we can write it in CFG
3666- // instead of llvm-ir.
36673684 if array_ty. is_storage_bytes ( ) {
3685+ if ns. target == Target :: Soroban {
3686+ if let Some ( byte) = soroban_bytes_subscript_read (
3687+ array,
3688+ index,
3689+ elem_ty,
3690+ cfg,
3691+ contract_no,
3692+ func,
3693+ ns,
3694+ vartab,
3695+ opt,
3696+ target,
3697+ ) {
3698+ return byte;
3699+ }
3700+ }
36683701 return Expression :: Subscript {
36693702 loc : * loc,
36703703 ty : elem_ty. clone ( ) ,
@@ -3723,11 +3756,26 @@ fn array_subscript(
37233756 None => {
37243757 if let Type :: StorageRef ( ..) = array_ty {
37253758 if ns. target == Target :: Solana || ns. target == Target :: Soroban {
3726- Expression :: StorageArrayLength {
3727- loc : * loc,
3728- ty : ns. storage_type ( ) ,
3729- array : Box :: new ( array. clone ( ) ) ,
3730- elem_ty : array_ty. storage_array_elem ( ) . deref_into ( ) ,
3759+ let elem_ty = array_ty. storage_array_elem ( ) . deref_into ( ) ;
3760+ // On Soroban every array is a host VecObject: get the length via
3761+ // the hook (arrays.rs, vec_len). Solana keeps StorageArrayLength.
3762+ if ns. target == Target :: Soroban {
3763+ target. lower_storage_array_length (
3764+ loc,
3765+ & ns. storage_type ( ) ,
3766+ array. clone ( ) ,
3767+ & elem_ty,
3768+ cfg,
3769+ vartab,
3770+ ns,
3771+ )
3772+ } else {
3773+ Expression :: StorageArrayLength {
3774+ loc : * loc,
3775+ ty : ns. storage_type ( ) ,
3776+ array : Box :: new ( array. clone ( ) ) ,
3777+ elem_ty,
3778+ }
37313779 }
37323780 } else {
37333781 let ty = if ns. target == Target :: Soroban {
@@ -3937,12 +3985,6 @@ fn array_subscript(
39373985 if ns. target == Target :: Soroban {
39383986 let index = index. cast ( & Type :: Uint ( 64 ) , ns) ;
39393987
3940- let index = if elem_ty. is_reference_type ( ns) {
3941- soroban_encode_arg ( index, cfg, vartab, ns)
3942- } else {
3943- index
3944- } ;
3945-
39463988 let val = Expression :: Subscript {
39473989 loc : * loc,
39483990 ty : elem_ty. clone ( ) ,
0 commit comments