@@ -292,6 +292,27 @@ impl<'a> Binary<'a> {
292292 export_list. push ( "__lshrti3" ) ;
293293 export_list. push ( "__ashrti3" ) ;
294294
295+ if self . ns . target == crate :: Target :: Soroban {
296+ let mut f = self . module . get_first_function ( ) ;
297+ while let Some ( func) = f {
298+ let name = func. get_name ( ) . to_str ( ) . unwrap ( ) ;
299+ // leave LLVM intrinsics alone
300+ if name. starts_with ( "llvm." ) {
301+ f = func. get_next_function ( ) ;
302+ continue ;
303+ }
304+
305+ if export_list. contains ( & name) {
306+ func. set_linkage ( inkwell:: module:: Linkage :: External ) ;
307+ } else {
308+ func. set_linkage ( inkwell:: module:: Linkage :: Internal ) ;
309+ }
310+
311+ f = func. get_next_function ( ) ;
312+ }
313+ return ;
314+ }
315+
295316 while let Some ( f) = func {
296317 let name = f. get_name ( ) . to_str ( ) . unwrap ( ) ;
297318
@@ -1036,71 +1057,7 @@ impl<'a> Binary<'a> {
10361057 size : IntValue < ' a > ,
10371058 elem_size : IntValue < ' a > ,
10381059 init : Option < & Vec < u8 > > ,
1039- ty : & Type ,
10401060 ) -> BasicValueEnum < ' a > {
1041- if self . ns . target == Target :: Soroban {
1042- if matches ! ( ty, Type :: Bytes ( _) ) {
1043- let n = if let Type :: Bytes ( n) = ty {
1044- n
1045- } else {
1046- unreachable ! ( )
1047- } ;
1048-
1049- let data = self
1050- . builder
1051- . build_alloca ( self . context . i64_type ( ) . array_type ( ( * n / 8 ) as u32 ) , "data" )
1052- . unwrap ( ) ;
1053-
1054- let ty = self . context . struct_type (
1055- & [ data. get_type ( ) . into ( ) , self . context . i64_type ( ) . into ( ) ] ,
1056- false ,
1057- ) ;
1058-
1059- // Start with an undefined struct value
1060- let mut struct_value = ty. get_undef ( ) ;
1061-
1062- // Insert `data` into the first field of the struct
1063- struct_value = self
1064- . builder
1065- . build_insert_value ( struct_value, data, 0 , "insert_data" )
1066- . unwrap ( )
1067- . into_struct_value ( ) ;
1068-
1069- // Insert `size` into the second field of the struct
1070- struct_value = self
1071- . builder
1072- . build_insert_value ( struct_value, size, 1 , "insert_size" )
1073- . unwrap ( )
1074- . into_struct_value ( ) ;
1075-
1076- // Return the constructed struct value
1077- return struct_value. into ( ) ;
1078- } else if matches ! ( ty, Type :: String ) {
1079- let default = " " . as_bytes ( ) . to_vec ( ) ;
1080- let bs = init. unwrap_or ( & default) ;
1081-
1082- let data = self . emit_global_string ( "const_string" , bs, true ) ;
1083-
1084- // A constant string, or array, is represented by a struct with two fields: a pointer to the data, and its length.
1085- let ty = self . context . struct_type (
1086- & [
1087- self . context . ptr_type ( AddressSpace :: default ( ) ) . into ( ) ,
1088- self . context . i64_type ( ) . into ( ) ,
1089- ] ,
1090- false ,
1091- ) ;
1092-
1093- return ty
1094- . const_named_struct ( & [
1095- data. into ( ) ,
1096- self . context
1097- . i64_type ( )
1098- . const_int ( bs. len ( ) as u64 , false )
1099- . into ( ) ,
1100- ] )
1101- . as_basic_value_enum ( ) ;
1102- }
1103- }
11041061 if let Some ( init) = init {
11051062 if init. is_empty ( ) {
11061063 return self
@@ -1116,16 +1073,22 @@ impl<'a> Binary<'a> {
11161073 Some ( s) => self . emit_global_string ( "const_string" , s, true ) ,
11171074 } ;
11181075
1119- self . builder
1120- . build_call (
1076+ println ! ( "calling soroban alloc : {:?}" , size) ;
1077+ let allocator = if self . ns . target == Target :: Soroban {
1078+ self . builder . build_call (
1079+ self . module . get_function ( "soroban_alloc_init" ) . unwrap ( ) ,
1080+ & [ size. into ( ) , init. into ( ) ] ,
1081+ "soroban_alloc" ,
1082+ )
1083+ } else {
1084+ self . builder . build_call (
11211085 self . module . get_function ( "vector_new" ) . unwrap ( ) ,
11221086 & [ size. into ( ) , elem_size. into ( ) , init. into ( ) ] ,
1123- "" ,
1087+ "vector_new " ,
11241088 )
1125- . unwrap ( )
1126- . try_as_basic_value ( )
1127- . left ( )
1128- . unwrap ( )
1089+ } ;
1090+
1091+ allocator. unwrap ( ) . try_as_basic_value ( ) . left ( ) . unwrap ( )
11291092 }
11301093
11311094 /// Number of element in a vector
@@ -1134,19 +1097,19 @@ impl<'a> Binary<'a> {
11341097 // slice
11351098 let slice = vector. into_struct_value ( ) ;
11361099
1137- let len_type = if self . ns . target == Target :: Soroban {
1100+ /* let len_type = if self.ns.target == Target::Soroban {
11381101 self.context.i64_type()
11391102 } else {
11401103 self.context.i32_type()
1141- } ;
1104+ };*/
11421105
11431106 self . builder
11441107 . build_int_truncate (
11451108 self . builder
11461109 . build_extract_value ( slice, 1 , "slice_len" )
11471110 . unwrap ( )
11481111 . into_int_value ( ) ,
1149- len_type ,
1112+ self . context . i32_type ( ) ,
11501113 "len" ,
11511114 )
11521115 . unwrap ( )
@@ -1376,11 +1339,12 @@ static BPF_IR: [&[u8]; 6] = [
13761339 include_bytes ! ( "../../target/bpf/heap.bc" ) ,
13771340] ;
13781341
1379- static WASM_IR : [ & [ u8 ] ; 4 ] = [
1342+ static WASM_IR : [ & [ u8 ] ; 5 ] = [
13801343 include_bytes ! ( "../../target/wasm/stdlib.bc" ) ,
13811344 include_bytes ! ( "../../target/wasm/heap.bc" ) ,
13821345 include_bytes ! ( "../../target/wasm/bigint.bc" ) ,
13831346 include_bytes ! ( "../../target/wasm/format.bc" ) ,
1347+ include_bytes ! ( "../../target/wasm/soroban.bc" ) ,
13841348] ;
13851349
13861350static RIPEMD160_IR : & [ u8 ] = include_bytes ! ( "../../target/wasm/ripemd160.bc" ) ;
0 commit comments