1
1
// SPDX-License-Identifier: Apache-2.0
2
2
3
+ use anchor_syn:: Ty ;
3
4
use num_bigint:: BigInt ;
4
5
use solang_parser:: pt:: { self } ;
5
6
6
- use crate :: sema:: ast;
7
+ use crate :: sema:: ast:: { self , Function } ;
7
8
use crate :: {
8
9
codegen:: {
9
10
cfg:: { ASTFunction , ControlFlowGraph , Instr , InternalCallTy } ,
@@ -54,6 +55,7 @@ pub fn function_dispatch(
54
55
55
56
wrapper_cfg. returns = vec ! [ return_type] . into ( ) ;
56
57
wrapper_cfg. public = true ;
58
+ wrapper_cfg. function_no = cfg. function_no . clone ( ) ;
57
59
58
60
let mut vartab = Vartable :: from_symbol_table ( & function. symtable , ns. next_id ) ;
59
61
@@ -80,41 +82,88 @@ pub fn function_dispatch(
80
82
res : call_returns,
81
83
call : InternalCallTy :: Static { cfg_no } ,
82
84
return_tys,
83
- args : function
84
- . params
85
- . iter ( )
86
- . enumerate ( )
87
- . map ( |( i, p) | Expression :: ShiftRight {
88
- loc : pt:: Loc :: Codegen ,
89
- ty : Type :: Uint ( 64 ) ,
90
- left : Expression :: FunctionArg {
91
- loc : p. loc ,
92
- ty : p. ty . clone ( ) ,
93
- arg_no : i,
94
- }
95
- . into ( ) ,
96
- right : Expression :: NumberLiteral {
97
- loc : pt:: Loc :: Codegen ,
98
- ty : Type :: Uint ( 64 ) ,
99
- value : BigInt :: from ( 8_u64 ) ,
100
- }
101
- . into ( ) ,
102
-
103
- signed : false ,
104
- } )
105
- . collect ( ) ,
85
+ args : decode_args ( function, ns) ,
106
86
} ;
107
87
108
88
wrapper_cfg. add ( & mut vartab, placeholder) ;
109
89
110
90
// TODO: support multiple returns
111
91
if value. len ( ) == 1 {
112
- // set the msb 8 bits of the return value to 6, the return value is 64 bits.
113
- // FIXME: this assumes that the solidity function always returns one value.
92
+ let added = encode_return ( function, value[ 0 ] . clone ( ) ) ;
93
+ wrapper_cfg. add ( & mut vartab, Instr :: Return { value : vec ! [ added] } ) ;
94
+ } else {
95
+ // Return 2 as numberliteral. 2 is the soroban Void type encoded.
96
+ let two = Expression :: NumberLiteral {
97
+ loc : pt:: Loc :: Codegen ,
98
+ ty : Type :: Uint ( 64 ) ,
99
+ value : BigInt :: from ( 2_u64 ) ,
100
+ } ;
101
+
102
+ wrapper_cfg. add ( & mut vartab, Instr :: Return { value : vec ! [ two] } ) ;
103
+ }
104
+
105
+ vartab. finalize ( ns, & mut wrapper_cfg) ;
106
+ cfg. public = false ;
107
+ wrapper_cfgs. push ( wrapper_cfg) ;
108
+ }
109
+
110
+ wrapper_cfgs
111
+ }
112
+
113
+ fn decode_args ( function : & Function , ns : & Namespace ) -> Vec < Expression > {
114
+ let mut args = Vec :: new ( ) ;
115
+
116
+ for ( i, arg) in function. params . iter ( ) . enumerate ( ) {
117
+ println ! ( "ARGUMENTS {:?}" , arg) ;
118
+
119
+ let arg = match arg. ty {
120
+ Type :: Uint ( 64 ) | Type :: Uint ( 32 ) => Expression :: ShiftRight {
121
+ loc : arg. loc ,
122
+ ty : Type :: Uint ( 64 ) ,
123
+ left : Box :: new ( Expression :: FunctionArg {
124
+ loc : arg. loc ,
125
+ ty : arg. ty . clone ( ) ,
126
+ arg_no : i,
127
+ } ) ,
128
+ right : Box :: new ( Expression :: NumberLiteral {
129
+ loc : arg. loc ,
130
+ ty : Type :: Uint ( 64 ) ,
131
+ value : BigInt :: from ( 8_u64 ) ,
132
+ } ) ,
133
+ signed : false ,
134
+ } ,
135
+ Type :: Address ( _) => Expression :: FunctionArg {
136
+ loc : arg. loc ,
137
+ ty : arg. ty . clone ( ) ,
138
+ arg_no : i,
139
+ }
140
+ . cast ( & Type :: Address ( false ) , ns) ,
141
+
142
+ // FIXME: Should properly decode the value instead of just passing it
143
+ Type :: Uint ( 128 ) | Type :: Int ( 128 ) => Expression :: FunctionArg {
144
+ loc : arg. loc ,
145
+ ty : arg. ty . clone ( ) ,
146
+ arg_no : i,
147
+ } ,
148
+
149
+ _ => unimplemented ! ( ) ,
150
+ } ;
151
+
152
+ args. push ( arg) ;
153
+ }
154
+
155
+ args
156
+ }
157
+
158
+ // TODO: Implement for UINT32
159
+ fn encode_return ( function : & Function , value : Expression ) -> Expression {
160
+ let returned = function. returns [ 0 ] . clone ( ) ;
161
+ match returned. ty {
162
+ Type :: Uint ( 64 ) => {
114
163
let shifted = Expression :: ShiftLeft {
115
164
loc : pt:: Loc :: Codegen ,
116
165
ty : Type :: Uint ( 64 ) ,
117
- left : value[ 0 ] . clone ( ) . into ( ) ,
166
+ left : value. clone ( ) . into ( ) ,
118
167
right : Expression :: NumberLiteral {
119
168
loc : pt:: Loc :: Codegen ,
120
169
ty : Type :: Uint ( 64 ) ,
@@ -137,22 +186,39 @@ pub fn function_dispatch(
137
186
right : tag. into ( ) ,
138
187
} ;
139
188
140
- wrapper_cfg. add ( & mut vartab, Instr :: Return { value : vec ! [ added] } ) ;
141
- } else {
142
- // Return 2 as numberliteral. 2 is the soroban Void type encoded.
143
- let two = Expression :: NumberLiteral {
189
+ added
190
+ }
191
+
192
+ // TODO: support UINT32 here
193
+ Type :: Uint ( 32 ) => {
194
+ let shifted = Expression :: ShiftLeft {
144
195
loc : pt:: Loc :: Codegen ,
145
196
ty : Type :: Uint ( 64 ) ,
146
- value : BigInt :: from ( 2_u64 ) ,
197
+ left : value. clone ( ) . into ( ) ,
198
+ right : Expression :: NumberLiteral {
199
+ loc : pt:: Loc :: Codegen ,
200
+ ty : Type :: Uint ( 64 ) ,
201
+ value : BigInt :: from ( 8_u64 ) ,
202
+ }
203
+ . into ( ) ,
147
204
} ;
148
205
149
- wrapper_cfg. add ( & mut vartab, Instr :: Return { value : vec ! [ two] } ) ;
150
- }
206
+ let tag = Expression :: NumberLiteral {
207
+ loc : pt:: Loc :: Codegen ,
208
+ ty : Type :: Uint ( 64 ) ,
209
+ value : BigInt :: from ( 4_u64 ) ,
210
+ } ;
151
211
152
- vartab. finalize ( ns, & mut wrapper_cfg) ;
153
- cfg. public = false ;
154
- wrapper_cfgs. push ( wrapper_cfg) ;
155
- }
212
+ let added = Expression :: Add {
213
+ loc : pt:: Loc :: Codegen ,
214
+ ty : Type :: Uint ( 64 ) ,
215
+ overflowing : true ,
216
+ left : shifted. into ( ) ,
217
+ right : tag. into ( ) ,
218
+ } ;
156
219
157
- wrapper_cfgs
220
+ added
221
+ }
222
+ _ => unimplemented ! ( ) ,
223
+ }
158
224
}
0 commit comments