Bladeren bron

The compiled binary should not have a reference to namespace

Since there can be multiple namespaces in a single binary.

Signed-off-by: Sean Young <sean@mess.org>
Sean Young 4 jaren geleden
bovenliggende
commit
ee966dfdd8
8 gewijzigde bestanden met toevoegingen van 857 en 452 verwijderingen
  1. 1 1
      clippy.toml
  2. 142 91
      src/emit/ethabiencoder.rs
  3. 104 60
      src/emit/ewasm.rs
  4. 47 16
      src/emit/generic.rs
  5. 250 108
      src/emit/mod.rs
  6. 41 14
      src/emit/sabre.rs
  7. 104 64
      src/emit/solana.rs
  8. 168 98
      src/emit/substrate.rs

+ 1 - 1
clippy.toml

@@ -1,2 +1,2 @@
-too-many-arguments-threshold = 11
+too-many-arguments-threshold = 12
 cognitive-complexity-threshold = 37

+ 142 - 91
src/emit/ethabiencoder.rs

@@ -33,6 +33,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
         args: &'b [BasicValueEnum<'a>],
         tys: &'b [ast::Type],
         bswap: bool,
+        ns: &ast::Namespace,
     ) -> Self {
         debug_assert_eq!(packed.len() + args.len(), tys.len());
 
@@ -41,7 +42,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
         let offset = binary.context.i32_type().const_int(
             args_tys
                 .iter()
-                .map(|ty| EncoderBuilder::encoded_fixed_length(ty, binary.ns))
+                .map(|ty| EncoderBuilder::encoded_fixed_length(ty, ns))
                 .sum(),
             false,
         );
@@ -52,7 +53,9 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
         for (i, arg) in packed.iter().enumerate() {
             length = binary.builder.build_int_add(
                 length,
-                EncoderBuilder::encoded_packed_length(*arg, load_args, &tys[i], function, binary),
+                EncoderBuilder::encoded_packed_length(
+                    *arg, load_args, &tys[i], function, binary, ns,
+                ),
                 "",
             );
         }
@@ -67,6 +70,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                     &args_tys[i],
                     function,
                     binary,
+                    ns,
                 ),
                 "",
             );
@@ -95,6 +99,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
         ty: &ast::Type,
         function: FunctionValue,
         binary: &Binary<'c>,
