ソースを参照

Store `Namespace` reference in `Binary` (#1800)

The PR's main change is to store a reference to the `Namespace` in the
`Binary`:
https://github.com/hyperledger-solang/solang/blob/6fccc021a759153f1d7802e7738d1b52f120e576/src/emit/binary.rs#L153

This saves having to pass the `Namespace` around while emitting code.

I tried to find all functions that take both a `Binary` and `Namespace`
and make it so that they instead take just a `Binary` and access the
`Namespace` therefrom, but I'm not 100% certain I found all such
functions.

All tests pass for me locally following these changes.

Signed-off-by: Samuel Moelius <samuel.moelius@trailofbits.com>
Samuel Moelius 5 ヶ月 前
コミット
9c02c83e9f

+ 76 - 80
src/emit/binary.rs

@@ -150,7 +150,7 @@ pub struct Binary<'a> {
     pub module: Module<'a>,
     pub module: Module<'a>,
     pub(crate) options: &'a Options,
     pub(crate) options: &'a Options,
     pub runtime: Option<Box<Binary<'a>>>,
     pub runtime: Option<Box<Binary<'a>>>,
-    target: Target,
+    pub ns: &'a Namespace,
     pub(crate) function_abort_value_transfers: bool,
     pub(crate) function_abort_value_transfers: bool,
     pub(crate) constructor_abort_value_transfers: bool,
     pub(crate) constructor_abort_value_transfers: bool,
     pub builder: Builder<'a>,
     pub builder: Builder<'a>,
@@ -219,13 +219,14 @@ impl<'a> Binary<'a> {
             _ => {}
             _ => {}
         }
         }
 
 
-        let target = inkwell::targets::Target::from_name(self.target.llvm_target_name()).unwrap();
+        let target =
+            inkwell::targets::Target::from_name(self.ns.target.llvm_target_name()).unwrap();
 
 
         let target_machine = target
         let target_machine = target
             .create_target_machine(
             .create_target_machine(
-                &self.target.llvm_target_triple(),
+                &self.ns.target.llvm_target_triple(),
                 "",
                 "",
-                self.target.llvm_features(),
+                self.ns.target.llvm_features(),
                 self.options.opt_level.into(),
                 self.options.opt_level.into(),
                 RelocMode::Default,
                 RelocMode::Default,
                 CodeModel::Default,
                 CodeModel::Default,
@@ -245,7 +246,7 @@ impl<'a> Binary<'a> {
                 let slice = out.as_slice();
                 let slice = out.as_slice();
 
 
                 if generate == Generate::Linked {
                 if generate == Generate::Linked {
-                    link(slice, &self.name, self.target).to_vec()
+                    link(slice, &self.name, self.ns.target).to_vec()
                 } else {
                 } else {
                     slice.to_vec()
                     slice.to_vec()
                 }
                 }
@@ -253,7 +254,11 @@ impl<'a> Binary<'a> {
             .map_err(|s| s.to_string())?;
             .map_err(|s| s.to_string())?;
 
 
         #[cfg(feature = "wasm_opt")]
         #[cfg(feature = "wasm_opt")]
-        if let Some(level) = self.options.wasm_opt.filter(|_| self.target.is_polkadot()) {
+        if let Some(level) = self
+            .options
+            .wasm_opt
+            .filter(|_| self.ns.target.is_polkadot())
+        {
             let mut infile = tempdir().map_err(|e| e.to_string())?.keep();
             let mut infile = tempdir().map_err(|e| e.to_string())?.keep();
             infile.push("code.wasm");
             infile.push("code.wasm");
             let outfile = infile.with_extension("wasmopt");
             let outfile = infile.with_extension("wasmopt");
@@ -325,7 +330,7 @@ impl<'a> Binary<'a> {
 
 
     pub fn new(
     pub fn new(
         context: &'a Context,
         context: &'a Context,
-        target: Target,
+        ns: &'a Namespace,
         name: &str,
         name: &str,
         filename: &str,
         filename: &str,
         opt: &'a Options,
         opt: &'a Options,
@@ -352,7 +357,7 @@ impl<'a> Binary<'a> {
             }
             }
         });
         });
 
 
-        let triple = target.llvm_target_triple();
+        let triple = ns.target.llvm_target_triple();
         let module = context.create_module(name);
         let module = context.create_module(name);
 
 
         let debug_metadata_version = context.i32_type().const_int(3, false);
         let debug_metadata_version = context.i32_type().const_int(3, false);
@@ -424,7 +429,7 @@ impl<'a> Binary<'a> {
             dibuilder,
             dibuilder,
             compile_unit,
             compile_unit,
             context,
             context,
-            target,
+            ns,
             functions: HashMap::new(),
             functions: HashMap::new(),
             code: RefCell::new(Vec::new()),
             code: RefCell::new(Vec::new()),
             options: opt,
             options: opt,
@@ -444,29 +449,31 @@ impl<'a> Binary<'a> {
     }
     }
 
 
     /// Set flags for early aborts if a value transfer is done and no function/constructor can handle it
     /// Set flags for early aborts if a value transfer is done and no function/constructor can handle it
-    pub fn set_early_value_aborts(&mut self, contract: &Contract, ns: &Namespace) {
+    pub fn set_early_value_aborts(&mut self, contract: &Contract) {
         // if there is no payable function, fallback or receive then abort all value transfers at the top
         // if there is no payable function, fallback or receive then abort all value transfers at the top
         // note that receive() is always payable so this just checkes for presence.
         // note that receive() is always payable so this just checkes for presence.
         self.function_abort_value_transfers = !contract.functions.iter().any(|function_no| {
         self.function_abort_value_transfers = !contract.functions.iter().any(|function_no| {
-            let f = &ns.functions[*function_no];
+            let f = &self.ns.functions[*function_no];
             !f.is_constructor() && f.is_payable()
             !f.is_constructor() && f.is_payable()
         });
         });
 
 
         self.constructor_abort_value_transfers = !contract.functions.iter().any(|function_no| {
         self.constructor_abort_value_transfers = !contract.functions.iter().any(|function_no| {
-            let f = &ns.functions[*function_no];
+            let f = &self.ns.functions[*function_no];
             f.is_constructor() && f.is_payable()
             f.is_constructor() && f.is_payable()
         });
         });
     }
     }
 
 
     /// llvm value type, as in chain currency (usually 128 bits int)
     /// llvm value type, as in chain currency (usually 128 bits int)
-    pub(crate) fn value_type(&self, ns: &Namespace) -> IntType<'a> {
+    pub(crate) fn value_type(&self) -> IntType<'a> {
         self.context
         self.context
-            .custom_width_int_type(ns.value_length as u32 * 8)
+            .custom_width_int_type(self.ns.value_length as u32 * 8)
     }
     }
 
 
     /// llvm address type
     /// llvm address type
-    pub(crate) fn address_type(&self, ns: &Namespace) -> ArrayType<'a> {
-        self.context.i8_type().array_type(ns.address_length as u32)
+    pub(crate) fn address_type(&self) -> ArrayType<'a> {
+        self.context
+            .i8_type()
+            .array_type(self.ns.address_length as u32)
     }
     }
 
 
     /// Creates global string in the llvm module with initializer
     /// Creates global string in the llvm module with initializer
@@ -771,7 +778,7 @@ impl<'a> Binary<'a> {
     }
     }
 
 
     /// Convert a BigInt number to llvm const value
     /// Convert a BigInt number to llvm const value
-    pub(crate) fn number_literal(&self, bits: u32, n: &BigInt, _ns: &Namespace) -> IntValue<'a> {
+    pub(crate) fn number_literal(&self, bits: u32, n: &BigInt) -> IntValue<'a> {
         let ty = self.context.custom_width_int_type(bits);
         let ty = self.context.custom_width_int_type(bits);
         let s = n.to_string();
         let s = n.to_string();
 
 
@@ -779,40 +786,35 @@ impl<'a> Binary<'a> {
     }
     }
 
 
     /// Emit function prototype
     /// Emit function prototype
-    pub(crate) fn function_type(
-        &self,
-        params: &[Type],
-        returns: &[Type],
-        ns: &Namespace,
-    ) -> FunctionType<'a> {
+    pub(crate) fn function_type(&self, params: &[Type], returns: &[Type]) -> FunctionType<'a> {
         // function parameters
         // function parameters
         let mut args = params
         let mut args = params
             .iter()
             .iter()
-            .map(|ty| self.llvm_var_ty(ty, ns).into())
+            .map(|ty| self.llvm_var_ty(ty).into())
             .collect::<Vec<BasicMetadataTypeEnum>>();
             .collect::<Vec<BasicMetadataTypeEnum>>();
 
 
-        if ns.target == Target::Soroban {
+        if self.ns.target == Target::Soroban {
             match returns.iter().next() {
             match returns.iter().next() {
-                Some(ret) => return self.llvm_type(ret, ns).fn_type(&args, false),
+                Some(ret) => return self.llvm_type(ret).fn_type(&args, false),
                 None => return self.context.void_type().fn_type(&args, false),
                 None => return self.context.void_type().fn_type(&args, false),
             }
             }
         }
         }
         // add return values
         // add return values
         for ty in returns {
         for ty in returns {
-            args.push(if ty.is_reference_type(ns) && !ty.is_contract_storage() {
-                self.llvm_type(ty, ns)
-                    .ptr_type(AddressSpace::default())
-                    .ptr_type(AddressSpace::default())
-                    .into()
-            } else {
-                self.llvm_type(ty, ns)
-                    .ptr_type(AddressSpace::default())
-                    .into()
-            });
+            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()
+                },
+            );
         }
         }
 
 
         // On Solana, we need to pass around the accounts
         // On Solana, we need to pass around the accounts
