Quellcode durchsuchen

Fix VariableDefinition Display impl (#1252) (#1254)

Signed-off-by: Lucas Steuernagel <lucas.tnagel@gmail.com>
Lucas Steuernagel vor 2 Jahren
Ursprung
Commit
77d78369fa
5 geänderte Dateien mit 54 neuen und 61 gelöschten Zeilen
  1. 3 0
      integration/solana/.gitignore
  2. 21 8
      src/emit/solana/target.rs
  3. BIN
      stdlib/bpf/bigint.bc
  4. BIN
      stdlib/bpf/solana.bc
  5. 30 53
      stdlib/solana.c

+ 3 - 0
integration/solana/.gitignore

@@ -1,5 +1,8 @@
 *.js
 *.so
 *.key
+*.json
+!tsconfig.json
+!package.json
 node_modules
 package-lock.json

+ 21 - 8
src/emit/solana/target.rs

@@ -8,7 +8,7 @@ use crate::emit::expression::{expression, string_to_basic_value};
 use crate::emit::loop_builder::LoopBuilder;
 use crate::emit::solana::SolanaTarget;
 use crate::emit::{ContractArgs, TargetRuntime, Variable};
-use crate::sema::ast::{self, Namespace};
+use crate::sema::ast::{self, Namespace, Type};
 use inkwell::types::{BasicType, BasicTypeEnum, IntType};
 use inkwell::values::{
     ArrayValue, BasicMetadataValueEnum, BasicValueEnum, FunctionValue, IntValue, PointerValue,
@@ -1264,23 +1264,23 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
 
         let sol_params = function.get_last_param().unwrap().into_pointer_value();
 
-        let create_contract = binary.module.get_function("create_contract").unwrap();
+        let external_call_func = binary.module.get_function("external_call").unwrap();
 
         let (signer_seeds, signer_seeds_len) = if let Some((seeds, len)) = contract_args.seeds {
             (
                 seeds,
                 binary.builder.build_int_cast(
                     len,
-                    create_contract.get_type().get_param_types()[5].into_int_type(),
+                    external_call_func.get_type().get_param_types()[5].into_int_type(),
                     "len",
                 ),
             )
         } else {
             (
-                create_contract.get_type().get_param_types()[4]
+                external_call_func.get_type().get_param_types()[4]
                     .const_zero()
                     .into_pointer_value(),
-                create_contract.get_type().get_param_types()[5]
+                external_call_func.get_type().get_param_types()[5]
                     .const_zero()
                     .into_int_value(),
             )
@@ -1289,7 +1289,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         let ret = binary
             .builder
             .build_call(
-                create_contract,
+                external_call_func,
                 &[
                     binary.vector_bytes(encoded_args).into(),
                     encoded_args_len.into(),
@@ -1431,7 +1431,7 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         address: Option<PointerValue<'b>>,
         contract_args: ContractArgs<'b>,
         _ty: ast::CallTy,
-        _ns: &ast::Namespace,
+        ns: &ast::Namespace,
         _loc: Loc,
     ) {
         let address = address.unwrap();
@@ -1582,9 +1582,22 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                 .build_call(
                     external_call,
                     &[
-                        address.into(),
                         payload.into(),
                         payload_len.into(),
+                        address.into(),
+                        binary
+                            .llvm_type(&Type::Address(false), ns)
+                            .ptr_type(AddressSpace::default())
+                            .const_null()
+                            .into(),
+                        external_call.get_type().get_param_types()[4]
+                            .ptr_type(AddressSpace::default())
+                            .const_null()
+                            .into(),
+                        external_call.get_type().get_param_types()[5]
+                            .into_int_type()
+                            .const_zero()
+                            .into(),
                         parameters.into(),
                     ],
                     "",

BIN
stdlib/bpf/bigint.bc


BIN
stdlib/bpf/solana.bc


+ 30 - 53
stdlib/solana.c

@@ -55,11 +55,16 @@ uint64_t sol_invoke_signed_c(
     const SolSignerSeeds *signers_seeds,
     int signers_seeds_len);
 
-uint64_t external_call(const SolPubkey *address, uint8_t *input, uint32_t input_len, SolParameters *params)
+
+// Calls an external function when 'program_id' is NULL or
+// creates a new contract and calls its constructor.
+uint64_t external_call(uint8_t *input, uint32_t input_len, SolPubkey *address,
+                         SolPubkey *program_id, const SolSignerSeeds *seeds,
+                         int seeds_len, SolParameters *params)
 {
     SolAccountMeta metas[10];
     SolInstruction instruction = {
-        .program_id = NULL,
+        .program_id = program_id,
         .accounts = metas,
         .account_len = params->ka_num,
         .data = input,
@@ -67,21 +72,23 @@ uint64_t external_call(const SolPubkey *address, uint8_t *input, uint32_t input_
     };
 
     int meta_no = 1;
+    int new_address_idx = -1;
 
     for (int account_no = 0; account_no < params->ka_num; account_no++)
     {
-        const SolAccountInfo *acc = &params->ka[account_no];
+        SolAccountInfo *acc = &params->ka[account_no];
 
-        if (SolPubkey_same(address, acc->key))
+        // The address for the new contract should go first. Note that there
+        // may be duplicate entries, the order of those does not matter.
+        if (new_address_idx < 0 && SolPubkey_same(address, acc->key))
         {
             metas[0].pubkey = acc->key;
             metas[0].is_writable = acc->is_writable;
             metas[0].is_signer = acc->is_signer;
-            instruction.program_id = acc->owner;
+            new_address_idx = account_no;
         }
         else
         {
-
             metas[meta_no].pubkey = acc->key;
             metas[meta_no].is_writable = acc->is_writable;
             metas[meta_no].is_signer = acc->is_signer;
@@ -89,63 +96,33 @@ uint64_t external_call(const SolPubkey *address, uint8_t *input, uint32_t input_
         }
     }
 
-    if (instruction.program_id)
-    {
-        return sol_invoke_signed_c(&instruction, params->ka, params->ka_num, NULL, 0);
-    }
-    else
+    // If the program_id is null, we are dealing with an external call
+    if (!program_id)
     {
-        sol_log("call to account not in transaction");
+        if (new_address_idx < 0)
+        {
+            sol_log("call to account not in transaction");
 
-        return ERROR_INVALID_ACCOUNT_DATA;
+            return ERROR_INVALID_ACCOUNT_DATA;
+        }
+        else
+        {
+            instruction.program_id = params->ka[new_address_idx].owner;
+            return sol_invoke_signed_c(&instruction, params->ka, params->ka_num, NULL, 0);
+        }
     }
-}
-
-// This function creates a new address and calls its constructor.
-uint64_t create_contract(uint8_t *input, uint32_t input_len, SolPubkey *address,
-                         SolPubkey *program_id, const SolSignerSeeds *seeds,
-                         int seeds_len, SolParameters *params)
-{
-    SolAccountMeta metas[10];
-    const SolInstruction instruction = {
-        .program_id = program_id,
-        .accounts = metas,
-        .account_len = params->ka_num,
-        .data = input,
-        .data_len = input_len,
-    };
-
-    int meta_no = 1;
-    bool seen_new_address = false;
-
-    for (int account_no = 0; account_no < params->ka_num; account_no++)
+    else
     {
-        SolAccountInfo *acc = &params->ka[account_no];
-
-        // The address for the new contract should go first. Note that there
-        // may be duplicate entries, the order of those does not matter.
-        if (!seen_new_address && SolPubkey_same(address, acc->key))
+        // This is a constructor call
+        if (new_address_idx < 0)
         {
-            metas[0].pubkey = acc->key;
-            metas[0].is_writable = acc->is_writable;
-            metas[0].is_signer = acc->is_signer;
-            seen_new_address = true;
+            return ERROR_NEW_ACCOUNT_NEEDED;
         }
         else
         {
-            metas[meta_no].pubkey = acc->key;
-            metas[meta_no].is_writable = acc->is_writable;
-            metas[meta_no].is_signer = acc->is_signer;
-            meta_no += 1;
+            return sol_invoke_signed_c(&instruction, params->ka, params->ka_num, seeds, seeds_len);
         }
     }
-
-    if (!seen_new_address)
-    {
-        return ERROR_NEW_ACCOUNT_NEEDED;
-    }
-
-    return sol_invoke_signed_c(&instruction, params->ka, params->ka_num, seeds, seeds_len);
 }
 
 uint64_t *sol_account_lamport(