+        ns: &ast::Namespace,
     ) -> IntValue<'c> {
         match ty {
             ast::Type::Struct(n) => {
@@ -120,7 +125,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
 
                 let mut normal_sum = binary.context.i32_type().const_zero();
 
-                for (i, field) in binary.ns.structs[*n].fields.iter().enumerate() {
+                for (i, field) in ns.structs[*n].fields.iter().enumerate() {
                     let elem = unsafe {
                         binary.builder.build_gep(
                             arg.into_pointer_value(),
@@ -138,6 +143,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                         &field.ty,
                         function,
                         binary,
+                        ns,
                     );
 
                     normal_sum = binary.builder.build_int_add(normal_sum, len, "");
@@ -151,15 +157,16 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
 
                 let mut null_sum = binary.context.i32_type().const_zero();
 
-                for field in &binary.ns.structs[*n].fields {
+                for field in &ns.structs[*n].fields {
                     null_sum = binary.builder.build_int_add(
                         null_sum,
                         EncoderBuilder::encoded_packed_length(
-                            binary.default_value(&field.ty),
+                            binary.default_value(&field.ty, ns),
                             false,
                             &field.ty,
                             function,
                             binary,
+                            ns,
                         ),
                         "",
                     );
@@ -177,7 +184,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
 
                 sum.as_basic_value().into_int_value()
             }
-            ast::Type::Array(elem_ty, dims) if elem_ty.is_dynamic(binary.ns) => {
+            ast::Type::Array(elem_ty, dims) if elem_ty.is_dynamic(ns) => {
                 let arg = if load {
                     binary.builder.build_load(arg.into_pointer_value(), "")
                 } else {
@@ -219,7 +226,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                     len,
                     &mut normal_length,
                     |index, sum| {
-                        let elem = binary.array_subscript(ty, arg.into_pointer_value(), index);
+                        let elem = binary.array_subscript(ty, arg.into_pointer_value(), index, ns);
 
                         *sum = binary.builder.build_int_add(
                             EncoderBuilder::encoded_packed_length(
@@ -228,6 +235,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                                 &elem_ty,
                                 function,
                                 binary,
+                                ns,
                             ),
                             *sum,
                             "",
@@ -241,12 +249,12 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
 
                 binary.builder.position_at_end(null_array);
 
-                let elem = binary.default_value(&elem_ty.deref_any());
+                let elem = binary.default_value(&elem_ty.deref_any(), ns);
 
                 let null_length = binary.builder.build_int_add(
                     binary.builder.build_int_mul(
                         EncoderBuilder::encoded_packed_length(
-                            elem, false, elem_ty, function, binary,
+                            elem, false, elem_ty, function, binary, ns,
                         ),
                         len,
                         "",
@@ -288,7 +296,9 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                 // plus fixed size elements
                 binary.builder.build_int_mul(
                     len,
-                    EncoderBuilder::encoded_packed_length(arg, false, &elem_ty, function, binary),
+                    EncoderBuilder::encoded_packed_length(
+                        arg, false, &elem_ty, function, binary, ns,
+                    ),
                     "",
                 )
             }
@@ -309,9 +319,9 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
             ast::Type::Contract(_) | ast::Type::Address(_) => binary
                 .context
                 .i32_type()
-                .const_int(binary.ns.address_length as u64, false),
+                .const_int(ns.address_length as u64, false),
             ast::Type::Ref(ty) => {
-                EncoderBuilder::encoded_packed_length(arg, false, ty, function, binary)
+                EncoderBuilder::encoded_packed_length(arg, false, ty, function, binary, ns)
             }
             _ => unreachable!(),
         }
@@ -324,9 +334,10 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
         ty: &ast::Type,
         function: FunctionValue,
         binary: &Binary<'c>,
+        ns: &ast::Namespace,
     ) -> IntValue<'c> {
         match ty {
-            ast::Type::Struct(n) if ty.is_dynamic(binary.ns) => {
+            ast::Type::Struct(n) if ty.is_dynamic(ns) => {
                 let arg = if load {
                     binary.builder.build_load(arg.into_pointer_value(), "")
                 } else {
@@ -349,14 +360,14 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
 
                 let mut normal_sum = binary.context.i32_type().const_zero();
 
-                for (i, field) in binary.ns.structs[*n].fields.iter().enumerate() {
+                for (i, field) in ns.structs[*n].fields.iter().enumerate() {
                     // a struct with dynamic fields gets stored in the dynamic part
                     normal_sum = binary.builder.build_int_add(
                         normal_sum,
-                        binary.context.i32_type().const_int(
-                            EncoderBuilder::encoded_fixed_length(&field.ty, binary.ns),
-                            false,
-                        ),
+                        binary
+                            .context
+                            .i32_type()
+                            .const_int(EncoderBuilder::encoded_fixed_length(&field.ty, ns), false),
                         "",
                     );
 
@@ -377,6 +388,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                         &field.ty,
                         function,
                         binary,
+                        ns,
                     );
 
                     normal_sum = binary.builder.build_int_add(normal_sum, len, "");
@@ -390,25 +402,26 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
 
                 let mut null_sum = binary.context.i32_type().const_zero();
 
-                for field in &binary.ns.structs[*n].fields {
+                for field in &ns.structs[*n].fields {
                     // a struct with dynamic fields gets stored in the dynamic part
                     null_sum = binary.builder.build_int_add(
                         null_sum,
-                        binary.context.i32_type().const_int(
-                            EncoderBuilder::encoded_fixed_length(&field.ty, binary.ns),
-                            false,
-                        ),
+                        binary
+                            .context
+                            .i32_type()
+                            .const_int(EncoderBuilder::encoded_fixed_length(&field.ty, ns), false),
                         "",
                     );
 
                     null_sum = binary.builder.build_int_add(
                         null_sum,
                         EncoderBuilder::encoded_dynamic_length(
-                            binary.default_value(&field.ty),
+                            binary.default_value(&field.ty, ns),
                             false,
                             &field.ty,
                             function,
                             binary,
+                            ns,
                         ),
                         "",
                     );
@@ -426,7 +439,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
 
                 sum.as_basic_value().into_int_value()
             }
-            ast::Type::Array(elem_ty, dims) if ty.is_dynamic(binary.ns) => {
+            ast::Type::Array(elem_ty, dims) if ty.is_dynamic(ns) => {
                 let arg = if load {
                     binary.builder.build_load(arg.into_pointer_value(), "")
                 } else {
@@ -459,10 +472,10 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                     sum,
                     binary.builder.build_int_mul(
                         len,
-                        binary.context.i32_type().const_int(
-                            EncoderBuilder::encoded_fixed_length(&elem_ty, binary.ns),
-                            false,
-                        ),
+                        binary
+                            .context
+                            .i32_type()
+                            .const_int(EncoderBuilder::encoded_fixed_length(&elem_ty, ns), false),
                         "",
                     ),
                     "",
@@ -487,14 +500,15 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                 binary.builder.position_at_end(normal_array);
 
                 // the element of the array are dynamic; we need to iterate over the array to find the encoded length
-                if elem_ty.is_dynamic(binary.ns) {
+                if elem_ty.is_dynamic(ns) {
                     binary.emit_loop_cond_first_with_int(
                         function,
                         binary.context.i32_type().const_zero(),
                         len,
                         &mut normal_length,
                         |index, sum| {
-                            let elem = binary.array_subscript(ty, arg.into_pointer_value(), index);
+                            let elem =
+                                binary.array_subscript(ty, arg.into_pointer_value(), index, ns);
 
                             *sum = binary.builder.build_int_add(
                                 EncoderBuilder::encoded_dynamic_length(
@@ -503,6 +517,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                                     &elem_ty,
                                     function,
                                     binary,
+                                    ns,
                                 ),
                                 *sum,
                                 "",
@@ -517,12 +532,12 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
 
                 binary.builder.position_at_end(null_array);
 
-                let elem = binary.default_value(&elem_ty.deref_any());
+                let elem = binary.default_value(&elem_ty.deref_any(), ns);
 
                 let null_length = binary.builder.build_int_add(
                     binary.builder.build_int_mul(
                         EncoderBuilder::encoded_dynamic_length(
-                            elem, false, elem_ty, function, binary,
+                            elem, false, elem_ty, function, binary, ns,
                         ),
                         len,
                         "",
@@ -616,6 +631,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
         binary: &Binary<'a>,
         function: FunctionValue<'a>,
         output: PointerValue<'a>,
+        ns: &ast::Namespace,
     ) {
         let mut output = output;
         let mut ty_iter = self.tys.iter();
@@ -623,7 +639,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
         for arg in self.packed.iter() {
             let ty = ty_iter.next().unwrap();
 
-            self.encode_packed_ty(binary, self.load_args, function, ty, *arg, &mut output);
+            self.encode_packed_ty(binary, self.load_args, function, ty, *arg, &mut output, ns);
         }
 
         // We use a little trick here. The length might or might not include the selector.
@@ -654,6 +670,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
 
             self.encode_ty(
                 binary,
+                ns,
                 self.load_args,
                 function,
                 ty,
@@ -671,6 +688,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
     fn encode_ty(
         &self,
         binary: &Binary<'a>,
+        ns: &ast::Namespace,
         load: bool,
         function: FunctionValue<'a>,
         ty: &ast::Type,
@@ -686,7 +704,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
             | ast::Type::Int(_)
             | ast::Type::Uint(_)
             | ast::Type::Bytes(_) => {
-                self.encode_primitive(binary, load, function, ty, *fixed, arg);
+                self.encode_primitive(binary, load, function, ty, *fixed, arg, ns);
 
                 *fixed = unsafe {
                     binary.builder.build_gep(
@@ -697,7 +715,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                 };
             }
             ast::Type::Enum(n) => {
-                self.encode_primitive(binary, load, function, &binary.ns.enums[*n].ty, *fixed, arg);
+                self.encode_primitive(binary, load, function, &ns.enums[*n].ty, *fixed, arg, ns);
 
                 *fixed = unsafe {
                     binary.builder.build_gep(
@@ -707,7 +725,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                     )
                 };
             }
-            ast::Type::Array(elem_ty, dim) if ty.is_dynamic(binary.ns) => {
+            ast::Type::Array(elem_ty, dim) if ty.is_dynamic(ns) => {
                 let arg = if load {
                     binary.builder.build_load(arg.into_pointer_value(), "")
                 } else {
@@ -725,6 +743,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                     &ast::Type::Uint(32),
                     *fixed,
                     (*offset).into(),
+                    ns,
                 );
 
                 *fixed = unsafe {
@@ -753,6 +772,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                         &ast::Type::Uint(32),
                         *dynamic,
                         len.into(),
+                        ns,
                     );
 
                     *dynamic = unsafe {
@@ -773,10 +793,10 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                 };
 
                 let array_data_offset = binary.builder.build_int_mul(
-                    binary.context.i32_type().const_int(
-                        EncoderBuilder::encoded_fixed_length(&elem_ty, binary.ns),
-                        false,
-                    ),
+                    binary
+                        .context
+                        .i32_type()
+                        .const_int(EncoderBuilder::encoded_fixed_length(&elem_ty, ns), false),
                     array_length,
                     "array_data_offset",
                 );
@@ -833,10 +853,11 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                     builder.over(binary, binary.context.i32_type().const_zero(), array_length);
 
                 // loop body
-                let elem = binary.array_subscript(ty, arg.into_pointer_value(), index);
+                let elem = binary.array_subscript(ty, arg.into_pointer_value(), index, ns);
 
                 self.encode_ty(
                     binary,
+                    ns,
                     true,
                     function,
                     &elem_ty.deref_any(),
@@ -893,10 +914,11 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                 let _ = builder.over(binary, binary.context.i32_type().const_zero(), array_length);
 
                 // loop body
-                let elem = binary.default_value(&elem_ty.deref_any());
+                let elem = binary.default_value(&elem_ty.deref_any(), ns);
 
                 self.encode_ty(
                     binary,
+                    ns,
                     false,
                     function,
                     &elem_ty.deref_any(),
@@ -1015,6 +1037,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
 
                 self.encode_ty(
                     binary,
+                    ns,
                     true,
                     function,
                     &elem_ty.deref_any(),
@@ -1043,7 +1066,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                 // Create a loop for generating an array of empty values
                 // FIXME: all fixed-length types are encoded as zeros, and the memory has
                 // already been zero'ed out, so this is pointless. Just step over it.
-                let elem = binary.default_value(&elem_ty.deref_any());
+                let elem = binary.default_value(&elem_ty.deref_any(), ns);
 
                 let mut builder = LoopBuilder::new(binary, function);
 
@@ -1083,6 +1106,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                 // loop body
                 self.encode_ty(
                     binary,
+                    ns,
                     false,
                     function,
                     &elem_ty.deref_any(),
@@ -1136,7 +1160,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
 
                 *dynamic = dynamic_phi.as_basic_value().into_pointer_value();
             }
-            ast::Type::Struct(n) if ty.is_dynamic(binary.ns) => {
+            ast::Type::Struct(n) if ty.is_dynamic(ns) => {
                 let arg = if load {
                     binary.builder.build_load(arg.into_pointer_value(), "")
                 } else {
@@ -1151,6 +1175,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                     &ast::Type::Uint(32),
                     *fixed,
                     (*offset).into(),
+                    ns,
                 );
 
                 *fixed = unsafe {
@@ -1165,10 +1190,10 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                 let mut null_fields_dynamic = *dynamic;
 
                 // add size of fixed fields to dynamic
-                let fixed_field_length = binary.ns.structs[*n]
+                let fixed_field_length = ns.structs[*n]
                     .fields
                     .iter()
-                    .map(|f| EncoderBuilder::encoded_fixed_length(&f.ty, binary.ns))
+                    .map(|f| EncoderBuilder::encoded_fixed_length(&f.ty, ns))
                     .sum();
 
                 *dynamic = unsafe {
@@ -1206,7 +1231,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                     .i32_type()
                     .const_int(fixed_field_length, false);
 
-                for (i, field) in binary.ns.structs[*n].fields.iter().enumerate() {
+                for (i, field) in ns.structs[*n].fields.iter().enumerate() {
                     let elem = unsafe {
                         binary.builder.build_gep(
                             arg.into_pointer_value(),
@@ -1220,6 +1245,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
 
                     self.encode_ty(
                         binary,
+                        ns,
                         true,
                         function,
                         &field.ty,
@@ -1243,11 +1269,12 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                     .i32_type()
                     .const_int(fixed_field_length, false);
 
-                for field in &binary.ns.structs[*n].fields {
-                    let elem = binary.default_value(&field.ty);
+                for field in &ns.structs[*n].fields {
+                    let elem = binary.default_value(&field.ty, ns);
 
                     self.encode_ty(
                         binary,
+                        ns,
                         false,
                         function,
                         &field.ty,
@@ -1313,7 +1340,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                 let mut normal_offset = *offset;
                 let mut normal_dynamic = *dynamic;
 
-                for (i, field) in binary.ns.structs[*n].fields.iter().enumerate() {
+                for (i, field) in ns.structs[*n].fields.iter().enumerate() {
                     let elem = unsafe {
                         binary.builder.build_gep(
                             arg,
@@ -1327,6 +1354,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
 
                     self.encode_ty(
                         binary,
+                        ns,
                         true,
                         function,
                         &field.ty,
@@ -1348,11 +1376,12 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                 let mut null_dynamic = *dynamic;
 
                 // FIXME: abi encoding fixed length fields with default values. This should always be 0
-                for field in &binary.ns.structs[*n].fields {
-                    let elem = binary.default_value(&field.ty);
+                for field in &ns.structs[*n].fields {
+                    let elem = binary.default_value(&field.ty, ns);
 
                     self.encode_ty(
                         binary,
+                        ns,
                         false,
                         function,
                         &field.ty,
@@ -1401,7 +1430,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                 *offset = offset_phi.as_basic_value().into_int_value();
             }
             ast::Type::Ref(ty) => {
-                self.encode_ty(binary, load, function, ty, arg, fixed, offset, dynamic);
+                self.encode_ty(binary, ns, load, function, ty, arg, fixed, offset, dynamic);
             }
             ast::Type::String | ast::Type::DynamicBytes => {
                 // write the current offset to fixed
@@ -1412,6 +1441,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                     &ast::Type::Uint(32),
                     *fixed,
                     (*offset).into(),
+                    ns,
                 );
 
                 *fixed = unsafe {
@@ -1438,6 +1468,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                     &ast::Type::Uint(32),
                     *dynamic,
                     len.into(),
+                    ns,
                 );
 
                 *dynamic = unsafe {
@@ -1511,6 +1542,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
         ty: &ast::Type,
         arg: BasicValueEnum<'a>,
         output: &mut PointerValue<'a>,
+        ns: &ast::Namespace,
     ) {
         match &ty {
             ast::Type::Bool => {
@@ -1598,9 +1630,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                 if load =>
             {
                 let n = match ty {
-                    ast::Type::Contract(_) | ast::Type::Address(_) => {
-                        binary.ns.address_length as u16 * 8
-                    }
+                    ast::Type::Contract(_) | ast::Type::Address(_) => ns.address_length as u16 * 8,
                     ast::Type::Uint(b) => *b,
                     ast::Type::Int(b) => *b,
                     _ => unreachable!(),
@@ -1629,9 +1659,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                 if !load =>
             {
                 let n = match ty {
-                    ast::Type::Contract(_) | ast::Type::Address(_) => {
-                        binary.ns.address_length as u16 * 8
-                    }
+                    ast::Type::Contract(_) | ast::Type::Address(_) => ns.address_length as u16 * 8,
                     ast::Type::Uint(b) => *b,
                     ast::Type::Int(b) => *b,
                     _ => unreachable!(),
@@ -1749,7 +1777,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                     builder.over(binary, binary.context.i32_type().const_zero(), array_length);
 
                 // loop body
-                let elem = binary.array_subscript(ty, arg.into_pointer_value(), index);
+                let elem = binary.array_subscript(ty, arg.into_pointer_value(), index, ns);
 
                 self.encode_packed_ty(
                     binary,
@@ -1758,6 +1786,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                     &elem_ty.deref_any(),
                     elem.into(),
                     &mut normal_output,
+                    ns,
                 );
 
                 builder.set_loop_phi_value(binary, "output", normal_output.into());
@@ -1785,7 +1814,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                 let _ = builder.over(binary, binary.context.i32_type().const_zero(), array_length);
 
                 // loop body
-                let elem = binary.default_value(&elem_ty.deref_any());
+                let elem = binary.default_value(&elem_ty.deref_any(), ns);
 
                 self.encode_packed_ty(
                     binary,
@@ -1794,6 +1823,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                     &elem_ty.deref_any(),
                     elem,
                     &mut null_output,
+                    ns,
                 );
 
                 builder.set_loop_phi_value(binary, "output", null_output.into());
@@ -1842,7 +1872,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
 
                 let mut normal_output = *output;
 
-                for (i, field) in binary.ns.structs[*n].fields.iter().enumerate() {
+                for (i, field) in ns.structs[*n].fields.iter().enumerate() {
                     let elem = unsafe {
                         binary.builder.build_gep(
                             arg,
@@ -1861,6 +1891,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                         &field.ty,
                         elem.into(),
                         &mut normal_output,
+                        ns,
                     );
                 }
 
@@ -1873,8 +1904,8 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                 let mut null_output = *output;
 
                 // FIXME: abi encoding fixed length fields with default values. This should always be 0
-                for field in &binary.ns.structs[*n].fields {
-                    let elem = binary.default_value(&field.ty);
+                for field in &ns.structs[*n].fields {
+                    let elem = binary.default_value(&field.ty, ns);
 
                     self.encode_packed_ty(
                         binary,
@@ -1883,6 +1914,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                         &field.ty,
                         elem,
                         &mut null_output,
+                        ns,
                     );
                 }
 
@@ -1903,7 +1935,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                 *output = output_phi.as_basic_value().into_pointer_value();
             }
             ast::Type::Ref(ty) => {
-                self.encode_packed_ty(binary, load, function, ty, arg, output);
+                self.encode_packed_ty(binary, load, function, ty, arg, output, ns);
             }
             ast::Type::String | ast::Type::DynamicBytes => {
                 let arg = if load {
@@ -1956,6 +1988,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
         ty: &ast::Type,
         dest: PointerValue,
         arg: BasicValueEnum<'a>,
+        ns: &ast::Namespace,
     ) {
         match ty {
             ast::Type::Bool => {
@@ -2126,9 +2159,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                 if load =>
             {
                 let n = match ty {
-                    ast::Type::Contract(_) | ast::Type::Address(_) => {
-                        binary.ns.address_length as u16 * 8
-                    }
+                    ast::Type::Contract(_) | ast::Type::Address(_) => ns.address_length as u16 * 8,
                     ast::Type::Uint(b) => *b,
                     ast::Type::Int(b) => *b,
                     _ => unreachable!(),
@@ -2213,9 +2244,7 @@ impl<'a, 'b> EncoderBuilder<'a, 'b> {
                 if !load =>
             {
                 let n = match ty {
-                    ast::Type::Contract(_) | ast::Type::Address(_) => {
-                        binary.ns.address_length as u16 * 8
-                    }
+                    ast::Type::Contract(_) | ast::Type::Address(_) => ns.address_length as u16 * 8,
                     ast::Type::Uint(b) => *b,
                     ast::Type::Int(b) => *b,
                     _ => unreachable!(),
@@ -2362,6 +2391,7 @@ impl EthAbiDecoder {
         offset: &mut IntValue<'a>,
         data: PointerValue<'a>,
         length: IntValue,
+        ns: &ast::Namespace,
     ) -> BasicValueEnum<'a> {
         // TODO: investigate whether we can use build_int_nuw_add() and avoid 64 bit conversions
         let new_offset = binary.builder.build_int_add(
@@ -2377,7 +2407,7 @@ impl EthAbiDecoder {
         *offset = new_offset;
 
         let ty = if let ast::Type::Enum(n) = ty {
-            &binary.ns.enums[*n].ty
+            &ns.enums[*n].ty
         } else {
             ty
         };
@@ -2435,7 +2465,7 @@ impl EthAbiDecoder {
             ast::Type::Address(_) | ast::Type::Contract(_) => {
                 let int_type = binary
                     .context
-                    .custom_width_int_type(binary.ns.address_length as u32 * 8);
+                    .custom_width_int_type(ns.address_length as u32 * 8);
                 let type_size = int_type.size_of();
 
                 let store =
@@ -2607,10 +2637,11 @@ impl EthAbiDecoder {
         base_offset: IntValue<'b>,
         data: PointerValue<'b>,
         length: IntValue,
+        ns: &ast::Namespace,
     ) -> BasicValueEnum<'b> {
         match &ty {
             ast::Type::Array(elem_ty, dim) => {
-                let llvm_ty = binary.llvm_type(ty.deref_any());
+                let llvm_ty = binary.llvm_type(ty.deref_any(), ns);
 
                 let size = llvm_ty
                     .size_of()
@@ -2640,7 +2671,7 @@ impl EthAbiDecoder {
 
                     // if the struct has dynamic fields, read offset from dynamic section and
                     // read fields from there
-                    let mut dataoffset = if ty.is_dynamic(binary.ns) {
+                    let mut dataoffset = if ty.is_dynamic(ns) {
                         let dataoffset = binary.builder.build_int_z_extend(
                             self.decode_primitive(
                                 binary,
@@ -2650,6 +2681,7 @@ impl EthAbiDecoder {
                                 offset,
                                 data,
                                 length,
+                                ns,
                             )
                             .into_int_value(),
                             binary.context.i64_type(),
@@ -2665,7 +2697,7 @@ impl EthAbiDecoder {
 
                     // In dynamic struct sections, the offsets are relative to the start of the section.
                     // Ethereum ABI encoding is just insane.
-                    let base_offset = if ty.is_dynamic(binary.ns) {
+                    let base_offset = if ty.is_dynamic(ns) {
                         dataoffset
                     } else {
                         base_offset
@@ -2697,12 +2729,13 @@ impl EthAbiDecoder {
                                 base_offset,
                                 data,
                                 length,
+                                ns,
                             );
                         },
                     );
 
                     // if the struct is not dynamic, we have read the fields from fixed section so update
-                    if !ty.is_dynamic(binary.ns) {
+                    if !ty.is_dynamic(ns) {
                         *offset = dataoffset;
                     }
                 } else {
@@ -2716,6 +2749,7 @@ impl EthAbiDecoder {
                                 offset,
                                 data,
                                 length,
+                                ns,
                             )
                             .into_int_value(),
                             binary.context.i64_type(),
@@ -2734,13 +2768,14 @@ impl EthAbiDecoder {
                             &mut dataoffset,
                             data,
                             length,
+                            ns,
                         )
                         .into_int_value();
 
                     // in dynamic arrays, offsets are counted from after the array length
                     let base_offset = dataoffset;
 
-                    let llvm_elem_ty = binary.llvm_var(&elem_ty.deref_any());
+                    let llvm_elem_ty = binary.llvm_var(&elem_ty.deref_any(), ns);
                     let elem_size = llvm_elem_ty
                         .size_of()
                         .unwrap()
@@ -2810,6 +2845,7 @@ impl EthAbiDecoder {
                                 base_offset,
                                 data,
                                 length,
+                                ns,
                             );
                         },
                     );
@@ -2822,7 +2858,7 @@ impl EthAbiDecoder {
                 dest.into()
             }
             ast::Type::Struct(n) => {
-                let llvm_ty = binary.llvm_type(ty.deref_any());
+                let llvm_ty = binary.llvm_type(ty.deref_any(), ns);
 
                 let size = llvm_ty
                     .size_of()
@@ -2844,12 +2880,12 @@ impl EthAbiDecoder {
                 let struct_pointer = binary.builder.build_pointer_cast(
                     new,
                     llvm_ty.ptr_type(AddressSpace::Generic),
-                    &binary.ns.structs[*n].name,
+                    &ns.structs[*n].name,
                 );
 
                 // if the struct has dynamic fields, read offset from dynamic section and
                 // read fields from there
-                let mut dataoffset = if ty.is_dynamic(binary.ns) {
+                let mut dataoffset = if ty.is_dynamic(ns) {
                     let dataoffset = binary.builder.build_int_z_extend(
                         self.decode_primitive(
                             binary,
@@ -2859,6 +2895,7 @@ impl EthAbiDecoder {
                             offset,
                             data,
                             length,
+                            ns,
                         )
                         .into_int_value(),
                         binary.context.i64_type(),
@@ -2874,13 +2911,13 @@ impl EthAbiDecoder {
 
                 // In dynamic struct sections, the offsets are relative to the start of the section.
                 // Ethereum ABI encoding is just insane.
-                let base_offset = if ty.is_dynamic(binary.ns) {
+                let base_offset = if ty.is_dynamic(ns) {
                     dataoffset
                 } else {
                     base_offset
                 };
 
-                for (i, field) in binary.ns.structs[*n].fields.iter().enumerate() {
+                for (i, field) in ns.structs[*n].fields.iter().enumerate() {
                     let elem = unsafe {
                         binary.builder.build_gep(
                             struct_pointer,
@@ -2901,11 +2938,12 @@ impl EthAbiDecoder {
                         base_offset,
                         data,
                         length,
+                        ns,
                     );
                 }
 
                 // if the struct is not dynamic, we have read the fields from fixed section so update
-                if !ty.is_dynamic(binary.ns) {
+                if !ty.is_dynamic(ns) {
                     *offset = dataoffset;
                 }
 
@@ -2915,9 +2953,17 @@ impl EthAbiDecoder {
 
                 struct_pointer.into()
             }
-            ast::Type::Ref(ty) => {
-                self.decode_ty(binary, function, ty, to, offset, base_offset, data, length)
-            }
+            ast::Type::Ref(ty) => self.decode_ty(
+                binary,
+                function,
+                ty,
+                to,
+                offset,
+                base_offset,
+                data,
+                length,
+                ns,
+            ),
             ast::Type::String | ast::Type::DynamicBytes => {
                 // we read the offset and the length as 32 bits. Since we are in 32 bits wasm,
                 // we cannot deal with more than 4GB of abi encoded data.
@@ -2930,6 +2976,7 @@ impl EthAbiDecoder {
                         offset,
                         data,
                         length,
+                        ns,
                     )
                     .into_int_value(),
                     binary.context.i64_type(),
@@ -2949,6 +2996,7 @@ impl EthAbiDecoder {
                         &mut dataoffset,
                         data,
                         length,
+                        ns,
                     )
                     .into_int_value(),
                     binary.context.i64_type(),
@@ -3006,7 +3054,7 @@ impl EthAbiDecoder {
 
                 v.into()
             }
-            _ => self.decode_primitive(binary, function, ty, to, offset, data, length),
+            _ => self.decode_primitive(binary, function, ty, to, offset, data, length, ns),
         }
     }
 
@@ -3046,6 +3094,7 @@ impl EthAbiDecoder {
         data: PointerValue<'a>,
         datalength: IntValue<'a>,
         spec: &[ast::Parameter],
+        ns: &ast::Namespace,
     ) {
         let data = binary.builder.build_pointer_cast(
             data,
@@ -3073,6 +3122,7 @@ impl EthAbiDecoder {
                 binary.context.i64_type().const_zero(),
                 data,
                 data_length,
+                ns,
             ));
         }
     }
@@ -3086,8 +3136,9 @@ pub fn encode_to_vector<'b>(
     args: &[BasicValueEnum<'b>],
     tys: &[ast::Type],
     bswap: bool,
+    ns: &ast::Namespace,
 ) -> PointerValue<'b> {
-    let encoder = EncoderBuilder::new(binary, function, false, packed, args, tys, bswap);
+    let encoder = EncoderBuilder::new(binary, function, false, packed, args, tys, bswap, ns);
 
     let length = encoder.encoded_length();
 
@@ -3168,7 +3219,7 @@ pub fn encode_to_vector<'b>(
         "",
     );
 
-    encoder.finish(binary, function, data);
+    encoder.finish(binary, function, data, ns);
 
     v
 }

+ 104 - 60
src/emit/ewasm.rs

@@ -45,16 +45,16 @@ impl EwasmTarget {
             None,
         );
 
-        runtime_code.set_early_value_aborts(contract);
+        runtime_code.set_early_value_aborts(contract, ns);
 
         // externals
         b.declare_externals(&mut runtime_code);
 
         // This also emits the constructors. We are relying on DCE to eliminate them from
         // the final code.
-        b.emit_functions(&mut runtime_code, contract);
+        b.emit_functions(&mut runtime_code, contract, ns);
 
-        b.function_dispatch(&runtime_code, contract);
+        b.function_dispatch(&runtime_code, contract, ns);
 
         runtime_code.internalize(&["main"]);
 
@@ -74,7 +74,7 @@ impl EwasmTarget {
             Some(Box::new(runtime_code)),
         );
 
-        deploy_code.set_early_value_aborts(contract);
+        deploy_code.set_early_value_aborts(contract, ns);
 
         // externals
         b.declare_externals(&mut deploy_code);
@@ -82,9 +82,9 @@ impl EwasmTarget {
         // FIXME: this emits the constructors, as well as the functions. In Ethereum Solidity,
         // no functions can be called from the constructor. We should either disallow this too
         // and not emit functions, or use lto linking to optimize any unused functions away.
-        b.emit_functions(&mut deploy_code, contract);
+        b.emit_functions(&mut deploy_code, contract, ns);
 
-        b.deployer_dispatch(&mut deploy_code, contract, &runtime_bs);
+        b.deployer_dispatch(&mut deploy_code, contract, &runtime_bs, ns);
 
         deploy_code.internalize(&[
             "main",
@@ -126,6 +126,7 @@ impl EwasmTarget {
         &self,
         binary: &Binary<'a>,
         function: FunctionValue,
+        ns: &ast::Namespace,
     ) -> (PointerValue<'a>, IntValue<'a>) {
         let entry = binary.context.append_basic_block(function, "entry");
 
@@ -133,7 +134,7 @@ impl EwasmTarget {
 
         // first thing to do is abort value transfers if we're not payable
         if binary.function_abort_value_transfers {
-            self.abort_if_value_transfer(binary, function);
+            self.abort_if_value_transfer(binary, function, ns);
         }
 
         // init our heap
@@ -197,6 +198,7 @@ impl EwasmTarget {
         &self,
         binary: &mut Binary<'a>,
         function: FunctionValue,
+        ns: &ast::Namespace,
     ) -> (PointerValue<'a>, IntValue<'a>) {
         let entry = binary.context.append_basic_block(function, "entry");
 
@@ -204,7 +206,7 @@ impl EwasmTarget {
 
         // first thing to do is abort value transfers if constructors not payable
         if binary.constructor_abort_value_transfers {
-            self.abort_if_value_transfer(binary, function);
+            self.abort_if_value_transfer(binary, function, ns);
         }
 
         // init our heap
@@ -601,8 +603,14 @@ impl EwasmTarget {
             .add_attribute(AttributeLoc::Function, noreturn);
     }
 
-    fn deployer_dispatch(&mut self, binary: &mut Binary, contract: &ast::Contract, runtime: &[u8]) {
-        let initializer = self.emit_initializer(binary, contract);
+    fn deployer_dispatch(
+        &mut self,
+        binary: &mut Binary,
+        contract: &ast::Contract,
+        runtime: &[u8],
+        ns: &ast::Namespace,
+    ) {
+        let initializer = self.emit_initializer(binary, contract, ns);
 
         // create start function
         let ret = binary.context.void_type();
@@ -610,7 +618,7 @@ impl EwasmTarget {
         let function = binary.module.add_function("main", ftype, None);
 
         // FIXME: If there is no constructor, do not copy the calldata (but check calldatasize == 0)
-        let (argsdata, length) = self.deployer_prelude(binary, function);
+        let (argsdata, length) = self.deployer_prelude(binary, function, ns);
 
         // init our storage vars
         binary.builder.build_call(initializer, &[], "");
@@ -625,8 +633,15 @@ impl EwasmTarget {
             let mut args = Vec::new();
 
             // insert abi decode
-            self.abi
-                .decode(binary, function, &mut args, argsdata, length, &cfg.params);
+            self.abi.decode(
+                binary,
+                function,
+                &mut args,
+                argsdata,
+                length,
+                &cfg.params,
+                ns,
+            );
 
             binary
                 .builder
@@ -654,17 +669,23 @@ impl EwasmTarget {
         binary.builder.build_unreachable();
     }
 
-    fn function_dispatch(&mut self, binary: &Binary, contract: &ast::Contract) {
+    fn function_dispatch(
+        &mut self,
+        binary: &Binary,
+        contract: &ast::Contract,
+        ns: &ast::Namespace,
+    ) {
         // create start function
         let ret = binary.context.void_type();
         let ftype = ret.fn_type(&[], false);
         let function = binary.module.add_function("main", ftype, None);
 
-        let (argsdata, argslen) = self.runtime_prelude(binary, function);
+        let (argsdata, argslen) = self.runtime_prelude(binary, function, ns);
 
         self.emit_function_dispatch(
             binary,
             contract,
+            ns,
             pt::FunctionTy::Function,
             argsdata,
             argslen,
@@ -683,9 +704,11 @@ impl EwasmTarget {
         packed: &[BasicValueEnum<'b>],
         args: &[BasicValueEnum<'b>],
         tys: &[ast::Type],
+        ns: &ast::Namespace,
     ) -> (PointerValue<'b>, IntValue<'b>) {
-        let encoder =
-            ethabiencoder::EncoderBuilder::new(binary, function, load, packed, args, tys, false);
+        let encoder = ethabiencoder::EncoderBuilder::new(
+            binary, function, load, packed, args, tys, false, ns,
+        );
 
         let mut length = encoder.encoded_length();
 
@@ -738,7 +761,7 @@ impl EwasmTarget {
             };
         }
 
-        encoder.finish(binary, function, data);
+        encoder.finish(binary, function, data, ns);
 
         (encoded_data, length)
     }
@@ -819,6 +842,7 @@ impl<'a> TargetRuntime<'a> for EwasmTarget {
         _binary: &Binary<'a>,
         _function: FunctionValue,
         _slot: PointerValue<'a>,
+        _ns: &ast::Namespace,
     ) -> PointerValue<'a> {
         unimplemented!();
     }
@@ -848,6 +872,7 @@ impl<'a> TargetRuntime<'a> for EwasmTarget {
         _ty: &ast::Type,
         _slot: IntValue<'a>,
         _val: BasicValueEnum<'a>,
+        _ns: &ast::Namespace,
     ) -> BasicValueEnum<'a> {
         unimplemented!();
     }
@@ -857,6 +882,7 @@ impl<'a> TargetRuntime<'a> for EwasmTarget {
         _function: FunctionValue<'a>,
         _ty: &ast::Type,
         _slot: IntValue<'a>,
+        _ns: &ast::Namespace,
     ) -> BasicValueEnum<'a> {
         unimplemented!();
     }
@@ -998,12 +1024,15 @@ impl<'a> TargetRuntime<'a> for EwasmTarget {
         src: PointerValue,
         length: IntValue,
         dest: PointerValue,
+        ns: &ast::Namespace,
     ) {
-        let balance = binary.builder.build_alloca(binary.value_type(), "balance");
+        let balance = binary
+            .builder
+            .build_alloca(binary.value_type(ns), "balance");
 
         binary
             .builder
-            .build_store(balance, binary.value_type().const_zero());
+            .build_store(balance, binary.value_type(ns).const_zero());
 
         let keccak256_pre_compile_address: [u8; 20] =
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20];
@@ -1133,8 +1162,9 @@ impl<'a> TargetRuntime<'a> for EwasmTarget {
         packed: &[BasicValueEnum<'b>],
         args: &[BasicValueEnum<'b>],
         tys: &[ast::Type],
+        ns: &ast::Namespace,
     ) -> PointerValue<'b> {
-        ethabiencoder::encode_to_vector(binary, function, packed, args, tys, false)
+        ethabiencoder::encode_to_vector(binary, function, packed, args, tys, false, ns)
     }
 
     fn abi_encode<'b>(
@@ -1145,6 +1175,7 @@ impl<'a> TargetRuntime<'a> for EwasmTarget {
         function: FunctionValue<'b>,
         args: &[BasicValueEnum<'b>],
         tys: &[ast::Type],
+        ns: &ast::Namespace,
     ) -> (PointerValue<'b>, IntValue<'b>) {
         let mut tys = tys.to_vec();
 
@@ -1155,7 +1186,7 @@ impl<'a> TargetRuntime<'a> for EwasmTarget {
             vec![]
         };
 
-        self.encode(binary, None, load, function, &packed, args, &tys)
+        self.encode(binary, None, load, function, &packed, args, &tys, ns)
     }
 
     fn abi_decode<'b>(
@@ -1166,8 +1197,10 @@ impl<'a> TargetRuntime<'a> for EwasmTarget {
         data: PointerValue<'b>,
         length: IntValue<'b>,
         spec: &[ast::Parameter],
+        ns: &ast::Namespace,
     ) {
-        self.abi.decode(binary, function, args, data, length, spec);
+        self.abi
+            .decode(binary, function, args, data, length, spec, ns);
     }
 
     fn print(&self, binary: &Binary, string_ptr: PointerValue, string_len: IntValue) {
@@ -1190,13 +1223,14 @@ impl<'a> TargetRuntime<'a> for EwasmTarget {
         _gas: IntValue<'b>,
         value: Option<IntValue<'b>>,
         _salt: Option<IntValue<'b>>,
+        ns: &ast::Namespace,
     ) {
-        let resolver_binary = &binary.ns.contracts[contract_no];
+        let resolver_binary = &ns.contracts[contract_no];
 
         let target_binary = Binary::build(
             binary.context,
             &resolver_binary,
-            binary.ns,
+            ns,
             "",
             binary.opt,
             binary.math_overflow_check,
@@ -1212,7 +1246,7 @@ impl<'a> TargetRuntime<'a> for EwasmTarget {
         );
 
         let tys: Vec<ast::Type> = match constructor_no {
-            Some(function_no) => binary.ns.functions[function_no]
+            Some(function_no) => ns.functions[function_no]
                 .params
                 .iter()
                 .map(|p| p.ty.clone())
@@ -1229,23 +1263,26 @@ impl<'a> TargetRuntime<'a> for EwasmTarget {
             &[],
             args,
             &tys,
+            ns,
         );
 
         // value is a u128
-        let value_ptr = binary.builder.build_alloca(binary.value_type(), "balance");
+        let value_ptr = binary
+            .builder
+            .build_alloca(binary.value_type(ns), "balance");
 
         binary.builder.build_store(
             value_ptr,
             match value {
                 Some(v) => v,
-                None => binary.value_type().const_zero(),
+                None => binary.value_type(ns).const_zero(),
             },
         );
 
         // address needs its bytes reordered
         let be_address = binary
             .builder
-            .build_alloca(binary.address_type(), "be_address");
+            .build_alloca(binary.address_type(ns), "be_address");
 
         // call create
         let ret = binary
@@ -1346,11 +1383,12 @@ impl<'a> TargetRuntime<'a> for EwasmTarget {
         gas: IntValue<'b>,
         value: IntValue<'b>,
         callty: ast::CallTy,
+        ns: &ast::Namespace,
     ) {
         // address needs its bytes reordered
         let be_address = binary
             .builder
-            .build_alloca(binary.address_type(), "be_address");
+            .build_alloca(binary.address_type(ns), "be_address");
 
         binary.builder.build_call(
             binary.module.get_function("__leNtobeN").unwrap(),
@@ -1382,7 +1420,9 @@ impl<'a> TargetRuntime<'a> for EwasmTarget {
             // needs value
 
             // value is a u128
-            let value_ptr = binary.builder.build_alloca(binary.value_type(), "balance");
+            let value_ptr = binary
+                .builder
+                .build_alloca(binary.value_type(ns), "balance");
             binary.builder.build_store(value_ptr, value);
 
             // call create
@@ -1587,10 +1627,10 @@ impl<'a> TargetRuntime<'a> for EwasmTarget {
     }
 
     /// ewasm value is always 128 bits
-    fn value_transferred<'b>(&self, binary: &Binary<'b>) -> IntValue<'b> {
+    fn value_transferred<'b>(&self, binary: &Binary<'b>, ns: &ast::Namespace) -> IntValue<'b> {
         let value = binary
             .builder
-            .build_alloca(binary.value_type(), "value_transferred");
+            .build_alloca(binary.value_type(ns), "value_transferred");
 
         binary.builder.build_call(
             binary.module.get_function("getCallValue").unwrap(),
@@ -1612,10 +1652,10 @@ impl<'a> TargetRuntime<'a> for EwasmTarget {
     }
 
     /// Terminate execution, destroy binary and send remaining funds to addr
-    fn selfdestruct<'b>(&self, binary: &Binary<'b>, addr: IntValue<'b>) {
+    fn selfdestruct<'b>(&self, binary: &Binary<'b>, addr: IntValue<'b>, ns: &ast::Namespace) {
         let address = binary
             .builder
-            .build_alloca(binary.address_type(), "address");
+            .build_alloca(binary.address_type(ns), "address");
 
         binary.builder.build_store(address, addr);
 
@@ -1640,6 +1680,7 @@ impl<'a> TargetRuntime<'a> for EwasmTarget {
         hash: HashTy,
         input: PointerValue<'b>,
         input_len: IntValue<'b>,
+        ns: &ast::Namespace,
     ) -> IntValue<'b> {
         let (precompile, hashlen) = match hash {
             HashTy::Keccak256 => (
@@ -1663,11 +1704,13 @@ impl<'a> TargetRuntime<'a> for EwasmTarget {
             "res",
         );
 
-        let balance = binary.builder.build_alloca(binary.value_type(), "balance");
+        let balance = binary
+            .builder
+            .build_alloca(binary.value_type(ns), "balance");
 
         binary
             .builder
-            .build_store(balance, binary.value_type().const_zero());
+            .build_store(balance, binary.value_type(ns).const_zero());
 
         let address = binary.emit_global_string(&format!("precompile_{}", hash), &precompile, true);
 
@@ -1715,9 +1758,10 @@ impl<'a> TargetRuntime<'a> for EwasmTarget {
         );
 
         // bytes32 needs to reverse bytes
-        let temp = binary
-            .builder
-            .build_alloca(binary.llvm_type(&ast::Type::Bytes(hashlen as u8)), "hash");
+        let temp = binary.builder.build_alloca(
+            binary.llvm_type(&ast::Type::Bytes(hashlen as u8), ns),
+            "hash",
+        );
 
         binary.builder.build_call(
             binary.module.get_function("__beNtoleN").unwrap(),
@@ -1747,6 +1791,7 @@ impl<'a> TargetRuntime<'a> for EwasmTarget {
         data: PointerValue<'b>,
         data_len: IntValue<'b>,
         topics: Vec<(PointerValue<'b>, IntValue<'b>)>,
+        ns: &ast::Namespace,
     ) {
         let empty_topic = binary
             .context
@@ -1756,7 +1801,7 @@ impl<'a> TargetRuntime<'a> for EwasmTarget {
 
         let mut encoded_topics = [empty_topic; 4];
 
-        let event = &binary.ns.events[event_no];
+        let event = &ns.events[event_no];
 
         let mut topic_count = 0;
 
@@ -1782,7 +1827,7 @@ impl<'a> TargetRuntime<'a> for EwasmTarget {
                     "hash",
                 );
 
-                self.keccak256_hash(binary, ptr, len, dest);
+                self.keccak256_hash(binary, ptr, len, dest, ns);
 
                 encoded_topics[topic_count] = dest;
             }
@@ -1816,6 +1861,7 @@ impl<'a> TargetRuntime<'a> for EwasmTarget {
         expr: &ast::Expression,
         vartab: &HashMap<usize, Variable<'b>>,
         function: FunctionValue<'b>,
+        ns: &ast::Namespace,
     ) -> BasicValueEnum<'b> {
         macro_rules! straight_call {
             ($name:literal, $func:literal) => {{
@@ -1868,26 +1914,22 @@ impl<'a> TargetRuntime<'a> for EwasmTarget {
                 single_value_stack!("block_difficulty", "getBlockDifficulty", 256)
             }
             ast::Expression::Builtin(_, _, ast::Builtin::Origin, _) => {
-                single_value_stack!("origin", "getTxOrigin", binary.ns.address_length as u32 * 8)
+                single_value_stack!("origin", "getTxOrigin", ns.address_length as u32 * 8)
             }
             ast::Expression::Builtin(_, _, ast::Builtin::Sender, _) => {
-                single_value_stack!("caller", "getCaller", binary.ns.address_length as u32 * 8)
+                single_value_stack!("caller", "getCaller", ns.address_length as u32 * 8)
+            }
+            ast::Expression::Builtin(_, _, ast::Builtin::BlockCoinbase, _) => {
+                single_value_stack!("coinbase", "getBlockCoinbase", ns.address_length as u32 * 8)
+            }
+            ast::Expression::Builtin(_, _, ast::Builtin::Gasprice, _) => {
+                single_value_stack!("gas_price", "getTxGasPrice", ns.value_length as u32 * 8)
             }
-            ast::Expression::Builtin(_, _, ast::Builtin::BlockCoinbase, _) => single_value_stack!(
-                "coinbase",
-                "getBlockCoinbase",
-                binary.ns.address_length as u32 * 8
-            ),
-            ast::Expression::Builtin(_, _, ast::Builtin::Gasprice, _) => single_value_stack!(
-                "gas_price",
-                "getTxGasPrice",
-                binary.ns.value_length as u32 * 8
-            ),
             ast::Expression::Builtin(_, _, ast::Builtin::Value, _) => {
-                single_value_stack!("value", "getCallValue", binary.ns.value_length as u32 * 8)
+                single_value_stack!("value", "getCallValue", ns.value_length as u32 * 8)
             }
             ast::Expression::Builtin(_, _, ast::Builtin::BlockHash, args) => {
-                let block_number = self.expression(binary, &args[0], vartab, function);
+                let block_number = self.expression(binary, &args[0], vartab, function, ns);
 
                 let value = binary
                     .builder
@@ -1914,7 +1956,7 @@ impl<'a> TargetRuntime<'a> for EwasmTarget {
             ast::Expression::Builtin(_, _, ast::Builtin::GetAddress, _) => {
                 let value = binary
                     .builder
-                    .build_alloca(binary.address_type(), "self_address");
+                    .build_alloca(binary.address_type(ns), "self_address");
 
                 binary.builder.build_call(
                     binary.module.get_function("getAddress").unwrap(),
@@ -1933,16 +1975,18 @@ impl<'a> TargetRuntime<'a> for EwasmTarget {
             }
             ast::Expression::Builtin(_, _, ast::Builtin::Balance, addr) => {
                 let addr = self
-                    .expression(binary, &addr[0], vartab, function)
+                    .expression(binary, &addr[0], vartab, function, ns)
                     .into_int_value();
 
                 let address = binary
                     .builder
-                    .build_alloca(binary.address_type(), "address");
+                    .build_alloca(binary.address_type(ns), "address");
 
                 binary.builder.build_store(address, addr);
 
-                let balance = binary.builder.build_alloca(binary.value_type(), "balance");
+                let balance = binary
+                    .builder
+                    .build_alloca(binary.value_type(ns), "balance");
 
                 binary.builder.build_call(
                     binary.module.get_function("getExternalBalance").unwrap(),

+ 47 - 16
src/emit/generic.rs

@@ -45,10 +45,10 @@ impl GenericTarget {
         // externals
         b.declare_externals(&mut binary);
 
-        b.emit_functions(&mut binary, contract);
+        b.emit_functions(&mut binary, contract, ns);
 
-        b.emit_constructor(&mut binary, contract);
-        b.emit_function(&mut binary, contract);
+        b.emit_constructor(&mut binary, contract, ns);
+        b.emit_function(&mut binary, contract, ns);
 
         binary
     }
@@ -102,8 +102,13 @@ impl GenericTarget {
         );
     }
 
-    fn emit_constructor(&mut self, binary: &mut Binary, contract: &ast::Contract) {
-        let initializer = self.emit_initializer(binary, contract);
+    fn emit_constructor(
+        &mut self,
+        binary: &mut Binary,
+        contract: &ast::Contract,
+        ns: &ast::Namespace,
+    ) {
+        let initializer = self.emit_initializer(binary, contract, ns);
 
         let u8_ptr_ty = binary.context.i8_type().ptr_type(AddressSpace::Generic);
         let u32_ty = binary.context.i32_type();
@@ -129,14 +134,21 @@ impl GenericTarget {
             .functions
             .iter()
             .enumerate()
-            .map(|(cfg_no, function_no)| (cfg_no, &binary.ns.functions[*function_no]))
+            .map(|(cfg_no, function_no)| (cfg_no, &ns.functions[*function_no]))
             .find(|(_, f)| f.is_constructor())
         {
             let mut args = Vec::new();
 
             // insert abi decode
-            self.abi
-                .decode(binary, function, &mut args, argsdata, argslen, &con.params);
+            self.abi.decode(
+                binary,
+                function,
+                &mut args,
+                argsdata,
+                argslen,
+                &con.params,
+                ns,
+            );
 
             binary
                 .builder
@@ -150,7 +162,12 @@ impl GenericTarget {
     }
 
     // emit function dispatch
-    fn emit_function<'s>(&'s mut self, binary: &'s mut Binary, contract: &ast::Contract) {
+    fn emit_function<'s>(
+        &'s mut self,
+        binary: &'s mut Binary,
+        contract: &ast::Contract,
+        ns: &ast::Namespace,
+    ) {
         let u8_ptr_ty = binary.context.i8_type().ptr_type(AddressSpace::Generic);
         let u32_ty = binary.context.i32_type();
 
@@ -175,6 +192,7 @@ impl GenericTarget {
         self.emit_function_dispatch(
             binary,
             contract,
+            ns,
             pt::FunctionTy::Function,
             argsdata,
             argslen,
@@ -297,6 +315,7 @@ impl<'a> TargetRuntime<'a> for GenericTarget {
         _contract: &Binary<'a>,
         _function: FunctionValue,
         _slot: PointerValue<'a>,
+        _ns: &ast::Namespace,
     ) -> PointerValue<'a> {
         unimplemented!();
     }
@@ -317,6 +336,7 @@ impl<'a> TargetRuntime<'a> for GenericTarget {
         _ty: &ast::Type,
         _slot: IntValue<'a>,
         _val: BasicValueEnum<'a>,
+        _ns: &ast::Namespace,
     ) -> BasicValueEnum<'a> {
         unimplemented!();
     }
@@ -326,6 +346,7 @@ impl<'a> TargetRuntime<'a> for GenericTarget {
         _function: FunctionValue,
         _ty: &ast::Type,
         _slot: IntValue<'a>,
+        _ns: &ast::Namespace,
     ) -> BasicValueEnum<'a> {
         unimplemented!();
     }
@@ -335,6 +356,7 @@ impl<'a> TargetRuntime<'a> for GenericTarget {
         _function: FunctionValue,
         slot: IntValue<'a>,
         _ty: &ast::Type,
+        _ns: &ast::Namespace,
     ) -> IntValue<'a> {
         let slot_ptr = contract.builder.build_alloca(slot.get_type(), "slot");
         contract.builder.build_store(slot_ptr, slot);
@@ -450,6 +472,7 @@ impl<'a> TargetRuntime<'a> for GenericTarget {
         src: PointerValue,
         length: IntValue,
         dest: PointerValue,
+        _ns: &ast::Namespace,
     ) {
         contract.builder.build_call(
             contract.module.get_function("keccak256").unwrap(),
@@ -513,8 +536,9 @@ impl<'a> TargetRuntime<'a> for GenericTarget {
         packed: &[BasicValueEnum<'b>],
         args: &[BasicValueEnum<'b>],
         tys: &[ast::Type],
+        ns: &ast::Namespace,
     ) -> PointerValue<'b> {
-        ethabiencoder::encode_to_vector(contract, function, packed, args, tys, false)
+        ethabiencoder::encode_to_vector(contract, function, packed, args, tys, false, ns)
     }
 
     fn abi_encode<'b>(
@@ -525,6 +549,7 @@ impl<'a> TargetRuntime<'a> for GenericTarget {
         function: FunctionValue<'b>,
         args: &[BasicValueEnum<'b>],
         tys: &[ast::Type],
+        ns: &ast::Namespace,
     ) -> (PointerValue<'b>, IntValue<'b>) {
         let mut tys = tys.to_vec();
 
@@ -536,7 +561,7 @@ impl<'a> TargetRuntime<'a> for GenericTarget {
         };
 
         let encoder = ethabiencoder::EncoderBuilder::new(
-            contract, function, load, args, &packed, &tys, false,
+            contract, function, load, args, &packed, &tys, false, ns,
         );
 
         let length = encoder.encoded_length();
@@ -553,7 +578,7 @@ impl<'a> TargetRuntime<'a> for GenericTarget {
             .unwrap()
             .into_pointer_value();
 
-        encoder.finish(contract, function, encoded_data);
+        encoder.finish(contract, function, encoded_data, ns);
 
         (encoded_data, length)
     }
@@ -566,9 +591,10 @@ impl<'a> TargetRuntime<'a> for GenericTarget {
         data: PointerValue<'b>,
         length: IntValue<'b>,
         spec: &[ast::Parameter],
+        ns: &ast::Namespace,
     ) {
         self.abi
-            .decode(contract, function, args, data, length, spec);
+            .decode(contract, function, args, data, length, spec, ns);
     }
 
     fn print(&self, contract: &Binary, string_ptr: PointerValue, string_len: IntValue) {
@@ -592,6 +618,7 @@ impl<'a> TargetRuntime<'a> for GenericTarget {
         _gas: IntValue<'b>,
         _value: Option<IntValue<'b>>,
         _salt: Option<IntValue<'b>>,
+        _ns: &ast::Namespace,
     ) {
         panic!("generic cannot create new contracts");
     }
@@ -608,6 +635,7 @@ impl<'a> TargetRuntime<'a> for GenericTarget {
         _gas: IntValue<'b>,
         _value: IntValue<'b>,
         _ty: ast::CallTy,
+        _ns: &ast::Namespace,
     ) {
         panic!("generic cannot call other contracts");
     }
@@ -622,12 +650,12 @@ impl<'a> TargetRuntime<'a> for GenericTarget {
     }
 
     /// Sabre does not know about balances
-    fn value_transferred<'b>(&self, binary: &Binary<'b>) -> IntValue<'b> {
-        binary.value_type().const_zero()
+    fn value_transferred<'b>(&self, binary: &Binary<'b>, ns: &ast::Namespace) -> IntValue<'b> {
+        binary.value_type(ns).const_zero()
     }
 
     /// Terminate execution, destroy contract and send remaining funds to addr
-    fn selfdestruct<'b>(&self, _binary: &Binary<'b>, _addr: IntValue<'b>) {
+    fn selfdestruct<'b>(&self, _binary: &Binary<'b>, _addr: IntValue<'b>, _ns: &ast::Namespace) {
         panic!("generic does not have the concept of selfdestruct");
     }
 
@@ -639,6 +667,7 @@ impl<'a> TargetRuntime<'a> for GenericTarget {
         _data: PointerValue<'b>,
         _data_len: IntValue<'b>,
         _topics: Vec<(PointerValue<'b>, IntValue<'b>)>,
+        _ns: &ast::Namespace,
     ) {
         unimplemented!();
     }
@@ -650,6 +679,7 @@ impl<'a> TargetRuntime<'a> for GenericTarget {
         _expr: &ast::Expression,
         _vartab: &HashMap<usize, Variable<'b>>,
         _function: FunctionValue<'b>,
+        _ns: &ast::Namespace,
     ) -> BasicValueEnum<'b> {
         unimplemented!();
     }
@@ -661,6 +691,7 @@ impl<'a> TargetRuntime<'a> for GenericTarget {
         _hash: HashTy,
         _input: PointerValue<'b>,
         _input_len: IntValue<'b>,
+        _ns: &ast::Namespace,
     ) -> IntValue<'b> {
         unimplemented!()
     }

File diff suppressed because it is too large
+ 250 - 108
src/emit/mod.rs


+ 41 - 14
src/emit/sabre.rs

@@ -44,9 +44,9 @@ impl SabreTarget {
         // externals
         b.declare_externals(&mut c);
 
-        b.emit_functions(&mut c, contract);
+        b.emit_functions(&mut c, contract, ns);
 
-        b.emit_entrypoint(&mut c, contract);
+        b.emit_entrypoint(&mut c, contract, ns);
 
         c.internalize(&[
             "entrypoint",
@@ -114,8 +114,13 @@ impl SabreTarget {
         );
     }
 
-    fn emit_entrypoint(&mut self, binary: &mut Binary, contract: &ast::Contract) {
-        let initializer = self.emit_initializer(binary, contract);
+    fn emit_entrypoint(
+        &mut self,
+        binary: &mut Binary,
+        contract: &ast::Contract,
+        ns: &ast::Namespace,
+    ) {
+        let initializer = self.emit_initializer(binary, contract, ns);
 
         let bytes_ptr = binary.context.i32_type().ptr_type(AddressSpace::Generic);
 
@@ -184,14 +189,21 @@ impl SabreTarget {
             .functions
             .iter()
             .enumerate()
-            .map(|(cfg_no, function_no)| (cfg_no, &binary.ns.functions[*function_no]))
+            .map(|(cfg_no, function_no)| (cfg_no, &ns.functions[*function_no]))
             .find(|(_, f)| f.is_constructor())
         {
             let mut args = Vec::new();
 
             // insert abi decode
-            self.abi
-                .decode(binary, function, &mut args, argsdata, argslen, &con.params);
+            self.abi.decode(
+                binary,
+                function,
+                &mut args,
+                argsdata,
+                argslen,
+                &con.params,
+                ns,
+            );
 
             binary
                 .builder
@@ -208,6 +220,7 @@ impl SabreTarget {
         self.emit_function_dispatch(
             binary,
             contract,
+            ns,
             pt::FunctionTy::Function,
             argsdata,
             argslen,
@@ -368,6 +381,7 @@ impl<'a> TargetRuntime<'a> for SabreTarget {
         _binary: &Binary<'a>,
         _function: FunctionValue,
         _slot: PointerValue<'a>,
+        _ns: &ast::Namespace,
     ) -> PointerValue<'a> {
         unimplemented!();
     }
@@ -416,6 +430,7 @@ impl<'a> TargetRuntime<'a> for SabreTarget {
         _ty: &ast::Type,
         _slot: IntValue<'a>,
         _val: BasicValueEnum<'a>,
+        _ns: &ast::Namespace,
     ) -> BasicValueEnum<'a> {
         unimplemented!();
     }
@@ -425,6 +440,7 @@ impl<'a> TargetRuntime<'a> for SabreTarget {
         _function: FunctionValue,
         _ty: &ast::Type,
         _slot: IntValue<'a>,
+        _ns: &ast::Namespace,
     ) -> BasicValueEnum<'a> {
         unimplemented!();
     }
@@ -538,6 +554,7 @@ impl<'a> TargetRuntime<'a> for SabreTarget {
         src: PointerValue,
         length: IntValue,
         dest: PointerValue,
+        _ns: &ast::Namespace,
     ) {
         binary.builder.build_call(
             binary.module.get_function("keccak256").unwrap(),
@@ -591,6 +608,7 @@ impl<'a> TargetRuntime<'a> for SabreTarget {
         _packed: &[BasicValueEnum<'b>],
         _args: &[BasicValueEnum<'b>],
         _spec: &[ast::Type],
+        _ns: &ast::Namespace,
     ) -> PointerValue<'b> {
         unimplemented!();
     }
@@ -603,6 +621,7 @@ impl<'a> TargetRuntime<'a> for SabreTarget {
         function: FunctionValue<'b>,
         args: &[BasicValueEnum<'b>],
         tys: &[ast::Type],
+        ns: &ast::Namespace,
     ) -> (PointerValue<'b>, IntValue<'b>) {
         let mut tys = tys.to_vec();
 
@@ -613,8 +632,9 @@ impl<'a> TargetRuntime<'a> for SabreTarget {
             vec![]
         };
 
-        let encoder =
-            ethabiencoder::EncoderBuilder::new(binary, function, load, args, &packed, &tys, false);
+        let encoder = ethabiencoder::EncoderBuilder::new(
+            binary, function, load, args, &packed, &tys, false, ns,
+        );
 
         let length = encoder.encoded_length();
 
@@ -630,7 +650,7 @@ impl<'a> TargetRuntime<'a> for SabreTarget {
             .unwrap()
             .into_pointer_value();
 
-        encoder.finish(binary, function, encoded_data);
+        encoder.finish(binary, function, encoded_data, ns);
 
         (encoded_data, length)
     }
@@ -643,8 +663,10 @@ impl<'a> TargetRuntime<'a> for SabreTarget {
         data: PointerValue<'b>,
         length: IntValue<'b>,
         spec: &[ast::Parameter],
+        ns: &ast::Namespace,
     ) {
-        self.abi.decode(binary, function, args, data, length, spec);
+        self.abi
+            .decode(binary, function, args, data, length, spec, ns);
     }
 
     fn print(&self, binary: &Binary, string_ptr: PointerValue, string_len: IntValue) {
@@ -672,6 +694,7 @@ impl<'a> TargetRuntime<'a> for SabreTarget {
         _gas: IntValue<'b>,
         _value: Option<IntValue<'b>>,
         _salt: Option<IntValue<'b>>,
+        _ns: &ast::Namespace,
     ) {
         panic!("Sabre cannot create new binarys");
     }
@@ -688,6 +711,7 @@ impl<'a> TargetRuntime<'a> for SabreTarget {
         _gas: IntValue<'b>,
         _value: IntValue<'b>,
         _ty: ast::CallTy,
+        _ns: &ast::Namespace,
     ) {
         panic!("Sabre cannot call other binarys");
     }
@@ -702,12 +726,12 @@ impl<'a> TargetRuntime<'a> for SabreTarget {
     }
 
     /// Sabre does not know about balances
-    fn value_transferred<'b>(&self, binary: &Binary<'b>) -> IntValue<'b> {
-        binary.value_type().const_zero()
+    fn value_transferred<'b>(&self, binary: &Binary<'b>, ns: &ast::Namespace) -> IntValue<'b> {
+        binary.value_type(ns).const_zero()
     }
 
     /// Terminate execution, destroy binary and send remaining funds to addr
-    fn selfdestruct<'b>(&self, _binary: &Binary<'b>, _addr: IntValue<'b>) {
+    fn selfdestruct<'b>(&self, _binary: &Binary<'b>, _addr: IntValue<'b>, _ns: &ast::Namespace) {
         panic!("Sabre does not have the concept of selfdestruct");
     }
 
@@ -719,6 +743,7 @@ impl<'a> TargetRuntime<'a> for SabreTarget {
         _data: PointerValue<'b>,
         _data_len: IntValue<'b>,
         _topics: Vec<(PointerValue<'b>, IntValue<'b>)>,
+        _ns: &ast::Namespace,
     ) {
         unimplemented!();
     }
@@ -730,6 +755,7 @@ impl<'a> TargetRuntime<'a> for SabreTarget {
         _expr: &ast::Expression,
         _vartab: &HashMap<usize, Variable<'b>>,
         _function: FunctionValue<'b>,
+        _ns: &ast::Namespace,
     ) -> BasicValueEnum<'b> {
         unimplemented!();
     }
@@ -741,6 +767,7 @@ impl<'a> TargetRuntime<'a> for SabreTarget {
         _hash: HashTy,
         _input: PointerValue<'b>,
         _input_len: IntValue<'b>,
+        _ns: &ast::Namespace,
     ) -> IntValue<'b> {
         unimplemented!()
     }

+ 104 - 64
src/emit/solana.rs

@@ -76,9 +76,9 @@ impl SolanaTarget {
         // externals
         target.declare_externals(&mut binary);
 
-        target.emit_functions(&mut binary, contract);
+        target.emit_functions(&mut binary, contract, ns);
 
-        let storage_initializer = target.emit_initializer(&mut binary, contract);
+        let storage_initializer = target.emit_initializer(&mut binary, contract, ns);
 
         let constructor = contract
             .cfg
@@ -95,6 +95,7 @@ impl SolanaTarget {
                 storage_initializer,
                 constructor,
             }],
+            ns,
         );
 
         binary.internalize(&[
@@ -161,9 +162,9 @@ impl SolanaTarget {
 
             target.magic = u32::from_le_bytes(hash[0..4].try_into().unwrap());
 
-            target.emit_functions(&mut binary, contract);
+            target.emit_functions(&mut binary, contract, ns);
 
-            let storage_initializer = target.emit_initializer(&mut binary, contract);
+            let storage_initializer = target.emit_initializer(&mut binary, contract, ns);
 
             let constructor = contract
                 .cfg
@@ -182,7 +183,7 @@ impl SolanaTarget {
             binary.functions.drain();
         }
 
-        target.emit_dispatch(&mut binary, &contracts);
+        target.emit_dispatch(&mut binary, &contracts, ns);
 
         binary.internalize(&[
             "entrypoint",
@@ -364,7 +365,12 @@ impl SolanaTarget {
             .into_int_value()
     }
 
-    fn emit_dispatch<'b>(&mut self, binary: &mut Binary<'b>, contracts: &[Contract<'b>]) {
+    fn emit_dispatch<'b>(
+        &mut self,
+        binary: &mut Binary<'b>,
+        contracts: &[Contract<'b>],
+        ns: &ast::Namespace,
+    ) {
         let function = binary.module.get_function("solang_dispatch").unwrap();
 
         let entry = binary.context.append_basic_block(function, "entry");
@@ -470,6 +476,7 @@ impl SolanaTarget {
             self.emit_function_dispatch(
                 binary,
                 &contract.contract,
+                ns,
                 pt::FunctionTy::Function,
                 input,
                 input_len,
@@ -585,7 +592,7 @@ impl SolanaTarget {
 
                 // insert abi decode
                 self.abi
-                    .decode(binary, function, &mut args, input, input_len, params);
+                    .decode(binary, function, &mut args, input, input_len, params, ns);
 
                 let params_ty = constructor_function
                     .get_type()
@@ -642,8 +649,9 @@ impl SolanaTarget {
         slot: IntValue<'b>,
         function: FunctionValue<'b>,
         zero: bool,
+        ns: &ast::Namespace,
     ) {
-        if !zero && !ty.is_dynamic(binary.ns) {
+        if !zero && !ty.is_dynamic(ns) {
             // nothing to do
             return;
         }
@@ -683,7 +691,7 @@ impl SolanaTarget {
                 "offset_ptr",
             );
 
-            if elem_ty.is_dynamic(binary.ns) || zero {
+            if elem_ty.is_dynamic(ns) || zero {
                 let length = if let Some(length) = dim[0].as_ref() {
                     binary
                         .context
@@ -695,10 +703,10 @@ impl SolanaTarget {
                         .build_load(offset_ptr, "offset")
                         .into_int_value();
 
-                    self.storage_array_length(binary, function, slot, elem_ty)
+                    self.storage_array_length(binary, function, slot, elem_ty, ns)
                 };
 
-                let elem_size = elem_ty.size_of(binary.ns).to_u64().unwrap();
+                let elem_size = elem_ty.size_of(ns).to_u64().unwrap();
 
                 // loop over the array
                 let mut builder = LoopBuilder::new(binary, function);
@@ -720,6 +728,7 @@ impl SolanaTarget {
                     offset_val,
                     function,
                     zero,
+                    ns,
                 );
 
                 let offset_val = binary.builder.build_int_add(
@@ -754,8 +763,8 @@ impl SolanaTarget {
                 binary.builder.build_store(offset_ptr, new_offset);
             }
         } else if let ast::Type::Struct(struct_no) = ty {
-            for (i, field) in binary.ns.structs[*struct_no].fields.iter().enumerate() {
-                let field_offset = binary.ns.structs[*struct_no].offsets[i].to_u64().unwrap();
+            for (i, field) in ns.structs[*struct_no].fields.iter().enumerate() {
+                let field_offset = ns.structs[*struct_no].offsets[i].to_u64().unwrap();
 
                 let offset = binary.builder.build_int_add(
                     slot,
@@ -763,10 +772,10 @@ impl SolanaTarget {
                     "field_offset",
                 );
 
-                self.storage_free(binary, &field.ty, data, offset, function, zero);
+                self.storage_free(binary, &field.ty, data, offset, function, zero, ns);
             }
         } else {
-            let ty = binary.llvm_type(ty);
+            let ty = binary.llvm_type(ty, ns);
 
             binary.builder.build_store(
                 binary
@@ -783,6 +792,7 @@ impl SolanaTarget {
         binary: &Binary<'b>,
         key_ty: &ast::Type,
         value_ty: &ast::Type,
+        ns: &ast::Namespace,
     ) -> BasicTypeEnum<'b> {
         let key = if matches!(
             key_ty,
@@ -790,7 +800,7 @@ impl SolanaTarget {
         ) {
             binary.context.i32_type().into()
         } else {
-            binary.llvm_type(key_ty)
+            binary.llvm_type(key_ty, ns)
         };
 
         binary
@@ -802,7 +812,7 @@ impl SolanaTarget {
                     if value_ty.is_mapping() {
                         binary.context.i32_type().into()
                     } else {
-                        binary.llvm_type(value_ty) // value
+                        binary.llvm_type(value_ty, ns) // value
                     },
                 ],
                 false,
@@ -816,11 +826,12 @@ impl SolanaTarget {
         binary: &Binary<'b>,
         key_ty: &ast::Type,
         value_ty: &ast::Type,
+        ns: &ast::Namespace,
     ) -> FunctionValue<'b> {
         let function_name = format!(
             "sparse_lookup_{}_{}",
-            key_ty.to_wasm_string(binary.ns),
-            value_ty.to_wasm_string(binary.ns)
+            key_ty.to_wasm_string(ns),
+            value_ty.to_wasm_string(ns)
         );
 
         if let Some(function) = binary.module.get_function(&function_name) {
@@ -832,6 +843,7 @@ impl SolanaTarget {
         let function_ty = binary.function_type(
             &[ast::Type::Uint(32), key_ty.clone()],
             &[ast::Type::Uint(32)],
+            ns,
         );
 
         let function =
@@ -846,7 +858,7 @@ impl SolanaTarget {
         let offset = function.get_nth_param(0).unwrap().into_int_value();
         let key = function.get_nth_param(1).unwrap();
 
-        let entry_ty = self.sparse_entry(binary, key_ty, value_ty);
+        let entry_ty = self.sparse_entry(binary, key_ty, value_ty, ns);
         let value_offset = unsafe {
             entry_ty
                 .ptr_type(AddressSpace::Generic)
@@ -880,7 +892,7 @@ impl SolanaTarget {
                 .left()
                 .unwrap()
                 .into_int_value()
-        } else if key_ty.bits(binary.ns) > 64 {
+        } else if key_ty.bits(ns) > 64 {
             binary
                 .builder
                 .build_int_truncate(key.into_int_value(), binary.context.i64_type(), "")
@@ -1224,12 +1236,13 @@ impl SolanaTarget {
         value_ty: &ast::Type,
         slot: IntValue<'b>,
         index: BasicValueEnum<'b>,
+        ns: &ast::Namespace,
     ) -> IntValue<'b> {
         let offset = binary.build_alloca(function, binary.context.i32_type(), "offset");
 
         let current_block = binary.builder.get_insert_block().unwrap();
 
-        let lookup = self.sparse_lookup_function(binary, key_ty, value_ty);
+        let lookup = self.sparse_lookup_function(binary, key_ty, value_ty, ns);
 
         binary.builder.position_at_end(current_block);
 
@@ -1288,11 +1301,12 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         ty: &ast::Type,
         slot: &mut IntValue<'a>,
         function: FunctionValue<'a>,
+        ns: &ast::Namespace,
     ) {
         // binary storage is in 2nd account
         let data = self.contract_storage_data(binary);
 
-        self.storage_free(binary, ty, data, *slot, function, true);
+        self.storage_free(binary, ty, data, *slot, function, true, ns);
     }
 
     fn set_storage_extfunc(
@@ -1309,6 +1323,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         _binary: &Binary<'a>,
         _function: FunctionValue,
         _slot: PointerValue<'a>,
+        _ns: &ast::Namespace,
     ) -> PointerValue<'a> {
         unimplemented!();
     }
@@ -1475,18 +1490,19 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         ty: &ast::Type,
         slot: IntValue<'a>,
         index: BasicValueEnum<'a>,
+        ns: &ast::Namespace,
     ) -> IntValue<'a> {
         let account = self.contract_storage_account(binary);
 
         if let ast::Type::Mapping(key, value) = ty.deref_any() {
-            self.sparse_lookup(binary, function, key, value, slot, index)
-        } else if ty.is_sparse_solana(binary.ns) {
+            self.sparse_lookup(binary, function, key, value, slot, index, ns)
+        } else if ty.is_sparse_solana(ns) {
             // sparse array
             let elem_ty = ty.storage_array_elem().deref_into();
 
             let key = ast::Type::Uint(256);
 
-            self.sparse_lookup(binary, function, &key, &elem_ty, slot, index)
+            self.sparse_lookup(binary, function, &key, &elem_ty, slot, index, ns)
         } else {
             // 3rd member of account is data pointer
             let data = unsafe {
@@ -1519,7 +1535,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
             let elem_size = binary
                 .context
                 .i32_type()
-                .const_int(elem_ty.size_of(binary.ns).to_u64().unwrap(), false);
+                .const_int(elem_ty.size_of(ns).to_u64().unwrap(), false);
 
             binary.builder.build_int_add(
                 offset,
@@ -1538,6 +1554,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         ty: &ast::Type,
         slot: IntValue<'a>,
         val: BasicValueEnum<'a>,
+        ns: &ast::Namespace,
     ) -> BasicValueEnum<'a> {
         let data = self.contract_storage_data(binary);
         let account = self.contract_storage_account(binary);
@@ -1569,7 +1586,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         let member_size = binary
             .context
             .i32_type()
-            .const_int(ty.size_of(binary.ns).to_u64().unwrap(), false);
+            .const_int(ty.size_of(ns).to_u64().unwrap(), false);
         let new_length = binary
             .builder
             .build_int_add(length, member_size, "new_length");
@@ -1623,7 +1640,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
             "",
         );
 
-        self.storage_store(binary, ty, &mut new_offset, val, function);
+        self.storage_store(binary, ty, &mut new_offset, val, function, ns);
 
         if ty.is_reference_type() {
             // Caller expects a reference to storage; note that storage_store() should not modify
@@ -1640,6 +1657,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         function: FunctionValue<'a>,
         ty: &ast::Type,
         slot: IntValue<'a>,
+        ns: &ast::Namespace,
     ) -> BasicValueEnum<'a> {
         let data = self.contract_storage_data(binary);
         let account = self.contract_storage_account(binary);
@@ -1697,7 +1715,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         let member_size = binary
             .context
             .i32_type()
-            .const_int(ty.size_of(binary.ns).to_u64().unwrap(), false);
+            .const_int(ty.size_of(ns).to_u64().unwrap(), false);
 
         binary.builder.position_at_end(retrieve_block);
 
@@ -1707,7 +1725,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
 
         let mut new_offset = binary.builder.build_int_add(offset, new_length, "");
 
-        let val = self.storage_load(binary, ty, &mut new_offset, function);
+        let val = self.storage_load(binary, ty, &mut new_offset, function, ns);
 
         // delete existing storage -- pointers need to be freed
         //self.storage_free(binary, ty, account, data, new_offset, function, false);
@@ -1733,6 +1751,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         _function: FunctionValue,
         slot: IntValue<'a>,
         elem_ty: &ast::Type,
+        ns: &ast::Namespace,
     ) -> IntValue<'a> {
         let data = self.contract_storage_data(binary);
 
@@ -1754,7 +1773,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         let member_size = binary
             .context
             .i32_type()
-            .const_int(elem_ty.size_of(binary.ns).to_u64().unwrap(), false);
+            .const_int(elem_ty.size_of(ns).to_u64().unwrap(), false);
 
         let length_bytes = binary
             .builder
@@ -1792,6 +1811,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         ty: &ast::Type,
         slot: &mut IntValue<'a>,
         function: FunctionValue,
+        ns: &ast::Namespace,
     ) -> BasicValueEnum<'a> {
         let data = self.contract_storage_data(binary);
 
@@ -1843,7 +1863,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                     .unwrap()
             }
             ast::Type::Struct(struct_no) => {
-                let llvm_ty = binary.llvm_type(ty.deref_any());
+                let llvm_ty = binary.llvm_type(ty.deref_any(), ns);
                 // LLVMSizeOf() produces an i64
                 let size = binary.builder.build_int_truncate(
                     llvm_ty.size_of().unwrap(),
@@ -1869,8 +1889,8 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                     "dest",
                 );
 
-                for (i, field) in binary.ns.structs[*struct_no].fields.iter().enumerate() {
-                    let field_offset = binary.ns.structs[*struct_no].offsets[i].to_u64().unwrap();
+                for (i, field) in ns.structs[*struct_no].fields.iter().enumerate() {
+                    let field_offset = ns.structs[*struct_no].offsets[i].to_u64().unwrap();
 
                     let mut offset = binary.builder.build_int_add(
                         *slot,
@@ -1878,7 +1898,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                         "field_offset",
                     );
 
-                    let val = self.storage_load(binary, &field.ty, &mut offset, function);
+                    let val = self.storage_load(binary, &field.ty, &mut offset, function, ns);
 
                     let elem = unsafe {
                         binary.builder.build_gep(
@@ -1897,7 +1917,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                 dest.into()
             }
             ast::Type::Array(elem_ty, dim) => {
-                let llvm_ty = binary.llvm_type(ty.deref_any());
+                let llvm_ty = binary.llvm_type(ty.deref_any(), ns);
 
                 let dest;
                 let length;
@@ -1937,12 +1957,12 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                         binary
                             .context
                             .i32_type()
-                            .const_int(elem_ty.size_of(binary.ns).to_u64().unwrap(), false),
+                            .const_int(elem_ty.size_of(ns).to_u64().unwrap(), false),
                         binary.context.i32_type(),
                         "size_of",
                     );
 
-                    length = self.storage_array_length(binary, function, slot, &elem_ty);
+                    length = self.storage_array_length(binary, function, slot, &elem_ty, ns);
 
                     slot = binary
                         .builder
@@ -1959,7 +1979,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                     dest = binary.vector_new(length, elem_size, None);
                 };
 
-                let elem_size = elem_ty.size_of(binary.ns).to_u64().unwrap();
+                let elem_size = elem_ty.size_of(ns).to_u64().unwrap();
 
                 // loop over the array
                 let mut builder = LoopBuilder::new(binary, function);
@@ -1970,14 +1990,19 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
 
                 let index = builder.over(binary, binary.context.i32_type().const_zero(), length);
 
-                let elem = binary.array_subscript(ty.deref_any(), dest, index);
+                let elem = binary.array_subscript(ty.deref_any(), dest, index, ns);
 
                 let elem_ty = ty.array_deref();
 
                 let mut offset_val = offset_phi.into_int_value();
 
-                let val =
-                    self.storage_load(binary, &elem_ty.deref_memory(), &mut offset_val, function);
+                let val = self.storage_load(
+                    binary,
+                    &elem_ty.deref_memory(),
+                    &mut offset_val,
+                    function,
+                    ns,
+                );
 
                 binary.builder.build_store(elem, val);
 
@@ -1998,7 +2023,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
             _ => binary.builder.build_load(
                 binary.builder.build_pointer_cast(
                     member,
-                    binary.llvm_type(ty).ptr_type(AddressSpace::Generic),
+                    binary.llvm_type(ty, ns).ptr_type(AddressSpace::Generic),
                     "",
                 ),
                 "",
@@ -2013,6 +2038,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         slot: &mut IntValue<'a>,
         val: BasicValueEnum<'a>,
         function: FunctionValue<'a>,
+        ns: &ast::Namespace,
     ) {
         let data = self.contract_storage_data(binary);
         let account = self.contract_storage_account(binary);
@@ -2138,7 +2164,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
             );
         } else if let ast::Type::Array(elem_ty, dim) = ty {
             // make sure any pointers are freed
-            self.storage_free(binary, ty, data, *slot, function, false);
+            self.storage_free(binary, ty, data, *slot, function, false, ns);
 
             let offset_ptr = binary.builder.build_pointer_cast(
                 member,
@@ -2162,7 +2188,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                 let member_size = binary
                     .context
                     .i32_type()
-                    .const_int(elem_ty.size_of(binary.ns).to_u64().unwrap(), false);
+                    .const_int(elem_ty.size_of(ns).to_u64().unwrap(), false);
                 let new_length = binary
                     .builder
                     .build_int_mul(length, member_size, "new_length");
@@ -2217,7 +2243,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                     .into_int_value();
             }
 
-            let elem_size = elem_ty.size_of(binary.ns).to_u64().unwrap();
+            let elem_size = elem_ty.size_of(ns).to_u64().unwrap();
 
             // loop over the array
             let mut builder = LoopBuilder::new(binary, function);
@@ -2228,7 +2254,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
 
             let index = builder.over(binary, binary.context.i32_type().const_zero(), length);
 
-            let elem = binary.array_subscript(ty, val.into_pointer_value(), index);
+            let elem = binary.array_subscript(ty, val.into_pointer_value(), index, ns);
 
             let mut offset_val = offset_phi.into_int_value();
 
@@ -2240,6 +2266,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                 &mut offset_val,
                 binary.builder.build_load(elem, "array_elem"),
                 function,
+                ns,
             );
 
             offset_val = binary.builder.build_int_add(
@@ -2254,8 +2281,8 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
             // done
             builder.finish(binary);
         } else if let ast::Type::Struct(struct_no) = ty {
-            for (i, field) in binary.ns.structs[*struct_no].fields.iter().enumerate() {
-                let field_offset = binary.ns.structs[*struct_no].offsets[i].to_u64().unwrap();
+            for (i, field) in ns.structs[*struct_no].fields.iter().enumerate() {
+                let field_offset = ns.structs[*struct_no].offsets[i].to_u64().unwrap();
 
                 let mut offset = binary.builder.build_int_add(
                     *slot,
@@ -2275,7 +2302,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                 };
 
                 // free any existing dynamic storage
-                self.storage_free(binary, &field.ty, data, offset, function, false);
+                self.storage_free(binary, &field.ty, data, offset, function, false, ns);
 
                 self.storage_store(
                     binary,
@@ -2283,6 +2310,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                     &mut offset,
                     binary.builder.build_load(elem, &field.name),
                     function,
+                    ns,
                 );
             }
         } else {
@@ -2304,6 +2332,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         src: PointerValue,
         length: IntValue,
         dest: PointerValue,
+        _ns: &ast::Namespace,
     ) {
         binary.builder.build_call(
             binary.module.get_function("keccak256").unwrap(),
@@ -2406,8 +2435,9 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         packed: &[BasicValueEnum<'b>],
         args: &[BasicValueEnum<'b>],
         tys: &[ast::Type],
+        ns: &ast::Namespace,
     ) -> PointerValue<'b> {
-        ethabiencoder::encode_to_vector(binary, function, packed, args, tys, true)
+        ethabiencoder::encode_to_vector(binary, function, packed, args, tys, true, ns)
     }
 
     fn abi_encode(
@@ -2418,6 +2448,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         function: FunctionValue<'a>,
         args: &[BasicValueEnum<'a>],
         tys: &[ast::Type],
+        ns: &ast::Namespace,
     ) -> (PointerValue<'a>, IntValue<'a>) {
         debug_assert_eq!(args.len(), tys.len());
 
@@ -2430,8 +2461,9 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
             vec![]
         };
 
-        let encoder =
-            ethabiencoder::EncoderBuilder::new(binary, function, load, &packed, args, &tys, true);
+        let encoder = ethabiencoder::EncoderBuilder::new(
+            binary, function, load, &packed, args, &tys, true, ns,
+        );
 
         let length = encoder.encoded_length();
 
@@ -2519,7 +2551,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
             "data_ptr",
         );
 
-        encoder.finish(binary, function, output);
+        encoder.finish(binary, function, output, ns);
 
         (output, length)
     }
@@ -2532,8 +2564,10 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         data: PointerValue<'b>,
         length: IntValue<'b>,
         spec: &[ast::Parameter],
+        ns: &ast::Namespace,
     ) {
-        self.abi.decode(binary, function, args, data, length, spec);
+        self.abi
+            .decode(binary, function, args, data, length, spec, ns);
     }
 
     fn print(&self, binary: &Binary, string_ptr: PointerValue, string_len: IntValue) {
@@ -2562,6 +2596,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         _gas: IntValue<'b>,
         _value: Option<IntValue<'b>>,
         _salt: Option<IntValue<'b>>,
+        _ns: &ast::Namespace,
     ) {
         unimplemented!();
     }
@@ -2578,6 +2613,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         _gas: IntValue<'b>,
         _value: IntValue<'b>,
         _ty: ast::CallTy,
+        _ns: &ast::Namespace,
     ) {
         debug_assert!(address.is_none());
 
@@ -2668,12 +2704,12 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
     }
 
     /// Value received
-    fn value_transferred<'b>(&self, binary: &Binary<'b>) -> IntValue<'b> {
-        binary.value_type().const_zero()
+    fn value_transferred<'b>(&self, binary: &Binary<'b>, ns: &ast::Namespace) -> IntValue<'b> {
+        binary.value_type(ns).const_zero()
     }
 
     /// Terminate execution, destroy binary and send remaining funds to addr
-    fn selfdestruct<'b>(&self, _binary: &Binary<'b>, _addr: IntValue<'b>) {
+    fn selfdestruct<'b>(&self, _binary: &Binary<'b>, _addr: IntValue<'b>, _ns: &ast::Namespace) {
         unimplemented!();
     }
 
@@ -2685,6 +2721,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         _data: PointerValue<'b>,
         _data_len: IntValue<'b>,
         _topics: Vec<(PointerValue<'b>, IntValue<'b>)>,
+        _ns: &ast::Namespace,
     ) {
         // Solana does not implement events, ignore for now
     }
@@ -2696,6 +2733,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         expr: &ast::Expression,
         _vartab: &HashMap<usize, Variable<'b>>,
         _function: FunctionValue<'b>,
+        ns: &ast::Namespace,
     ) -> BasicValueEnum<'b> {
         match expr {
             ast::Expression::Builtin(_, _, ast::Builtin::Timestamp, _) => {
@@ -2743,7 +2781,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
 
                 let value = binary
                     .builder
-                    .build_alloca(binary.address_type(), "self_address");
+                    .build_alloca(binary.address_type(ns), "self_address");
 
                 binary.builder.build_call(
                     binary.module.get_function("__beNtoleN").unwrap(),
@@ -2767,7 +2805,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                         binary
                             .context
                             .i32_type()
-                            .const_int(binary.ns.address_length as u64, false)
+                            .const_int(ns.address_length as u64, false)
                             .into(),
                     ],
                     "",
@@ -2786,6 +2824,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         hash: HashTy,
         input: PointerValue<'b>,
         input_len: IntValue<'b>,
+        ns: &ast::Namespace,
     ) -> IntValue<'b> {
         let (fname, hashlen) = match hash {
             HashTy::Keccak256 => ("sol_keccak256", 32),
@@ -2842,9 +2881,10 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         }
 
         // bytes32 needs to reverse bytes
-        let temp = binary
-            .builder
-            .build_alloca(binary.llvm_type(&ast::Type::Bytes(hashlen as u8)), "hash");
+        let temp = binary.builder.build_alloca(
+            binary.llvm_type(&ast::Type::Bytes(hashlen as u8), ns),
+            "hash",
+        );
 
         binary.builder.build_call(
             binary.module.get_function("__beNtoleN").unwrap(),

File diff suppressed because it is too large
+ 168 - 98
src/emit/substrate.rs


Some files were not shown because too many files changed in this diff