-        if ns.target == Target::Solana {
+        if self.ns.target == Target::Solana {
             args.push(
             args.push(
                 self.module
                 self.module
                     .get_struct_type("struct.SolParameters")
                     .get_struct_type("struct.SolParameters")
@@ -882,8 +884,8 @@ impl<'a> Binary<'a> {
     }
     }
 
 
     /// Return the llvm type for a variable holding the type, not the type itself
     /// Return the llvm type for a variable holding the type, not the type itself
-    pub(crate) fn llvm_var_ty(&self, ty: &Type, ns: &Namespace) -> BasicTypeEnum<'a> {
-        let llvm_ty = self.llvm_type(ty, ns);
+    pub(crate) fn llvm_var_ty(&self, ty: &Type) -> BasicTypeEnum<'a> {
+        let llvm_ty = self.llvm_type(ty);
         match ty.deref_memory() {
         match ty.deref_memory() {
             Type::Struct(_)
             Type::Struct(_)
             | Type::Array(..)
             | Type::Array(..)
@@ -897,8 +899,8 @@ impl<'a> Binary<'a> {
     }
     }
 
 
     /// Return the llvm type for field in struct or array
     /// Return the llvm type for field in struct or array
-    pub(crate) fn llvm_field_ty(&self, ty: &Type, ns: &Namespace) -> BasicTypeEnum<'a> {
-        let llvm_ty = self.llvm_type(ty, ns);
+    pub(crate) fn llvm_field_ty(&self, ty: &Type) -> BasicTypeEnum<'a> {
+        let llvm_ty = self.llvm_type(ty);
         match ty.deref_memory() {
         match ty.deref_memory() {
             Type::Array(_, dim) if dim.last() == Some(&ArrayLength::Dynamic) => llvm_ty
             Type::Array(_, dim) if dim.last() == Some(&ArrayLength::Dynamic) => llvm_ty
                 .ptr_type(AddressSpace::default())
                 .ptr_type(AddressSpace::default())
@@ -911,7 +913,7 @@ impl<'a> Binary<'a> {
     }
     }
 
 
     /// Return the llvm type for the resolved type.
     /// Return the llvm type for the resolved type.
-    pub(crate) fn llvm_type(&self, ty: &Type, ns: &Namespace) -> BasicTypeEnum<'a> {
+    pub(crate) fn llvm_type(&self, ty: &Type) -> BasicTypeEnum<'a> {
         emit_context!(self);
         emit_context!(self);
         if ty.is_builtin_struct() == Some(StructType::AccountInfo) {
         if ty.is_builtin_struct() == Some(StructType::AccountInfo) {
             self.context
             self.context
@@ -938,26 +940,26 @@ impl<'a> Binary<'a> {
                 }
                 }
                 Type::Value => BasicTypeEnum::IntType(
                 Type::Value => BasicTypeEnum::IntType(
                     self.context
                     self.context
-                        .custom_width_int_type(ns.value_length as u32 * 8),
+                        .custom_width_int_type(self.ns.value_length as u32 * 8),
                 ),
                 ),
                 Type::Contract(_) | Type::Address(_) => {
                 Type::Contract(_) | Type::Address(_) => {
                     // Soroban addresses are 64 bit wide integer that represents a refrenece for the real Address on the Host side.
                     // Soroban addresses are 64 bit wide integer that represents a refrenece for the real Address on the Host side.
-                    if ns.target == Target::Soroban {
+                    if self.ns.target == Target::Soroban {
                         BasicTypeEnum::IntType(self.context.i64_type())
                         BasicTypeEnum::IntType(self.context.i64_type())
                     } else {
                     } else {
-                        BasicTypeEnum::ArrayType(self.address_type(ns))
+                        BasicTypeEnum::ArrayType(self.address_type())
                     }
                     }
                 }
                 }
                 Type::Bytes(n) => {
                 Type::Bytes(n) => {
                     BasicTypeEnum::IntType(self.context.custom_width_int_type(*n as u32 * 8))
                     BasicTypeEnum::IntType(self.context.custom_width_int_type(*n as u32 * 8))
                 }
                 }
-                Type::Enum(n) => self.llvm_type(&ns.enums[*n].ty, ns),
+                Type::Enum(n) => self.llvm_type(&self.ns.enums[*n].ty),
                 Type::String | Type::DynamicBytes => {
                 Type::String | Type::DynamicBytes => {
                     self.module.get_struct_type("struct.vector").unwrap().into()
                     self.module.get_struct_type("struct.vector").unwrap().into()
                 }
                 }
                 Type::Array(base_ty, dims) => {
                 Type::Array(base_ty, dims) => {
                     dims.iter()
                     dims.iter()
-                        .fold(self.llvm_field_ty(base_ty, ns), |aty, dim| match dim {
+                        .fold(self.llvm_field_ty(base_ty), |aty, dim| match dim {
                             ArrayLength::Fixed(d) => aty.array_type(d.to_u32().unwrap()).into(),
                             ArrayLength::Fixed(d) => aty.array_type(d.to_u32().unwrap()).into(),
                             ArrayLength::Dynamic => {
                             ArrayLength::Dynamic => {
                                 self.module.get_struct_type("struct.vector").unwrap().into()
                                 self.module.get_struct_type("struct.vector").unwrap().into()
@@ -974,35 +976,35 @@ impl<'a> Binary<'a> {
                     .context
                     .context
                     .struct_type(
                     .struct_type(
                         &str_ty
                         &str_ty
-                            .definition(ns)
+                            .definition(self.ns)
                             .fields
                             .fields
                             .iter()
                             .iter()
-                            .map(|f| self.llvm_field_ty(&f.ty, ns))
+                            .map(|f| self.llvm_field_ty(&f.ty))
                             .collect::<Vec<BasicTypeEnum>>(),
                             .collect::<Vec<BasicTypeEnum>>(),
                         false,
                         false,
                     )
                     )
                     .as_basic_type_enum(),
                     .as_basic_type_enum(),
-                Type::Mapping(..) => self.llvm_type(&ns.storage_type(), ns),
+                Type::Mapping(..) => self.llvm_type(&self.ns.storage_type()),
                 Type::Ref(r) => {
                 Type::Ref(r) => {
-                    if ns.target == Target::Soroban {
+                    if self.ns.target == Target::Soroban {
                         return BasicTypeEnum::IntType(self.context.i64_type());
                         return BasicTypeEnum::IntType(self.context.i64_type());
                     }
                     }
 
 
-                    self.llvm_type(r, ns)
+                    self.llvm_type(r)
                         .ptr_type(AddressSpace::default())
                         .ptr_type(AddressSpace::default())
                         .as_basic_type_enum()
                         .as_basic_type_enum()
                 }
                 }
-                Type::StorageRef(..) => self.llvm_type(&ns.storage_type(), ns),
+                Type::StorageRef(..) => self.llvm_type(&self.ns.storage_type()),
                 Type::InternalFunction {
                 Type::InternalFunction {
                     params, returns, ..
                     params, returns, ..
                 } => {
                 } => {
-                    let ftype = self.function_type(params, returns, ns);
+                    let ftype = self.function_type(params, returns);
 
 
                     BasicTypeEnum::PointerType(ftype.ptr_type(AddressSpace::default()))
                     BasicTypeEnum::PointerType(ftype.ptr_type(AddressSpace::default()))
                 }
                 }
                 Type::ExternalFunction { .. } => {
                 Type::ExternalFunction { .. } => {
-                    let address = self.llvm_type(&Type::Address(false), ns);
-                    let selector = self.llvm_type(&Type::FunctionSelector, ns);
+                    let address = self.llvm_type(&Type::Address(false));
+                    let selector = self.llvm_type(&Type::FunctionSelector);
                     self.context
                     self.context
                         .struct_type(&[selector, address], false)
                         .struct_type(&[selector, address], false)
                         .as_basic_type_enum()
                         .as_basic_type_enum()
@@ -1010,28 +1012,26 @@ impl<'a> Binary<'a> {
                 Type::Slice(ty) => BasicTypeEnum::StructType(
                 Type::Slice(ty) => BasicTypeEnum::StructType(
                     self.context.struct_type(
                     self.context.struct_type(
                         &[
                         &[
-                            self.llvm_type(ty, ns)
-                                .ptr_type(AddressSpace::default())
-                                .into(),
+                            self.llvm_type(ty).ptr_type(AddressSpace::default()).into(),
                             self.context
                             self.context
-                                .custom_width_int_type(ns.target.ptr_size().into())
+                                .custom_width_int_type(self.ns.target.ptr_size().into())
                                 .into(),
                                 .into(),
                         ],
                         ],
                         false,
                         false,
                     ),
                     ),
                 ),
                 ),
-                Type::UserType(no) => self.llvm_type(&ns.user_types[*no].ty, ns),
+                Type::UserType(no) => self.llvm_type(&self.ns.user_types[*no].ty),
                 Type::BufferPointer => self
                 Type::BufferPointer => self
                     .context
                     .context
                     .i8_type()
                     .i8_type()
                     .ptr_type(AddressSpace::default())
                     .ptr_type(AddressSpace::default())
                     .as_basic_type_enum(),
                     .as_basic_type_enum(),
                 Type::FunctionSelector => {
                 Type::FunctionSelector => {
-                    self.llvm_type(&Type::Bytes(ns.target.selector_length()), ns)
+                    self.llvm_type(&Type::Bytes(self.ns.target.selector_length()))
                 }
                 }
                 // Soroban functions always return a 64 bit value.
                 // Soroban functions always return a 64 bit value.
                 Type::Void => {
                 Type::Void => {
-                    if ns.target == Target::Soroban {
+                    if self.ns.target == Target::Soroban {
                         BasicTypeEnum::IntType(self.context.i64_type())
                         BasicTypeEnum::IntType(self.context.i64_type())
                     } else {
                     } else {
                         unreachable!()
                         unreachable!()
@@ -1049,9 +1049,8 @@ impl<'a> Binary<'a> {
         elem_size: IntValue<'a>,
         elem_size: IntValue<'a>,
         init: Option<&Vec<u8>>,
         init: Option<&Vec<u8>>,
         ty: &Type,
         ty: &Type,
-        ns: &Namespace,
     ) -> BasicValueEnum<'a> {
     ) -> BasicValueEnum<'a> {
-        if self.target == Target::Soroban {
+        if self.ns.target == Target::Soroban {
             if matches!(ty, Type::Bytes(_)) {
             if matches!(ty, Type::Bytes(_)) {
                 let n = if let Type::Bytes(n) = ty {
                 let n = if let Type::Bytes(n) = ty {
                     n
                     n
@@ -1096,7 +1095,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.
                 // 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(
                 let ty = self.context.struct_type(
                     &[
                     &[
-                        self.llvm_type(&Type::Bytes(bs.len() as u8), ns)
+                        self.llvm_type(&Type::Bytes(bs.len() as u8))
                             .ptr_type(AddressSpace::default())
                             .ptr_type(AddressSpace::default())
                             .into(),
                             .into(),
                         self.context.i64_type().into(),
                         self.context.i64_type().into(),
@@ -1150,7 +1149,7 @@ impl<'a> Binary<'a> {
             // slice
             // slice
             let slice = vector.into_struct_value();
             let slice = vector.into_struct_value();
 
 
-            let len_type = if self.target == Target::Soroban {
+            let len_type = if self.ns.target == Target::Soroban {
                 self.context.i64_type()
                 self.context.i64_type()
             } else {
             } else {
                 self.context.i32_type()
                 self.context.i32_type()
@@ -1235,13 +1234,12 @@ impl<'a> Binary<'a> {
         array_ty: &Type,
         array_ty: &Type,
         array: PointerValue<'a>,
         array: PointerValue<'a>,
         index: IntValue<'a>,
         index: IntValue<'a>,
-        ns: &Namespace,
     ) -> PointerValue<'a> {
     ) -> PointerValue<'a> {
         match array_ty {
         match array_ty {
             Type::Array(_, dim) => {
             Type::Array(_, dim) => {
                 if matches!(dim.last(), Some(ArrayLength::Fixed(_))) {
                 if matches!(dim.last(), Some(ArrayLength::Fixed(_))) {
                     // fixed size array
                     // fixed size array
-                    let llvm_ty = self.llvm_type(array_ty, ns);
+                    let llvm_ty = self.llvm_type(array_ty);
                     unsafe {
                     unsafe {
                         self.builder
                         self.builder
                             .build_gep(
                             .build_gep(
@@ -1254,7 +1252,7 @@ impl<'a> Binary<'a> {
                     }
                     }
                 } else {
                 } else {
                     let elem_ty = array_ty.array_deref();
                     let elem_ty = array_ty.array_deref();
-                    let llvm_elem_ty = self.llvm_type(elem_ty.deref_memory(), ns);
+                    let llvm_elem_ty = self.llvm_type(elem_ty.deref_memory());
 
 
                     // dynamic length array or vector
                     // dynamic length array or vector
                     let index = self
                     let index = self
@@ -1296,12 +1294,11 @@ impl<'a> Binary<'a> {
         target: &T,
         target: &T,
         reason_string: String,
         reason_string: String,
         reason_loc: Option<pt::Loc>,
         reason_loc: Option<pt::Loc>,
-        ns: &Namespace,
     ) {
     ) {
         if !self.options.log_runtime_errors {
         if !self.options.log_runtime_errors {
             return;
             return;
         }
         }
-        let error_with_loc = error_msg_with_loc(ns, reason_string, reason_loc);
+        let error_with_loc = error_msg_with_loc(self.ns, reason_string, reason_loc);
         let global_string =
         let global_string =
             self.emit_global_string("runtime_error", error_with_loc.as_bytes(), true);
             self.emit_global_string("runtime_error", error_with_loc.as_bytes(), true);
         target.print(
         target.print(
@@ -1316,12 +1313,8 @@ impl<'a> Binary<'a> {
     /// Emit encoded error data of "Panic(uint256)" as interned global string.
     /// Emit encoded error data of "Panic(uint256)" as interned global string.
     ///
     ///
     /// On Solana, because reverts do not return data, a nil ptr is returned.
     /// On Solana, because reverts do not return data, a nil ptr is returned.
-    pub(super) fn panic_data_const(
-        &self,
-        ns: &Namespace,
-        code: PanicCode,
-    ) -> (PointerValue<'a>, IntValue<'a>) {
-        if ns.target == Target::Solana || ns.target == Target::Soroban {
+    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 (
             return (
                 self.context
                 self.context
                     .i8_type()
                     .i8_type()
@@ -1336,8 +1329,11 @@ impl<'a> Binary<'a> {
             ty: Type::Uint(256),
             ty: Type::Uint(256),
             value: (code as u8).into(),
             value: (code as u8).into(),
         };
         };
-        let bytes = create_encoder(ns, false)
-            .const_encode(&[SolidityError::Panic(code).selector_expression(ns), expr])
+        let bytes = create_encoder(self.ns, false)
+            .const_encode(&[
+                SolidityError::Panic(code).selector_expression(self.ns),
+                expr,
+            ])
             .unwrap();
             .unwrap();
         (
         (
             self.emit_global_string(&code.to_string(), &bytes, true),
             self.emit_global_string(&code.to_string(), &bytes, true),

+ 11 - 14
src/emit/cfg.rs

@@ -4,7 +4,7 @@ use crate::codegen::{cfg::ControlFlowGraph, vartable::Storage};
 use crate::emit::binary::Binary;
 use crate::emit::binary::Binary;
 use crate::emit::instructions::process_instruction;
 use crate::emit::instructions::process_instruction;
 use crate::emit::{TargetRuntime, Variable};
 use crate::emit::{TargetRuntime, Variable};
-use crate::sema::ast::{Contract, Namespace};
+use crate::sema::ast::Contract;
 use crate::Target;
 use crate::Target;
 use inkwell::debug_info::{AsDIScope, DISubprogram, DIType};
 use inkwell::debug_info::{AsDIScope, DISubprogram, DIType};
 use inkwell::types::BasicType;
 use inkwell::types::BasicType;
@@ -31,7 +31,6 @@ pub(super) fn emit_cfg<'a, T: TargetRuntime<'a> + ?Sized>(
     contract: &Contract,
     contract: &Contract,
     cfg: &ControlFlowGraph,
     cfg: &ControlFlowGraph,
     function: FunctionValue<'a>,
     function: FunctionValue<'a>,
-    ns: &Namespace,
 ) {
 ) {
     let dibuilder = &bin.dibuilder;
     let dibuilder = &bin.dibuilder;
     let compile_unit = &bin.compile_unit;
     let compile_unit = &bin.compile_unit;
@@ -78,7 +77,7 @@ pub(super) fn emit_cfg<'a, T: TargetRuntime<'a> + ?Sized>(
 
 
                 let func_loc = cfg.blocks[0].instr.first().unwrap().loc();
                 let func_loc = cfg.blocks[0].instr.first().unwrap().loc();
                 let line_num = if let pt::Loc::File(file_offset, offset, _) = func_loc {
                 let line_num = if let pt::Loc::File(file_offset, offset, _) = func_loc {
-                    let (line, _) = ns.files[file_offset].offset_to_line_column(offset);
+                    let (line, _) = bin.ns.files[file_offset].offset_to_line_column(offset);
                     line
                     line
                 } else {
                 } else {
                     0
                     0
@@ -106,10 +105,10 @@ pub(super) fn emit_cfg<'a, T: TargetRuntime<'a> + ?Sized>(
 
 
     let mut work = VecDeque::new();
     let mut work = VecDeque::new();
 
 
-    blocks.insert(0, create_block(0, bin, cfg, function, ns));
+    blocks.insert(0, create_block(0, bin, cfg, function));
 
 
     // On Solana, the last argument is the accounts
     // On Solana, the last argument is the accounts
-    if ns.target == Target::Solana {
+    if bin.ns.target == Target::Solana {
         bin.parameters = Some(function.get_last_param().unwrap().into_pointer_value());
         bin.parameters = Some(function.get_last_param().unwrap().into_pointer_value());
     }
     }
 
 
@@ -118,10 +117,10 @@ pub(super) fn emit_cfg<'a, T: TargetRuntime<'a> + ?Sized>(
 
 
     for (no, v) in &cfg.vars {
     for (no, v) in &cfg.vars {
         match v.storage {
         match v.storage {
-            Storage::Local if v.ty.is_reference_type(ns) && !v.ty.is_contract_storage() => {
+            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
                 // a null pointer means an empty, zero'ed thing, be it string, struct or array
                 let value = bin
                 let value = bin
-                    .llvm_type(&v.ty, ns)
+                    .llvm_type(&v.ty)
                     .ptr_type(AddressSpace::default())
                     .ptr_type(AddressSpace::default())
                     .const_null()
                     .const_null()
                     .into();
                     .into();
@@ -133,14 +132,14 @@ pub(super) fn emit_cfg<'a, T: TargetRuntime<'a> + ?Sized>(
                     *no,
                     *no,
                     Variable {
                     Variable {
                         value: bin
                         value: bin
-                            .llvm_type(&ns.storage_type(), ns)
+                            .llvm_type(&bin.ns.storage_type())
                             .into_int_type()
                             .into_int_type()
                             .const_zero()
                             .const_zero()
                             .into(),
                             .into(),
                     },
                     },
                 );
                 );
             }
             }
-            Storage::Constant(_) | Storage::Contract(_) if v.ty.is_reference_type(ns) => {
+            Storage::Constant(_) | Storage::Contract(_) if v.ty.is_reference_type(bin.ns) => {
                 // This needs a placeholder
                 // This needs a placeholder
                 vars.insert(
                 vars.insert(
                     *no,
                     *no,
@@ -150,7 +149,7 @@ pub(super) fn emit_cfg<'a, T: TargetRuntime<'a> + ?Sized>(
                 );
                 );
             }
             }
             Storage::Local | Storage::Contract(_) | Storage::Constant(_) => {
             Storage::Local | Storage::Contract(_) | Storage::Constant(_) => {
-                let ty = bin.llvm_type(&v.ty, ns);
+                let ty = bin.llvm_type(&v.ty);
                 vars.insert(
                 vars.insert(
                     *no,
                     *no,
                     Variable {
                     Variable {
@@ -184,7 +183,7 @@ pub(super) fn emit_cfg<'a, T: TargetRuntime<'a> + ?Sized>(
             if bin.options.generate_debug_information {
             if bin.options.generate_debug_information {
                 let debug_loc = ins.loc();
                 let debug_loc = ins.loc();
                 if let pt::Loc::File(file_offset, offset, _) = debug_loc {
                 if let pt::Loc::File(file_offset, offset, _) = debug_loc {
-                    let (line, col) = ns.files[file_offset].offset_to_line_column(offset);
+                    let (line, col) = bin.ns.files[file_offset].offset_to_line_column(offset);
                     let debug_loc = dibuilder.create_debug_location(
                     let debug_loc = dibuilder.create_debug_location(
                         bin.context,
                         bin.context,
                         line as u32,
                         line as u32,
@@ -214,7 +213,6 @@ pub(super) fn emit_cfg<'a, T: TargetRuntime<'a> + ?Sized>(
                 bin,
                 bin,
                 &mut w,
                 &mut w,
                 function,
                 function,
-                ns,
                 cfg,
                 cfg,
                 &mut work,
                 &mut work,
                 &mut blocks,
                 &mut blocks,
@@ -231,7 +229,6 @@ pub(super) fn create_block<'a>(
     bin: &Binary<'a>,
     bin: &Binary<'a>,
     cfg: &ControlFlowGraph,
     cfg: &ControlFlowGraph,
     function: FunctionValue<'a>,
     function: FunctionValue<'a>,
-    ns: &Namespace,
 ) -> BasicBlock<'a> {
 ) -> BasicBlock<'a> {
     let cfg_bb = &cfg.blocks[block_no];
     let cfg_bb = &cfg.blocks[block_no];
     let mut phis = HashMap::new();
     let mut phis = HashMap::new();
@@ -242,7 +239,7 @@ pub(super) fn create_block<'a>(
 
 
     if let Some(ref cfg_phis) = cfg_bb.phis {
     if let Some(ref cfg_phis) = cfg_bb.phis {
         for v in cfg_phis {
         for v in cfg_phis {
-            let ty = bin.llvm_var_ty(&cfg.vars[v].ty, ns);
+            let ty = bin.llvm_var_ty(&cfg.vars[v].ty);
 
 
             phis.insert(*v, bin.builder.build_phi(ty, &cfg.vars[v].id.name).unwrap());
             phis.insert(*v, bin.builder.build_phi(ty, &cfg.vars[v].id.name).unwrap());
         }
         }

ファイルの差分が大きいため隠しています
+ 155 - 180
src/emit/expression.rs


+ 2 - 4
src/emit/functions.rs

@@ -2,7 +2,7 @@
 
 
 use crate::{
 use crate::{
     emit::{binary::Binary, cfg::emit_cfg, TargetRuntime},
     emit::{binary::Binary, cfg::emit_cfg, TargetRuntime},
-    sema::ast::{Contract, Namespace, Type},
+    sema::ast::{Contract, Type},
 };
 };
 use inkwell::module::Linkage;
 use inkwell::module::Linkage;
 
 
@@ -11,7 +11,6 @@ pub(super) fn emit_functions<'a, T: TargetRuntime<'a>>(
     target: &mut T,
     target: &mut T,
     bin: &mut Binary<'a>,
     bin: &mut Binary<'a>,
     contract: &Contract,
     contract: &Contract,
-    ns: &Namespace,
 ) {
 ) {
     let mut defines = Vec::new();
     let mut defines = Vec::new();
 
 
@@ -26,7 +25,6 @@ pub(super) fn emit_functions<'a, T: TargetRuntime<'a>>(
                     .iter()
                     .iter()
                     .map(|p| p.ty.clone())
                     .map(|p| p.ty.clone())
                     .collect::<Vec<Type>>(),
                     .collect::<Vec<Type>>(),
-                ns,
             );
             );
 
 
             let func_decl = if let Some(func) = bin.module.get_function(&cfg.name) {
             let func_decl = if let Some(func) = bin.module.get_function(&cfg.name) {
@@ -46,6 +44,6 @@ pub(super) fn emit_functions<'a, T: TargetRuntime<'a>>(
     }
     }
 
 
     for (func_decl, cfg) in defines {
     for (func_decl, cfg) in defines {
-        emit_cfg(target, bin, contract, cfg, func_decl, ns);
+        emit_cfg(target, bin, contract, cfg, func_decl);
     }
     }
 }
 }

+ 123 - 146
src/emit/instructions.rs

@@ -9,7 +9,7 @@ use crate::emit::binary::Binary;
 use crate::emit::cfg::{create_block, BasicBlock, Work};
 use crate::emit::cfg::{create_block, BasicBlock, Work};
 use crate::emit::expression::expression;
 use crate::emit::expression::expression;
 use crate::emit::{ContractArgs, TargetRuntime, Variable};
 use crate::emit::{ContractArgs, TargetRuntime, Variable};
-use crate::sema::ast::{Contract, ExternalCallAccounts, Namespace, RetrieveType, Type};
+use crate::sema::ast::{Contract, ExternalCallAccounts, RetrieveType, Type};
 use crate::Target;
 use crate::Target;
 use inkwell::types::BasicType;
 use inkwell::types::BasicType;
 use inkwell::values::{
 use inkwell::values::{
@@ -28,7 +28,6 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
     bin: &Binary<'a>,
     bin: &Binary<'a>,
     w: &mut Work<'a>,
     w: &mut Work<'a>,
     function: FunctionValue<'a>,
     function: FunctionValue<'a>,
-    ns: &Namespace,
     cfg: &ControlFlowGraph,
     cfg: &ControlFlowGraph,
     work: &mut VecDeque<Work<'a>>,
     work: &mut VecDeque<Work<'a>>,
     blocks: &mut HashMap<usize, BasicBlock<'a>>,
     blocks: &mut HashMap<usize, BasicBlock<'a>>,
@@ -36,16 +35,16 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
 ) {
 ) {
     match ins {
     match ins {
         Instr::Nop => (),
         Instr::Nop => (),
-        Instr::Return { value } if value.is_empty() && ns.target != Target::Soroban => {
+        Instr::Return { value } if value.is_empty() && bin.ns.target != Target::Soroban => {
             bin.builder
             bin.builder
                 .build_return(Some(&bin.return_values[&ReturnCode::Success]))
                 .build_return(Some(&bin.return_values[&ReturnCode::Success]))
                 .unwrap();
                 .unwrap();
         }
         }
-        Instr::Return { value } if ns.target != Target::Soroban => {
+        Instr::Return { value } if bin.ns.target != Target::Soroban => {
             let returns_offset = cfg.params.len();
             let returns_offset = cfg.params.len();
             for (i, val) in value.iter().enumerate() {
             for (i, val) in value.iter().enumerate() {
                 let arg = function.get_nth_param((returns_offset + i) as u32).unwrap();
                 let arg = function.get_nth_param((returns_offset + i) as u32).unwrap();
-                let retval = expression(target, bin, val, &w.vars, function, ns);
+                let retval = expression(target, bin, val, &w.vars, function);
 
 
                 bin.builder
                 bin.builder
                     .build_store(arg.into_pointer_value(), retval)
                     .build_store(arg.into_pointer_value(), retval)
@@ -58,7 +57,7 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
         }
         }
         Instr::Return { value } => match value.iter().next() {
         Instr::Return { value } => match value.iter().next() {
             Some(val) => {
             Some(val) => {
-                let retval = expression(target, bin, val, &w.vars, function, ns);
+                let retval = expression(target, bin, val, &w.vars, function);
                 bin.builder.build_return(Some(&retval)).unwrap();
                 bin.builder.build_return(Some(&retval)).unwrap();
             }
             }
             None => {
             None => {
@@ -69,27 +68,26 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
             if let Expression::Undefined { ty: expr_type } = expr {
             if let Expression::Undefined { ty: expr_type } = expr {
                 // If the variable has been declared as undefined, but we can
                 // If the variable has been declared as undefined, but we can
                 // initialize it with a default value
                 // initialize it with a default value
-                if let Some(default_expr) = expr_type.default(ns) {
+                if let Some(default_expr) = expr_type.default(bin.ns) {
                     w.vars.get_mut(res).unwrap().value =
                     w.vars.get_mut(res).unwrap().value =
-                        expression(target, bin, &default_expr, &w.vars, function, ns);
+                        expression(target, bin, &default_expr, &w.vars, function);
                 }
                 }
             } else {
             } else {
                 w.vars.get_mut(res).unwrap().value =
                 w.vars.get_mut(res).unwrap().value =
-                    expression(target, bin, expr, &w.vars, function, ns);
+                    expression(target, bin, expr, &w.vars, function);
             }
             }
         }
         }
         Instr::Branch { block: dest } => {
         Instr::Branch { block: dest } => {
             let pos = bin.builder.get_insert_block().unwrap();
             let pos = bin.builder.get_insert_block().unwrap();
 
 
-            let bb = add_or_retrieve_block(*dest, pos, bin, function, blocks, work, w, cfg, ns);
+            let bb = add_or_retrieve_block(*dest, pos, bin, function, blocks, work, w, cfg);
 
 
             bin.builder.position_at_end(pos);
             bin.builder.position_at_end(pos);
             bin.builder.build_unconditional_branch(bb).unwrap();
             bin.builder.build_unconditional_branch(bb).unwrap();
         }
         }
         Instr::Store { dest, data } => {
         Instr::Store { dest, data } => {
-            let value_ref = expression(target, bin, data, &w.vars, function, ns);
-            let dest_ref =
-                expression(target, bin, dest, &w.vars, function, ns).into_pointer_value();
+            let value_ref = expression(target, bin, data, &w.vars, function);
+            let dest_ref = expression(target, bin, dest, &w.vars, function).into_pointer_value();
             bin.builder.build_store(dest_ref, value_ref).unwrap();
             bin.builder.build_store(dest_ref, value_ref).unwrap();
         }
         }
         Instr::BranchCond {
         Instr::BranchCond {
@@ -97,15 +95,13 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
             true_block: true_,
             true_block: true_,
             false_block: false_,
             false_block: false_,
         } => {
         } => {
-            let cond = expression(target, bin, cond, &w.vars, function, ns);
+            let cond = expression(target, bin, cond, &w.vars, function);
 
 
             let pos = bin.builder.get_insert_block().unwrap();
             let pos = bin.builder.get_insert_block().unwrap();
 
 
-            let bb_true =
-                add_or_retrieve_block(*true_, pos, bin, function, blocks, work, w, cfg, ns);
+            let bb_true = add_or_retrieve_block(*true_, pos, bin, function, blocks, work, w, cfg);
 
 
-            let bb_false =
-                add_or_retrieve_block(*false_, pos, bin, function, blocks, work, w, cfg, ns);
+            let bb_false = add_or_retrieve_block(*false_, pos, bin, function, blocks, work, w, cfg);
 
 
             bin.builder.position_at_end(pos);
             bin.builder.position_at_end(pos);
             bin.builder
             bin.builder
@@ -118,15 +114,15 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
             storage,
             storage,
             storage_type,
             storage_type,
         } => {
         } => {
-            let mut slot = expression(target, bin, storage, &w.vars, function, ns).into_int_value();
+            let mut slot = expression(target, bin, storage, &w.vars, function).into_int_value();
 
 
             w.vars.get_mut(res).unwrap().value =
             w.vars.get_mut(res).unwrap().value =
-                target.storage_load(bin, ty, &mut slot, function, ns, storage_type);
+                target.storage_load(bin, ty, &mut slot, function, storage_type);
         }
         }
         Instr::ClearStorage { ty, storage } => {
         Instr::ClearStorage { ty, storage } => {
-            let mut slot = expression(target, bin, storage, &w.vars, function, ns).into_int_value();
+            let mut slot = expression(target, bin, storage, &w.vars, function).into_int_value();
 
 
-            target.storage_delete(bin, ty, &mut slot, function, ns);
+            target.storage_delete(bin, ty, &mut slot, function);
         }
         }
         Instr::SetStorage {
         Instr::SetStorage {
             ty,
             ty,
@@ -134,11 +130,11 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
             storage,
             storage,
             storage_type,
             storage_type,
         } => {
         } => {
-            let value = expression(target, bin, value, &w.vars, function, ns);
+            let value = expression(target, bin, value, &w.vars, function);
 
 
-            let mut slot = expression(target, bin, storage, &w.vars, function, ns).into_int_value();
+            let mut slot = expression(target, bin, storage, &w.vars, function).into_int_value();
 
 
-            target.storage_store(bin, ty, true, &mut slot, value, function, ns, storage_type);
+            target.storage_store(bin, ty, true, &mut slot, value, function, storage_type);
         }
         }
         Instr::SetStorageBytes {
         Instr::SetStorageBytes {
             storage,
             storage,
@@ -146,10 +142,10 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
             offset,
             offset,
         } => {
         } => {
             let index_loc = offset.loc();
             let index_loc = offset.loc();
-            let value = expression(target, bin, value, &w.vars, function, ns);
+            let value = expression(target, bin, value, &w.vars, function);
 
 
-            let slot = expression(target, bin, storage, &w.vars, function, ns).into_int_value();
-            let offset = expression(target, bin, offset, &w.vars, function, ns).into_int_value();
+            let slot = expression(target, bin, storage, &w.vars, function).into_int_value();
+            let offset = expression(target, bin, offset, &w.vars, function).into_int_value();
 
 
             target.set_storage_bytes_subscript(
             target.set_storage_bytes_subscript(
                 bin,
                 bin,
@@ -157,7 +153,6 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
                 slot,
                 slot,
                 offset,
                 offset,
                 value.into_int_value(),
                 value.into_int_value(),
-                ns,
                 index_loc,
                 index_loc,
             );
             );
         }
         }
@@ -169,17 +164,16 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
         } => {
         } => {
             let val = value
             let val = value
                 .as_ref()
                 .as_ref()
-                .map(|expr| expression(target, bin, expr, &w.vars, function, ns));
-            let slot = expression(target, bin, storage, &w.vars, function, ns).into_int_value();
+                .map(|expr| expression(target, bin, expr, &w.vars, function));
+            let slot = expression(target, bin, storage, &w.vars, function).into_int_value();
 
 
-            w.vars.get_mut(res).unwrap().value =
-                target.storage_push(bin, function, ty, slot, val, ns);
+            w.vars.get_mut(res).unwrap().value = target.storage_push(bin, function, ty, slot, val);
         }
         }
         Instr::PopStorage { res, ty, storage } => {
         Instr::PopStorage { res, ty, storage } => {
             let loc = storage.loc();
             let loc = storage.loc();
-            let slot = expression(target, bin, storage, &w.vars, function, ns).into_int_value();
+            let slot = expression(target, bin, storage, &w.vars, function).into_int_value();
 
 
-            let value = target.storage_pop(bin, function, ty, slot, res.is_some(), ns, loc);
+            let value = target.storage_pop(bin, function, ty, slot, res.is_some(), loc);
 
 
             if let Some(res) = res {
             if let Some(res) = res {
                 w.vars.get_mut(res).unwrap().value = value.unwrap();
                 w.vars.get_mut(res).unwrap().value = value.unwrap();
@@ -193,11 +187,11 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
         } => {
         } => {
             let arr = w.vars[array].value;
             let arr = w.vars[array].value;
 
 
-            let llvm_ty = bin.llvm_type(ty, ns);
+            let llvm_ty = bin.llvm_type(ty);
             let elem_ty = ty.array_elem();
             let elem_ty = ty.array_elem();
 
 
             // Calculate total size for reallocation
             // Calculate total size for reallocation
-            let llvm_elem_ty = bin.llvm_field_ty(&elem_ty, ns);
+            let llvm_elem_ty = bin.llvm_field_ty(&elem_ty);
             let elem_size = llvm_elem_ty
             let elem_size = llvm_elem_ty
                 .size_of()
                 .size_of()
                 .unwrap()
                 .unwrap()
@@ -247,10 +241,10 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
                     )
                     )
                     .unwrap()
                     .unwrap()
             };
             };
-            let value = expression(target, bin, value, &w.vars, function, ns);
-            let value = if elem_ty.is_fixed_reference_type(ns) {
+            let value = expression(target, bin, value, &w.vars, function);
+            let value = if elem_ty.is_fixed_reference_type(bin.ns) {
                 w.vars.get_mut(res).unwrap().value = slot_ptr.into();
                 w.vars.get_mut(res).unwrap().value = slot_ptr.into();
-                let load_ty = bin.llvm_type(&elem_ty, ns);
+                let load_ty = bin.llvm_type(&elem_ty);
                 bin.builder
                 bin.builder
                     .build_load(load_ty, value.into_pointer_value(), "elem")
                     .build_load(load_ty, value.into_pointer_value(), "elem")
                     .unwrap()
                     .unwrap()
@@ -334,15 +328,15 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
                 .unwrap();
                 .unwrap();
 
 
             bin.builder.position_at_end(error);
             bin.builder.position_at_end(error);
-            bin.log_runtime_error(target, "pop from empty array".to_string(), Some(*loc), ns);
-            let (revert_out, revert_out_len) = bin.panic_data_const(ns, PanicCode::EmptyArrayPop);
+            bin.log_runtime_error(target, "pop from empty array".to_string(), Some(*loc));
+            let (revert_out, revert_out_len) = bin.panic_data_const(PanicCode::EmptyArrayPop);
             target.assert_failure(bin, revert_out, revert_out_len);
             target.assert_failure(bin, revert_out, revert_out_len);
 
 
             bin.builder.position_at_end(pop);
             bin.builder.position_at_end(pop);
-            let llvm_ty = bin.llvm_type(ty, ns);
+            let llvm_ty = bin.llvm_type(ty);
 
 
             let elem_ty = ty.array_elem();
             let elem_ty = ty.array_elem();
-            let llvm_elem_ty = bin.llvm_field_ty(&elem_ty, ns);
+            let llvm_elem_ty = bin.llvm_field_ty(&elem_ty);
 
 
             // Calculate total size for reallocation
             // Calculate total size for reallocation
             let elem_size = llvm_elem_ty
             let elem_size = llvm_elem_ty
@@ -378,12 +372,12 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
                     )
                     )
                     .unwrap()
                     .unwrap()
             };
             };
-            if elem_ty.is_fixed_reference_type(ns) {
+            if elem_ty.is_fixed_reference_type(bin.ns) {
                 w.vars.get_mut(res).unwrap().value = slot_ptr.into();
                 w.vars.get_mut(res).unwrap().value = slot_ptr.into();
             } else {
             } else {
                 let ret_val = bin
                 let ret_val = bin
                     .builder
                     .builder
-                    .build_load(bin.llvm_type(&elem_ty, ns), slot_ptr, "")
+                    .build_load(bin.llvm_type(&elem_ty), slot_ptr, "")
                     .unwrap();
                     .unwrap();
                 w.vars.get_mut(res).unwrap().value = ret_val;
                 w.vars.get_mut(res).unwrap().value = ret_val;
             }
             }
@@ -447,14 +441,14 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
         Instr::AssertFailure {
         Instr::AssertFailure {
             encoded_args: Some(expr),
             encoded_args: Some(expr),
         } => {
         } => {
-            let data = expression(target, bin, expr, &w.vars, function, ns);
+            let data = expression(target, bin, expr, &w.vars, function);
             let vector_bytes = bin.vector_bytes(data);
             let vector_bytes = bin.vector_bytes(data);
             let len = bin.vector_len(data);
             let len = bin.vector_len(data);
 
 
             target.assert_failure(bin, vector_bytes, len);
             target.assert_failure(bin, vector_bytes, len);
         }
         }
         Instr::Print { expr } => {
         Instr::Print { expr } => {
-            let expr = expression(target, bin, expr, &w.vars, function, ns);
+            let expr = expression(target, bin, expr, &w.vars, function);
 
 
             target.print(bin, bin.vector_bytes(expr), bin.vector_len(expr));
             target.print(bin, bin.vector_bytes(expr), bin.vector_len(expr));
         }
         }
@@ -468,18 +462,18 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
 
 
             let mut parms = args
             let mut parms = args
                 .iter()
                 .iter()
-                .map(|p| expression(target, bin, p, &w.vars, function, ns).into())
+                .map(|p| expression(target, bin, p, &w.vars, function).into())
                 .collect::<Vec<BasicMetadataValueEnum>>();
                 .collect::<Vec<BasicMetadataValueEnum>>();
 
 
             // Soroban doesn't write return values to imported memory
             // Soroban doesn't write return values to imported memory
-            if !res.is_empty() && ns.target != Target::Soroban {
+            if !res.is_empty() && bin.ns.target != Target::Soroban {
                 for v in f.returns.iter() {
                 for v in f.returns.iter() {
-                    parms.push(if ns.target == Target::Solana {
-                        bin.build_alloca(function, bin.llvm_var_ty(&v.ty, ns), v.name_as_str())
+                    parms.push(if bin.ns.target == Target::Solana {
+                        bin.build_alloca(function, bin.llvm_var_ty(&v.ty), v.name_as_str())
                             .into()
                             .into()
                     } else {
                     } else {
                         bin.builder
                         bin.builder
-                            .build_alloca(bin.llvm_var_ty(&v.ty, ns), v.name_as_str())
+                            .build_alloca(bin.llvm_var_ty(&v.ty), v.name_as_str())
                             .unwrap()
                             .unwrap()
                             .into()
                             .into()
                     });
                     });
@@ -498,7 +492,7 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
                 .left();
                 .left();
 
 
             // Soroban doesn't have return codes, and only returns a single i64 value
             // Soroban doesn't have return codes, and only returns a single i64 value
-            if ns.target != Target::Soroban {
+            if bin.ns.target != Target::Soroban {
                 let success = bin
                 let success = bin
                     .builder
                     .builder
                     .build_int_compare(
                     .build_int_compare(
@@ -522,7 +516,7 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
 
 
                 if !res.is_empty() {
                 if !res.is_empty() {
                     for (i, v) in f.returns.iter().enumerate() {
                     for (i, v) in f.returns.iter().enumerate() {
-                        let load_ty = bin.llvm_var_ty(&v.ty, ns);
+                        let load_ty = bin.llvm_var_ty(&v.ty);
                         let val = bin
                         let val = bin
                             .builder
                             .builder
                             .build_load(
                             .build_load(
@@ -534,7 +528,7 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
                         let dest = w.vars[&res[i]].value;
                         let dest = w.vars[&res[i]].value;
 
 
                         if dest.is_pointer_value()
                         if dest.is_pointer_value()
-                            && !(v.ty.is_reference_type(ns)
+                            && !(v.ty.is_reference_type(bin.ns)
                                 || matches!(v.ty, Type::ExternalFunction { .. }))
                                 || matches!(v.ty, Type::ExternalFunction { .. }))
                         {
                         {
                             bin.builder
                             bin.builder
@@ -557,19 +551,19 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
         } => {
         } => {
             let mut parms = args
             let mut parms = args
                 .iter()
                 .iter()
-                .map(|p| expression(target, bin, p, &w.vars, function, ns).into())
+                .map(|p| expression(target, bin, p, &w.vars, function).into())
                 .collect::<Vec<BasicMetadataValueEnum>>();
                 .collect::<Vec<BasicMetadataValueEnum>>();
 
 
-            let callee = &ns.functions[*ast_func_no];
+            let callee = &bin.ns.functions[*ast_func_no];
 
 
             if !res.is_empty() {
             if !res.is_empty() {
                 for v in callee.returns.iter() {
                 for v in callee.returns.iter() {
-                    parms.push(if ns.target == Target::Solana {
-                        bin.build_alloca(function, bin.llvm_var_ty(&v.ty, ns), v.name_as_str())
+                    parms.push(if bin.ns.target == Target::Solana {
+                        bin.build_alloca(function, bin.llvm_var_ty(&v.ty), v.name_as_str())
                             .into()
                             .into()
                     } else {
                     } else {
                         bin.builder
                         bin.builder
-                            .build_alloca(bin.llvm_var_ty(&v.ty, ns), v.name_as_str())
+                            .build_alloca(bin.llvm_var_ty(&v.ty), v.name_as_str())
                             .unwrap()
                             .unwrap()
                             .into()
                             .into()
                     });
                     });
@@ -581,8 +575,7 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
                 function,
                 function,
                 callee,
                 callee,
                 &parms,
                 &parms,
-                args.first().map(|arg| bin.llvm_type(&arg.ty(), ns)),
-                ns,
+                args.first().map(|arg| bin.llvm_type(&arg.ty())),
             ) {
             ) {
                 let success = bin
                 let success = bin
                     .builder
                     .builder
@@ -607,12 +600,12 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
 
 
             if !res.is_empty() {
             if !res.is_empty() {
                 for (i, v) in callee.returns.iter().enumerate() {
                 for (i, v) in callee.returns.iter().enumerate() {
-                    let load_ty = if v.ty.is_reference_type(ns) {
-                        bin.llvm_type(&v.ty, ns)
+                    let load_ty = if v.ty.is_reference_type(bin.ns) {
+                        bin.llvm_type(&v.ty)
                             .ptr_type(AddressSpace::default())
                             .ptr_type(AddressSpace::default())
                             .as_basic_type_enum()
                             .as_basic_type_enum()
                     } else {
                     } else {
-                        bin.llvm_type(&v.ty, ns)
+                        bin.llvm_type(&v.ty)
                     };
                     };
                     let val = bin
                     let val = bin
                         .builder
                         .builder
@@ -626,7 +619,7 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
                     let dest = w.vars[&res[i]].value;
                     let dest = w.vars[&res[i]].value;
 
 
                     if dest.is_pointer_value()
                     if dest.is_pointer_value()
-                        && !(v.ty.is_reference_type(ns)
+                        && !(v.ty.is_reference_type(bin.ns)
                             || matches!(v.ty, Type::ExternalFunction { .. }))
                             || matches!(v.ty, Type::ExternalFunction { .. }))
                     {
                     {
                         bin.builder
                         bin.builder
@@ -650,22 +643,19 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
                 params, returns, ..
                 params, returns, ..
             } = ty.deref_any()
             } = ty.deref_any()
             {
             {
-                (bin.function_type(params, returns, ns), returns)
+                (bin.function_type(params, returns), returns)
             } else {
             } else {
                 panic!("should be Type::InternalFunction type");
                 panic!("should be Type::InternalFunction type");
             };
             };
 
 
             let mut parms = args
             let mut parms = args
                 .iter()
                 .iter()
-                .map(|p| expression(target, bin, p, &w.vars, function, ns).into())
+                .map(|p| expression(target, bin, p, &w.vars, function).into())
                 .collect::<Vec<BasicMetadataValueEnum>>();
                 .collect::<Vec<BasicMetadataValueEnum>>();
 
 
             if !res.is_empty() {
             if !res.is_empty() {
                 for ty in returns.iter() {
                 for ty in returns.iter() {
-                    parms.push(
-                        bin.build_alloca(function, bin.llvm_var_ty(ty, ns), "")
-                            .into(),
-                    );
+                    parms.push(bin.build_alloca(function, bin.llvm_var_ty(ty), "").into());
                 }
                 }
             }
             }
 
 
@@ -675,7 +665,7 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
             }
             }
 
 
             let callable =
             let callable =
-                expression(target, bin, call_expr, &w.vars, function, ns).into_pointer_value();
+                expression(target, bin, call_expr, &w.vars, function).into_pointer_value();
 
 
             let ptr_ok = bin.context.append_basic_block(function, "fn_ptr_ok");
             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 ptr_nil_block = bin.context.append_basic_block(function, "fn_ptr_nil");
@@ -693,14 +683,9 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
                 .unwrap();
                 .unwrap();
 
 
             bin.builder.position_at_end(ptr_nil_block);
             bin.builder.position_at_end(ptr_nil_block);
-            bin.log_runtime_error(
-                target,
-                "internal function uninitialized".to_string(),
-                None,
-                ns,
-            );
+            bin.log_runtime_error(target, "internal function uninitialized".to_string(), None);
             let (revert_out, revert_out_len) =
             let (revert_out, revert_out_len) =
-                bin.panic_data_const(ns, PanicCode::InternalFunctionUninitialized);
+                bin.panic_data_const(PanicCode::InternalFunctionUninitialized);
             target.assert_failure(bin, revert_out, revert_out_len);
             target.assert_failure(bin, revert_out, revert_out_len);
 
 
             bin.builder.position_at_end(ptr_ok);
             bin.builder.position_at_end(ptr_ok);
@@ -735,7 +720,7 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
 
 
             if !res.is_empty() {
             if !res.is_empty() {
                 for (i, ty) in returns.iter().enumerate() {
                 for (i, ty) in returns.iter().enumerate() {
-                    let load_ty = bin.llvm_var_ty(ty, ns);
+                    let load_ty = bin.llvm_var_ty(ty);
                     let val = bin
                     let val = bin
                         .builder
                         .builder
                         .build_load(load_ty, parms[args.len() + i].into_pointer_value(), "")
                         .build_load(load_ty, parms[args.len() + i].into_pointer_value(), "")
@@ -743,7 +728,7 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
 
 
                     let dest = w.vars[&res[i]].value;
                     let dest = w.vars[&res[i]].value;
 
 
-                    if dest.is_pointer_value() && !ty.is_reference_type(ns) {
+                    if dest.is_pointer_value() && !ty.is_reference_type(bin.ns) {
                         bin.builder
                         bin.builder
                             .build_store(dest.into_pointer_value(), val)
                             .build_store(dest.into_pointer_value(), val)
                             .unwrap();
                             .unwrap();
@@ -761,7 +746,7 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
         } => {
         } => {
             let parms = args
             let parms = args
                 .iter()
                 .iter()
-                .map(|p| expression(target, bin, p, &w.vars, function, ns).into())
+                .map(|p| expression(target, bin, p, &w.vars, function).into())
                 .collect::<Vec<BasicMetadataValueEnum>>();
                 .collect::<Vec<BasicMetadataValueEnum>>();
 
 
             let call = bin.module.get_function(name).unwrap();
             let call = bin.module.get_function(name).unwrap();
@@ -791,34 +776,33 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
             accounts,
             accounts,
             constructor_no: _,
             constructor_no: _,
         } => {
         } => {
-            let encoded_args = expression(target, bin, encoded_args, &w.vars, function, ns);
+            let encoded_args = expression(target, bin, encoded_args, &w.vars, function);
             let encoded_args_len = bin.vector_len(encoded_args).as_basic_value_enum();
             let encoded_args_len = bin.vector_len(encoded_args).as_basic_value_enum();
 
 
-            let address_stack = bin.build_alloca(function, bin.address_type(ns), "address");
+            let address_stack = bin.build_alloca(function, bin.address_type(), "address");
 
 
-            let gas = expression(target, bin, gas, &w.vars, function, ns).into_int_value();
+            let gas = expression(target, bin, gas, &w.vars, function).into_int_value();
             let value = value
             let value = value
                 .as_ref()
                 .as_ref()
-                .map(|v| expression(target, bin, v, &w.vars, function, ns).into_int_value());
+                .map(|v| expression(target, bin, v, &w.vars, function).into_int_value());
             let salt = salt
             let salt = salt
                 .as_ref()
                 .as_ref()
-                .map(|v| expression(target, bin, v, &w.vars, function, ns).into_int_value());
+                .map(|v| expression(target, bin, v, &w.vars, function).into_int_value());
 
 
-            let llvm_accounts = process_account_metas(target, accounts, bin, &w.vars, function, ns);
+            let llvm_accounts = process_account_metas(target, accounts, bin, &w.vars, function);
 
 
             if let Some(address) = address {
             if let Some(address) = address {
                 let address =
                 let address =
-                    expression(target, bin, address, &w.vars, function, ns).into_array_value();
+                    expression(target, bin, address, &w.vars, function).into_array_value();
 
 
                 bin.builder.build_store(address_stack, address).unwrap();
                 bin.builder.build_store(address_stack, address).unwrap();
             }
             }
 
 
             let seeds = if let Some(seeds) = seeds {
             let seeds = if let Some(seeds) = seeds {
                 let len = seeds.ty().array_length().unwrap().to_u64().unwrap();
                 let len = seeds.ty().array_length().unwrap().to_u64().unwrap();
-                let seeds_ty = bin.llvm_type(
-                    &Type::Slice(Box::new(Type::Slice(Box::new(Type::Bytes(1))))),
-                    ns,
-                );
+                let seeds_ty = bin.llvm_type(&Type::Slice(Box::new(Type::Slice(Box::new(
+                    Type::Bytes(1),
+                )))));
 
 
                 let output_seeds = bin.build_array_alloca(
                 let output_seeds = bin.build_array_alloca(
                     function,
                     function,
@@ -829,8 +813,7 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
 
 
                 if let Expression::ArrayLiteral { values, .. } = seeds {
                 if let Expression::ArrayLiteral { values, .. } = seeds {
                     for i in 0..len {
                     for i in 0..len {
-                        let val =
-                            expression(target, bin, &values[i as usize], &w.vars, function, ns);
+                        let val = expression(target, bin, &values[i as usize], &w.vars, function);
 
 
                         let seed_count = values[i as usize]
                         let seed_count = values[i as usize]
                             .ty()
                             .ty()
@@ -898,13 +881,12 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
                     seeds,
                     seeds,
                     flags: None,
                     flags: None,
                 },
                 },
-                ns,
                 *loc,
                 *loc,
             );
             );
 
 
             w.vars.get_mut(res).unwrap().value = bin
             w.vars.get_mut(res).unwrap().value = bin
                 .builder
                 .builder
-                .build_load(bin.address_type(ns), address_stack, "address")
+                .build_load(bin.address_type(), address_stack, "address")
                 .unwrap();
                 .unwrap();
         }
         }
         Instr::ExternalCall {
         Instr::ExternalCall {
@@ -920,14 +902,14 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
             ..
             ..
         } => {
         } => {
             let loc = payload.loc();
             let loc = payload.loc();
-            let gas = expression(target, bin, gas, &w.vars, function, ns).into_int_value();
-            let value = expression(target, bin, value, &w.vars, function, ns).into_int_value();
+            let gas = expression(target, bin, gas, &w.vars, function).into_int_value();
+            let value = expression(target, bin, value, &w.vars, function).into_int_value();
             let payload_ty = payload.ty();
             let payload_ty = payload.ty();
-            let payload = expression(target, bin, payload, &w.vars, function, ns);
+            let payload = expression(target, bin, payload, &w.vars, function);
 
 
             let address = if let Some(address) = address {
             let address = if let Some(address) = address {
-                let address = expression(target, bin, address, &w.vars, function, ns);
-                if ns.target == Target::Soroban {
+                let address = expression(target, bin, address, &w.vars, function);
+                if bin.ns.target == Target::Soroban {
                     Some(address)
                     Some(address)
                 } else {
                 } else {
                     let addr = bin.build_array_alloca(
                     let addr = bin.build_array_alloca(
@@ -935,7 +917,7 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
                         bin.context.i8_type(),
                         bin.context.i8_type(),
                         bin.context
                         bin.context
                             .i32_type()
                             .i32_type()
-                            .const_int(ns.address_length as u64, false),
+                            .const_int(bin.ns.address_length as u64, false),
                         "address",
                         "address",
                     );
                     );
 
 
@@ -947,13 +929,13 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
                 None
                 None
             };
             };
 
 
-            let accounts = process_account_metas(target, accounts, bin, &w.vars, function, ns);
+            let accounts = process_account_metas(target, accounts, bin, &w.vars, function);
 
 
             let (payload_ptr, payload_len) = if payload_ty == Type::DynamicBytes {
             let (payload_ptr, payload_len) = if payload_ty == Type::DynamicBytes {
                 (bin.vector_bytes(payload), bin.vector_len(payload))
                 (bin.vector_bytes(payload), bin.vector_len(payload))
             } else {
             } else {
                 let ptr = payload.into_pointer_value();
                 let ptr = payload.into_pointer_value();
-                let len = bin.llvm_type(&payload_ty, ns).size_of().unwrap();
+                let len = bin.llvm_type(&payload_ty).size_of().unwrap();
 
 
                 (ptr, len)
                 (ptr, len)
             };
             };
@@ -965,13 +947,13 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
             let seeds_ty =
             let seeds_ty =
                 Type::Slice(Type::Slice(Type::Slice(Type::Bytes(1).into()).into()).into());
                 Type::Slice(Type::Slice(Type::Slice(Type::Bytes(1).into()).into()).into());
 
 
-            let seeds = seeds.as_ref().map(|seeds| {
-                expression_to_slice(target, bin, seeds, &seeds_ty, &w.vars, function, ns)
-            });
+            let seeds = seeds
+                .as_ref()
+                .map(|seeds| expression_to_slice(target, bin, seeds, &seeds_ty, &w.vars, function));
 
 
             let flags = flags
             let flags = flags
                 .as_ref()
                 .as_ref()
-                .map(|e| expression(target, bin, e, &w.vars, function, ns).into_int_value());
+                .map(|e| expression(target, bin, e, &w.vars, function).into_int_value());
             let success = match success {
             let success = match success {
                 Some(n) => Some(&mut w.vars.get_mut(n).unwrap().value),
                 Some(n) => Some(&mut w.vars.get_mut(n).unwrap().value),
                 None => None,
                 None => None,
@@ -994,7 +976,6 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
                     flags,
                     flags,
                 },
                 },
                 callty.clone(),
                 callty.clone(),
-                ns,
                 loc,
                 loc,
             );
             );
         }
         }
@@ -1004,11 +985,10 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
             value,
             value,
         } => {
         } => {
             let loc = value.loc();
             let loc = value.loc();
-            let value = expression(target, bin, value, &w.vars, function, ns).into_int_value();
-            let address =
-                expression(target, bin, address, &w.vars, function, ns).into_array_value();
+            let value = expression(target, bin, value, &w.vars, function).into_int_value();
+            let address = expression(target, bin, address, &w.vars, function).into_array_value();
 
 
-            let addr = bin.build_alloca(function, bin.address_type(ns), "address");
+            let addr = bin.build_alloca(function, bin.address_type(), "address");
 
 
             bin.builder.build_store(addr, address).unwrap();
             bin.builder.build_store(addr, address).unwrap();
             let success = match success {
             let success = match success {
@@ -1016,30 +996,30 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
                 None => None,
                 None => None,
             };
             };
 
 
-            target.value_transfer(bin, function, success, addr, value, ns, loc);
+            target.value_transfer(bin, function, success, addr, value, loc);
         }
         }
         Instr::SelfDestruct { recipient } => {
         Instr::SelfDestruct { recipient } => {
             let recipient =
             let recipient =
-                expression(target, bin, recipient, &w.vars, function, ns).into_array_value();
+                expression(target, bin, recipient, &w.vars, function).into_array_value();
 
 
-            target.selfdestruct(bin, recipient, ns);
+            target.selfdestruct(bin, recipient);
         }
         }
         Instr::EmitEvent { data, topics, .. } => {
         Instr::EmitEvent { data, topics, .. } => {
-            let data = expression(target, bin, data, &w.vars, function, ns);
+            let data = expression(target, bin, data, &w.vars, function);
             let topics = topics
             let topics = topics
                 .iter()
                 .iter()
-                .map(|a| expression(target, bin, a, &w.vars, function, ns))
+                .map(|a| expression(target, bin, a, &w.vars, function))
                 .collect::<Vec<BasicValueEnum>>();
                 .collect::<Vec<BasicValueEnum>>();
             target.emit_event(bin, function, data, &topics);
             target.emit_event(bin, function, data, &topics);
         }
         }
         Instr::WriteBuffer { buf, offset, value } => {
         Instr::WriteBuffer { buf, offset, value } => {
-            let v = expression(target, bin, buf, &w.vars, function, ns);
+            let v = expression(target, bin, buf, &w.vars, function);
             let data = bin.vector_bytes(v);
             let data = bin.vector_bytes(v);
 
 
-            let offset = expression(target, bin, offset, &w.vars, function, ns).into_int_value();
-            let emit_value = expression(target, bin, value, &w.vars, function, ns);
+            let offset = expression(target, bin, offset, &w.vars, function).into_int_value();
+            let emit_value = expression(target, bin, value, &w.vars, function);
 
 
-            if ns.target == Target::Soroban {
+            if bin.ns.target == Target::Soroban {
                 let new_offset = bin
                 let new_offset = bin
                     .builder
                     .builder
                     .build_int_unsigned_div(
                     .build_int_unsigned_div(
@@ -1067,10 +1047,10 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
                         .unwrap()
                         .unwrap()
                 };
                 };
 
 
-                let is_bytes = if let Type::Bytes(n) = value.ty().unwrap_user_type(ns) {
+                let is_bytes = if let Type::Bytes(n) = value.ty().unwrap_user_type(bin.ns) {
                     n
                     n
                 } else if value.ty() == Type::FunctionSelector {
                 } else if value.ty() == Type::FunctionSelector {
-                    ns.target.selector_length()
+                    bin.ns.target.selector_length()
                 } else {
                 } else {
                     0
                     0
                 };
                 };
@@ -1109,18 +1089,18 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
             bytes,
             bytes,
         } => {
         } => {
             let src = if from.ty().is_dynamic_memory() {
             let src = if from.ty().is_dynamic_memory() {
-                bin.vector_bytes(expression(target, bin, from, &w.vars, function, ns))
+                bin.vector_bytes(expression(target, bin, from, &w.vars, function))
             } else {
             } else {
-                expression(target, bin, from, &w.vars, function, ns).into_pointer_value()
+                expression(target, bin, from, &w.vars, function).into_pointer_value()
             };
             };
 
 
             let dest = if to.ty().is_dynamic_memory() {
             let dest = if to.ty().is_dynamic_memory() {
-                bin.vector_bytes(expression(target, bin, to, &w.vars, function, ns))
+                bin.vector_bytes(expression(target, bin, to, &w.vars, function))
             } else {
             } else {
-                expression(target, bin, to, &w.vars, function, ns).into_pointer_value()
+                expression(target, bin, to, &w.vars, function).into_pointer_value()
             };
             };
 
 
-            let size = expression(target, bin, bytes, &w.vars, function, ns);
+            let size = expression(target, bin, bytes, &w.vars, function);
 
 
             bin.builder
             bin.builder
                 .build_call(
                 .build_call(
@@ -1136,20 +1116,19 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
             default,
             default,
         } => {
         } => {
             let pos = bin.builder.get_insert_block().unwrap();
             let pos = bin.builder.get_insert_block().unwrap();
-            let cond = expression(target, bin, cond, &w.vars, function, ns);
+            let cond = expression(target, bin, cond, &w.vars, function);
             let cases = cases
             let cases = cases
                 .iter()
                 .iter()
                 .map(|(exp, block_no)| {
                 .map(|(exp, block_no)| {
-                    let exp = expression(target, bin, exp, &w.vars, function, ns);
-                    let bb = add_or_retrieve_block(
-                        *block_no, pos, bin, function, blocks, work, w, cfg, ns,
-                    );
+                    let exp = expression(target, bin, exp, &w.vars, function);
+                    let bb =
+                        add_or_retrieve_block(*block_no, pos, bin, function, blocks, work, w, cfg);
                     (exp.into_int_value(), bb)
                     (exp.into_int_value(), bb)
                 })
                 })
                 .collect::<Vec<(IntValue, inkwell::basic_block::BasicBlock)>>();
                 .collect::<Vec<(IntValue, inkwell::basic_block::BasicBlock)>>();
 
 
             let default_bb =
             let default_bb =
-                add_or_retrieve_block(*default, pos, bin, function, blocks, work, w, cfg, ns);
+                add_or_retrieve_block(*default, pos, bin, function, blocks, work, w, cfg);
             bin.builder.position_at_end(pos);
             bin.builder.position_at_end(pos);
             bin.builder
             bin.builder
                 .build_switch(cond.into_int_value(), default_bb, cases.as_ref())
                 .build_switch(cond.into_int_value(), default_bb, cases.as_ref())
@@ -1157,13 +1136,13 @@ pub(super) fn process_instruction<'a, T: TargetRuntime<'a> + ?Sized>(
         }
         }
 
 
         Instr::ReturnData { data, data_len } => {
         Instr::ReturnData { data, data_len } => {
-            let data = if data.ty().is_reference_type(ns) {
-                bin.vector_bytes(expression(target, bin, data, &w.vars, function, ns))
+            let data = if data.ty().is_reference_type(bin.ns) {
+                bin.vector_bytes(expression(target, bin, data, &w.vars, function))
             } else {
             } else {
-                expression(target, bin, data, &w.vars, function, ns).into_pointer_value()
+                expression(target, bin, data, &w.vars, function).into_pointer_value()
             };
             };
 
 
-            let data_len = expression(target, bin, data_len, &w.vars, function, ns);
+            let data_len = expression(target, bin, data_len, &w.vars, function);
             target.return_abi_data(bin, data, data_len);
             target.return_abi_data(bin, data, data_len);
         }
         }
 
 
@@ -1188,10 +1167,9 @@ fn add_or_retrieve_block<'a>(
     work: &mut VecDeque<Work<'a>>,
     work: &mut VecDeque<Work<'a>>,
     w: &mut Work<'a>,
     w: &mut Work<'a>,
     cfg: &ControlFlowGraph,
     cfg: &ControlFlowGraph,
-    ns: &Namespace,
 ) -> inkwell::basic_block::BasicBlock<'a> {
 ) -> inkwell::basic_block::BasicBlock<'a> {
     if let std::collections::hash_map::Entry::Vacant(e) = blocks.entry(block_no) {
     if let std::collections::hash_map::Entry::Vacant(e) = blocks.entry(block_no) {
-        e.insert(create_block(block_no, bin, cfg, function, ns));
+        e.insert(create_block(block_no, bin, cfg, function));
         work.push_back(Work {
         work.push_back(Work {
             block_no,
             block_no,
             vars: w.vars.clone(),
             vars: w.vars.clone(),
@@ -1215,11 +1193,10 @@ fn process_account_metas<'a, T: TargetRuntime<'a> + ?Sized>(
     bin: &Binary<'a>,
     bin: &Binary<'a>,
     vartab: &HashMap<usize, Variable<'a>>,
     vartab: &HashMap<usize, Variable<'a>>,
     function: FunctionValue<'a>,
     function: FunctionValue<'a>,
-    ns: &Namespace,
 ) -> Option<(PointerValue<'a>, IntValue<'a>)> {
 ) -> Option<(PointerValue<'a>, IntValue<'a>)> {
     if let ExternalCallAccounts::Present(accounts) = accounts {
     if let ExternalCallAccounts::Present(accounts) = accounts {
         let ty = accounts.ty();
         let ty = accounts.ty();
-        let expr = expression(target, bin, accounts, vartab, function, ns);
+        let expr = expression(target, bin, accounts, vartab, function);
 
 
         if let Some(n) = ty.array_length() {
         if let Some(n) = ty.array_length() {
             let accounts = expr.into_pointer_value();
             let accounts = expr.into_pointer_value();

+ 7 - 15
src/emit/math.rs

@@ -3,7 +3,6 @@
 use crate::codegen::revert::PanicCode;
 use crate::codegen::revert::PanicCode;
 use crate::emit::binary::Binary;
 use crate::emit::binary::Binary;
 use crate::emit::{BinaryOp, TargetRuntime};
 use crate::emit::{BinaryOp, TargetRuntime};
-use crate::sema::ast::Namespace;
 use inkwell::types::IntType;
 use inkwell::types::IntType;
 use inkwell::values::{FunctionValue, IntValue, PointerValue};
 use inkwell::values::{FunctionValue, IntValue, PointerValue};
 use inkwell::IntPredicate;
 use inkwell::IntPredicate;
@@ -22,7 +21,6 @@ fn signed_ovf_detect<'a, T: TargetRuntime<'a> + ?Sized>(
     right: IntValue<'a>,
     right: IntValue<'a>,
     bits: u32,
     bits: u32,
     function: FunctionValue<'a>,
     function: FunctionValue<'a>,
-    ns: &Namespace,
     loc: Loc,
     loc: Loc,
 ) -> IntValue<'a> {
 ) -> IntValue<'a> {
     // We check for signed overflow based on the facts:
     // We check for signed overflow based on the facts:
@@ -238,8 +236,8 @@ fn signed_ovf_detect<'a, T: TargetRuntime<'a> + ?Sized>(
 
 
     bin.builder.position_at_end(error_block);
     bin.builder.position_at_end(error_block);
 
 
-    bin.log_runtime_error(target, "multiplication overflow".to_string(), Some(loc), ns);
-    let (revert_out, revert_out_len) = bin.panic_data_const(ns, PanicCode::MathOverflow);
+    bin.log_runtime_error(target, "multiplication overflow".to_string(), Some(loc));
+    let (revert_out, revert_out_len) = bin.panic_data_const(PanicCode::MathOverflow);
     target.assert_failure(bin, revert_out, revert_out_len);
     target.assert_failure(bin, revert_out, revert_out_len);
 
 
     bin.builder.position_at_end(return_block);
     bin.builder.position_at_end(return_block);
@@ -308,7 +306,6 @@ pub(super) fn multiply<'a, T: TargetRuntime<'a> + ?Sized>(
     left: IntValue<'a>,
     left: IntValue<'a>,
     right: IntValue<'a>,
     right: IntValue<'a>,
     signed: bool,
     signed: bool,
-    ns: &Namespace,
     loc: Loc,
     loc: Loc,
 ) -> IntValue<'a> {
 ) -> IntValue<'a> {
     let bits = left.get_type().get_bit_width();
     let bits = left.get_type().get_bit_width();
@@ -349,7 +346,7 @@ pub(super) fn multiply<'a, T: TargetRuntime<'a> + ?Sized>(
         if !unchecked {
         if !unchecked {
             if signed {
             if signed {
                 return signed_ovf_detect(
                 return signed_ovf_detect(
-                    target, bin, mul_ty, mul_bits, left, right, bits, function, ns, loc,
+                    target, bin, mul_ty, mul_bits, left, right, bits, function, loc,
                 );
                 );
             }
             }
 
 
@@ -435,9 +432,9 @@ pub(super) fn multiply<'a, T: TargetRuntime<'a> + ?Sized>(
 
 
             bin.builder.position_at_end(error_block);
             bin.builder.position_at_end(error_block);
 
 
-            bin.log_runtime_error(target, "multiplication overflow".to_string(), Some(loc), ns);
+            bin.log_runtime_error(target, "multiplication overflow".to_string(), Some(loc));
 
 
-            let (revert_out, revert_out_len) = bin.panic_data_const(ns, PanicCode::MathOverflow);
+            let (revert_out, revert_out_len) = bin.panic_data_const(PanicCode::MathOverflow);
             target.assert_failure(bin, revert_out, revert_out_len);
             target.assert_failure(bin, revert_out, revert_out_len);
 
 
             bin.builder.position_at_end(return_block);
             bin.builder.position_at_end(return_block);
@@ -457,7 +454,6 @@ pub(super) fn multiply<'a, T: TargetRuntime<'a> + ?Sized>(
             right,
             right,
             BinaryOp::Multiply,
             BinaryOp::Multiply,
             signed,
             signed,
-            ns,
             loc,
             loc,
         )
         )
     } else {
     } else {
@@ -472,7 +468,6 @@ pub(super) fn power<'a, T: TargetRuntime<'a> + ?Sized>(
     bits: u32,
     bits: u32,
     signed: bool,
     signed: bool,
     o: PointerValue<'a>,
     o: PointerValue<'a>,
-    ns: &Namespace,
     loc: Loc,
     loc: Loc,
 ) -> FunctionValue<'a> {
 ) -> FunctionValue<'a> {
     /*
     /*
@@ -558,7 +553,6 @@ pub(super) fn power<'a, T: TargetRuntime<'a> + ?Sized>(
         result.as_basic_value().into_int_value(),
         result.as_basic_value().into_int_value(),
         base.as_basic_value().into_int_value(),
         base.as_basic_value().into_int_value(),
         signed,
         signed,
-        ns,
         loc,
         loc,
     );
     );
 
 
@@ -613,7 +607,6 @@ pub(super) fn power<'a, T: TargetRuntime<'a> + ?Sized>(
         base.as_basic_value().into_int_value(),
         base.as_basic_value().into_int_value(),
         base.as_basic_value().into_int_value(),
         base.as_basic_value().into_int_value(),
         signed,
         signed,
-        ns,
         loc,
         loc,
     );
     );
 
 
@@ -639,7 +632,6 @@ pub(super) fn build_binary_op_with_overflow_check<'a, T: TargetRuntime<'a> + ?Si
     right: IntValue<'a>,
     right: IntValue<'a>,
     op: BinaryOp,
     op: BinaryOp,
     signed: bool,
     signed: bool,
-    ns: &Namespace,
     loc: Loc,
     loc: Loc,
 ) -> IntValue<'a> {
 ) -> IntValue<'a> {
     let ret_ty = bin.context.struct_type(
     let ret_ty = bin.context.struct_type(
@@ -675,8 +667,8 @@ pub(super) fn build_binary_op_with_overflow_check<'a, T: TargetRuntime<'a> + ?Si
 
 
     bin.builder.position_at_end(error_block);
     bin.builder.position_at_end(error_block);
 
 
-    bin.log_runtime_error(target, "math overflow".to_string(), Some(loc), ns);
-    let (revert_out, revert_out_len) = bin.panic_data_const(ns, PanicCode::MathOverflow);
+    bin.log_runtime_error(target, "math overflow".to_string(), Some(loc));
+    let (revert_out, revert_out_len) = bin.panic_data_const(PanicCode::MathOverflow);
     target.assert_failure(bin, revert_out, revert_out_len);
     target.assert_failure(bin, revert_out, revert_out_len);
 
 
     bin.builder.position_at_end(success_block);
     bin.builder.position_at_end(success_block);

+ 3 - 20
src/emit/mod.rs

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: Apache-2.0
 // SPDX-License-Identifier: Apache-2.0
 
 
 use crate::codegen::Expression;
 use crate::codegen::Expression;
-use crate::sema::ast::{CallTy, Function, Namespace, Type};
+use crate::sema::ast::{CallTy, Function, Type};
 use std::collections::HashMap;
 use std::collections::HashMap;
 use std::fmt;
 use std::fmt;
 use std::str;
 use std::str;
@@ -84,7 +84,6 @@ pub trait TargetRuntime<'a> {
         ty: &ast::Type,
         ty: &ast::Type,
         slot: &mut IntValue<'a>,
         slot: &mut IntValue<'a>,
         function: FunctionValue<'a>,
         function: FunctionValue<'a>,
-        ns: &ast::Namespace,
         storage_type: &Option<StorageType>,
         storage_type: &Option<StorageType>,
     ) -> BasicValueEnum<'a>;
     ) -> BasicValueEnum<'a>;
 
 
@@ -97,7 +96,6 @@ pub trait TargetRuntime<'a> {
         slot: &mut IntValue<'a>,
         slot: &mut IntValue<'a>,
         dest: BasicValueEnum<'a>,
         dest: BasicValueEnum<'a>,
         function: FunctionValue<'a>,
         function: FunctionValue<'a>,
-        ns: &ast::Namespace,
         storage_type: &Option<StorageType>,
         storage_type: &Option<StorageType>,
     );
     );
 
 
@@ -108,7 +106,6 @@ pub trait TargetRuntime<'a> {
         ty: &Type,
         ty: &Type,
         slot: &mut IntValue<'a>,
         slot: &mut IntValue<'a>,
         function: FunctionValue<'a>,
         function: FunctionValue<'a>,
-        ns: &Namespace,
     );
     );
 
 
     // Bytes and string have special storage layout
     // Bytes and string have special storage layout
@@ -141,7 +138,6 @@ pub trait TargetRuntime<'a> {
         bin: &Binary<'a>,
         bin: &Binary<'a>,
         function: FunctionValue,
         function: FunctionValue,
         slot: PointerValue<'a>,
         slot: PointerValue<'a>,
-        ns: &Namespace,
     ) -> PointerValue<'a>;
     ) -> PointerValue<'a>;
 
 
     fn get_storage_bytes_subscript(
     fn get_storage_bytes_subscript(
@@ -151,7 +147,6 @@ pub trait TargetRuntime<'a> {
         slot: IntValue<'a>,
         slot: IntValue<'a>,
         index: IntValue<'a>,
         index: IntValue<'a>,
         loc: Loc,
         loc: Loc,
-        ns: &Namespace,
     ) -> IntValue<'a>;
     ) -> IntValue<'a>;
 
 
     fn set_storage_bytes_subscript(
     fn set_storage_bytes_subscript(
@@ -161,7 +156,6 @@ pub trait TargetRuntime<'a> {
         slot: IntValue<'a>,
         slot: IntValue<'a>,
         index: IntValue<'a>,
         index: IntValue<'a>,
         value: IntValue<'a>,
         value: IntValue<'a>,
-        ns: &Namespace,
         loc: Loc,
         loc: Loc,
     );
     );
 
 
@@ -172,7 +166,6 @@ pub trait TargetRuntime<'a> {
         ty: &Type,
         ty: &Type,
         slot: IntValue<'a>,
         slot: IntValue<'a>,
         index: BasicValueEnum<'a>,
         index: BasicValueEnum<'a>,
-        ns: &Namespace,
     ) -> IntValue<'a>;
     ) -> IntValue<'a>;
 
 
     fn storage_push(
     fn storage_push(
@@ -182,7 +175,6 @@ pub trait TargetRuntime<'a> {
         ty: &Type,
         ty: &Type,
         slot: IntValue<'a>,
         slot: IntValue<'a>,
         val: Option<BasicValueEnum<'a>>,
         val: Option<BasicValueEnum<'a>>,
-        ns: &Namespace,
     ) -> BasicValueEnum<'a>;
     ) -> BasicValueEnum<'a>;
 
 
     fn storage_pop(
     fn storage_pop(
@@ -192,7 +184,6 @@ pub trait TargetRuntime<'a> {
         ty: &Type,
         ty: &Type,
         slot: IntValue<'a>,
         slot: IntValue<'a>,
         load: bool,
         load: bool,
-        ns: &Namespace,
         loc: Loc,
         loc: Loc,
     ) -> Option<BasicValueEnum<'a>>;
     ) -> Option<BasicValueEnum<'a>>;
 
 
@@ -202,7 +193,6 @@ pub trait TargetRuntime<'a> {
         _function: FunctionValue,
         _function: FunctionValue,
         _slot: IntValue<'a>,
         _slot: IntValue<'a>,
         _elem_ty: &Type,
         _elem_ty: &Type,
-        _ns: &Namespace,
     ) -> IntValue<'a>;
     ) -> IntValue<'a>;
 
 
     /// keccak256 hash
     /// keccak256 hash
@@ -212,7 +202,6 @@ pub trait TargetRuntime<'a> {
         src: PointerValue,
         src: PointerValue,
         length: IntValue,
         length: IntValue,
         dest: PointerValue,
         dest: PointerValue,
-        ns: &Namespace,
     );
     );
 
 
     /// Prints a string
     /// Prints a string
@@ -234,7 +223,6 @@ pub trait TargetRuntime<'a> {
         builtin_func: &Function,
         builtin_func: &Function,
         args: &[BasicMetadataValueEnum<'a>],
         args: &[BasicMetadataValueEnum<'a>],
         first_arg_type: Option<BasicTypeEnum>,
         first_arg_type: Option<BasicTypeEnum>,
-        ns: &Namespace,
     ) -> Option<BasicValueEnum<'a>>;
     ) -> Option<BasicValueEnum<'a>>;
 
 
     /// Calls constructor
     /// Calls constructor
@@ -248,7 +236,6 @@ pub trait TargetRuntime<'a> {
         encoded_args: BasicValueEnum<'b>,
         encoded_args: BasicValueEnum<'b>,
         encoded_args_len: BasicValueEnum<'b>,
         encoded_args_len: BasicValueEnum<'b>,
         contract_args: ContractArgs<'b>,
         contract_args: ContractArgs<'b>,
-        ns: &Namespace,
         loc: Loc,
         loc: Loc,
     );
     );
 
 
@@ -263,7 +250,6 @@ pub trait TargetRuntime<'a> {
         address: Option<BasicValueEnum<'b>>,
         address: Option<BasicValueEnum<'b>>,
         contract_args: ContractArgs<'b>,
         contract_args: ContractArgs<'b>,
         ty: CallTy,
         ty: CallTy,
-        ns: &Namespace,
         loc: Loc,
         loc: Loc,
     );
     );
 
 
@@ -275,7 +261,6 @@ pub trait TargetRuntime<'a> {
         _success: Option<&mut BasicValueEnum<'b>>,
         _success: Option<&mut BasicValueEnum<'b>>,
         _address: PointerValue<'b>,
         _address: PointerValue<'b>,
         _value: IntValue<'b>,
         _value: IntValue<'b>,
-        _ns: &Namespace,
         loc: Loc,
         loc: Loc,
     );
     );
 
 
@@ -286,17 +271,16 @@ pub trait TargetRuntime<'a> {
         expr: &Expression,
         expr: &Expression,
         vartab: &HashMap<usize, Variable<'b>>,
         vartab: &HashMap<usize, Variable<'b>>,
         function: FunctionValue<'b>,
         function: FunctionValue<'b>,
-        ns: &Namespace,
     ) -> BasicValueEnum<'b>;
     ) -> BasicValueEnum<'b>;
 
 
     /// Return the return data from an external call (either revert error or return values)
     /// Return the return data from an external call (either revert error or return values)
     fn return_data<'b>(&self, bin: &Binary<'b>, function: FunctionValue<'b>) -> PointerValue<'b>;
     fn return_data<'b>(&self, bin: &Binary<'b>, function: FunctionValue<'b>) -> PointerValue<'b>;
 
 
     /// Return the value we received
     /// Return the value we received
-    fn value_transferred<'b>(&self, bin: &Binary<'b>, ns: &Namespace) -> IntValue<'b>;
+    fn value_transferred<'b>(&self, binary: &Binary<'b>) -> IntValue<'b>;
 
 
     /// Terminate execution, destroy bin and send remaining funds to addr
     /// Terminate execution, destroy bin and send remaining funds to addr
-    fn selfdestruct<'b>(&self, bin: &Binary<'b>, addr: ArrayValue<'b>, ns: &Namespace);
+    fn selfdestruct<'b>(&self, binary: &Binary<'b>, addr: ArrayValue<'b>);
 
 
     /// Crypto Hash
     /// Crypto Hash
     fn hash<'b>(
     fn hash<'b>(
@@ -306,7 +290,6 @@ pub trait TargetRuntime<'a> {
         hash: HashTy,
         hash: HashTy,
         string: PointerValue<'b>,
         string: PointerValue<'b>,
         length: IntValue<'b>,
         length: IntValue<'b>,
-        ns: &Namespace,
     ) -> IntValue<'b>;
     ) -> IntValue<'b>;
 
 
     /// Emit event
     /// Emit event

+ 7 - 12
src/emit/polkadot/mod.rs

@@ -30,7 +30,7 @@ impl PolkadotTarget {
         let filename = ns.files[contract.loc.file_no()].file_name();
         let filename = ns.files[contract.loc.file_no()].file_name();
         let mut bin = Binary::new(
         let mut bin = Binary::new(
             context,
             context,
-            ns.target,
+            ns,
             &contract.id.name,
             &contract.id.name,
             filename.as_str(),
             filename.as_str(),
             opt,
             opt,
@@ -45,7 +45,7 @@ impl PolkadotTarget {
             .i32_type()
             .i32_type()
             .const_all_ones()
             .const_all_ones()
             .const_to_pointer(ptr);
             .const_to_pointer(ptr);
-        bin.set_early_value_aborts(contract, ns);
+        bin.set_early_value_aborts(contract);
 
 
         let scratch_len = bin.module.add_global(
         let scratch_len = bin.module.add_global(
             context.i32_type(),
             context.i32_type(),
@@ -70,7 +70,7 @@ impl PolkadotTarget {
 
 
         target.declare_externals(&bin);
         target.declare_externals(&bin);
 
 
-        emit_functions(&mut target, &mut bin, contract, ns);
+        emit_functions(&mut target, &mut bin, contract);
 
 
         let function_name = CString::new(STORAGE_INITIALIZER).unwrap();
         let function_name = CString::new(STORAGE_INITIALIZER).unwrap();
         let mut storage_initializers = bin
         let mut storage_initializers = bin
@@ -82,8 +82,8 @@ impl PolkadotTarget {
             .expect("storage initializer is always present");
             .expect("storage initializer is always present");
         assert!(storage_initializers.next().is_none());
         assert!(storage_initializers.next().is_none());
 
 
-        target.emit_dispatch(Some(storage_initializer), &mut bin, ns);
-        target.emit_dispatch(None, &mut bin, ns);
+        target.emit_dispatch(Some(storage_initializer), &mut bin);
+        target.emit_dispatch(None, &mut bin);
 
 
         bin.internalize(&[
         bin.internalize(&[
             "deploy",
             "deploy",
@@ -274,12 +274,7 @@ impl PolkadotTarget {
     }
     }
 
 
     /// Emits the "deploy" function if `storage_initializer` is `Some`, otherwise emits the "call" function.
     /// Emits the "deploy" function if `storage_initializer` is `Some`, otherwise emits the "call" function.
-    fn emit_dispatch(
-        &mut self,
-        storage_initializer: Option<FunctionValue>,
-        bin: &mut Binary,
-        ns: &Namespace,
-    ) {
+    fn emit_dispatch(&mut self, storage_initializer: Option<FunctionValue>, bin: &mut Binary) {
         let ty = bin.context.void_type().fn_type(&[], false);
         let ty = bin.context.void_type().fn_type(&[], false);
         let export_name = if storage_initializer.is_some() {
         let export_name = if storage_initializer.is_some() {
             "deploy"
             "deploy"
@@ -291,7 +286,7 @@ impl PolkadotTarget {
         let args = vec![
         let args = vec![
             BasicMetadataValueEnum::PointerValue(input),
             BasicMetadataValueEnum::PointerValue(input),
             BasicMetadataValueEnum::IntValue(input_length),
             BasicMetadataValueEnum::IntValue(input_length),
-            BasicMetadataValueEnum::IntValue(self.value_transferred(bin, ns)),
+            BasicMetadataValueEnum::IntValue(self.value_transferred(bin)),
             BasicMetadataValueEnum::PointerValue(bin.selector.as_pointer_value()),
             BasicMetadataValueEnum::PointerValue(bin.selector.as_pointer_value()),
         ];
         ];
         let dispatch_cfg_name = &storage_initializer
         let dispatch_cfg_name = &storage_initializer

+ 76 - 103
src/emit/polkadot/storage.rs

@@ -5,7 +5,7 @@ use crate::emit::polkadot::PolkadotTarget;
 use crate::emit::storage::StorageSlot;
 use crate::emit::storage::StorageSlot;
 use crate::emit::TargetRuntime;
 use crate::emit::TargetRuntime;
 use crate::emit_context;
 use crate::emit_context;
-use crate::sema::ast::{ArrayLength, Namespace, Type};
+use crate::sema::ast::{ArrayLength, Type};
 use inkwell::types::{BasicType, BasicTypeEnum};
 use inkwell::types::{BasicType, BasicTypeEnum};
 use inkwell::values::{ArrayValue, BasicValueEnum, FunctionValue, IntValue, PointerValue};
 use inkwell::values::{ArrayValue, BasicValueEnum, FunctionValue, IntValue, PointerValue};
 use inkwell::{AddressSpace, IntPredicate};
 use inkwell::{AddressSpace, IntPredicate};
@@ -43,18 +43,13 @@ impl StorageSlot for PolkadotTarget {
         );
         );
     }
     }
 
 
-    fn get_storage_address<'a>(
-        &self,
-        bin: &Binary<'a>,
-        slot: PointerValue<'a>,
-        ns: &Namespace,
-    ) -> ArrayValue<'a> {
+    fn get_storage_address<'a>(&self, bin: &Binary<'a>, slot: PointerValue<'a>) -> ArrayValue<'a> {
         emit_context!(bin);
         emit_context!(bin);
 
 
         let (scratch_buf, scratch_len) = scratch_buf!();
         let (scratch_buf, scratch_len) = scratch_buf!();
 
 
         bin.builder
         bin.builder
-            .build_store(scratch_len, i32_const!(ns.address_length as u64))
+            .build_store(scratch_len, i32_const!(bin.ns.address_length as u64))
             .unwrap();
             .unwrap();
 
 
         let exists = seal_get_storage!(
         let exists = seal_get_storage!(
@@ -73,10 +68,10 @@ impl StorageSlot for PolkadotTarget {
             .build_select(
             .build_select(
                 exists_is_zero,
                 exists_is_zero,
                 bin.builder
                 bin.builder
-                    .build_load(bin.address_type(ns), scratch_buf, "address")
+                    .build_load(bin.address_type(), scratch_buf, "address")
                     .unwrap()
                     .unwrap()
                     .into_array_value(),
                     .into_array_value(),
-                bin.address_type(ns).const_zero(),
+                bin.address_type().const_zero(),
                 "retrieved_address",
                 "retrieved_address",
             )
             )
             .unwrap()
             .unwrap()
@@ -100,15 +95,14 @@ impl StorageSlot for PolkadotTarget {
         slot: &mut IntValue<'a>,
         slot: &mut IntValue<'a>,
         slot_ptr: PointerValue<'a>,
         slot_ptr: PointerValue<'a>,
         function: FunctionValue,
         function: FunctionValue,
-        ns: &Namespace,
     ) -> BasicValueEnum<'a> {
     ) -> BasicValueEnum<'a> {
         emit_context!(bin);
         emit_context!(bin);
 
 
         match ty {
         match ty {
-            Type::Ref(ty) => self.storage_load_slot(bin, ty, slot, slot_ptr, function, ns),
+            Type::Ref(ty) => self.storage_load_slot(bin, ty, slot, slot_ptr, function),
             Type::Array(elem_ty, dim) => {
             Type::Array(elem_ty, dim) => {
                 if let Some(ArrayLength::Fixed(d)) = dim.last() {
                 if let Some(ArrayLength::Fixed(d)) = dim.last() {
-                    let llvm_ty = bin.llvm_type(ty.deref_any(), ns);
+                    let llvm_ty = bin.llvm_type(ty.deref_any());
                     // LLVMSizeOf() produces an i64
                     // LLVMSizeOf() produces an i64
                     let size = bin
                     let size = bin
                         .builder
                         .builder
@@ -138,11 +132,10 @@ impl StorageSlot for PolkadotTarget {
                                     .unwrap()
                                     .unwrap()
                             };
                             };
 
 
-                            let val =
-                                self.storage_load_slot(bin, &ty, slot, slot_ptr, function, ns);
+                            let val = self.storage_load_slot(bin, &ty, slot, slot_ptr, function);
 
 
-                            let val = if ty.deref_memory().is_fixed_reference_type(ns) {
-                                let load_ty = bin.llvm_type(ty.deref_any(), ns);
+                            let val = if ty.deref_memory().is_fixed_reference_type(bin.ns) {
+                                let load_ty = bin.llvm_type(ty.deref_any());
                                 bin.builder
                                 bin.builder
                                     .build_load(load_ty, val.into_pointer_value(), "elem")
                                     .build_load(load_ty, val.into_pointer_value(), "elem")
                                     .unwrap()
                                     .unwrap()
@@ -162,14 +155,14 @@ impl StorageSlot for PolkadotTarget {
                     let size = bin
                     let size = bin
                         .builder
                         .builder
                         .build_int_truncate(
                         .build_int_truncate(
-                            self.storage_load_slot(bin, &slot_ty, slot, slot_ptr, function, ns)
+                            self.storage_load_slot(bin, &slot_ty, slot, slot_ptr, function)
                                 .into_int_value(),
                                 .into_int_value(),
                             bin.context.i32_type(),
                             bin.context.i32_type(),
                             "size",
                             "size",
                         )
                         )
                         .unwrap();
                         .unwrap();
 
 
-                    let llvm_elem_ty = bin.llvm_field_ty(elem_ty, ns);
+                    let llvm_elem_ty = bin.llvm_field_ty(elem_ty);
 
 
                     let elem_size = bin
                     let elem_size = bin
                         .builder
                         .builder
@@ -203,7 +196,6 @@ impl StorageSlot for PolkadotTarget {
                             .size_of()
                             .size_of()
                             .const_cast(bin.context.i32_type(), false),
                             .const_cast(bin.context.i32_type(), false),
                         slot_ptr,
                         slot_ptr,
-                        ns,
                     );
                     );
 
 
                     let mut elem_slot = bin
                     let mut elem_slot = bin
@@ -218,15 +210,15 @@ impl StorageSlot for PolkadotTarget {
                         size,
                         size,
                         &mut elem_slot,
                         &mut elem_slot,
                         |elem_no: IntValue<'a>, slot: &mut IntValue<'a>| {
                         |elem_no: IntValue<'a>, slot: &mut IntValue<'a>| {
-                            let elem = bin.array_subscript(ty, dest, elem_no, ns);
+                            let elem = bin.array_subscript(ty, dest, elem_no);
 
 
                             let entry =
                             let entry =
-                                self.storage_load_slot(bin, elem_ty, slot, slot_ptr, function, ns);
+                                self.storage_load_slot(bin, elem_ty, slot, slot_ptr, function);
 
 
-                            let entry = if elem_ty.deref_memory().is_fixed_reference_type(ns) {
+                            let entry = if elem_ty.deref_memory().is_fixed_reference_type(bin.ns) {
                                 bin.builder
                                 bin.builder
                                     .build_load(
                                     .build_load(
-                                        bin.llvm_type(elem_ty.deref_memory(), ns),
+                                        bin.llvm_type(elem_ty.deref_memory()),
                                         entry.into_pointer_value(),
                                         entry.into_pointer_value(),
                                         "elem",
                                         "elem",
                                     )
                                     )
@@ -243,7 +235,7 @@ impl StorageSlot for PolkadotTarget {
                 }
                 }
             }
             }
             Type::Struct(str_ty) => {
             Type::Struct(str_ty) => {
-                let llvm_ty = bin.llvm_type(ty.deref_any(), ns);
+                let llvm_ty = bin.llvm_type(ty.deref_any());
                 // LLVMSizeOf() produces an i64
                 // LLVMSizeOf() produces an i64
                 let size = bin
                 let size = bin
                     .builder
                     .builder
@@ -260,8 +252,8 @@ impl StorageSlot for PolkadotTarget {
                     .unwrap()
                     .unwrap()
                     .into_pointer_value();
                     .into_pointer_value();
 
 
-                for (i, field) in str_ty.definition(ns).fields.iter().enumerate() {
-                    let val = self.storage_load_slot(bin, &field.ty, slot, slot_ptr, function, ns);
+                for (i, field) in str_ty.definition(bin.ns).fields.iter().enumerate() {
+                    let val = self.storage_load_slot(bin, &field.ty, slot, slot_ptr, function);
 
 
                     let elem = unsafe {
                     let elem = unsafe {
                         bin.builder
                         bin.builder
@@ -274,8 +266,8 @@ impl StorageSlot for PolkadotTarget {
                             .unwrap()
                             .unwrap()
                     };
                     };
 
 
-                    let val = if field.ty.deref_memory().is_fixed_reference_type(ns) {
-                        let load_ty = bin.llvm_type(field.ty.deref_memory(), ns);
+                    let val = if field.ty.deref_memory().is_fixed_reference_type(bin.ns) {
+                        let load_ty = bin.llvm_type(field.ty.deref_memory());
                         bin.builder
                         bin.builder
                             .build_load(load_ty, val.into_pointer_value(), field.name_as_str())
                             .build_load(load_ty, val.into_pointer_value(), field.name_as_str())
                             .unwrap()
                             .unwrap()
@@ -295,7 +287,7 @@ impl StorageSlot for PolkadotTarget {
 
 
                 *slot = bin
                 *slot = bin
                     .builder
                     .builder
-                    .build_int_add(*slot, bin.number_literal(256, &BigInt::one(), ns), "string")
+                    .build_int_add(*slot, bin.number_literal(256, &BigInt::one()), "string")
                     .unwrap();
                     .unwrap();
 
 
                 ret.into()
                 ret.into()
@@ -305,14 +297,14 @@ impl StorageSlot for PolkadotTarget {
 
 
                 let ptr_ty = bin
                 let ptr_ty = bin
                     .context
                     .context
-                    .custom_width_int_type(ns.target.ptr_size() as u32);
+                    .custom_width_int_type(bin.ns.target.ptr_size() as u32);
 
 
                 let ret = self.get_storage_int(bin, function, slot_ptr, ptr_ty);
                 let ret = self.get_storage_int(bin, function, slot_ptr, ptr_ty);
 
 
                 bin.builder
                 bin.builder
                     .build_int_to_ptr(
                     .build_int_to_ptr(
                         ret,
                         ret,
-                        bin.llvm_type(ty.deref_any(), ns)
+                        bin.llvm_type(ty.deref_any())
                             .ptr_type(AddressSpace::default()),
                             .ptr_type(AddressSpace::default()),
                         "",
                         "",
                     )
                     )
@@ -322,11 +314,11 @@ impl StorageSlot for PolkadotTarget {
             Type::ExternalFunction { .. } => {
             Type::ExternalFunction { .. } => {
                 bin.builder.build_store(slot_ptr, *slot).unwrap();
                 bin.builder.build_store(slot_ptr, *slot).unwrap();
 
 
-                let ret = self.get_storage_extfunc(bin, function, slot_ptr, ns);
+                let ret = self.get_storage_extfunc(bin, function, slot_ptr);
 
 
                 *slot = bin
                 *slot = bin
                     .builder
                     .builder
-                    .build_int_add(*slot, bin.number_literal(256, &BigInt::one(), ns), "string")
+                    .build_int_add(*slot, bin.number_literal(256, &BigInt::one()), "string")
                     .unwrap();
                     .unwrap();
 
 
                 ret.into()
                 ret.into()
@@ -334,11 +326,11 @@ impl StorageSlot for PolkadotTarget {
             Type::Address(_) | Type::Contract(_) => {
             Type::Address(_) | Type::Contract(_) => {
                 bin.builder.build_store(slot_ptr, *slot).unwrap();
                 bin.builder.build_store(slot_ptr, *slot).unwrap();
 
 
-                let ret = self.get_storage_address(bin, slot_ptr, ns);
+                let ret = self.get_storage_address(bin, slot_ptr);
 
 
                 *slot = bin
                 *slot = bin
                     .builder
                     .builder
-                    .build_int_add(*slot, bin.number_literal(256, &BigInt::one(), ns), "string")
+                    .build_int_add(*slot, bin.number_literal(256, &BigInt::one()), "string")
                     .unwrap();
                     .unwrap();
 
 
                 ret.into()
                 ret.into()
@@ -350,12 +342,12 @@ impl StorageSlot for PolkadotTarget {
                     bin,
                     bin,
                     function,
                     function,
                     slot_ptr,
                     slot_ptr,
-                    bin.llvm_type(ty.deref_any(), ns).into_int_type(),
+                    bin.llvm_type(ty.deref_any()).into_int_type(),
                 );
                 );
 
 
                 *slot = bin
                 *slot = bin
                     .builder
                     .builder
-                    .build_int_add(*slot, bin.number_literal(256, &BigInt::one(), ns), "int")
+                    .build_int_add(*slot, bin.number_literal(256, &BigInt::one()), "int")
                     .unwrap();
                     .unwrap();
 
 
                 ret.into()
                 ret.into()
@@ -371,7 +363,6 @@ impl StorageSlot for PolkadotTarget {
         slot_ptr: PointerValue<'a>,
         slot_ptr: PointerValue<'a>,
         dest: BasicValueEnum<'a>,
         dest: BasicValueEnum<'a>,
         function: FunctionValue<'a>,
         function: FunctionValue<'a>,
-        ns: &Namespace,
     ) {
     ) {
         match ty.deref_any() {
         match ty.deref_any() {
             Type::Array(elem_ty, dim) => {
             Type::Array(elem_ty, dim) => {
@@ -385,7 +376,7 @@ impl StorageSlot for PolkadotTarget {
                             let mut elem = unsafe {
                             let mut elem = unsafe {
                                 bin.builder
                                 bin.builder
                                     .build_gep(
                                     .build_gep(
-                                        bin.llvm_type(ty.deref_any(), ns),
+                                        bin.llvm_type(ty.deref_any()),
                                         dest.into_pointer_value(),
                                         dest.into_pointer_value(),
                                         &[bin.context.i32_type().const_zero(), index],
                                         &[bin.context.i32_type().const_zero(), index],
                                         "index_access",
                                         "index_access",
@@ -393,11 +384,11 @@ impl StorageSlot for PolkadotTarget {
                                     .unwrap()
                                     .unwrap()
                             };
                             };
 
 
-                            if elem_ty.is_reference_type(ns)
-                                && !elem_ty.deref_memory().is_fixed_reference_type(ns)
+                            if elem_ty.is_reference_type(bin.ns)
+                                && !elem_ty.deref_memory().is_fixed_reference_type(bin.ns)
                             {
                             {
                                 let load_ty =
                                 let load_ty =
-                                    bin.llvm_type(elem_ty, ns).ptr_type(AddressSpace::default());
+                                    bin.llvm_type(elem_ty).ptr_type(AddressSpace::default());
                                 elem = bin
                                 elem = bin
                                     .builder
                                     .builder
                                     .build_load(load_ty, elem, "")
                                     .build_load(load_ty, elem, "")
@@ -412,15 +403,14 @@ impl StorageSlot for PolkadotTarget {
                                 slot_ptr,
                                 slot_ptr,
                                 elem.into(),
                                 elem.into(),
                                 function,
                                 function,
-                                ns,
                             );
                             );
 
 
-                            if !elem_ty.is_reference_type(ns) {
+                            if !elem_ty.is_reference_type(bin.ns) {
                                 *slot = bin
                                 *slot = bin
                                     .builder
                                     .builder
                                     .build_int_add(
                                     .build_int_add(
                                         *slot,
                                         *slot,
-                                        bin.number_literal(256, &elem_ty.storage_slots(ns), ns),
+                                        bin.number_literal(256, &elem_ty.storage_slots(bin.ns)),
                                         "",
                                         "",
                                     )
                                     )
                                     .unwrap();
                                     .unwrap();
@@ -434,7 +424,7 @@ impl StorageSlot for PolkadotTarget {
                     let slot_ty = Type::Uint(256);
                     let slot_ty = Type::Uint(256);
 
 
                     // details about our array elements
                     // details about our array elements
-                    let llvm_elem_ty = bin.llvm_field_ty(elem_ty, ns);
+                    let llvm_elem_ty = bin.llvm_field_ty(elem_ty);
                     let elem_size = bin
                     let elem_size = bin
                         .builder
                         .builder
                         .build_int_truncate(
                         .build_int_truncate(
@@ -449,7 +439,7 @@ impl StorageSlot for PolkadotTarget {
                     let previous_size = bin
                     let previous_size = bin
                         .builder
                         .builder
                         .build_int_truncate(
                         .build_int_truncate(
-                            self.storage_load_slot(bin, &slot_ty, slot, slot_ptr, function, ns)
+                            self.storage_load_slot(bin, &slot_ty, slot, slot_ptr, function)
                                 .into_int_value(),
                                 .into_int_value(),
                             bin.context.i32_type(),
                             bin.context.i32_type(),
                             "previous_size",
                             "previous_size",
@@ -458,7 +448,7 @@ impl StorageSlot for PolkadotTarget {
 
 
                     let new_slot = bin
                     let new_slot = bin
                         .builder
                         .builder
-                        .build_alloca(bin.llvm_type(&slot_ty, ns).into_int_type(), "new")
+                        .build_alloca(bin.llvm_type(&slot_ty).into_int_type(), "new")
                         .unwrap();
                         .unwrap();
 
 
                     // set new length
                     // set new length
@@ -468,14 +458,14 @@ impl StorageSlot for PolkadotTarget {
                             bin.builder
                             bin.builder
                                 .build_int_z_extend(
                                 .build_int_z_extend(
                                     len,
                                     len,
-                                    bin.llvm_type(&slot_ty, ns).into_int_type(),
+                                    bin.llvm_type(&slot_ty).into_int_type(),
                                     "",
                                     "",
                                 )
                                 )
                                 .unwrap(),
                                 .unwrap(),
                         )
                         )
                         .unwrap();
                         .unwrap();
 
 
-                    self.set_storage(bin, slot_ptr, new_slot, bin.llvm_type(&slot_ty, ns));
+                    self.set_storage(bin, slot_ptr, new_slot, bin.llvm_type(&slot_ty));
 
 
                     self.keccak256_hash(
                     self.keccak256_hash(
                         bin,
                         bin,
@@ -484,13 +474,12 @@ impl StorageSlot for PolkadotTarget {
                             .size_of()
                             .size_of()
                             .const_cast(bin.context.i32_type(), false),
                             .const_cast(bin.context.i32_type(), false),
                         new_slot,
                         new_slot,
-                        ns,
                     );
                     );
 
 
                     let mut elem_slot = bin
                     let mut elem_slot = bin
                         .builder
                         .builder
                         .build_load(
                         .build_load(
-                            bin.llvm_type(&slot_ty, ns).into_int_type(),
+                            bin.llvm_type(&slot_ty).into_int_type(),
                             new_slot,
                             new_slot,
                             "elem_slot",
                             "elem_slot",
                         )
                         )
@@ -508,7 +497,7 @@ impl StorageSlot for PolkadotTarget {
                             let mut elem = unsafe {
                             let mut elem = unsafe {
                                 bin.builder
                                 bin.builder
                                     .build_gep(
                                     .build_gep(
-                                        bin.llvm_type(ty.deref_any(), ns),
+                                        bin.llvm_type(ty.deref_any()),
                                         dest.into_pointer_value(),
                                         dest.into_pointer_value(),
                                         &[
                                         &[
                                             bin.context.i32_type().const_zero(),
                                             bin.context.i32_type().const_zero(),
@@ -520,8 +509,8 @@ impl StorageSlot for PolkadotTarget {
                                     .unwrap()
                                     .unwrap()
                             };
                             };
 
 
-                            if elem_ty.is_reference_type(ns)
-                                && !elem_ty.deref_memory().is_fixed_reference_type(ns)
+                            if elem_ty.is_reference_type(bin.ns)
+                                && !elem_ty.deref_memory().is_fixed_reference_type(bin.ns)
                             {
                             {
                                 elem = bin
                                 elem = bin
                                     .builder
                                     .builder
@@ -537,15 +526,14 @@ impl StorageSlot for PolkadotTarget {
                                 slot_ptr,
                                 slot_ptr,
                                 elem.into(),
                                 elem.into(),
                                 function,
                                 function,
-                                ns,
                             );
                             );
 
 
-                            if !elem_ty.is_reference_type(ns) {
+                            if !elem_ty.is_reference_type(bin.ns) {
                                 *slot = bin
                                 *slot = bin
                                     .builder
                                     .builder
                                     .build_int_add(
                                     .build_int_add(
                                         *slot,
                                         *slot,
-                                        bin.number_literal(256, &elem_ty.storage_slots(ns), ns),
+                                        bin.number_literal(256, &elem_ty.storage_slots(bin.ns)),
                                         "",
                                         "",
                                     )
                                     )
                                     .unwrap();
                                     .unwrap();
@@ -561,14 +549,14 @@ impl StorageSlot for PolkadotTarget {
                         previous_size,
                         previous_size,
                         &mut elem_slot,
                         &mut elem_slot,
                         |_: IntValue<'a>, slot: &mut IntValue<'a>| {
                         |_: IntValue<'a>, slot: &mut IntValue<'a>| {
-                            self.storage_delete_slot(bin, elem_ty, slot, slot_ptr, function, ns);
+                            self.storage_delete_slot(bin, elem_ty, slot, slot_ptr, function);
 
 
-                            if !elem_ty.is_reference_type(ns) {
+                            if !elem_ty.is_reference_type(bin.ns) {
                                 *slot = bin
                                 *slot = bin
                                     .builder
                                     .builder
                                     .build_int_add(
                                     .build_int_add(
                                         *slot,
                                         *slot,
-                                        bin.number_literal(256, &elem_ty.storage_slots(ns), ns),
+                                        bin.number_literal(256, &elem_ty.storage_slots(bin.ns)),
                                         "",
                                         "",
                                     )
                                     )
                                     .unwrap();
                                     .unwrap();
@@ -578,11 +566,11 @@ impl StorageSlot for PolkadotTarget {
                 }
                 }
             }
             }
             Type::Struct(str_ty) => {
             Type::Struct(str_ty) => {
-                for (i, field) in str_ty.definition(ns).fields.iter().enumerate() {
+                for (i, field) in str_ty.definition(bin.ns).fields.iter().enumerate() {
                     let mut elem = unsafe {
                     let mut elem = unsafe {
                         bin.builder
                         bin.builder
                             .build_gep(
                             .build_gep(
-                                bin.llvm_type(ty.deref_any(), ns),
+                                bin.llvm_type(ty.deref_any()),
                                 dest.into_pointer_value(),
                                 dest.into_pointer_value(),
                                 &[
                                 &[
                                     bin.context.i32_type().const_zero(),
                                     bin.context.i32_type().const_zero(),
@@ -593,10 +581,10 @@ impl StorageSlot for PolkadotTarget {
                             .unwrap()
                             .unwrap()
                     };
                     };
 
 
-                    if field.ty.is_reference_type(ns) && !field.ty.is_fixed_reference_type(ns) {
-                        let load_ty = bin
-                            .llvm_type(&field.ty, ns)
-                            .ptr_type(AddressSpace::default());
+                    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());
                         elem = bin
                         elem = bin
                             .builder
                             .builder
                             .build_load(load_ty, elem, field.name_as_str())
                             .build_load(load_ty, elem, field.name_as_str())
@@ -604,24 +592,16 @@ impl StorageSlot for PolkadotTarget {
                             .into_pointer_value();
                             .into_pointer_value();
                     }
                     }
 
 
-                    self.storage_store_slot(
-                        bin,
-                        &field.ty,
-                        slot,
-                        slot_ptr,
-                        elem.into(),
-                        function,
-                        ns,
-                    );
+                    self.storage_store_slot(bin, &field.ty, slot, slot_ptr, elem.into(), function);
 
 
-                    if !field.ty.is_reference_type(ns)
+                    if !field.ty.is_reference_type(bin.ns)
                         || matches!(field.ty, Type::String | Type::DynamicBytes)
                         || matches!(field.ty, Type::String | Type::DynamicBytes)
                     {
                     {
                         *slot = bin
                         *slot = bin
                             .builder
                             .builder
                             .build_int_add(
                             .build_int_add(
                                 *slot,
                                 *slot,
-                                bin.number_literal(256, &field.ty.storage_slots(ns), ns),
+                                bin.number_literal(256, &field.ty.storage_slots(bin.ns)),
                                 field.name_as_str(),
                                 field.name_as_str(),
                             )
                             )
                             .unwrap();
                             .unwrap();
@@ -641,13 +621,13 @@ impl StorageSlot for PolkadotTarget {
                     function,
                     function,
                     slot_ptr,
                     slot_ptr,
                     dest.into_pointer_value(),
                     dest.into_pointer_value(),
-                    bin.llvm_type(ty, ns),
+                    bin.llvm_type(ty),
                 );
                 );
             }
             }
             Type::InternalFunction { .. } => {
             Type::InternalFunction { .. } => {
                 let ptr_ty = bin
                 let ptr_ty = bin
                     .context
                     .context
-                    .custom_width_int_type(ns.target.ptr_size() as u32);
+                    .custom_width_int_type(bin.ns.target.ptr_size() as u32);
 
 
                 let m = bin.build_alloca(function, ptr_ty, "");
                 let m = bin.build_alloca(function, ptr_ty, "");
 
 
@@ -668,16 +648,11 @@ impl StorageSlot for PolkadotTarget {
                 if dest.is_pointer_value() {
                 if dest.is_pointer_value() {
                     bin.builder.build_store(slot_ptr, *slot).unwrap();
                     bin.builder.build_store(slot_ptr, *slot).unwrap();
 
 
-                    self.set_storage(
-                        bin,
-                        slot_ptr,
-                        dest.into_pointer_value(),
-                        bin.llvm_type(ty, ns),
-                    );
+                    self.set_storage(bin, slot_ptr, dest.into_pointer_value(), bin.llvm_type(ty));
                 } else {
                 } else {
                     let address = bin
                     let address = bin
                         .builder
                         .builder
-                        .build_alloca(bin.address_type(ns), "address")
+                        .build_alloca(bin.address_type(), "address")
                         .unwrap();
                         .unwrap();
 
 
                     bin.builder
                     bin.builder
@@ -690,7 +665,7 @@ impl StorageSlot for PolkadotTarget {
                         bin,
                         bin,
                         slot_ptr,
                         slot_ptr,
                         address,
                         address,
-                        bin.address_type(ns).as_basic_type_enum(),
+                        bin.address_type().as_basic_type_enum(),
                     );
                     );
                 }
                 }
             }
             }
@@ -709,7 +684,7 @@ impl StorageSlot for PolkadotTarget {
                 // TODO ewasm allocates 32 bytes here, even though we have just
                 // TODO ewasm allocates 32 bytes here, even though we have just
                 // allocated test. This can be folded into one allocation, if llvm
                 // allocated test. This can be folded into one allocation, if llvm
                 // does not already fold it into one.
                 // does not already fold it into one.
-                self.set_storage(bin, slot_ptr, dest, bin.llvm_type(ty.deref_any(), ns));
+                self.set_storage(bin, slot_ptr, dest, bin.llvm_type(ty.deref_any()));
             }
             }
         }
         }
     }
     }
@@ -721,7 +696,6 @@ impl StorageSlot for PolkadotTarget {
         slot: &mut IntValue<'a>,
         slot: &mut IntValue<'a>,
         slot_ptr: PointerValue<'a>,
         slot_ptr: PointerValue<'a>,
         function: FunctionValue<'a>,
         function: FunctionValue<'a>,
-        ns: &Namespace,
     ) {
     ) {
         match ty.deref_any() {
         match ty.deref_any() {
             Type::Array(_, dim) => {
             Type::Array(_, dim) => {
@@ -734,14 +708,14 @@ impl StorageSlot for PolkadotTarget {
                         bin.context.i64_type().const_int(d.to_u64().unwrap(), false),
                         bin.context.i64_type().const_int(d.to_u64().unwrap(), false),
                         slot,
                         slot,
                         |_index: IntValue<'a>, slot: &mut IntValue<'a>| {
                         |_index: IntValue<'a>, slot: &mut IntValue<'a>| {
-                            self.storage_delete_slot(bin, &ty, slot, slot_ptr, function, ns);
+                            self.storage_delete_slot(bin, &ty, slot, slot_ptr, function);
 
 
-                            if !ty.is_reference_type(ns) {
+                            if !ty.is_reference_type(bin.ns) {
                                 *slot = bin
                                 *slot = bin
                                     .builder
                                     .builder
                                     .build_int_add(
                                     .build_int_add(
                                         *slot,
                                         *slot,
-                                        bin.number_literal(256, &ty.storage_slots(ns), ns),
+                                        bin.number_literal(256, &ty.storage_slots(bin.ns)),
                                         "",
                                         "",
                                     )
                                     )
                                     .unwrap();
                                     .unwrap();
@@ -768,7 +742,6 @@ impl StorageSlot for PolkadotTarget {
                             .size_of()
                             .size_of()
                             .const_cast(bin.context.i32_type(), false),
                             .const_cast(bin.context.i32_type(), false),
                         buf,
                         buf,
-                        ns,
                     );
                     );
 
 
                     let mut entry_slot = bin
                     let mut entry_slot = bin
@@ -784,14 +757,14 @@ impl StorageSlot for PolkadotTarget {
                         length,
                         length,
                         &mut entry_slot,
                         &mut entry_slot,
                         |_index: IntValue<'a>, slot: &mut IntValue<'a>| {
                         |_index: IntValue<'a>, slot: &mut IntValue<'a>| {
-                            self.storage_delete_slot(bin, &ty, slot, slot_ptr, function, ns);
+                            self.storage_delete_slot(bin, &ty, slot, slot_ptr, function);
 
 
-                            if !ty.is_reference_type(ns) {
+                            if !ty.is_reference_type(bin.ns) {
                                 *slot = bin
                                 *slot = bin
                                     .builder
                                     .builder
                                     .build_int_add(
                                     .build_int_add(
                                         *slot,
                                         *slot,
-                                        bin.number_literal(256, &ty.storage_slots(ns), ns),
+                                        bin.number_literal(256, &ty.storage_slots(bin.ns)),
                                         "",
                                         "",
                                     )
                                     )
                                     .unwrap();
                                     .unwrap();
@@ -800,21 +773,21 @@ impl StorageSlot for PolkadotTarget {
                     );
                     );
 
 
                     // clear length itself
                     // clear length itself
-                    self.storage_delete_slot(bin, &Type::Uint(256), slot, slot_ptr, function, ns);
+                    self.storage_delete_slot(bin, &Type::Uint(256), slot, slot_ptr, function);
                 }
                 }
             }
             }
             Type::Struct(str_ty) => {
             Type::Struct(str_ty) => {
-                for field in &str_ty.definition(ns).fields {
-                    self.storage_delete_slot(bin, &field.ty, slot, slot_ptr, function, ns);
+                for field in &str_ty.definition(bin.ns).fields {
+                    self.storage_delete_slot(bin, &field.ty, slot, slot_ptr, function);
 
 
-                    if !field.ty.is_reference_type(ns)
+                    if !field.ty.is_reference_type(bin.ns)
                         || matches!(field.ty, Type::String | Type::DynamicBytes)
                         || matches!(field.ty, Type::String | Type::DynamicBytes)
                     {
                     {
                         *slot = bin
                         *slot = bin
                             .builder
                             .builder
                             .build_int_add(
                             .build_int_add(
                                 *slot,
                                 *slot,
-                                bin.number_literal(256, &field.ty.storage_slots(ns), ns),
+                                bin.number_literal(256, &field.ty.storage_slots(bin.ns)),
                                 field.name_as_str(),
                                 field.name_as_str(),
                             )
                             )
                             .unwrap();
                             .unwrap();

+ 43 - 71
src/emit/polkadot/target.rs

@@ -9,7 +9,7 @@ use crate::emit::polkadot::PolkadotTarget;
 use crate::emit::storage::StorageSlot;
 use crate::emit::storage::StorageSlot;
 use crate::emit::{ContractArgs, TargetRuntime, Variable};
 use crate::emit::{ContractArgs, TargetRuntime, Variable};
 use crate::sema::ast;
 use crate::sema::ast;
-use crate::sema::ast::{Function, Namespace, Type};
+use crate::sema::ast::{Function, Type};
 use crate::{codegen, emit_context};
 use crate::{codegen, emit_context};
 use inkwell::types::{BasicType, BasicTypeEnum, IntType};
 use inkwell::types::{BasicType, BasicTypeEnum, IntType};
 use inkwell::values::BasicValue;
 use inkwell::values::BasicValue;
@@ -48,12 +48,11 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
         bin: &Binary<'a>,
         bin: &Binary<'a>,
         _function: FunctionValue,
         _function: FunctionValue,
         slot: PointerValue<'a>,
         slot: PointerValue<'a>,
-        ns: &ast::Namespace,
     ) -> PointerValue<'a> {
     ) -> PointerValue<'a> {
         emit_context!(bin);
         emit_context!(bin);
 
 
         // This is the size of the external function struct
         // This is the size of the external function struct
-        let len = ns.address_length + 4;
+        let len = bin.ns.address_length + 4;
 
 
         let ef = call!(
         let ef = call!(
             "__malloc",
             "__malloc",
@@ -285,7 +284,6 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
         slot: IntValue<'a>,
         slot: IntValue<'a>,
         index: IntValue<'a>,
         index: IntValue<'a>,
         loc: Loc,
         loc: Loc,
-        ns: &Namespace,
     ) -> IntValue<'a> {
     ) -> IntValue<'a> {
         emit_context!(bin);
         emit_context!(bin);
 
 
@@ -342,9 +340,8 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
             self,
             self,
             "storage array index out of bounds".to_string(),
             "storage array index out of bounds".to_string(),
             Some(loc),
             Some(loc),
-            ns,
         );
         );
-        let (revert_out, revert_out_len) = bin.panic_data_const(ns, PanicCode::ArrayIndexOob);
+        let (revert_out, revert_out_len) = bin.panic_data_const(PanicCode::ArrayIndexOob);
         self.assert_failure(bin, revert_out, revert_out_len);
         self.assert_failure(bin, revert_out, revert_out_len);
 
 
         bin.builder.position_at_end(retrieve_block);
         bin.builder.position_at_end(retrieve_block);
@@ -373,7 +370,6 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
         slot: IntValue,
         slot: IntValue,
         index: IntValue,
         index: IntValue,
         val: IntValue,
         val: IntValue,
-        ns: &Namespace,
         loc: Loc,
         loc: Loc,
     ) {
     ) {
         emit_context!(bin);
         emit_context!(bin);
@@ -426,13 +422,8 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
             .unwrap();
             .unwrap();
 
 
         bin.builder.position_at_end(bang_block);
         bin.builder.position_at_end(bang_block);
-        bin.log_runtime_error(
-            self,
-            "storage index out of bounds".to_string(),
-            Some(loc),
-            ns,
-        );
-        let (revert_out, revert_out_len) = bin.panic_data_const(ns, PanicCode::ArrayIndexOob);
+        bin.log_runtime_error(self, "storage index out of bounds".to_string(), Some(loc));
+        let (revert_out, revert_out_len) = bin.panic_data_const(PanicCode::ArrayIndexOob);
         self.assert_failure(bin, revert_out, revert_out_len);
         self.assert_failure(bin, revert_out, revert_out_len);
 
 
         bin.builder.position_at_end(retrieve_block);
         bin.builder.position_at_end(retrieve_block);
@@ -467,7 +458,6 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
         _ty: &ast::Type,
         _ty: &ast::Type,
         slot: IntValue<'a>,
         slot: IntValue<'a>,
         val: Option<BasicValueEnum<'a>>,
         val: Option<BasicValueEnum<'a>>,
-        _ns: &ast::Namespace,
     ) -> BasicValueEnum<'a> {
     ) -> BasicValueEnum<'a> {
         emit_context!(bin);
         emit_context!(bin);
 
 
@@ -547,7 +537,6 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
         ty: &ast::Type,
         ty: &ast::Type,
         slot: IntValue<'a>,
         slot: IntValue<'a>,
         load: bool,
         load: bool,
-        ns: &ast::Namespace,
         loc: Loc,
         loc: Loc,
     ) -> Option<BasicValueEnum<'a>> {
     ) -> Option<BasicValueEnum<'a>> {
         emit_context!(bin);
         emit_context!(bin);
@@ -600,13 +589,8 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
             .unwrap();
             .unwrap();
 
 
         bin.builder.position_at_end(bang_block);
         bin.builder.position_at_end(bang_block);
-        bin.log_runtime_error(
-            self,
-            "pop from empty storage array".to_string(),
-            Some(loc),
-            ns,
-        );
-        let (revert_out, revert_out_len) = bin.panic_data_const(ns, PanicCode::EmptyArrayPop);
+        bin.log_runtime_error(self, "pop from empty storage array".to_string(), Some(loc));
+        let (revert_out, revert_out_len) = bin.panic_data_const(PanicCode::EmptyArrayPop);
         self.assert_failure(bin, revert_out, revert_out_len);
         self.assert_failure(bin, revert_out, revert_out_len);
 
 
         bin.builder.position_at_end(retrieve_block);
         bin.builder.position_at_end(retrieve_block);
@@ -631,7 +615,7 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
 
 
             Some(
             Some(
                 bin.builder
                 bin.builder
-                    .build_load(bin.llvm_type(ty, ns), offset, "popped_value")
+                    .build_load(bin.llvm_type(ty), offset, "popped_value")
                     .unwrap(),
                     .unwrap(),
             )
             )
         } else {
         } else {
@@ -655,7 +639,6 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
         _function: FunctionValue,
         _function: FunctionValue,
         slot: IntValue<'a>,
         slot: IntValue<'a>,
         _ty: &ast::Type,
         _ty: &ast::Type,
-        _ns: &ast::Namespace,
     ) -> IntValue<'a> {
     ) -> IntValue<'a> {
         emit_context!(bin);
         emit_context!(bin);
 
 
@@ -722,7 +705,6 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
         src: PointerValue,
         src: PointerValue,
         length: IntValue,
         length: IntValue,
         dest: PointerValue,
         dest: PointerValue,
-        _ns: &ast::Namespace,
     ) {
     ) {
         emit_context!(bin);
         emit_context!(bin);
 
 
@@ -781,14 +763,13 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
         encoded_args: BasicValueEnum<'b>,
         encoded_args: BasicValueEnum<'b>,
         encoded_args_len: BasicValueEnum<'b>,
         encoded_args_len: BasicValueEnum<'b>,
         contract_args: ContractArgs<'b>,
         contract_args: ContractArgs<'b>,
-        ns: &ast::Namespace,
         _loc: Loc,
         _loc: Loc,
     ) {
     ) {
         emit_context!(bin);
         emit_context!(bin);
 
 
-        let created_contract = &ns.contracts[contract_no];
+        let created_contract = &bin.ns.contracts[contract_no];
 
 
-        let code = created_contract.emit(ns, bin.options, contract_no);
+        let code = created_contract.emit(bin.ns, bin.options, contract_no);
 
 
         let (scratch_buf, scratch_len) = scratch_buf!();
         let (scratch_buf, scratch_len) = scratch_buf!();
 
 
@@ -813,12 +794,12 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
 
 
         let value_ptr = bin
         let value_ptr = bin
             .builder
             .builder
-            .build_alloca(bin.value_type(ns), "balance")
+            .build_alloca(bin.value_type(), "balance")
             .unwrap();
             .unwrap();
 
 
         let value = contract_args
         let value = contract_args
             .value
             .value
-            .unwrap_or_else(|| bin.value_type(ns).const_zero());
+            .unwrap_or_else(|| bin.value_type().const_zero());
         bin.builder.build_store(value_ptr, value).unwrap();
         bin.builder.build_store(value_ptr, value).unwrap();
 
 
         // code hash
         // code hash
@@ -834,7 +815,10 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
             .unwrap();
             .unwrap();
 
 
         bin.builder
         bin.builder
-            .build_store(address_len_ptr, i32_const!(ns.address_length as u64 * 32))
+            .build_store(
+                address_len_ptr,
+                i32_const!(bin.ns.address_length as u64 * 32),
+            )
             .unwrap();
             .unwrap();
 
 
         bin.builder
         bin.builder
@@ -875,7 +859,6 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
         address: Option<BasicValueEnum<'b>>,
         address: Option<BasicValueEnum<'b>>,
         contract_args: ContractArgs<'b>,
         contract_args: ContractArgs<'b>,
         call_type: ast::CallTy,
         call_type: ast::CallTy,
-        ns: &ast::Namespace,
         loc: Loc,
         loc: Loc,
     ) {
     ) {
         emit_context!(bin);
         emit_context!(bin);
@@ -890,7 +873,7 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
             ast::CallTy::Regular => {
             ast::CallTy::Regular => {
                 let value_ptr = bin
                 let value_ptr = bin
                     .builder
                     .builder
-                    .build_alloca(bin.value_type(ns), "balance")
+                    .build_alloca(bin.value_type(), "balance")
                     .unwrap();
                     .unwrap();
                 bin.builder
                 bin.builder
                     .build_store(value_ptr, contract_args.value.unwrap())
                     .build_store(value_ptr, contract_args.value.unwrap())
@@ -962,7 +945,7 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
 
 
                 bin.builder.position_at_end(not_found_block);
                 bin.builder.position_at_end(not_found_block);
                 let msg = "delegatecall callee is not a contract account";
                 let msg = "delegatecall callee is not a contract account";
-                bin.log_runtime_error(self, msg.into(), Some(loc), ns);
+                bin.log_runtime_error(self, msg.into(), Some(loc));
                 bin.builder.build_unconditional_branch(done_block).unwrap();
                 bin.builder.build_unconditional_branch(done_block).unwrap();
 
 
                 bin.builder.position_at_end(call_block);
                 bin.builder.position_at_end(call_block);
@@ -1002,7 +985,6 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
         success: Option<&mut BasicValueEnum<'b>>,
         success: Option<&mut BasicValueEnum<'b>>,
         address: PointerValue<'b>,
         address: PointerValue<'b>,
         value: IntValue<'b>,
         value: IntValue<'b>,
-        ns: &ast::Namespace,
         _loc: Loc,
         _loc: Loc,
     ) {
     ) {
         emit_context!(bin);
         emit_context!(bin);
@@ -1010,7 +992,7 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
         // balance is a u128
         // balance is a u128
         let value_ptr = bin
         let value_ptr = bin
             .builder
             .builder
-            .build_alloca(bin.value_type(ns), "balance")
+            .build_alloca(bin.value_type(), "balance")
             .unwrap();
             .unwrap();
         bin.builder.build_store(value_ptr, value).unwrap();
         bin.builder.build_store(value_ptr, value).unwrap();
 
 
@@ -1019,9 +1001,9 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
             "transfer",
             "transfer",
             &[
             &[
                 address.into(),
                 address.into(),
-                i32_const!(ns.address_length as u64).into(),
+                i32_const!(bin.ns.address_length as u64).into(),
                 value_ptr.into(),
                 value_ptr.into(),
-                i32_const!(ns.value_length as u64).into()
+                i32_const!(bin.ns.value_length as u64).into()
             ]
             ]
         )
         )
         .try_as_basic_value()
         .try_as_basic_value()
@@ -1052,13 +1034,10 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
     }
     }
 
 
     /// Polkadot value is usually 128 bits
     /// Polkadot value is usually 128 bits
-    fn value_transferred<'b>(&self, bin: &Binary<'b>, ns: &ast::Namespace) -> IntValue<'b> {
+    fn value_transferred<'b>(&self, bin: &Binary<'b>) -> IntValue<'b> {
         emit_context!(bin);
         emit_context!(bin);
 
 
-        let value = bin
-            .builder
-            .build_alloca(bin.value_type(ns), "value")
-            .unwrap();
+        let value = bin.builder.build_alloca(bin.value_type(), "value").unwrap();
 
 
         let value_len = bin
         let value_len = bin
             .builder
             .builder
@@ -1066,7 +1045,7 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
             .unwrap();
             .unwrap();
 
 
         bin.builder
         bin.builder
-            .build_store(value_len, i32_const!(ns.value_length as u64))
+            .build_store(value_len, i32_const!(bin.ns.value_length as u64))
             .unwrap();
             .unwrap();
 
 
         call!(
         call!(
@@ -1076,18 +1055,18 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
         );
         );
 
 
         bin.builder
         bin.builder
-            .build_load(bin.value_type(ns), value, "value_transferred")
+            .build_load(bin.value_type(), value, "value_transferred")
             .unwrap()
             .unwrap()
             .into_int_value()
             .into_int_value()
     }
     }
 
 
     /// Terminate execution, destroy contract and send remaining funds to addr
     /// Terminate execution, destroy contract and send remaining funds to addr
-    fn selfdestruct<'b>(&self, bin: &Binary<'b>, addr: ArrayValue<'b>, ns: &ast::Namespace) {
+    fn selfdestruct<'b>(&self, bin: &Binary<'b>, addr: ArrayValue<'b>) {
         emit_context!(bin);
         emit_context!(bin);
 
 
         let address = bin
         let address = bin
             .builder
             .builder
-            .build_alloca(bin.address_type(ns), "address")
+            .build_alloca(bin.address_type(), "address")
             .unwrap();
             .unwrap();
 
 
         bin.builder.build_store(address, addr).unwrap();
         bin.builder.build_store(address, addr).unwrap();
@@ -1106,7 +1085,6 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
         hash: HashTy,
         hash: HashTy,
         input: PointerValue<'b>,
         input: PointerValue<'b>,
         input_len: IntValue<'b>,
         input_len: IntValue<'b>,
-        ns: &ast::Namespace,
     ) -> IntValue<'b> {
     ) -> IntValue<'b> {
         emit_context!(bin);
         emit_context!(bin);
 
 
@@ -1128,7 +1106,7 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
         // bytes32 needs to reverse bytes
         // bytes32 needs to reverse bytes
         let temp = bin
         let temp = bin
             .builder
             .builder
-            .build_alloca(bin.llvm_type(&ast::Type::Bytes(hashlen as u8), ns), "hash")
+            .build_alloca(bin.llvm_type(&ast::Type::Bytes(hashlen as u8)), "hash")
             .unwrap();
             .unwrap();
 
 
         call!(
         call!(
@@ -1138,7 +1116,7 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
 
 
         bin.builder
         bin.builder
             .build_load(
             .build_load(
-                bin.llvm_type(&ast::Type::Bytes(hashlen as u8), ns),
+                bin.llvm_type(&ast::Type::Bytes(hashlen as u8)),
                 temp,
                 temp,
                 "hash",
                 "hash",
             )
             )
@@ -1232,7 +1210,6 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
         expr: &codegen::Expression,
         expr: &codegen::Expression,
         vartab: &HashMap<usize, Variable<'b>>,
         vartab: &HashMap<usize, Variable<'b>>,
         function: FunctionValue<'b>,
         function: FunctionValue<'b>,
-        ns: &ast::Namespace,
     ) -> BasicValueEnum<'b> {
     ) -> BasicValueEnum<'b> {
         emit_context!(bin);
         emit_context!(bin);
 
 
@@ -1363,13 +1340,13 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
                 let gas = if args.is_empty() {
                 let gas = if args.is_empty() {
                     bin.context.i64_type().const_int(1, false)
                     bin.context.i64_type().const_int(1, false)
                 } else {
                 } else {
-                    expression(self, bin, &args[0], vartab, function, ns).into_int_value()
+                    expression(self, bin, &args[0], vartab, function).into_int_value()
                 };
                 };
 
 
                 let (scratch_buf, scratch_len) = scratch_buf!();
                 let (scratch_buf, scratch_len) = scratch_buf!();
 
 
                 bin.builder
                 bin.builder
-                    .build_store(scratch_len, i32_const!(ns.value_length as u64))
+                    .build_store(scratch_len, i32_const!(bin.ns.value_length as u64))
                     .unwrap();
                     .unwrap();
 
 
                 call!(
                 call!(
@@ -1381,7 +1358,7 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
                 bin.builder
                 bin.builder
                     .build_load(
                     .build_load(
                         bin.context
                         bin.context
-                            .custom_width_int_type(ns.value_length as u32 * 8),
+                            .custom_width_int_type(bin.ns.value_length as u32 * 8),
                         scratch_buf,
                         scratch_buf,
                         "price",
                         "price",
                     )
                     )
@@ -1394,7 +1371,7 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
                 let (scratch_buf, scratch_len) = scratch_buf!();
                 let (scratch_buf, scratch_len) = scratch_buf!();
 
 
                 bin.builder
                 bin.builder
-                    .build_store(scratch_len, i32_const!(ns.address_length as u64))
+                    .build_store(scratch_len, i32_const!(bin.ns.address_length as u64))
                     .unwrap();
                     .unwrap();
 
 
                 call!(
                 call!(
@@ -1404,13 +1381,13 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
                 );
                 );
 
 
                 bin.builder
                 bin.builder
-                    .build_load(bin.address_type(ns), scratch_buf, "caller")
+                    .build_load(bin.address_type(), scratch_buf, "caller")
                     .unwrap()
                     .unwrap()
             }
             }
             codegen::Expression::Builtin {
             codegen::Expression::Builtin {
                 kind: codegen::Builtin::Value,
                 kind: codegen::Builtin::Value,
                 ..
                 ..
-            } => self.value_transferred(bin, ns).into(),
+            } => self.value_transferred(bin).into(),
             codegen::Expression::Builtin {
             codegen::Expression::Builtin {
                 kind: codegen::Builtin::MinimumBalance,
                 kind: codegen::Builtin::MinimumBalance,
                 ..
                 ..
@@ -1418,7 +1395,7 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
                 get_seal_value!(
                 get_seal_value!(
                     "seal_minimum_balance",
                     "seal_minimum_balance",
                     "minimum_balance",
                     "minimum_balance",
-                    ns.value_length as u32 * 8
+                    bin.ns.value_length as u32 * 8
                 )
                 )
             }
             }
             codegen::Expression::Builtin {
             codegen::Expression::Builtin {
@@ -1428,7 +1405,7 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
                 let (scratch_buf, scratch_len) = scratch_buf!();
                 let (scratch_buf, scratch_len) = scratch_buf!();
 
 
                 bin.builder
                 bin.builder
-                    .build_store(scratch_len, i32_const!(ns.address_length as u64))
+                    .build_store(scratch_len, i32_const!(bin.ns.address_length as u64))
                     .unwrap();
                     .unwrap();
 
 
                 call!(
                 call!(
@@ -1449,7 +1426,7 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
                 let (scratch_buf, scratch_len) = scratch_buf!();
                 let (scratch_buf, scratch_len) = scratch_buf!();
 
 
                 bin.builder
                 bin.builder
-                    .build_store(scratch_len, i32_const!(ns.value_length as u64))
+                    .build_store(scratch_len, i32_const!(bin.ns.value_length as u64))
                     .unwrap();
                     .unwrap();
 
 
                 call!(
                 call!(
@@ -1459,7 +1436,7 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
                 );
                 );
 
 
                 bin.builder
                 bin.builder
-                    .build_load(bin.value_type(ns), scratch_buf, "balance")
+                    .build_load(bin.value_type(), scratch_buf, "balance")
                     .unwrap()
                     .unwrap()
             }
             }
             _ => unreachable!("{:?}", expr),
             _ => unreachable!("{:?}", expr),
@@ -1472,14 +1449,13 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
         ty: &Type,
         ty: &Type,
         slot: &mut IntValue<'a>,
         slot: &mut IntValue<'a>,
         function: FunctionValue,
         function: FunctionValue,
-        ns: &Namespace,
         _storage_type: &Option<StorageType>,
         _storage_type: &Option<StorageType>,
     ) -> BasicValueEnum<'a> {
     ) -> BasicValueEnum<'a> {
         // The storage slot is an i256 accessed through a pointer, so we need
         // The storage slot is an i256 accessed through a pointer, so we need
         // to store it
         // to store it
         let slot_ptr = bin.builder.build_alloca(slot.get_type(), "slot").unwrap();
         let slot_ptr = bin.builder.build_alloca(slot.get_type(), "slot").unwrap();
 
 
-        self.storage_load_slot(bin, ty, slot, slot_ptr, function, ns)
+        self.storage_load_slot(bin, ty, slot, slot_ptr, function)
     }
     }
 
 
     fn storage_store(
     fn storage_store(
@@ -1490,12 +1466,11 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
         slot: &mut IntValue<'a>,
         slot: &mut IntValue<'a>,
         dest: BasicValueEnum<'a>,
         dest: BasicValueEnum<'a>,
         function: FunctionValue<'a>,
         function: FunctionValue<'a>,
-        ns: &Namespace,
         _: &Option<StorageType>,
         _: &Option<StorageType>,
     ) {
     ) {
         let slot_ptr = bin.builder.build_alloca(slot.get_type(), "slot").unwrap();
         let slot_ptr = bin.builder.build_alloca(slot.get_type(), "slot").unwrap();
 
 
-        self.storage_store_slot(bin, ty, slot, slot_ptr, dest, function, ns);
+        self.storage_store_slot(bin, ty, slot, slot_ptr, dest, function);
     }
     }
 
 
     fn storage_delete(
     fn storage_delete(
@@ -1504,11 +1479,10 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
         ty: &Type,
         ty: &Type,
         slot: &mut IntValue<'a>,
         slot: &mut IntValue<'a>,
         function: FunctionValue<'a>,
         function: FunctionValue<'a>,
-        ns: &Namespace,
     ) {
     ) {
         let slot_ptr = bin.builder.build_alloca(slot.get_type(), "slot").unwrap();
         let slot_ptr = bin.builder.build_alloca(slot.get_type(), "slot").unwrap();
 
 
-        self.storage_delete_slot(bin, ty, slot, slot_ptr, function, ns);
+        self.storage_delete_slot(bin, ty, slot, slot_ptr, function);
     }
     }
 
 
     fn builtin_function(
     fn builtin_function(
@@ -1518,7 +1492,6 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
         builtin_func: &Function,
         builtin_func: &Function,
         args: &[BasicMetadataValueEnum<'a>],
         args: &[BasicMetadataValueEnum<'a>],
         _first_arg_type: Option<BasicTypeEnum>,
         _first_arg_type: Option<BasicTypeEnum>,
-        ns: &Namespace,
     ) -> Option<BasicValueEnum<'a>> {
     ) -> Option<BasicValueEnum<'a>> {
         emit_context!(bin);
         emit_context!(bin);
 
 
@@ -1572,7 +1545,7 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
             "is_contract" => {
             "is_contract" => {
                 let address = bin
                 let address = bin
                     .builder
                     .builder
-                    .build_alloca(bin.address_type(ns), "maybe_contract")
+                    .build_alloca(bin.address_type(), "maybe_contract")
                     .unwrap();
                     .unwrap();
                 bin.builder
                 bin.builder
                     .build_store(address, args[0].into_array_value())
                     .build_store(address, args[0].into_array_value())
@@ -1621,7 +1594,6 @@ impl<'a> TargetRuntime<'a> for PolkadotTarget {
         _ty: &Type,
         _ty: &Type,
         _slot: IntValue<'a>,
         _slot: IntValue<'a>,
         _index: BasicValueEnum<'a>,
         _index: BasicValueEnum<'a>,
-        _ns: &Namespace,
     ) -> IntValue<'a> {
     ) -> IntValue<'a> {
         // not needed for slot-based storage chains
         // not needed for slot-based storage chains
         unimplemented!()
         unimplemented!()

+ 30 - 49
src/emit/solana/mod.rs

@@ -3,11 +3,10 @@
 pub(super) mod target;
 pub(super) mod target;
 
 
 use crate::sema::ast;
 use crate::sema::ast;
-use crate::Target;
 use std::cmp::Ordering;
 use std::cmp::Ordering;
 
 
 use crate::codegen::{cfg::ReturnCode, Options};
 use crate::codegen::{cfg::ReturnCode, Options};
-use crate::sema::ast::{Namespace, StructType, Type};
+use crate::sema::ast::{StructType, Type};
 use inkwell::module::{Linkage, Module};
 use inkwell::module::{Linkage, Module};
 use inkwell::types::BasicType;
 use inkwell::types::BasicType;
 use inkwell::values::{
 use inkwell::values::{
@@ -36,7 +35,7 @@ impl SolanaTarget {
         let filename = ns.files[contract.loc.file_no()].file_name();
         let filename = ns.files[contract.loc.file_no()].file_name();
         let mut bin = Binary::new(
         let mut bin = Binary::new(
             context,
             context,
-            Target::Solana,
+            ns,
             &contract.id.name,
             &contract.id.name,
             filename.as_str(),
             filename.as_str(),
             opt,
             opt,
@@ -67,9 +66,9 @@ impl SolanaTarget {
             context.i64_type().const_int(5u64 << 32, false),
             context.i64_type().const_int(5u64 << 32, false),
         );
         );
         // externals
         // externals
-        target.declare_externals(&mut bin, ns);
+        target.declare_externals(&mut bin);
 
 
-        emit_functions(&mut target, &mut bin, contract, ns);
+        emit_functions(&mut target, &mut bin, contract);
 
 
         bin.internalize(&[
         bin.internalize(&[
             "entrypoint",
             "entrypoint",
@@ -89,16 +88,13 @@ impl SolanaTarget {
         bin
         bin
     }
     }
 
 
-    fn declare_externals(&self, bin: &mut Binary, ns: &ast::Namespace) {
+    fn declare_externals(&self, bin: &mut Binary) {
         let void_ty = bin.context.void_type();
         let void_ty = bin.context.void_type();
         let u8_ptr = bin.context.i8_type().ptr_type(AddressSpace::default());
         let u8_ptr = bin.context.i8_type().ptr_type(AddressSpace::default());
         let u64_ty = bin.context.i64_type();
         let u64_ty = bin.context.i64_type();
         let u32_ty = bin.context.i32_type();
         let u32_ty = bin.context.i32_type();
-        let address = bin.address_type(ns).ptr_type(AddressSpace::default());
-        let seeds = bin.llvm_type(
-            &Type::Ref(Box::new(Type::Slice(Box::new(Type::Bytes(1))))),
-            ns,
-        );
+        let address = bin.address_type().ptr_type(AddressSpace::default());
+        let seeds = bin.llvm_type(&Type::Ref(Box::new(Type::Slice(Box::new(Type::Bytes(1))))));
 
 
         let sol_bytes = bin
         let sol_bytes = bin
             .context
             .context
@@ -312,9 +308,8 @@ impl SolanaTarget {
         slot: IntValue<'b>,
         slot: IntValue<'b>,
         function: FunctionValue<'b>,
         function: FunctionValue<'b>,
         zero: bool,
         zero: bool,
-        ns: &ast::Namespace,
     ) {
     ) {
-        if !zero && !ty.is_dynamic(ns) {
+        if !zero && !ty.is_dynamic(bin.ns) {
             // nothing to do
             // nothing to do
             return;
             return;
         }
         }
@@ -350,7 +345,7 @@ impl SolanaTarget {
             let mut elem_slot = slot;
             let mut elem_slot = slot;
             let mut free_array = None;
             let mut free_array = None;
 
 
-            if elem_ty.is_dynamic(ns) || zero {
+            if elem_ty.is_dynamic(bin.ns) || zero {
                 let length = if let Some(ast::ArrayLength::Fixed(length)) = dim.last() {
                 let length = if let Some(ast::ArrayLength::Fixed(length)) = dim.last() {
                     bin.context
                     bin.context
                         .i32_type()
                         .i32_type()
@@ -364,10 +359,10 @@ impl SolanaTarget {
 
 
                     free_array = Some(elem_slot);
                     free_array = Some(elem_slot);
 
 
-                    self.storage_array_length(bin, function, slot, elem_ty, ns)
+                    self.storage_array_length(bin, function, slot, elem_ty)
                 };
                 };
 
 
-                let elem_size = elem_ty.solana_storage_size(ns).to_u64().unwrap();
+                let elem_size = elem_ty.solana_storage_size(bin.ns).to_u64().unwrap();
 
 
                 // loop over the array
                 // loop over the array
                 let mut builder = LoopBuilder::new(bin, function);
                 let mut builder = LoopBuilder::new(bin, function);
@@ -382,15 +377,7 @@ impl SolanaTarget {
 
 
                 let elem_ty = ty.array_deref();
                 let elem_ty = ty.array_deref();
 
 
-                self.storage_free(
-                    bin,
-                    elem_ty.deref_any(),
-                    data,
-                    offset_val,
-                    function,
-                    zero,
-                    ns,
-                );
+                self.storage_free(bin, elem_ty.deref_any(), data, offset_val, function, zero);
 
 
                 let offset_val = bin
                 let offset_val = bin
                     .builder
                     .builder
@@ -426,8 +413,8 @@ impl SolanaTarget {
                 }
                 }
             }
             }
         } else if let ast::Type::Struct(struct_ty) = ty {
         } else if let ast::Type::Struct(struct_ty) = ty {
-            for (i, field) in struct_ty.definition(ns).fields.iter().enumerate() {
-                let field_offset = struct_ty.definition(ns).storage_offsets[i]
+            for (i, field) in struct_ty.definition(bin.ns).fields.iter().enumerate() {
+                let field_offset = struct_ty.definition(bin.ns).storage_offsets[i]
                     .to_u64()
                     .to_u64()
                     .unwrap();
                     .unwrap();
 
 
@@ -440,16 +427,16 @@ impl SolanaTarget {
                     )
                     )
                     .unwrap();
                     .unwrap();
 
 
-                self.storage_free(bin, &field.ty, data, offset, function, zero, ns);
+                self.storage_free(bin, &field.ty, data, offset, function, zero);
             }
             }
         } else if matches!(ty, Type::Address(_) | Type::Contract(_)) {
         } else if matches!(ty, Type::Address(_) | Type::Contract(_)) {
-            let ty = bin.llvm_type(ty, ns);
+            let ty = bin.llvm_type(ty);
 
 
             bin.builder
             bin.builder
                 .build_store(member, ty.into_array_type().const_zero())
                 .build_store(member, ty.into_array_type().const_zero())
                 .unwrap();
                 .unwrap();
         } else {
         } else {
-            let ty = bin.llvm_type(ty, ns);
+            let ty = bin.llvm_type(ty);
 
 
             bin.builder
             bin.builder
                 .build_store(member, ty.into_int_type().const_zero())
                 .build_store(member, ty.into_int_type().const_zero())
@@ -463,7 +450,6 @@ impl SolanaTarget {
         bin: &Binary<'b>,
         bin: &Binary<'b>,
         key_ty: &ast::Type,
         key_ty: &ast::Type,
         value_ty: &ast::Type,
         value_ty: &ast::Type,
-        ns: &ast::Namespace,
     ) -> BasicTypeEnum<'b> {
     ) -> BasicTypeEnum<'b> {
         let key = if matches!(
         let key = if matches!(
             key_ty,
             key_ty,
@@ -471,7 +457,7 @@ impl SolanaTarget {
         ) {
         ) {
             bin.context.i32_type().into()
             bin.context.i32_type().into()
         } else {
         } else {
-            bin.llvm_type(key_ty, ns)
+            bin.llvm_type(key_ty)
         };
         };
 
 
         bin.context
         bin.context
@@ -482,7 +468,7 @@ impl SolanaTarget {
                     if value_ty.is_mapping() {
                     if value_ty.is_mapping() {
                         bin.context.i32_type().into()
                         bin.context.i32_type().into()
                     } else {
                     } else {
-                        bin.llvm_type(value_ty, ns) // value
+                        bin.llvm_type(value_ty) // value
                     },
                     },
                 ],
                 ],
                 false,
                 false,
@@ -496,12 +482,11 @@ impl SolanaTarget {
         bin: &Binary<'b>,
         bin: &Binary<'b>,
         key_ty: &ast::Type,
         key_ty: &ast::Type,
         value_ty: &ast::Type,
         value_ty: &ast::Type,
-        ns: &ast::Namespace,
     ) -> FunctionValue<'b> {
     ) -> FunctionValue<'b> {
         let function_name = format!(
         let function_name = format!(
             "sparse_lookup_{}_{}",
             "sparse_lookup_{}_{}",
-            key_ty.to_llvm_string(ns),
-            value_ty.to_llvm_string(ns)
+            key_ty.to_llvm_string(bin.ns),
+            value_ty.to_llvm_string(bin.ns)
         );
         );
 
 
         if let Some(function) = bin.module.get_function(&function_name) {
         if let Some(function) = bin.module.get_function(&function_name) {
@@ -513,7 +498,6 @@ impl SolanaTarget {
         let function_ty = bin.function_type(
         let function_ty = bin.function_type(
             &[ast::Type::Uint(32), key_ty.clone()],
             &[ast::Type::Uint(32), key_ty.clone()],
             &[ast::Type::Uint(32)],
             &[ast::Type::Uint(32)],
-            ns,
         );
         );
 
 
         let function =
         let function =
@@ -527,7 +511,7 @@ impl SolanaTarget {
         let offset = function.get_nth_param(0).unwrap().into_int_value();
         let offset = function.get_nth_param(0).unwrap().into_int_value();
         let key = function.get_nth_param(1).unwrap();
         let key = function.get_nth_param(1).unwrap();
 
 
-        let entry_ty = self.sparse_entry(bin, key_ty, value_ty, ns);
+        let entry_ty = self.sparse_entry(bin, key_ty, value_ty);
         let value_offset = unsafe {
         let value_offset = unsafe {
             entry_ty
             entry_ty
                 .ptr_type(AddressSpace::default())
                 .ptr_type(AddressSpace::default())
@@ -550,7 +534,7 @@ impl SolanaTarget {
         }
         }
         .unwrap();
         .unwrap();
 
 
-        let address = bin.build_alloca(function, bin.address_type(ns), "address");
+        let address = bin.build_alloca(function, bin.address_type(), "address");
 
 
         // calculate the correct bucket. We have an prime number of
         // calculate the correct bucket. We have an prime number of
         let bucket = if matches!(key_ty, ast::Type::String | ast::Type::DynamicBytes) {
         let bucket = if matches!(key_ty, ast::Type::String | ast::Type::DynamicBytes) {
@@ -579,7 +563,7 @@ impl SolanaTarget {
                 .left()
                 .left()
                 .unwrap()
                 .unwrap()
                 .into_int_value()
                 .into_int_value()
-        } else if key_ty.bits(ns) > 64 {
+        } else if key_ty.bits(bin.ns) > 64 {
             bin.builder
             bin.builder
                 .build_int_truncate(key.into_int_value(), bin.context.i64_type(), "")
                 .build_int_truncate(key.into_int_value(), bin.context.i64_type(), "")
                 .unwrap()
                 .unwrap()
@@ -736,7 +720,7 @@ impl SolanaTarget {
         } else {
         } else {
             let entry_key = bin
             let entry_key = bin
                 .builder
                 .builder
-                .build_load(bin.llvm_type(key_ty, ns), ptr, "key")
+                .build_load(bin.llvm_type(key_ty), ptr, "key")
                 .unwrap();
                 .unwrap();
 
 
             bin.builder
             bin.builder
@@ -982,13 +966,12 @@ impl SolanaTarget {
         value_ty: &ast::Type,
         value_ty: &ast::Type,
         slot: IntValue<'b>,
         slot: IntValue<'b>,
         index: BasicValueEnum<'b>,
         index: BasicValueEnum<'b>,
-        ns: &ast::Namespace,
     ) -> IntValue<'b> {
     ) -> IntValue<'b> {
         let offset = bin.build_alloca(function, bin.context.i32_type(), "offset");
         let offset = bin.build_alloca(function, bin.context.i32_type(), "offset");
 
 
         let current_block = bin.builder.get_insert_block().unwrap();
         let current_block = bin.builder.get_insert_block().unwrap();
 
 
-        let lookup = self.sparse_lookup_function(bin, key_ty, value_ty, ns);
+        let lookup = self.sparse_lookup_function(bin, key_ty, value_ty);
 
 
         bin.builder.position_at_end(current_block);
         bin.builder.position_at_end(current_block);
 
 
@@ -1044,7 +1027,6 @@ impl SolanaTarget {
         function: FunctionValue<'b>,
         function: FunctionValue<'b>,
         account_info: PointerValue<'b>,
         account_info: PointerValue<'b>,
         member: usize,
         member: usize,
-        ns: &ast::Namespace,
     ) -> BasicValueEnum<'b> {
     ) -> BasicValueEnum<'b> {
         let account_info_ty = bin.module.get_struct_type("struct.SolAccountInfo").unwrap();
         let account_info_ty = bin.module.get_struct_type("struct.SolAccountInfo").unwrap();
 
 
@@ -1078,13 +1060,13 @@ impl SolanaTarget {
 
 
                 let slice_alloca = bin.build_alloca(
                 let slice_alloca = bin.build_alloca(
                     function,
                     function,
-                    bin.llvm_type(&ast::Type::Slice(Box::new(Type::Bytes(1))), ns),
+                    bin.llvm_type(&ast::Type::Slice(Box::new(Type::Bytes(1)))),
                     "slice_alloca",
                     "slice_alloca",
                 );
                 );
                 let data_elem = bin
                 let data_elem = bin
                     .builder
                     .builder
                     .build_struct_gep(
                     .build_struct_gep(
-                        bin.llvm_type(&ast::Type::Slice(Box::new(Type::Bytes(1))), ns),
+                        bin.llvm_type(&ast::Type::Slice(Box::new(Type::Bytes(1)))),
                         slice_alloca,
                         slice_alloca,
                         0,
                         0,
                         "data",
                         "data",
@@ -1094,7 +1076,7 @@ impl SolanaTarget {
                 let data_len_elem = bin
                 let data_len_elem = bin
                     .builder
                     .builder
                     .build_struct_gep(
                     .build_struct_gep(
-                        bin.llvm_type(&ast::Type::Slice(Box::new(Type::Bytes(1))), ns),
+                        bin.llvm_type(&ast::Type::Slice(Box::new(Type::Bytes(1)))),
                         slice_alloca,
                         slice_alloca,
                         1,
                         1,
                         "data_len",
                         "data_len",
@@ -1125,7 +1107,6 @@ impl SolanaTarget {
         payload: PointerValue<'b>,
         payload: PointerValue<'b>,
         payload_len: IntValue<'b>,
         payload_len: IntValue<'b>,
         contract_args: ContractArgs<'b>,
         contract_args: ContractArgs<'b>,
-        ns: &Namespace,
     ) {
     ) {
         let instruction_ty: BasicTypeEnum = bin
         let instruction_ty: BasicTypeEnum = bin
             .context
             .context
@@ -1136,7 +1117,7 @@ impl SolanaTarget {
                         .unwrap()
                         .unwrap()
                         .ptr_type(AddressSpace::default())
                         .ptr_type(AddressSpace::default())
                         .as_basic_type_enum(),
                         .as_basic_type_enum(),
-                    bin.llvm_type(&Type::Struct(StructType::AccountMeta), ns)
+                    bin.llvm_type(&Type::Struct(StructType::AccountMeta))
                         .ptr_type(AddressSpace::default())
                         .ptr_type(AddressSpace::default())
                         .as_basic_type_enum(),
                         .as_basic_type_enum(),
                     bin.context.i64_type().as_basic_type_enum(),
                     bin.context.i64_type().as_basic_type_enum(),

+ 60 - 91
src/emit/solana/target.rs

@@ -7,7 +7,7 @@ use crate::emit::expression::expression;
 use crate::emit::loop_builder::LoopBuilder;
 use crate::emit::loop_builder::LoopBuilder;
 use crate::emit::solana::SolanaTarget;
 use crate::emit::solana::SolanaTarget;
 use crate::emit::{ContractArgs, TargetRuntime, Variable};
 use crate::emit::{ContractArgs, TargetRuntime, Variable};
-use crate::sema::ast::{self, Namespace};
+use crate::sema::ast;
 use inkwell::types::{BasicType, BasicTypeEnum, IntType};
 use inkwell::types::{BasicType, BasicTypeEnum, IntType};
 use inkwell::values::{
 use inkwell::values::{
     ArrayValue, BasicMetadataValueEnum, BasicValueEnum, FunctionValue, IntValue, PointerValue,
     ArrayValue, BasicMetadataValueEnum, BasicValueEnum, FunctionValue, IntValue, PointerValue,
@@ -25,12 +25,11 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         ty: &ast::Type,
         ty: &ast::Type,
         slot: &mut IntValue<'a>,
         slot: &mut IntValue<'a>,
         function: FunctionValue<'a>,
         function: FunctionValue<'a>,
-        ns: &ast::Namespace,
     ) {
     ) {
         // binary storage is in 2nd account
         // binary storage is in 2nd account
         let data = self.contract_storage_data(bin);
         let data = self.contract_storage_data(bin);
 
 
-        self.storage_free(bin, ty, data, *slot, function, true, ns);
+        self.storage_free(bin, ty, data, *slot, function, true);
     }
     }
 
 
     fn set_storage_extfunc(
     fn set_storage_extfunc(
@@ -48,7 +47,6 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         _bin: &Binary<'a>,
         _bin: &Binary<'a>,
         _function: FunctionValue,
         _function: FunctionValue,
         _slot: PointerValue<'a>,
         _slot: PointerValue<'a>,
-        _ns: &ast::Namespace,
     ) -> PointerValue<'a> {
     ) -> PointerValue<'a> {
         unimplemented!();
         unimplemented!();
     }
     }
@@ -81,7 +79,6 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         slot: IntValue<'a>,
         slot: IntValue<'a>,
         index: IntValue<'a>,
         index: IntValue<'a>,
         loc: Loc,
         loc: Loc,
-        ns: &Namespace,
     ) -> IntValue<'a> {
     ) -> IntValue<'a> {
         let data = self.contract_storage_data(bin);
         let data = self.contract_storage_data(bin);
 
 
@@ -129,7 +126,6 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
             self,
             self,
             "storage array index out of bounds".to_string(),
             "storage array index out of bounds".to_string(),
             Some(loc),
             Some(loc),
-            ns,
         );
         );
         self.assert_failure(
         self.assert_failure(
             bin,
             bin,
@@ -163,7 +159,6 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         slot: IntValue,
         slot: IntValue,
         index: IntValue,
         index: IntValue,
         val: IntValue,
         val: IntValue,
-        ns: &Namespace,
         loc: Loc,
         loc: Loc,
     ) {
     ) {
         let data = self.contract_storage_data(bin);
         let data = self.contract_storage_data(bin);
@@ -207,12 +202,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
             .unwrap();
             .unwrap();
 
 
         bin.builder.position_at_end(bang_block);
         bin.builder.position_at_end(bang_block);
-        bin.log_runtime_error(
-            self,
-            "storage index out of bounds".to_string(),
-            Some(loc),
-            ns,
-        );
+        bin.log_runtime_error(self, "storage index out of bounds".to_string(), Some(loc));
         self.assert_failure(
         self.assert_failure(
             bin,
             bin,
             bin.context
             bin.context
@@ -242,19 +232,18 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         ty: &ast::Type,
         ty: &ast::Type,
         slot: IntValue<'a>,
         slot: IntValue<'a>,
         index: BasicValueEnum<'a>,
         index: BasicValueEnum<'a>,
-        ns: &ast::Namespace,
     ) -> IntValue<'a> {
     ) -> IntValue<'a> {
         let account = self.contract_storage_account(bin);
         let account = self.contract_storage_account(bin);
 
 
         if let ast::Type::Mapping(ast::Mapping { key, value, .. }) = ty.deref_any() {
         if let ast::Type::Mapping(ast::Mapping { key, value, .. }) = ty.deref_any() {
-            self.sparse_lookup(bin, function, key, value, slot, index, ns)
-        } else if ty.is_sparse_solana(ns) {
+            self.sparse_lookup(bin, function, key, value, slot, index)
+        } else if ty.is_sparse_solana(bin.ns) {
             // sparse array
             // sparse array
             let elem_ty = ty.storage_array_elem().deref_into();
             let elem_ty = ty.storage_array_elem().deref_into();
 
 
             let key = ast::Type::Uint(256);
             let key = ast::Type::Uint(256);
 
 
-            self.sparse_lookup(bin, function, &key, &elem_ty, slot, index, ns)
+            self.sparse_lookup(bin, function, &key, &elem_ty, slot, index)
         } else {
         } else {
             // 3rd member of account is data pointer
             // 3rd member of account is data pointer
             let data = unsafe {
             let data = unsafe {
@@ -298,7 +287,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
             let elem_size = bin
             let elem_size = bin
                 .context
                 .context
                 .i32_type()
                 .i32_type()
-                .const_int(elem_ty.solana_storage_size(ns).to_u64().unwrap(), false);
+                .const_int(elem_ty.solana_storage_size(bin.ns).to_u64().unwrap(), false);
 
 
             bin.builder
             bin.builder
                 .build_int_add(
                 .build_int_add(
@@ -319,7 +308,6 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         ty: &ast::Type,
         ty: &ast::Type,
         slot: IntValue<'a>,
         slot: IntValue<'a>,
         val: Option<BasicValueEnum<'a>>,
         val: Option<BasicValueEnum<'a>>,
-        ns: &ast::Namespace,
     ) -> BasicValueEnum<'a> {
     ) -> BasicValueEnum<'a> {
         let data = self.contract_storage_data(bin);
         let data = self.contract_storage_data(bin);
         let account = self.contract_storage_account(bin);
         let account = self.contract_storage_account(bin);
@@ -352,7 +340,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         let member_size = bin
         let member_size = bin
             .context
             .context
             .i32_type()
             .i32_type()
-            .const_int(ty.storage_slots(ns).to_u64().unwrap(), false);
+            .const_int(ty.storage_slots(bin.ns).to_u64().unwrap(), false);
         let new_length = bin
         let new_length = bin
             .builder
             .builder
             .build_int_add(length, member_size, "new_length")
             .build_int_add(length, member_size, "new_length")
@@ -412,10 +400,10 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
             .unwrap();
             .unwrap();
 
 
         if let Some(val) = val {
         if let Some(val) = val {
-            self.storage_store(bin, ty, false, &mut new_offset, val, function, ns, &None);
+            self.storage_store(bin, ty, false, &mut new_offset, val, function, &None);
         }
         }
 
 
-        if ty.is_reference_type(ns) {
+        if ty.is_reference_type(bin.ns) {
             // Caller expects a reference to storage; note that storage_store() should not modify
             // Caller expects a reference to storage; note that storage_store() should not modify
             // new_offset even if the argument is mut
             // new_offset even if the argument is mut
             new_offset.into()
             new_offset.into()
@@ -431,7 +419,6 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         ty: &ast::Type,
         ty: &ast::Type,
         slot: IntValue<'a>,
         slot: IntValue<'a>,
         load: bool,
         load: bool,
-        ns: &ast::Namespace,
         loc: Loc,
         loc: Loc,
     ) -> Option<BasicValueEnum<'a>> {
     ) -> Option<BasicValueEnum<'a>> {
         let data = self.contract_storage_data(bin);
         let data = self.contract_storage_data(bin);
@@ -481,12 +468,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
             .unwrap();
             .unwrap();
 
 
         bin.builder.position_at_end(bang_block);
         bin.builder.position_at_end(bang_block);
-        bin.log_runtime_error(
-            self,
-            "pop from empty storage array".to_string(),
-            Some(loc),
-            ns,
-        );
+        bin.log_runtime_error(self, "pop from empty storage array".to_string(), Some(loc));
         self.assert_failure(
         self.assert_failure(
             bin,
             bin,
             bin.context
             bin.context
@@ -501,7 +483,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         let member_size = bin
         let member_size = bin
             .context
             .context
             .i32_type()
             .i32_type()
-            .const_int(ty.storage_slots(ns).to_u64().unwrap(), false);
+            .const_int(ty.storage_slots(bin.ns).to_u64().unwrap(), false);
 
 
         let new_length = bin
         let new_length = bin
             .builder
             .builder
@@ -511,13 +493,13 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         let mut old_elem_offset = bin.builder.build_int_add(offset, new_length, "").unwrap();
         let mut old_elem_offset = bin.builder.build_int_add(offset, new_length, "").unwrap();
 
 
         let val = if load {
         let val = if load {
-            Some(self.storage_load(bin, ty, &mut old_elem_offset, function, ns, &None))
+            Some(self.storage_load(bin, ty, &mut old_elem_offset, function, &None))
         } else {
         } else {
             None
             None
         };
         };
 
 
         // delete existing storage -- pointers need to be freed
         // delete existing storage -- pointers need to be freed
-        self.storage_free(bin, ty, data, old_elem_offset, function, false, ns);
+        self.storage_free(bin, ty, data, old_elem_offset, function, false);
 
 
         // we can assume pointer will stay the same after realloc to smaller size
         // we can assume pointer will stay the same after realloc to smaller size
         bin.builder
         bin.builder
@@ -542,7 +524,6 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         _function: FunctionValue,
         _function: FunctionValue,
         slot: IntValue<'a>,
         slot: IntValue<'a>,
         elem_ty: &ast::Type,
         elem_ty: &ast::Type,
-        ns: &ast::Namespace,
     ) -> IntValue<'a> {
     ) -> IntValue<'a> {
         let data = self.contract_storage_data(bin);
         let data = self.contract_storage_data(bin);
 
 
@@ -562,7 +543,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         let member_size = bin
         let member_size = bin
             .context
             .context
             .i32_type()
             .i32_type()
-            .const_int(elem_ty.storage_slots(ns).to_u64().unwrap(), false);
+            .const_int(elem_ty.storage_slots(bin.ns).to_u64().unwrap(), false);
 
 
         let length_bytes = bin
         let length_bytes = bin
             .builder
             .builder
@@ -601,7 +582,6 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         ty: &ast::Type,
         ty: &ast::Type,
         slot: &mut IntValue<'a>,
         slot: &mut IntValue<'a>,
         function: FunctionValue<'a>,
         function: FunctionValue<'a>,
-        ns: &ast::Namespace,
         _storage_type: &Option<StorageType>,
         _storage_type: &Option<StorageType>,
     ) -> BasicValueEnum<'a> {
     ) -> BasicValueEnum<'a> {
         let data = self.contract_storage_data(bin);
         let data = self.contract_storage_data(bin);
@@ -656,7 +636,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                     .unwrap()
                     .unwrap()
             }
             }
             ast::Type::Struct(struct_ty) => {
             ast::Type::Struct(struct_ty) => {
-                let llvm_ty = bin.llvm_type(ty.deref_any(), ns);
+                let llvm_ty = bin.llvm_type(ty.deref_any());
                 // LLVMSizeOf() produces an i64
                 // LLVMSizeOf() produces an i64
                 let size = bin
                 let size = bin
                     .builder
                     .builder
@@ -680,8 +660,8 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                     .unwrap()
                     .unwrap()
                     .into_pointer_value();
                     .into_pointer_value();
 
 
-                for (i, field) in struct_ty.definition(ns).fields.iter().enumerate() {
-                    let field_offset = struct_ty.definition(ns).storage_offsets[i]
+                for (i, field) in struct_ty.definition(bin.ns).fields.iter().enumerate() {
+                    let field_offset = struct_ty.definition(bin.ns).storage_offsets[i]
                         .to_u64()
                         .to_u64()
                         .unwrap();
                         .unwrap();
 
 
@@ -694,7 +674,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                         )
                         )
                         .unwrap();
                         .unwrap();
 
 
-                    let val = self.storage_load(bin, &field.ty, &mut offset, function, ns, &None);
+                    let val = self.storage_load(bin, &field.ty, &mut offset, function, &None);
 
 
                     let elem = unsafe {
                     let elem = unsafe {
                         bin.builder
                         bin.builder
@@ -710,8 +690,8 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                             .unwrap()
                             .unwrap()
                     };
                     };
 
 
-                    let val = if field.ty.is_fixed_reference_type(ns) {
-                        let load_ty = bin.llvm_type(&field.ty, ns);
+                    let val = if field.ty.is_fixed_reference_type(bin.ns) {
+                        let load_ty = bin.llvm_type(&field.ty);
                         bin.builder
                         bin.builder
                             .build_load(load_ty, val.into_pointer_value(), "elem")
                             .build_load(load_ty, val.into_pointer_value(), "elem")
                             .unwrap()
                             .unwrap()
@@ -725,7 +705,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                 new.into()
                 new.into()
             }
             }
             ast::Type::Array(elem_ty, dim) => {
             ast::Type::Array(elem_ty, dim) => {
-                let llvm_ty = bin.llvm_type(ty.deref_any(), ns);
+                let llvm_ty = bin.llvm_type(ty.deref_any());
 
 
                 let dest;
                 let dest;
                 let length;
                 let length;
@@ -764,7 +744,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                         false,
                         false,
                     );
                     );
                 } else {
                 } else {
-                    let llvm_elem_ty = bin.llvm_field_ty(elem_ty, ns);
+                    let llvm_elem_ty = bin.llvm_field_ty(elem_ty);
                     let elem_size = bin
                     let elem_size = bin
                         .builder
                         .builder
                         .build_int_truncate(
                         .build_int_truncate(
@@ -774,7 +754,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                         )
                         )
                         .unwrap();
                         .unwrap();
 
 
-                    length = self.storage_array_length(bin, function, slot, elem_ty, ns);
+                    length = self.storage_array_length(bin, function, slot, elem_ty);
 
 
                     slot = bin
                     slot = bin
                         .builder
                         .builder
@@ -783,11 +763,11 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                         .into_int_value();
                         .into_int_value();
 
 
                     dest = bin
                     dest = bin
-                        .vector_new(length, elem_size, None, elem_ty, ns)
+                        .vector_new(length, elem_size, None, elem_ty)
                         .into_pointer_value();
                         .into_pointer_value();
                 };
                 };
 
 
-                let elem_size = elem_ty.solana_storage_size(ns).to_u64().unwrap();
+                let elem_size = elem_ty.solana_storage_size(bin.ns).to_u64().unwrap();
 
 
                 // loop over the array
                 // loop over the array
                 let mut builder = LoopBuilder::new(bin, function);
                 let mut builder = LoopBuilder::new(bin, function);
@@ -797,7 +777,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
 
 
                 let index = builder.over(bin, bin.context.i32_type().const_zero(), length);
                 let index = builder.over(bin, bin.context.i32_type().const_zero(), length);
 
 
-                let elem = bin.array_subscript(ty.deref_any(), dest, index, ns);
+                let elem = bin.array_subscript(ty.deref_any(), dest, index);
 
 
                 let elem_ty = ty.array_deref();
                 let elem_ty = ty.array_deref();
 
 
@@ -808,12 +788,11 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                     elem_ty.deref_memory(),
                     elem_ty.deref_memory(),
                     &mut offset_val,
                     &mut offset_val,
                     function,
                     function,
-                    ns,
                     &None,
                     &None,
                 );
                 );
 
 
-                let val = if elem_ty.deref_memory().is_fixed_reference_type(ns) {
-                    let load_ty = bin.llvm_type(elem_ty.deref_any(), ns);
+                let val = if elem_ty.deref_memory().is_fixed_reference_type(bin.ns) {
+                    let load_ty = bin.llvm_type(elem_ty.deref_any());
                     bin.builder
                     bin.builder
                         .build_load(load_ty, val.into_pointer_value(), "elem")
                         .build_load(load_ty, val.into_pointer_value(), "elem")
                         .unwrap()
                         .unwrap()
@@ -842,7 +821,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
             }
             }
             _ => bin
             _ => bin
                 .builder
                 .builder
-                .build_load(bin.llvm_var_ty(ty, ns), member, "")
+                .build_load(bin.llvm_var_ty(ty), member, "")
                 .unwrap(),
                 .unwrap(),
         }
         }
     }
     }
@@ -855,7 +834,6 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         offset: &mut IntValue<'a>,
         offset: &mut IntValue<'a>,
         val: BasicValueEnum<'a>,
         val: BasicValueEnum<'a>,
         function: FunctionValue<'a>,
         function: FunctionValue<'a>,
-        ns: &ast::Namespace,
         _: &Option<StorageType>,
         _: &Option<StorageType>,
     ) {
     ) {
         let data = self.contract_storage_data(bin);
         let data = self.contract_storage_data(bin);
@@ -1041,7 +1019,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         } else if let ast::Type::Array(elem_ty, dim) = ty {
         } else if let ast::Type::Array(elem_ty, dim) = ty {
             // make sure any pointers are freed
             // make sure any pointers are freed
             if existing {
             if existing {
-                self.storage_free(bin, ty, data, *offset, function, false, ns);
+                self.storage_free(bin, ty, data, *offset, function, false);
             }
             }
 
 
             let length = if let Some(ast::ArrayLength::Fixed(length)) = dim.last() {
             let length = if let Some(ast::ArrayLength::Fixed(length)) = dim.last() {
@@ -1059,7 +1037,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                 let member_size = bin
                 let member_size = bin
                     .context
                     .context
                     .i32_type()
                     .i32_type()
-                    .const_int(elem_ty.solana_storage_size(ns).to_u64().unwrap(), false);
+                    .const_int(elem_ty.solana_storage_size(bin.ns).to_u64().unwrap(), false);
                 let new_length = bin
                 let new_length = bin
                     .builder
                     .builder
                     .build_int_mul(length, member_size, "new_length")
                     .build_int_mul(length, member_size, "new_length")
@@ -1118,7 +1096,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                     .into_int_value();
                     .into_int_value();
             }
             }
 
 
-            let elem_size = elem_ty.solana_storage_size(ns).to_u64().unwrap();
+            let elem_size = elem_ty.solana_storage_size(bin.ns).to_u64().unwrap();
 
 
             // loop over the array
             // loop over the array
             let mut builder = LoopBuilder::new(bin, function);
             let mut builder = LoopBuilder::new(bin, function);
@@ -1129,7 +1107,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
 
 
             let index = builder.over(bin, bin.context.i32_type().const_zero(), length);
             let index = builder.over(bin, bin.context.i32_type().const_zero(), length);
 
 
-            let elem = bin.array_subscript(ty, val.into_pointer_value(), index, ns);
+            let elem = bin.array_subscript(ty, val.into_pointer_value(), index);
 
 
             let mut offset_val = offset_phi.into_int_value();
             let mut offset_val = offset_phi.into_int_value();
 
 
@@ -1140,20 +1118,19 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                 elem_ty.deref_any(),
                 elem_ty.deref_any(),
                 false, // storage already freed with storage_free
                 false, // storage already freed with storage_free
                 &mut offset_val,
                 &mut offset_val,
-                if elem_ty.deref_memory().is_fixed_reference_type(ns) {
+                if elem_ty.deref_memory().is_fixed_reference_type(bin.ns) {
                     elem.into()
                     elem.into()
                 } else {
                 } else {
-                    let load_ty = if elem_ty.is_dynamic(ns) {
-                        bin.llvm_type(elem_ty.deref_memory(), ns)
+                    let load_ty = if elem_ty.is_dynamic(bin.ns) {
+                        bin.llvm_type(elem_ty.deref_memory())
                             .ptr_type(AddressSpace::default())
                             .ptr_type(AddressSpace::default())
                             .as_basic_type_enum()
                             .as_basic_type_enum()
                     } else {
                     } else {
-                        bin.llvm_type(elem_ty.deref_memory(), ns)
+                        bin.llvm_type(elem_ty.deref_memory())
                     };
                     };
                     bin.builder.build_load(load_ty, elem, "array_elem").unwrap()
                     bin.builder.build_load(load_ty, elem, "array_elem").unwrap()
                 },
                 },
                 function,
                 function,
-                ns,
                 &None,
                 &None,
             );
             );
 
 
@@ -1172,8 +1149,8 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
             // done
             // done
             builder.finish(bin);
             builder.finish(bin);
         } else if let ast::Type::Struct(struct_ty) = ty {
         } else if let ast::Type::Struct(struct_ty) = ty {
-            for (i, field) in struct_ty.definition(ns).fields.iter().enumerate() {
-                let field_offset = struct_ty.definition(ns).storage_offsets[i]
+            for (i, field) in struct_ty.definition(bin.ns).fields.iter().enumerate() {
+                let field_offset = struct_ty.definition(bin.ns).storage_offsets[i]
                     .to_u64()
                     .to_u64()
                     .unwrap();
                     .unwrap();
 
 
@@ -1186,7 +1163,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                     )
                     )
                     .unwrap();
                     .unwrap();
 
 
-                let val_ty = bin.llvm_type(ty, ns);
+                let val_ty = bin.llvm_type(ty);
                 let elem = unsafe {
                 let elem = unsafe {
                     bin.builder
                     bin.builder
                         .build_gep(
                         .build_gep(
@@ -1203,7 +1180,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
 
 
                 // free any existing dynamic storage
                 // free any existing dynamic storage
                 if existing {
                 if existing {
-                    self.storage_free(bin, &field.ty, data, offset, function, false, ns);
+                    self.storage_free(bin, &field.ty, data, offset, function, false);
                 }
                 }
 
 
                 self.storage_store(
                 self.storage_store(
@@ -1211,22 +1188,21 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                     &field.ty,
                     &field.ty,
                     existing,
                     existing,
                     &mut offset,
                     &mut offset,
-                    if field.ty.is_fixed_reference_type(ns) {
+                    if field.ty.is_fixed_reference_type(bin.ns) {
                         elem.into()
                         elem.into()
                     } else {
                     } else {
-                        let load_ty = if field.ty.is_dynamic(ns) {
-                            bin.llvm_type(&field.ty, ns)
+                        let load_ty = if field.ty.is_dynamic(bin.ns) {
+                            bin.llvm_type(&field.ty)
                                 .ptr_type(AddressSpace::default())
                                 .ptr_type(AddressSpace::default())
                                 .as_basic_type_enum()
                                 .as_basic_type_enum()
                         } else {
                         } else {
-                            bin.llvm_type(&field.ty, ns)
+                            bin.llvm_type(&field.ty)
                         };
                         };
                         bin.builder
                         bin.builder
                             .build_load(load_ty, elem, field.name_as_str())
                             .build_load(load_ty, elem, field.name_as_str())
                             .unwrap()
                             .unwrap()
                     },
                     },
                     function,
                     function,
-                    ns,
                     &None,
                     &None,
                 );
                 );
             }
             }
@@ -1241,7 +1217,6 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         _src: PointerValue,
         _src: PointerValue,
         _length: IntValue,
         _length: IntValue,
         _dest: PointerValue,
         _dest: PointerValue,
-        _ns: &ast::Namespace,
     ) {
     ) {
         unreachable!();
         unreachable!();
     }
     }
@@ -1301,7 +1276,6 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         encoded_args: BasicValueEnum<'b>,
         encoded_args: BasicValueEnum<'b>,
         encoded_args_len: BasicValueEnum<'b>,
         encoded_args_len: BasicValueEnum<'b>,
         mut contract_args: ContractArgs<'b>,
         mut contract_args: ContractArgs<'b>,
-        ns: &ast::Namespace,
         _loc: Loc,
         _loc: Loc,
     ) {
     ) {
         contract_args.program_id = Some(address);
         contract_args.program_id = Some(address);
@@ -1311,7 +1285,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
 
 
         assert!(contract_args.accounts.is_some());
         assert!(contract_args.accounts.is_some());
         // The AccountMeta array is always present for Solana contracts
         // The AccountMeta array is always present for Solana contracts
-        self.build_invoke_signed_c(bin, function, payload, payload_len, contract_args, ns);
+        self.build_invoke_signed_c(bin, function, payload, payload_len, contract_args);
     }
     }
 
 
     fn builtin_function(
     fn builtin_function(
@@ -1321,7 +1295,6 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         builtin_func: &ast::Function,
         builtin_func: &ast::Function,
         args: &[BasicMetadataValueEnum<'a>],
         args: &[BasicMetadataValueEnum<'a>],
         first_arg_type: Option<BasicTypeEnum>,
         first_arg_type: Option<BasicTypeEnum>,
-        ns: &ast::Namespace,
     ) -> Option<BasicValueEnum<'a>> {
     ) -> Option<BasicValueEnum<'a>> {
         let first_arg_type =
         let first_arg_type =
             first_arg_type.expect("solana does not have builtin without any parameter");
             first_arg_type.expect("solana does not have builtin without any parameter");
@@ -1338,7 +1311,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                 .const_int(first_arg_type.into_array_type().len() as u64, false);
                 .const_int(first_arg_type.into_array_type().len() as u64, false);
 
 
             // address
             // address
-            let address = bin.build_alloca(function, bin.address_type(ns), "address");
+            let address = bin.build_alloca(function, bin.address_type(), "address");
 
 
             bin.builder
             bin.builder
                 .build_store(address, args[1].into_array_value())
                 .build_store(address, args[1].into_array_value())
@@ -1373,7 +1346,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                 .const_int(first_arg_type.into_array_type().len() as u64, false);
                 .const_int(first_arg_type.into_array_type().len() as u64, false);
 
 
             // address
             // address
-            let address = bin.build_alloca(function, bin.address_type(ns), "address");
+            let address = bin.build_alloca(function, bin.address_type(), "address");
 
 
             bin.builder
             bin.builder
                 .build_store(address, args[1].into_array_value())
                 .build_store(address, args[1].into_array_value())
@@ -1413,7 +1386,6 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         address: Option<BasicValueEnum<'b>>,
         address: Option<BasicValueEnum<'b>>,
         mut contract_args: ContractArgs<'b>,
         mut contract_args: ContractArgs<'b>,
         _ty: ast::CallTy,
         _ty: ast::CallTy,
-        ns: &ast::Namespace,
         _loc: Loc,
         _loc: Loc,
     ) {
     ) {
         let address = address.unwrap();
         let address = address.unwrap();
@@ -1429,7 +1401,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         };
         };
 
 
         contract_args.program_id = Some(address.into_pointer_value());
         contract_args.program_id = Some(address.into_pointer_value());
-        self.build_invoke_signed_c(bin, function, payload, payload_len, contract_args, ns);
+        self.build_invoke_signed_c(bin, function, payload, payload_len, contract_args);
     }
     }
 
 
     /// Get return buffer for external call
     /// Get return buffer for external call
@@ -1558,7 +1530,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
     }
     }
 
 
     /// Value received is not available on solana
     /// Value received is not available on solana
-    fn value_transferred<'b>(&self, _bin: &Binary<'b>, _ns: &ast::Namespace) -> IntValue<'b> {
+    fn value_transferred<'b>(&self, _binary: &Binary<'b>) -> IntValue<'b> {
         unreachable!();
         unreachable!();
     }
     }
 
 
@@ -1570,14 +1542,13 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         _success: Option<&mut BasicValueEnum<'b>>,
         _success: Option<&mut BasicValueEnum<'b>>,
         _address: PointerValue<'b>,
         _address: PointerValue<'b>,
         _value: IntValue<'b>,
         _value: IntValue<'b>,
-        _ns: &ast::Namespace,
         _loc: Loc,
         _loc: Loc,
     ) {
     ) {
         unreachable!();
         unreachable!();
     }
     }
 
 
     /// Terminate execution, destroy binary and send remaining funds to addr
     /// Terminate execution, destroy binary and send remaining funds to addr
-    fn selfdestruct<'b>(&self, _bin: &Binary<'b>, _addr: ArrayValue<'b>, _ns: &ast::Namespace) {
+    fn selfdestruct<'b>(&self, _binary: &Binary<'b>, _addr: ArrayValue<'b>) {
         unimplemented!();
         unimplemented!();
     }
     }
 
 
@@ -1655,7 +1626,6 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         expr: &codegen::Expression,
         expr: &codegen::Expression,
         vartab: &HashMap<usize, Variable<'b>>,
         vartab: &HashMap<usize, Variable<'b>>,
         function: FunctionValue<'b>,
         function: FunctionValue<'b>,
-        ns: &ast::Namespace,
     ) -> BasicValueEnum<'b> {
     ) -> BasicValueEnum<'b> {
         match expr {
         match expr {
             codegen::Expression::Builtin {
             codegen::Expression::Builtin {
@@ -1859,17 +1829,17 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
             } => {
             } => {
                 assert_eq!(args.len(), 3);
                 assert_eq!(args.len(), 3);
 
 
-                let address = bin.build_alloca(function, bin.address_type(ns), "address");
+                let address = bin.build_alloca(function, bin.address_type(), "address");
 
 
                 bin.builder
                 bin.builder
                     .build_store(
                     .build_store(
                         address,
                         address,
-                        expression(self, bin, &args[0], vartab, function, ns).into_array_value(),
+                        expression(self, bin, &args[0], vartab, function).into_array_value(),
                     )
                     )
                     .unwrap();
                     .unwrap();
 
 
-                let message = expression(self, bin, &args[1], vartab, function, ns);
-                let signature = expression(self, bin, &args[2], vartab, function, ns);
+                let message = expression(self, bin, &args[1], vartab, function);
+                let signature = expression(self, bin, &args[2], vartab, function);
                 let parameters = self.sol_parameters(bin);
                 let parameters = self.sol_parameters(bin);
                 let signature_verify = bin.module.get_function("signature_verify").unwrap();
                 let signature_verify = bin.module.get_function("signature_verify").unwrap();
 
 
@@ -1957,9 +1927,9 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
             }
             }
             codegen::Expression::StructMember { expr, member, .. } => {
             codegen::Expression::StructMember { expr, member, .. } => {
                 let account_info =
                 let account_info =
-                    expression(self, bin, expr, vartab, function, ns).into_pointer_value();
+                    expression(self, bin, expr, vartab, function).into_pointer_value();
 
 
-                self.account_info_member(bin, function, account_info, *member, ns)
+                self.account_info_member(bin, function, account_info, *member)
             }
             }
             _ => unimplemented!(),
             _ => unimplemented!(),
         }
         }
@@ -1973,7 +1943,6 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         hash: HashTy,
         hash: HashTy,
         input: PointerValue<'b>,
         input: PointerValue<'b>,
         input_len: IntValue<'b>,
         input_len: IntValue<'b>,
-        ns: &ast::Namespace,
     ) -> IntValue<'b> {
     ) -> IntValue<'b> {
         let (fname, hashlen) = match hash {
         let (fname, hashlen) = match hash {
             HashTy::Keccak256 => ("sol_keccak256", 32),
             HashTy::Keccak256 => ("sol_keccak256", 32),
@@ -2052,7 +2021,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         // bytes32 needs to reverse bytes
         // bytes32 needs to reverse bytes
         let temp = bin.build_alloca(
         let temp = bin.build_alloca(
             function,
             function,
-            bin.llvm_type(&ast::Type::Bytes(hashlen as u8), ns),
+            bin.llvm_type(&ast::Type::Bytes(hashlen as u8)),
             "hash",
             "hash",
         );
         );
 
 
@@ -2070,7 +2039,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
 
 
         bin.builder
         bin.builder
             .build_load(
             .build_load(
-                bin.llvm_type(&ast::Type::Bytes(hashlen as u8), ns),
+                bin.llvm_type(&ast::Type::Bytes(hashlen as u8)),
                 temp,
                 temp,
                 "hash",
                 "hash",
             )
             )

+ 3 - 12
src/emit/soroban/mod.rs

@@ -128,7 +128,7 @@ impl SorobanTarget {
         let filename = ns.files[contract.loc.file_no()].file_name();
         let filename = ns.files[contract.loc.file_no()].file_name();
         let mut bin = Binary::new(
         let mut bin = Binary::new(
             context,
             context,
-            ns.target,
+            ns,
             &contract.id.name,
             &contract.id.name,
             &filename,
             &filename,
             opt,
             opt,
@@ -138,14 +138,7 @@ impl SorobanTarget {
 
 
         let mut export_list = Vec::new();
         let mut export_list = Vec::new();
         Self::declare_externals(&mut bin);
         Self::declare_externals(&mut bin);
-        Self::emit_functions_with_spec(
-            contract,
-            &mut bin,
-            ns,
-            context,
-            contract_no,
-            &mut export_list,
-        );
+        Self::emit_functions_with_spec(contract, &mut bin, context, contract_no, &mut export_list);
         bin.internalize(export_list.as_slice());
         bin.internalize(export_list.as_slice());
 
 
         Self::emit_initializer(&mut bin, ns);
         Self::emit_initializer(&mut bin, ns);
@@ -160,7 +153,6 @@ impl SorobanTarget {
     fn emit_functions_with_spec<'a>(
     fn emit_functions_with_spec<'a>(
         contract: &'a ast::Contract,
         contract: &'a ast::Contract,
         bin: &mut Binary<'a>,
         bin: &mut Binary<'a>,
-        ns: &'a ast::Namespace,
         context: &'a Context,
         context: &'a Context,
         _contract_no: usize,
         _contract_no: usize,
         export_list: &mut Vec<&'a str>,
         export_list: &mut Vec<&'a str>,
@@ -171,7 +163,6 @@ impl SorobanTarget {
             let ftype = bin.function_type(
             let ftype = bin.function_type(
                 &cfg.params.iter().map(|p| p.ty.clone()).collect::<Vec<_>>(),
                 &cfg.params.iter().map(|p| p.ty.clone()).collect::<Vec<_>>(),
                 &cfg.returns.iter().map(|p| p.ty.clone()).collect::<Vec<_>>(),
                 &cfg.returns.iter().map(|p| p.ty.clone()).collect::<Vec<_>>(),
-                ns,
             );
             );
 
 
             // For each function, determine the name and the linkage
             // For each function, determine the name and the linkage
@@ -213,7 +204,7 @@ impl SorobanTarget {
             .add_function("storage_initializer", init_type, None);
             .add_function("storage_initializer", init_type, None);
 
 
         for (func_decl, cfg) in defines {
         for (func_decl, cfg) in defines {
-            emit_cfg(&mut SorobanTarget, bin, contract, cfg, func_decl, ns);
+            emit_cfg(&mut SorobanTarget, bin, contract, cfg, func_decl);
         }
         }
     }
     }
 
 

+ 3 - 20
src/emit/soroban/target.rs

@@ -10,7 +10,7 @@ use crate::emit::{TargetRuntime, Variable};
 use crate::emit_context;
 use crate::emit_context;
 use crate::sema::ast;
 use crate::sema::ast;
 use crate::sema::ast::CallTy;
 use crate::sema::ast::CallTy;
-use crate::sema::ast::{Function, Namespace, Type};
+use crate::sema::ast::{Function, Type};
 
 
 use inkwell::types::{BasicTypeEnum, IntType};
 use inkwell::types::{BasicTypeEnum, IntType};
 use inkwell::values::{
 use inkwell::values::{
@@ -43,7 +43,6 @@ impl<'a> TargetRuntime<'a> for SorobanTarget {
         ty: &ast::Type,
         ty: &ast::Type,
         slot: &mut IntValue<'a>,
         slot: &mut IntValue<'a>,
         function: FunctionValue<'a>,
         function: FunctionValue<'a>,
-        ns: &ast::Namespace,
         storage_type: &Option<StorageType>,
         storage_type: &Option<StorageType>,
     ) -> BasicValueEnum<'a> {
     ) -> BasicValueEnum<'a> {
         let storage_type = storage_type_to_int(storage_type);
         let storage_type = storage_type_to_int(storage_type);
@@ -75,7 +74,6 @@ impl<'a> TargetRuntime<'a> for SorobanTarget {
         slot: &mut IntValue<'a>,
         slot: &mut IntValue<'a>,
         dest: BasicValueEnum<'a>,
         dest: BasicValueEnum<'a>,
         function: FunctionValue<'a>,
         function: FunctionValue<'a>,
-        ns: &ast::Namespace,
         storage_type: &Option<StorageType>,
         storage_type: &Option<StorageType>,
     ) {
     ) {
         emit_context!(bin);
         emit_context!(bin);
@@ -115,7 +113,6 @@ impl<'a> TargetRuntime<'a> for SorobanTarget {
         ty: &Type,
         ty: &Type,
         slot: &mut IntValue<'a>,
         slot: &mut IntValue<'a>,
         function: FunctionValue<'a>,
         function: FunctionValue<'a>,
-        ns: &Namespace,
     ) {
     ) {
         unimplemented!()
         unimplemented!()
     }
     }
@@ -156,7 +153,6 @@ impl<'a> TargetRuntime<'a> for SorobanTarget {
         bin: &Binary<'a>,
         bin: &Binary<'a>,
         function: FunctionValue,
         function: FunctionValue,
         slot: PointerValue<'a>,
         slot: PointerValue<'a>,
-        ns: &Namespace,
     ) -> PointerValue<'a> {
     ) -> PointerValue<'a> {
         unimplemented!()
         unimplemented!()
     }
     }
@@ -168,7 +164,6 @@ impl<'a> TargetRuntime<'a> for SorobanTarget {
         slot: IntValue<'a>,
         slot: IntValue<'a>,
         index: IntValue<'a>,
         index: IntValue<'a>,
         loc: Loc,
         loc: Loc,
-        ns: &Namespace,
     ) -> IntValue<'a> {
     ) -> IntValue<'a> {
         unimplemented!()
         unimplemented!()
     }
     }
@@ -180,7 +175,6 @@ impl<'a> TargetRuntime<'a> for SorobanTarget {
         slot: IntValue<'a>,
         slot: IntValue<'a>,
         index: IntValue<'a>,
         index: IntValue<'a>,
         value: IntValue<'a>,
         value: IntValue<'a>,
-        ns: &Namespace,
         loc: Loc,
         loc: Loc,
     ) {
     ) {
         unimplemented!()
         unimplemented!()
@@ -193,7 +187,6 @@ impl<'a> TargetRuntime<'a> for SorobanTarget {
         ty: &Type,
         ty: &Type,
         slot: IntValue<'a>,
         slot: IntValue<'a>,
         index: BasicValueEnum<'a>,
         index: BasicValueEnum<'a>,
-        ns: &Namespace,
     ) -> IntValue<'a> {
     ) -> IntValue<'a> {
         unimplemented!()
         unimplemented!()
     }
     }
@@ -205,7 +198,6 @@ impl<'a> TargetRuntime<'a> for SorobanTarget {
         ty: &Type,
         ty: &Type,
         slot: IntValue<'a>,
         slot: IntValue<'a>,
         val: Option<BasicValueEnum<'a>>,
         val: Option<BasicValueEnum<'a>>,
-        ns: &Namespace,
     ) -> BasicValueEnum<'a> {
     ) -> BasicValueEnum<'a> {
         unimplemented!()
         unimplemented!()
     }
     }
@@ -217,7 +209,6 @@ impl<'a> TargetRuntime<'a> for SorobanTarget {
         ty: &Type,
         ty: &Type,
         slot: IntValue<'a>,
         slot: IntValue<'a>,
         load: bool,
         load: bool,
-        ns: &Namespace,
         loc: Loc,
         loc: Loc,
     ) -> Option<BasicValueEnum<'a>> {
     ) -> Option<BasicValueEnum<'a>> {
         unimplemented!()
         unimplemented!()
@@ -229,7 +220,6 @@ impl<'a> TargetRuntime<'a> for SorobanTarget {
         _function: FunctionValue,
         _function: FunctionValue,
         _slot: IntValue<'a>,
         _slot: IntValue<'a>,
         _elem_ty: &Type,
         _elem_ty: &Type,
-        _ns: &Namespace,
     ) -> IntValue<'a> {
     ) -> IntValue<'a> {
         unimplemented!()
         unimplemented!()
     }
     }
@@ -241,7 +231,6 @@ impl<'a> TargetRuntime<'a> for SorobanTarget {
         src: PointerValue,
         src: PointerValue,
         length: IntValue,
         length: IntValue,
         dest: PointerValue,
         dest: PointerValue,
-        ns: &Namespace,
     ) {
     ) {
         unimplemented!()
         unimplemented!()
     }
     }
@@ -300,7 +289,6 @@ impl<'a> TargetRuntime<'a> for SorobanTarget {
         builtin_func: &Function,
         builtin_func: &Function,
         args: &[BasicMetadataValueEnum<'a>],
         args: &[BasicMetadataValueEnum<'a>],
         first_arg_type: Option<BasicTypeEnum>,
         first_arg_type: Option<BasicTypeEnum>,
-        ns: &Namespace,
     ) -> Option<BasicValueEnum<'a>> {
     ) -> Option<BasicValueEnum<'a>> {
         unimplemented!()
         unimplemented!()
     }
     }
@@ -316,7 +304,6 @@ impl<'a> TargetRuntime<'a> for SorobanTarget {
         encoded_args: BasicValueEnum<'b>,
         encoded_args: BasicValueEnum<'b>,
         encoded_args_len: BasicValueEnum<'b>,
         encoded_args_len: BasicValueEnum<'b>,
         contract_args: ContractArgs<'b>,
         contract_args: ContractArgs<'b>,
-        ns: &Namespace,
         loc: Loc,
         loc: Loc,
     ) {
     ) {
         unimplemented!()
         unimplemented!()
@@ -333,7 +320,6 @@ impl<'a> TargetRuntime<'a> for SorobanTarget {
         address: Option<BasicValueEnum<'b>>,
         address: Option<BasicValueEnum<'b>>,
         contract_args: ContractArgs<'b>,
         contract_args: ContractArgs<'b>,
         ty: CallTy,
         ty: CallTy,
-        ns: &Namespace,
         loc: Loc,
         loc: Loc,
     ) {
     ) {
         let offset = bin.context.i64_type().const_int(0, false);
         let offset = bin.context.i64_type().const_int(0, false);
@@ -440,7 +426,6 @@ impl<'a> TargetRuntime<'a> for SorobanTarget {
         _success: Option<&mut BasicValueEnum<'b>>,
         _success: Option<&mut BasicValueEnum<'b>>,
         _address: PointerValue<'b>,
         _address: PointerValue<'b>,
         _value: IntValue<'b>,
         _value: IntValue<'b>,
-        _ns: &Namespace,
         loc: Loc,
         loc: Loc,
     ) {
     ) {
         unimplemented!()
         unimplemented!()
@@ -453,7 +438,6 @@ impl<'a> TargetRuntime<'a> for SorobanTarget {
         expr: &Expression,
         expr: &Expression,
         vartab: &HashMap<usize, Variable<'b>>,
         vartab: &HashMap<usize, Variable<'b>>,
         function: FunctionValue<'b>,
         function: FunctionValue<'b>,
-        ns: &Namespace,
     ) -> BasicValueEnum<'b> {
     ) -> BasicValueEnum<'b> {
         emit_context!(bin);
         emit_context!(bin);
 
 
@@ -610,12 +594,12 @@ impl<'a> TargetRuntime<'a> for SorobanTarget {
     }
     }
 
 
     /// Return the value we received
     /// Return the value we received
-    fn value_transferred<'b>(&self, bin: &Binary<'b>, ns: &Namespace) -> IntValue<'b> {
+    fn value_transferred<'b>(&self, bin: &Binary<'b>) -> IntValue<'b> {
         unimplemented!()
         unimplemented!()
     }
     }
 
 
     /// Terminate execution, destroy bin and send remaining funds to addr
     /// Terminate execution, destroy bin and send remaining funds to addr
-    fn selfdestruct<'b>(&self, bin: &Binary<'b>, addr: ArrayValue<'b>, ns: &Namespace) {
+    fn selfdestruct<'b>(&self, bin: &Binary<'b>, addr: ArrayValue<'b>) {
         unimplemented!()
         unimplemented!()
     }
     }
 
 
@@ -627,7 +611,6 @@ impl<'a> TargetRuntime<'a> for SorobanTarget {
         hash: HashTy,
         hash: HashTy,
         string: PointerValue<'b>,
         string: PointerValue<'b>,
         length: IntValue<'b>,
         length: IntValue<'b>,
-        ns: &Namespace,
     ) -> IntValue<'b> {
     ) -> IntValue<'b> {
         unimplemented!()
         unimplemented!()
     }
     }

+ 2 - 10
src/emit/storage.rs

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: Apache-2.0
 // SPDX-License-Identifier: Apache-2.0
 
 
 use crate::emit::binary::Binary;
 use crate::emit::binary::Binary;
-use crate::sema::ast::{Namespace, Type};
+use crate::sema::ast::Type;
 use inkwell::types::BasicTypeEnum;
 use inkwell::types::BasicTypeEnum;
 use inkwell::values::{ArrayValue, BasicValueEnum, FunctionValue, IntValue, PointerValue};
 use inkwell::values::{ArrayValue, BasicValueEnum, FunctionValue, IntValue, PointerValue};
 
 
@@ -15,12 +15,7 @@ pub(super) trait StorageSlot {
         dest_ty: BasicTypeEnum,
         dest_ty: BasicTypeEnum,
     );
     );
 
 
-    fn get_storage_address<'a>(
-        &self,
-        bin: &Binary<'a>,
-        slot: PointerValue<'a>,
-        ns: &Namespace,
-    ) -> ArrayValue<'a>;
+    fn get_storage_address<'a>(&self, bin: &Binary<'a>, slot: PointerValue<'a>) -> ArrayValue<'a>;
 
 
     /// Clear a particlar storage slot (slot-based storage chains should implement)
     /// Clear a particlar storage slot (slot-based storage chains should implement)
     fn storage_delete_single_slot(&self, bin: &Binary, slot: PointerValue);
     fn storage_delete_single_slot(&self, bin: &Binary, slot: PointerValue);
@@ -33,7 +28,6 @@ pub(super) trait StorageSlot {
         slot: &mut IntValue<'a>,
         slot: &mut IntValue<'a>,
         slot_ptr: PointerValue<'a>,
         slot_ptr: PointerValue<'a>,
         function: FunctionValue,
         function: FunctionValue,
-        ns: &Namespace,
     ) -> BasicValueEnum<'a>;
     ) -> BasicValueEnum<'a>;
 
 
     /// Recursively store a type to storage for slot-based storage
     /// Recursively store a type to storage for slot-based storage
@@ -45,7 +39,6 @@ pub(super) trait StorageSlot {
         slot_ptr: PointerValue<'a>,
         slot_ptr: PointerValue<'a>,
         dest: BasicValueEnum<'a>,
         dest: BasicValueEnum<'a>,
         function: FunctionValue<'a>,
         function: FunctionValue<'a>,
-        ns: &Namespace,
     );
     );
 
 
     /// Recursively clear bin storage for slot-based storage
     /// Recursively clear bin storage for slot-based storage
@@ -56,6 +49,5 @@ pub(super) trait StorageSlot {
         slot: &mut IntValue<'a>,
         slot: &mut IntValue<'a>,
         slot_ptr: PointerValue<'a>,
         slot_ptr: PointerValue<'a>,
         function: FunctionValue<'a>,
         function: FunctionValue<'a>,
-        ns: &Namespace,
     );
     );
 }
 }

+ 19 - 21
src/emit/strings.rs

@@ -4,7 +4,7 @@ use crate::codegen::Expression;
 use crate::emit::binary::Binary;
 use crate::emit::binary::Binary;
 use crate::emit::expression::expression;
 use crate::emit::expression::expression;
 use crate::emit::{TargetRuntime, Variable};
 use crate::emit::{TargetRuntime, Variable};
-use crate::sema::ast::{FormatArg, Namespace, RetrieveType, StringLocation, Type};
+use crate::sema::ast::{FormatArg, RetrieveType, StringLocation, Type};
 use crate::Target;
 use crate::Target;
 use inkwell::values::{BasicValueEnum, FunctionValue, IntValue, PointerValue};
 use inkwell::values::{BasicValueEnum, FunctionValue, IntValue, PointerValue};
 use inkwell::IntPredicate;
 use inkwell::IntPredicate;
@@ -17,7 +17,6 @@ pub(super) fn format_string<'a, T: TargetRuntime<'a> + ?Sized>(
     args: &[(FormatArg, Expression)],
     args: &[(FormatArg, Expression)],
     vartab: &HashMap<usize, Variable<'a>>,
     vartab: &HashMap<usize, Variable<'a>>,
     function: FunctionValue<'a>,
     function: FunctionValue<'a>,
-    ns: &Namespace,
 ) -> BasicValueEnum<'a> {
 ) -> BasicValueEnum<'a> {
     // first we need to calculate the space we need
     // first we need to calculate the space we need
     let mut length = bin.context.i32_type().const_zero();
     let mut length = bin.context.i32_type().const_zero();
@@ -39,23 +38,23 @@ pub(super) fn format_string<'a, T: TargetRuntime<'a> + ?Sized>(
                 Type::Bool => bin.context.i32_type().const_int(5, false),
                 Type::Bool => bin.context.i32_type().const_int(5, false),
                 // hex encode bytes
                 // hex encode bytes
                 Type::Contract(_) | Type::Address(_) => {
                 Type::Contract(_) | Type::Address(_) => {
-                    let len = if ns.target == Target::Solana && *spec != FormatArg::Hex {
-                        base58_size(ns.address_length)
+                    let len = if bin.ns.target == Target::Solana && *spec != FormatArg::Hex {
+                        base58_size(bin.ns.address_length)
                     } else {
                     } else {
-                        2 * ns.address_length
+                        2 * bin.ns.address_length
                     };
                     };
                     bin.context.i32_type().const_int(len as u64, false)
                     bin.context.i32_type().const_int(len as u64, false)
                 }
                 }
                 Type::Bytes(size) => bin.context.i32_type().const_int(size as u64 * 2, false),
                 Type::Bytes(size) => bin.context.i32_type().const_int(size as u64 * 2, false),
                 Type::String => {
                 Type::String => {
-                    let val = expression(target, bin, arg, vartab, function, ns);
+                    let val = expression(target, bin, arg, vartab, function);
 
 
                     evaluated_arg[i] = Some(val);
                     evaluated_arg[i] = Some(val);
 
 
                     bin.vector_len(val)
                     bin.vector_len(val)
                 }
                 }
                 Type::DynamicBytes => {
                 Type::DynamicBytes => {
-                    let val = expression(target, bin, arg, vartab, function, ns);
+                    let val = expression(target, bin, arg, vartab, function);
 
 
                     evaluated_arg[i] = Some(val);
                     evaluated_arg[i] = Some(val);
 
 
@@ -86,7 +85,7 @@ pub(super) fn format_string<'a, T: TargetRuntime<'a> + ?Sized>(
                 Type::Enum(enum_no) => bin
                 Type::Enum(enum_no) => bin
                     .context
                     .context
                     .i32_type()
                     .i32_type()
-                    .const_int(ns.enums[enum_no].ty.bits(ns) as u64 / 3, false),
+                    .const_int(bin.ns.enums[enum_no].ty.bits(bin.ns) as u64 / 3, false),
                 _ => unimplemented!("can't format this argument: {:?}", arg),
                 _ => unimplemented!("can't format this argument: {:?}", arg),
             }
             }
         };
         };
@@ -101,7 +100,6 @@ pub(super) fn format_string<'a, T: TargetRuntime<'a> + ?Sized>(
             bin.context.i32_type().const_int(1, false),
             bin.context.i32_type().const_int(1, false),
             None,
             None,
             &Type::String,
             &Type::String,
-            ns,
         )
         )
         .into_pointer_value();
         .into_pointer_value();
 
 
@@ -132,8 +130,8 @@ pub(super) fn format_string<'a, T: TargetRuntime<'a> + ?Sized>(
                 };
                 };
             }
             }
         } else {
         } else {
-            let val = evaluated_arg[i]
-                .unwrap_or_else(|| expression(target, bin, arg, vartab, function, ns));
+            let val =
+                evaluated_arg[i].unwrap_or_else(|| expression(target, bin, arg, vartab, function));
             let arg_ty = arg.ty();
             let arg_ty = arg.ty();
 
 
             match arg_ty {
             match arg_ty {
@@ -213,7 +211,7 @@ pub(super) fn format_string<'a, T: TargetRuntime<'a> + ?Sized>(
                 }
                 }
                 Type::Address(_) | Type::Contract(_) => {
                 Type::Address(_) | Type::Contract(_) => {
                     // FIXME: For Polkadot we should encode in the SS58 format
                     // FIXME: For Polkadot we should encode in the SS58 format
-                    let buf = bin.build_alloca(function, bin.address_type(ns), "address");
+                    let buf = bin.build_alloca(function, bin.address_type(), "address");
                     bin.builder
                     bin.builder
                         .build_store(buf, val.into_array_value())
                         .build_store(buf, val.into_array_value())
                         .unwrap();
                         .unwrap();
@@ -221,10 +219,11 @@ pub(super) fn format_string<'a, T: TargetRuntime<'a> + ?Sized>(
                     let len = bin
                     let len = bin
                         .context
                         .context
                         .i32_type()
                         .i32_type()
-                        .const_int(ns.address_length as u64, false);
+                        .const_int(bin.ns.address_length as u64, false);
 
 
-                    let written_len = if ns.target == Target::Solana && *spec != FormatArg::Hex {
-                        let calculated_len = base58_size(ns.address_length);
+                    let written_len = if bin.ns.target == Target::Solana && *spec != FormatArg::Hex
+                    {
+                        let calculated_len = base58_size(bin.ns.address_length);
                         let base58_len = bin
                         let base58_len = bin
                             .context
                             .context
                             .i32_type()
                             .i32_type()
@@ -250,7 +249,7 @@ pub(super) fn format_string<'a, T: TargetRuntime<'a> + ?Sized>(
 
 
                         bin.context
                         bin.context
                             .i32_type()
                             .i32_type()
-                            .const_int(2 * ns.address_length as u64, false)
+                            .const_int(2 * bin.ns.address_length as u64, false)
                     };
                     };
 
 
                     output = unsafe {
                     output = unsafe {
@@ -260,7 +259,7 @@ pub(super) fn format_string<'a, T: TargetRuntime<'a> + ?Sized>(
                     };
                     };
                 }
                 }
                 Type::Bytes(size) => {
                 Type::Bytes(size) => {
-                    let buf = bin.build_alloca(function, bin.llvm_type(&arg_ty, ns), "bytesN");
+                    let buf = bin.build_alloca(function, bin.llvm_type(&arg_ty), "bytesN");
 
 
                     bin.builder.build_store(buf, val.into_int_value()).unwrap();
                     bin.builder.build_store(buf, val.into_int_value()).unwrap();
 
 
@@ -390,7 +389,7 @@ pub(super) fn format_string<'a, T: TargetRuntime<'a> + ?Sized>(
                             .unwrap()
                             .unwrap()
                             .into_pointer_value();
                             .into_pointer_value();
                     } else {
                     } else {
-                        let buf = bin.build_alloca(function, bin.llvm_type(&arg_ty, ns), "uint");
+                        let buf = bin.build_alloca(function, bin.llvm_type(&arg_ty), "uint");
 
 
                         bin.builder.build_store(buf, val.into_int_value()).unwrap();
                         bin.builder.build_store(buf, val.into_int_value()).unwrap();
 
 
@@ -553,7 +552,7 @@ pub(super) fn format_string<'a, T: TargetRuntime<'a> + ?Sized>(
                             .unwrap()
                             .unwrap()
                             .into_pointer_value();
                             .into_pointer_value();
                     } else {
                     } else {
-                        let buf = bin.build_alloca(function, bin.llvm_type(&arg_ty, ns), "int");
+                        let buf = bin.build_alloca(function, bin.llvm_type(&arg_ty), "int");
 
 
                         bin.builder
                         bin.builder
                             .build_store(buf, val_phi.as_basic_value().into_int_value())
                             .build_store(buf, val_phi.as_basic_value().into_int_value())
@@ -628,7 +627,6 @@ pub(super) fn string_location<'a, T: TargetRuntime<'a> + ?Sized>(
     location: &StringLocation<Expression>,
     location: &StringLocation<Expression>,
     vartab: &HashMap<usize, Variable<'a>>,
     vartab: &HashMap<usize, Variable<'a>>,
     function: FunctionValue<'a>,
     function: FunctionValue<'a>,
-    ns: &Namespace,
 ) -> (PointerValue<'a>, IntValue<'a>) {
 ) -> (PointerValue<'a>, IntValue<'a>) {
     match location {
     match location {
         StringLocation::CompileTime(literal) => (
         StringLocation::CompileTime(literal) => (
@@ -644,7 +642,7 @@ pub(super) fn string_location<'a, T: TargetRuntime<'a> + ?Sized>(
                     bin.context.i32_type().const_int(value.len() as u64, false),
                     bin.context.i32_type().const_int(value.len() as u64, false),
                 )
                 )
             } else {
             } else {
-                let v = expression(target, bin, e, vartab, function, ns);
+                let v = expression(target, bin, e, vartab, function);
 
 
                 (bin.vector_bytes(v), bin.vector_len(v))
                 (bin.vector_bytes(v), bin.vector_len(v))
             }
             }

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません