Przeglądaj źródła

Bump inkwell crate to 0.5.0 (#1822)

Note that inkwell 0.6.0 does not work with Soroban yet. Something for a
later date.

Signed-off-by: Sean Young <sean@mess.org>
Sean Young 3 miesięcy temu
rodzic
commit
a3b6d3cc2d

+ 1 - 1
Cargo.toml

@@ -28,7 +28,7 @@ tiny-keccak = { version = "2.0", features = ["keccak"] }
 serde_json = "1.0"
 serde = "1.0"
 serde_derive = { version = "1.0" }
-inkwell = { version = "0.4.0", features = ["target-webassembly", "no-libffi-linking", "llvm16-0"], optional = true }
+inkwell = { version = "0.5.0", features = ["target-webassembly", "no-libffi-linking", "llvm16-0"], optional = true }
 blake2-rfc = "0.2.18"
 handlebars = "5.1"
 contract-metadata = "4.0.2"

+ 25 - 52
src/emit/binary.rs

@@ -50,9 +50,9 @@ static LLVM_INIT: OnceCell<()> = OnceCell::new();
 macro_rules! emit_context {
     ($binary:expr) => {
         #[allow(unused_macros)]
-        macro_rules! byte_ptr {
+        macro_rules! ptr {
             () => {
-                $binary.context.i8_type().ptr_type(AddressSpace::default())
+                $binary.context.ptr_type(AddressSpace::default())
             };
         }
 
@@ -439,10 +439,7 @@ impl<'a> Binary<'a> {
             scratch_len: None,
             parameters: None,
             return_values,
-            vector_init_empty: context
-                .i8_type()
-                .ptr_type(AddressSpace::default())
-                .const_null(),
+            vector_init_empty: context.ptr_type(AddressSpace::default()).const_null(),
             global_constant_strings: RefCell::new(HashMap::new()),
             return_data: RefCell::new(None),
         }
@@ -800,28 +797,13 @@ impl<'a> Binary<'a> {
             }
         }
         // add return values
-        for ty in returns {
-            args.push(
-                if ty.is_reference_type(self.ns) && !ty.is_contract_storage() {
-                    self.llvm_type(ty)
-                        .ptr_type(AddressSpace::default())
-                        .ptr_type(AddressSpace::default())
-                        .into()
-                } else {
-                    self.llvm_type(ty).ptr_type(AddressSpace::default()).into()
-                },
-            );
+        for _ in returns {
+            args.push(self.context.ptr_type(AddressSpace::default()).into());
         }
 
         // On Solana, we need to pass around the accounts
         if self.ns.target == Target::Solana {
-            args.push(
-                self.module
-                    .get_struct_type("struct.SolParameters")
-                    .unwrap()
-                    .ptr_type(AddressSpace::default())
-                    .into(),
-            );
+            args.push(self.context.ptr_type(AddressSpace::default()).into());
         }
 
         // Solana return type should be 64 bit, 32 bit on wasm
@@ -895,7 +877,8 @@ impl<'a> Binary<'a> {
             | Type::Array(..)
             | Type::DynamicBytes
             | Type::String
-            | Type::ExternalFunction { .. } => llvm_ty
+            | Type::ExternalFunction { .. } => self
+                .context
                 .ptr_type(AddressSpace::default())
                 .as_basic_type_enum(),
             _ => llvm_ty,
@@ -906,10 +889,12 @@ impl<'a> Binary<'a> {
     pub(crate) fn llvm_field_ty(&self, ty: &Type) -> BasicTypeEnum<'a> {
         let llvm_ty = self.llvm_type(ty);
         match ty.deref_memory() {
-            Type::Array(_, dim) if dim.last() == Some(&ArrayLength::Dynamic) => llvm_ty
+            Type::Array(_, dim) if dim.last() == Some(&ArrayLength::Dynamic) => self
+                .context
                 .ptr_type(AddressSpace::default())
                 .as_basic_type_enum(),
-            Type::DynamicBytes | Type::String => llvm_ty
+            Type::DynamicBytes | Type::String => self
+                .context
                 .ptr_type(AddressSpace::default())
                 .as_basic_type_enum(),
             _ => llvm_ty,
@@ -923,11 +908,11 @@ impl<'a> Binary<'a> {
             self.context
                 .struct_type(
                     &[
-                        byte_ptr!().as_basic_type_enum(),             // SolPubkey *
-                        byte_ptr!().as_basic_type_enum(),             // uint64_t *
+                        ptr!().as_basic_type_enum(),                  // SolPubkey *
+                        ptr!().as_basic_type_enum(),                  // uint64_t *
                         self.context.i64_type().as_basic_type_enum(), // uint64_t
-                        byte_ptr!().as_basic_type_enum(),             // uint8_t *
-                        byte_ptr!().as_basic_type_enum(),             // SolPubkey *
+                        ptr!().as_basic_type_enum(),                  // uint8_t *
+                        ptr!().as_basic_type_enum(),                  // SolPubkey *
                         self.context.i64_type().as_basic_type_enum(), // uint64_t
                         i8_basic_type_enum!(),                        // bool
                         i8_basic_type_enum!(),                        // bool
@@ -993,22 +978,18 @@ impl<'a> Binary<'a> {
                     )
                     .as_basic_type_enum(),
                 Type::Mapping(..) => self.llvm_type(&self.ns.storage_type()),
-                Type::Ref(r) => {
+                Type::Ref(..) => {
                     if self.ns.target == Target::Soroban {
                         return BasicTypeEnum::IntType(self.context.i64_type());
                     }
 
-                    self.llvm_type(r)
+                    self.context
                         .ptr_type(AddressSpace::default())
                         .as_basic_type_enum()
                 }
                 Type::StorageRef(..) => self.llvm_type(&self.ns.storage_type()),
-                Type::InternalFunction {
-                    params, returns, ..
-                } => {
-                    let ftype = self.function_type(params, returns);
-
-                    BasicTypeEnum::PointerType(ftype.ptr_type(AddressSpace::default()))
+                Type::InternalFunction { .. } => {
+                    BasicTypeEnum::PointerType(self.context.ptr_type(AddressSpace::default()))
                 }
                 Type::ExternalFunction { .. } => {
                     let address = self.llvm_type(&Type::Address(false));
@@ -1017,10 +998,10 @@ impl<'a> Binary<'a> {
                         .struct_type(&[selector, address], false)
                         .as_basic_type_enum()
                 }
-                Type::Slice(ty) => BasicTypeEnum::StructType(
+                Type::Slice(_) => BasicTypeEnum::StructType(
                     self.context.struct_type(
                         &[
-                            self.llvm_type(ty).ptr_type(AddressSpace::default()).into(),
+                            self.context.ptr_type(AddressSpace::default()).into(),
                             self.context
                                 .custom_width_int_type(self.ns.target.ptr_size().into())
                                 .into(),
@@ -1031,7 +1012,6 @@ impl<'a> Binary<'a> {
                 Type::UserType(no) => self.llvm_type(&self.ns.user_types[*no].ty),
                 Type::BufferPointer => self
                     .context
-                    .i8_type()
                     .ptr_type(AddressSpace::default())
                     .as_basic_type_enum(),
                 Type::FunctionSelector => {
@@ -1104,9 +1084,7 @@ impl<'a> Binary<'a> {
                 // A constant string, or array, is represented by a struct with two fields: a pointer to the data, and its length.
                 let ty = self.context.struct_type(
                     &[
-                        self.llvm_type(&Type::Bytes(bs.len() as u8))
-                            .ptr_type(AddressSpace::default())
-                            .into(),
+                        self.context.ptr_type(AddressSpace::default()).into(),
                         self.context.i64_type().into(),
                     ],
                     false,
@@ -1126,9 +1104,7 @@ impl<'a> Binary<'a> {
         if let Some(init) = init {
             if init.is_empty() {
                 return self
-                    .module
-                    .get_struct_type("struct.vector")
-                    .unwrap()
+                    .context
                     .ptr_type(AddressSpace::default())
                     .const_null()
                     .as_basic_value_enum();
@@ -1325,10 +1301,7 @@ impl<'a> Binary<'a> {
     pub(super) fn panic_data_const(&self, code: PanicCode) -> (PointerValue<'a>, IntValue<'a>) {
         if self.ns.target == Target::Solana || self.ns.target == Target::Soroban {
             return (
-                self.context
-                    .i8_type()
-                    .ptr_type(AddressSpace::default())
-                    .const_null(),
+                self.context.ptr_type(AddressSpace::default()).const_null(),
                 self.context.i32_type().const_zero(),
             );
         }

+ 6 - 8
src/emit/cfg.rs

@@ -55,15 +55,13 @@ pub(super) fn emit_cfg<'a, T: TargetRuntime<'a> + ?Sized>(
                 let di_return_type = dibuilder
                     .create_basic_type(&type_name, size as u64, 0x00, di_flags)
                     .unwrap();
-                let param_types = function.get_type().get_param_types();
-                let di_param_types: Vec<DIType<'_>> = param_types
+                let di_param_types: Vec<DIType<'_>> = cfg
+                    .params
                     .iter()
-                    .map(|typ| {
-                        let mut param_tname = "size_".to_owned();
-                        let param_size = typ.size_of().unwrap().get_type().get_bit_width();
-                        param_tname.push_str(&size.to_string());
+                    .map(|param| {
+                        let name = param.ty.to_string(bin.ns);
                         dibuilder
-                            .create_basic_type(&param_tname, param_size as u64, 0x00, di_flags)
+                            .create_basic_type(&name, param.ty.bits(bin.ns).into(), 0x00, di_flags)
                             .unwrap()
                             .as_type()
                     })
@@ -120,7 +118,7 @@ pub(super) fn emit_cfg<'a, T: TargetRuntime<'a> + ?Sized>(
             Storage::Local if v.ty.is_reference_type(bin.ns) && !v.ty.is_contract_storage() => {
                 // a null pointer means an empty, zero'ed thing, be it string, struct or array
                 let value = bin
-                    .llvm_type(&v.ty)
+                    .context
                     .ptr_type(AddressSpace::default())
                     .const_null()
                     .into();

+ 4 - 6
src/emit/expression.rs

@@ -135,9 +135,7 @@ pub(super) fn expression<'a, T: TargetRuntime<'a> + ?Sized>(
                 // A constant string, or array, is represented by a struct with two fields: a pointer to the data, and its length.
                 let ty = bin.context.struct_type(
                     &[
-                        bin.llvm_type(&Type::Bytes(bs.len() as u8))
-                            .ptr_type(AddressSpace::default())
-                            .into(),
+                        bin.context.ptr_type(AddressSpace::default()).into(),
                         bin.context.i64_type().into(),
                     ],
                     false,
@@ -1079,7 +1077,7 @@ pub(super) fn expression<'a, T: TargetRuntime<'a> + ?Sized>(
             let ptr = expression(target, bin, expr, vartab, function).into_pointer_value();
 
             if ty.is_reference_type(bin.ns) && !ty.is_fixed_reference_type(bin.ns) {
-                let loaded_type = bin.llvm_type(ty).ptr_type(AddressSpace::default());
+                let loaded_type = bin.context.ptr_type(AddressSpace::default());
                 let value = bin.builder.build_load(loaded_type, ptr, "").unwrap();
                 // if the pointer is null, it needs to be allocated
                 let allocation_needed = bin
@@ -1134,7 +1132,7 @@ pub(super) fn expression<'a, T: TargetRuntime<'a> + ?Sized>(
                 let combined_struct_ptr = bin
                     .builder
                     .build_phi(
-                        llvm_ty.ptr_type(AddressSpace::default()),
+                        bin.context.ptr_type(AddressSpace::default()),
                         &format!("ptr_{}", ty.to_string(bin.ns)),
                     )
                     .unwrap();
@@ -2314,7 +2312,7 @@ fn runtime_cast<'a>(
             .builder
             .build_int_to_ptr(
                 val.into_int_value(),
-                bin.llvm_type(to).ptr_type(AddressSpace::default()),
+                bin.context.ptr_type(AddressSpace::default()),
                 "int_to_ptr",
             )
             .unwrap()

+ 3 - 10
src/emit/instructions.rs

@@ -431,10 +431,7 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
         Instr::AssertFailure { encoded_args: None } => {
             target.assert_failure(
                 bin,
-                bin.context
-                    .i8_type()
-                    .ptr_type(AddressSpace::default())
-                    .const_null(),
+                bin.context.ptr_type(AddressSpace::default()).const_null(),
                 bin.context.i32_type().const_zero(),
             );
         }
@@ -601,7 +598,7 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
             if !res.is_empty() {
                 for (i, v) in callee.returns.iter().enumerate() {
                     let load_ty = if v.ty.is_reference_type(bin.ns) {
-                        bin.llvm_type(&v.ty)
+                        bin.context
                             .ptr_type(AddressSpace::default())
                             .as_basic_type_enum()
                     } else {
@@ -669,11 +666,7 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
 
             let ptr_ok = bin.context.append_basic_block(function, "fn_ptr_ok");
             let ptr_nil_block = bin.context.append_basic_block(function, "fn_ptr_nil");
-            let nil_ptr = bin
-                .context
-                .i8_type()
-                .ptr_type(AddressSpace::default())
-                .const_null();
+            let nil_ptr = bin.context.ptr_type(AddressSpace::default()).const_null();
             let is_ptr_nil = bin
                 .builder
                 .build_int_compare(IntPredicate::EQ, nil_ptr, callable, "check_nil_ptr")

+ 3 - 3
src/emit/polkadot/mod.rs

@@ -38,7 +38,7 @@ impl PolkadotTarget {
             None,
         );
 
-        let ptr = bin.context.i8_type().ptr_type(AddressSpace::default());
+        let ptr = bin.context.ptr_type(AddressSpace::default());
 
         bin.vector_init_empty = bin
             .context
@@ -181,9 +181,9 @@ impl PolkadotTarget {
 
     fn declare_externals(&self, bin: &Binary) {
         let ctx = bin.context;
-        let u8_ptr = ctx.i8_type().ptr_type(AddressSpace::default()).into();
+        let u8_ptr = ctx.ptr_type(AddressSpace::default()).into();
         let u32_val = ctx.i32_type().into();
-        let u32_ptr = ctx.i32_type().ptr_type(AddressSpace::default()).into();
+        let u32_ptr = ctx.ptr_type(AddressSpace::default()).into();
         let u64_val = ctx.i64_type().into();
 
         macro_rules! external {

+ 4 - 10
src/emit/polkadot/storage.rs

@@ -176,7 +176,7 @@ impl StorageSlot for PolkadotTarget {
                         .builder
                         .build_int_to_ptr(
                             bin.context.i32_type().const_all_ones(),
-                            bin.context.i8_type().ptr_type(AddressSpace::default()),
+                            bin.context.ptr_type(AddressSpace::default()),
                             "invalid",
                         )
                         .unwrap();
@@ -302,12 +302,7 @@ impl StorageSlot for PolkadotTarget {
                 let ret = self.get_storage_int(bin, function, slot_ptr, ptr_ty);
 
                 bin.builder
-                    .build_int_to_ptr(
-                        ret,
-                        bin.llvm_type(ty.deref_any())
-                            .ptr_type(AddressSpace::default()),
-                        "",
-                    )
+                    .build_int_to_ptr(ret, bin.context.ptr_type(AddressSpace::default()), "")
                     .unwrap()
                     .into()
             }
@@ -387,8 +382,7 @@ impl StorageSlot for PolkadotTarget {
                             if elem_ty.is_reference_type(bin.ns)
                                 && !elem_ty.deref_memory().is_fixed_reference_type(bin.ns)
                             {
-                                let load_ty =
-                                    bin.llvm_type(elem_ty).ptr_type(AddressSpace::default());
+                                let load_ty = bin.context.ptr_type(AddressSpace::default());
                                 elem = bin
                                     .builder
                                     .build_load(load_ty, elem, "")
@@ -584,7 +578,7 @@ impl StorageSlot for PolkadotTarget {
                     if field.ty.is_reference_type(bin.ns)
                         && !field.ty.is_fixed_reference_type(bin.ns)
                     {
-                        let load_ty = bin.llvm_type(&field.ty).ptr_type(AddressSpace::default());
+                        let load_ty = bin.context.ptr_type(AddressSpace::default());
                         elem = bin
                             .builder
                             .build_load(load_ty, elem, field.name_as_str())

+ 6 - 14
src/emit/polkadot/target.rs

@@ -221,11 +221,7 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
             .build_int_compare(IntPredicate::EQ, exists, i32_zero!(), "storage_exists")
             .unwrap();
 
-        let ty = bin
-            .module
-            .get_struct_type("struct.vector")
-            .unwrap()
-            .ptr_type(AddressSpace::default());
+        let ty = bin.context.ptr_type(AddressSpace::default());
 
         let entry = bin.builder.get_insert_block().unwrap();
 
@@ -264,11 +260,7 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
         res.add_incoming(&[
             (&loaded_string, retrieve_block),
             (
-                &bin.module
-                    .get_struct_type("struct.vector")
-                    .unwrap()
-                    .ptr_type(AddressSpace::default())
-                    .const_null(),
+                &bin.context.ptr_type(AddressSpace::default()).const_null(),
                 entry,
             ),
         ]);
@@ -683,7 +675,7 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
             "seal_return",
             &[
                 i32_zero!().into(),
-                byte_ptr!().const_zero().into(),
+                ptr!().const_zero().into(),
                 i32_zero!().into()
             ]
         );
@@ -695,7 +687,7 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
         emit_context!(bin);
 
         // we can't return specific errors
-        self.assert_failure(bin, byte_ptr!().const_zero(), i32_zero!());
+        self.assert_failure(bin, ptr!().const_zero(), i32_zero!());
     }
 
     /// Call the  keccak256 host function
@@ -1189,7 +1181,7 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
 
             topic_buf
         } else {
-            byte_ptr!().const_null()
+            ptr!().const_null()
         };
 
         call!(
@@ -1257,7 +1249,7 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
                         bin.builder
                             .build_int_to_ptr(
                                 bin.context.i32_type().const_all_ones(),
-                                byte_ptr!(),
+                                ptr!(),
                                 "no_initializer",
                             )
                             .unwrap()

+ 17 - 33
src/emit/solana/mod.rs

@@ -6,7 +6,7 @@ use crate::sema::ast;
 use std::cmp::Ordering;
 
 use crate::codegen::{cfg::ReturnCode, Options};
-use crate::sema::ast::{StructType, Type};
+use crate::sema::ast::Type;
 use inkwell::module::{Linkage, Module};
 use inkwell::types::BasicType;
 use inkwell::values::{
@@ -90,16 +90,13 @@ impl SolanaTarget {
 
     fn declare_externals(&self, bin: &mut Binary) {
         let void_ty = bin.context.void_type();
-        let u8_ptr = bin.context.i8_type().ptr_type(AddressSpace::default());
+        let u8_ptr = bin.context.ptr_type(AddressSpace::default());
         let u64_ty = bin.context.i64_type();
         let u32_ty = bin.context.i32_type();
-        let address = bin.address_type().ptr_type(AddressSpace::default());
+        let address = bin.context.ptr_type(AddressSpace::default());
         let seeds = bin.llvm_type(&Type::Ref(Box::new(Type::Slice(Box::new(Type::Bytes(1))))));
 
-        let sol_bytes = bin
-            .context
-            .struct_type(&[u8_ptr.into(), u64_ty.into()], false)
-            .ptr_type(AddressSpace::default());
+        let sol_bytes = bin.context.ptr_type(AddressSpace::default());
 
         let function = bin.module.add_function(
             "sol_log_",
@@ -172,7 +169,7 @@ impl SolanaTarget {
             "sol_log_data",
             void_ty.fn_type(
                 &[
-                    fields.ptr_type(AddressSpace::default()).into(),
+                    bin.context.ptr_type(AddressSpace::default()).into(),
                     u64_ty.into(),
                 ],
                 false,
@@ -218,16 +215,9 @@ impl SolanaTarget {
             u64_ty.fn_type(
                 &[
                     u8_ptr.into(),
-                    bin.module
-                        .get_struct_type("struct.SolAccountInfo")
-                        .unwrap()
-                        .ptr_type(AddressSpace::default())
-                        .into(),
+                    bin.context.ptr_type(AddressSpace::default()).into(),
                     bin.context.i32_type().into(),
-                    bin.context
-                        .i8_type()
-                        .ptr_type(AddressSpace::default())
-                        .into(),
+                    bin.context.ptr_type(AddressSpace::default()).into(),
                     bin.context.i32_type().into(),
                 ],
                 false,
@@ -277,7 +267,7 @@ impl SolanaTarget {
 
         bin.builder
             .build_load(
-                bin.context.i8_type().ptr_type(AddressSpace::default()),
+                bin.context.ptr_type(AddressSpace::default()),
                 unsafe {
                     bin.builder
                         .build_gep(
@@ -513,7 +503,7 @@ impl SolanaTarget {
 
         let entry_ty = self.sparse_entry(bin, key_ty, value_ty);
         let value_offset = unsafe {
-            entry_ty
+            bin.context
                 .ptr_type(AddressSpace::default())
                 .const_null()
                 .const_gep(
@@ -603,10 +593,7 @@ impl SolanaTarget {
         // we are walking the bucket list via the offset ptr
         let offset_ptr_phi = bin
             .builder
-            .build_phi(
-                bin.context.i32_type().ptr_type(AddressSpace::default()),
-                "offset_ptr",
-            )
+            .build_phi(bin.context.ptr_type(AddressSpace::default()), "offset_ptr")
             .unwrap();
 
         offset_ptr_phi.add_incoming(&[(&first_offset_ptr, entry)]);
@@ -1050,7 +1037,7 @@ impl SolanaTarget {
                 let data = bin
                     .builder
                     .build_load(
-                        bin.context.i8_type().ptr_type(AddressSpace::default()),
+                        bin.context.ptr_type(AddressSpace::default()),
                         bin.builder
                             .build_struct_gep(account_info_ty, account_info, 3, "data")
                             .unwrap(),
@@ -1112,17 +1099,14 @@ impl SolanaTarget {
             .context
             .struct_type(
                 &[
-                    bin.module
-                        .get_struct_type("struct.SolPubkey")
-                        .unwrap()
+                    bin.context
                         .ptr_type(AddressSpace::default())
                         .as_basic_type_enum(),
-                    bin.llvm_type(&Type::Struct(StructType::AccountMeta))
+                    bin.context
                         .ptr_type(AddressSpace::default())
                         .as_basic_type_enum(),
                     bin.context.i64_type().as_basic_type_enum(),
                     bin.context
-                        .i8_type()
                         .ptr_type(AddressSpace::default())
                         .as_basic_type_enum(),
                     bin.context.i64_type().as_basic_type_enum(),
@@ -1237,11 +1221,11 @@ impl SolanaTarget {
         } else {
             (
                 external_call.get_type().get_param_types()[3]
-                    .const_zero()
-                    .into_pointer_value(),
+                    .into_pointer_type()
+                    .const_zero(),
                 external_call.get_type().get_param_types()[4]
-                    .const_zero()
-                    .into_int_value(),
+                    .into_int_type()
+                    .const_zero(),
             )
         };
 

+ 11 - 33
src/emit/solana/target.rs

@@ -129,10 +129,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         );
         self.assert_failure(
             bin,
-            bin.context
-                .i8_type()
-                .ptr_type(AddressSpace::default())
-                .const_null(),
+            bin.context.ptr_type(AddressSpace::default()).const_null(),
             bin.context.i32_type().const_zero(),
         );
 
@@ -205,10 +202,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         bin.log_runtime_error(self, "storage index out of bounds".to_string(), Some(loc));
         self.assert_failure(
             bin,
-            bin.context
-                .i8_type()
-                .ptr_type(AddressSpace::default())
-                .const_null(),
+            bin.context.ptr_type(AddressSpace::default()).const_null(),
             bin.context.i32_type().const_zero(),
         );
 
@@ -262,11 +256,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
 
             let data = bin
                 .builder
-                .build_load(
-                    bin.context.i8_type().ptr_type(AddressSpace::default()),
-                    data,
-                    "data",
-                )
+                .build_load(bin.context.ptr_type(AddressSpace::default()), data, "data")
                 .unwrap()
                 .into_pointer_value();
 
@@ -471,10 +461,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         bin.log_runtime_error(self, "pop from empty storage array".to_string(), Some(loc));
         self.assert_failure(
             bin,
-            bin.context
-                .i8_type()
-                .ptr_type(AddressSpace::default())
-                .const_null(),
+            bin.context.ptr_type(AddressSpace::default()).const_null(),
             bin.context.i32_type().const_zero(),
         );
 
@@ -1122,7 +1109,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                     elem.into()
                 } else {
                     let load_ty = if elem_ty.is_dynamic(bin.ns) {
-                        bin.llvm_type(elem_ty.deref_memory())
+                        bin.context
                             .ptr_type(AddressSpace::default())
                             .as_basic_type_enum()
                     } else {
@@ -1192,7 +1179,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                         elem.into()
                     } else {
                         let load_ty = if field.ty.is_dynamic(bin.ns) {
-                            bin.llvm_type(&field.ty)
+                            bin.context
                                 .ptr_type(AddressSpace::default())
                                 .as_basic_type_enum()
                         } else {
@@ -1392,10 +1379,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
 
         if contract_args.accounts.is_none() {
             contract_args.accounts = Some((
-                bin.context
-                    .i64_type()
-                    .ptr_type(AddressSpace::default())
-                    .const_zero(),
+                bin.context.ptr_type(AddressSpace::default()).const_zero(),
                 bin.context.i32_type().const_zero(),
             ))
         };
@@ -1406,11 +1390,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
 
     /// Get return buffer for external call
     fn return_data<'b>(&self, bin: &Binary<'b>, function: FunctionValue<'b>) -> PointerValue<'b> {
-        let null_u8_ptr = bin
-            .context
-            .i8_type()
-            .ptr_type(AddressSpace::default())
-            .const_zero();
+        let null_u8_ptr = bin.context.ptr_type(AddressSpace::default()).const_zero();
 
         let length_as_64 = bin
             .builder
@@ -1703,10 +1683,9 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
 
                 let parameters = self.sol_parameters(bin);
 
-                let sol_pubkey_type = bin.module.get_struct_type("struct.SolPubkey").unwrap();
                 bin.builder
                     .build_load(
-                        sol_pubkey_type.ptr_type(AddressSpace::default()),
+                        bin.context.ptr_type(AddressSpace::default()),
                         bin.builder
                             .build_struct_gep(
                                 bin.module.get_struct_type("struct.SolParameters").unwrap(),
@@ -1731,7 +1710,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                 let input = bin
                     .builder
                     .build_load(
-                        bin.context.i8_type().ptr_type(AddressSpace::default()),
+                        bin.context.ptr_type(AddressSpace::default()),
                         bin.builder
                             .build_struct_gep(
                                 bin.module.get_struct_type("struct.SolParameters").unwrap(),
@@ -1794,7 +1773,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                 let input = bin
                     .builder
                     .build_load(
-                        bin.context.i8_type().ptr_type(AddressSpace::default()),
+                        bin.context.ptr_type(AddressSpace::default()),
                         bin.builder
                             .build_struct_gep(
                                 bin.module.get_struct_type("struct.SolParameters").unwrap(),
@@ -1975,7 +1954,6 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
             let sol_bytes = bin.context.struct_type(
                 &[
                     bin.context
-                        .i8_type()
                         .ptr_type(AddressSpace::default())
                         .as_basic_type_enum(),
                     bin.context.i64_type().as_basic_type_enum(),