Browse Source

Compare the full 64 bits address on Solana (#1295)

* Use newer llvm build with sbf
* Compare the full 64 bits address on Solana

vector_new() takes an initializer arguments, which has as special value
for "no initializer". We should check the full 64 bits, rather than
casting the lower 32 bits to int.

Signed-off-by: Sean Young <sean@mess.org>
Sean Young 2 years ago
parent
commit
48571b19d6

+ 7 - 7
.github/workflows/release.yml

@@ -9,7 +9,7 @@ jobs:
   linux-x86-64:
     name: Linux x86-64
     runs-on: solang-ubuntu-latest
-    container: ghcr.io/hyperledger/solang-llvm:ci
+    container: ghcr.io/hyperledger/solang-llvm:ci-2
     steps:
     - name: Checkout sources
       uses: actions/checkout@v3.1.0
@@ -33,7 +33,7 @@ jobs:
     name: Linux arm64
     runs-on: linux-arm64
     if: ${{ github.repository_owner == 'hyperledger' }}
-    container: ghcr.io/hyperledger/solang-llvm:ci
+    container: ghcr.io/hyperledger/solang-llvm:ci-2
     steps:
     - name: Checkout sources
       uses: actions/checkout@v3.1.0
@@ -62,7 +62,7 @@ jobs:
       with:
         submodules: recursive
     - name: Download LLVM
-      run: curl -sSL -o c:\llvm.zip https://github.com/hyperledger/solang-llvm/releases/download/llvm15-0/llvm15.0-win.zip
+      run: curl -sSL -o c:\llvm.zip https://github.com/hyperledger/solang-llvm/releases/download/llvm15-1/llvm15.0-win.zip
     - name: Extract LLVM
       run: unzip c:\llvm.zip -d c:/
     - name: Add LLVM to Path
@@ -93,7 +93,7 @@ jobs:
         submodules: recursive
     - uses: dtolnay/rust-toolchain@1.65.0
     - name: Get LLVM
-      run: curl -L --output llvm15.0-mac-arm.tar.xz https://github.com/hyperledger/solang-llvm/releases/download/llvm15-0/llvm15.0-mac-arm.tar.xz
+      run: curl -sSL --output llvm15.0-mac-arm.tar.xz https://github.com/hyperledger/solang-llvm/releases/download/llvm15-1/llvm15.0-mac-arm.tar.xz
     - name: Extract LLVM
       run: tar Jxf llvm15.0-mac-arm.tar.xz
     - name: Add LLVM to Path
@@ -123,7 +123,7 @@ jobs:
         submodules: recursive
     - uses: dtolnay/rust-toolchain@1.65.0
     - name: Get LLVM
-      run: wget -q -O llvm15.0-mac-intel.tar.xz https://github.com/hyperledger/solang-llvm/releases/download/llvm15-0/llvm15.0-mac-intel.tar.xz
+      run: wget -q -O llvm15.0-mac-intel.tar.xz https://github.com/hyperledger/solang-llvm/releases/download/llvm15-1/llvm15.0-mac-intel.tar.xz
     - name: Extract LLVM
       run: tar Jxf llvm15.0-mac-intel.tar.xz
     - name: Add LLVM to Path
@@ -146,8 +146,8 @@ jobs:
     needs: [mac-arm, mac-intel]
     steps:
     - run: |
-        curl -L --output solang-mac-intel https://github.com/hyperledger/solang/releases/download/${GITHUB_REF/refs\/tags\//}/solang-mac-intel
-        curl -L --output solang-mac-arm https://github.com/hyperledger/solang/releases/download/${GITHUB_REF/refs\/tags\//}/solang-mac-arm
+        curl -sSL --output solang-mac-intel https://github.com/hyperledger/solang/releases/download/${GITHUB_REF/refs\/tags\//}/solang-mac-intel
+        curl -sSL --output solang-mac-arm https://github.com/hyperledger/solang/releases/download/${GITHUB_REF/refs\/tags\//}/solang-mac-arm
         lipo -create -output solang-mac solang-mac-intel solang-mac-arm
     - name: Upload binary
       uses: svenstaro/upload-release-action@v2

+ 8 - 8
.github/workflows/test.yml

@@ -19,7 +19,7 @@ jobs:
   lints:
     name: Lints
     runs-on: solang-ubuntu-latest
-    container: ghcr.io/hyperledger/solang-llvm:ci
+    container: ghcr.io/hyperledger/solang-llvm:ci-2
     steps:
       - name: Checkout sources
         uses: actions/checkout@v3
@@ -59,7 +59,7 @@ jobs:
   linux-x86-64:
     name: Linux x86-64
     runs-on: solang-ubuntu-latest
-    container: ghcr.io/hyperledger/solang-llvm:ci
+    container: ghcr.io/hyperledger/solang-llvm:ci-2
     steps:
     - name: Checkout sources
       uses: actions/checkout@v3
@@ -80,7 +80,7 @@ jobs:
     name: Linux Arm
     runs-on: linux-arm64
     if: ${{ github.repository_owner == 'hyperledger' }}
-    container: ghcr.io/hyperledger/solang-llvm:ci
+    container: ghcr.io/hyperledger/solang-llvm:ci-2
     steps:
     - name: Checkout sources
       uses: actions/checkout@v3
@@ -106,7 +106,7 @@ jobs:
       with:
         submodules: recursive
     - name: Download LLVM
-      run: curl -sSL -o c:\llvm.zip https://github.com/hyperledger/solang-llvm/releases/download/llvm15-0/llvm15.0-win.zip
+      run: curl -sSL -o c:\llvm.zip https://github.com/hyperledger/solang-llvm/releases/download/llvm15-1/llvm15.0-win.zip
     - name: Extract LLVM
       run: unzip c:\llvm.zip -d c:/
     - name: Add LLVM to Path
@@ -137,7 +137,7 @@ jobs:
         submodules: recursive
     - uses: dtolnay/rust-toolchain@1.65.0
     - name: Get LLVM
-      run: curl -L --output llvm15.0-mac-arm.tar.xz https://github.com/hyperledger/solang-llvm/releases/download/llvm15-0/llvm15.0-mac-arm.tar.xz
+      run: curl -sSL --output llvm15.0-mac-arm.tar.xz https://github.com/hyperledger/solang-llvm/releases/download/llvm15-1/llvm15.0-mac-arm.tar.xz
     - name: Extract LLVM
       run: tar Jxf llvm15.0-mac-arm.tar.xz
     - name: Add LLVM to Path
@@ -161,7 +161,7 @@ jobs:
         submodules: recursive
     - uses: dtolnay/rust-toolchain@1.65.0
     - name: Get LLVM
-      run: wget -q -O llvm15.0-mac-intel.tar.xz https://github.com/hyperledger/solang-llvm/releases/download/llvm15-0/llvm15.0-mac-intel.tar.xz
+      run: wget -q -O llvm15.0-mac-intel.tar.xz https://github.com/hyperledger/solang-llvm/releases/download/llvm15-1/llvm15.0-mac-intel.tar.xz
     - name: Extract LLVM
       run: tar Jxf llvm15.0-mac-intel.tar.xz
     - name: Add LLVM to Path
@@ -216,7 +216,7 @@ jobs:
   anchor:
     name: Anchor Integration test
     runs-on: solang-ubuntu-latest
-    container: ghcr.io/hyperledger/solang-llvm:ci
+    container: ghcr.io/hyperledger/solang-llvm:ci-2
     needs: linux-x86-64
     steps:
     - name: Checkout sources
@@ -263,7 +263,7 @@ jobs:
   solana:
     name: Solana Integration test
     runs-on: solang-ubuntu-latest
-    container: ghcr.io/hyperledger/solang-llvm:ci
+    container: ghcr.io/hyperledger/solang-llvm:ci-2
     needs: linux-x86-64
     steps:
     - name: Checkout sources

+ 1 - 1
Cargo.toml

@@ -28,7 +28,7 @@ tiny-keccak = { version = "2.0", features = ["keccak"] }
 serde_json = "1.0"
 serde = "1.0"
 serde_derive = { version = "1.0" }
-inkwell = { version = "0.1.1", features = ["target-webassembly", "target-bpf", "no-libffi-linking", "llvm15-0"], optional = true }
+inkwell = { version = "0.2.0", features = ["target-webassembly", "no-libffi-linking", "llvm15-0"], optional = true }
 blake2-rfc = "0.2.18"
 handlebars = "4.3"
 contract-metadata = "2.1"

+ 1 - 1
Dockerfile

@@ -1,4 +1,4 @@
-FROM ghcr.io/hyperledger/solang-llvm:ci as builder
+FROM ghcr.io/hyperledger/solang-llvm:ci-2 as builder
 
 COPY . src
 WORKDIR /src/stdlib/

+ 1 - 1
docs/index.rst

@@ -14,7 +14,7 @@ Welcome to the Solang Solidity Compiler. Using Solang, you can compile smart con
 `Solana <https://www.solana.com/>`_ and
 `Parity Substrate <https://substrate.io/>`_. It uses the
 `llvm <https://www.llvm.org/>`_ compiler framework to produce WebAssembly
-(WASM) or BPF contract code. As result, the output is highly optimized, which saves you in gas costs
+(WASM) or Solana SBF contract code. As result, the output is highly optimized, which saves you in gas costs
 or compute units.
 
 Solang aims for source file compatibility with the Ethereum EVM Solidity compiler,

+ 5 - 5
docs/installing.rst

@@ -121,8 +121,8 @@ Linux
 ~~~~~
 
 A pre-built version of LLVM, specifically configured for Solang, is available at
-`<https://github.com/hyperledger/solang-llvm/releases/download/llvm15-0/llvm15.0-linux-x86-64.tar.xz>`_ for x86 processors
-and at `<https://github.com/hyperledger/solang-llvm/releases/download/llvm15-0/llvm15.0-linux-arm64.tar.xz>`_ for ARM.
+`<https://github.com/hyperledger/solang-llvm/releases/download/llvm15-1/llvm15.0-linux-x86-64.tar.xz>`_ for x86 processors
+and at `<https://github.com/hyperledger/solang-llvm/releases/download/llvm15-1/llvm15.0-linux-arm64.tar.xz>`_ for ARM.
 After downloading, untar the file in a terminal and add it to your path.
 
 .. code-block:: bash
@@ -134,7 +134,7 @@ Windows
 ~~~~~~~
 
 A pre-built version of LLVM, specifically configured for Solang, is available at
-`<https://github.com/hyperledger/solang-llvm/releases/download/llvm15-0/llvm15.0-win.zip>`_.
+`<https://github.com/hyperledger/solang-llvm/releases/download/llvm15-1/llvm15.0-win.zip>`_.
 
 After unzipping the file, add the bin directory to your path.
 
@@ -146,8 +146,8 @@ Mac
 ~~~
 
 A pre-built version of LLVM for intel macs, is available at
-`<https://github.com/hyperledger/solang-llvm/releases/download/llvm15-0/llvm15.0-mac-intel.tar.xz>`_ and for arm macs there is
-`<https://github.com/hyperledger/solang-llvm/releases/download/llvm15-0/llvm15.0-mac-arm.tar.xz>`_. After downloading,
+`<https://github.com/hyperledger/solang-llvm/releases/download/llvm15-1/llvm15.0-mac-intel.tar.xz>`_ and for arm macs there is
+`<https://github.com/hyperledger/solang-llvm/releases/download/llvm15-1/llvm15.0-mac-arm.tar.xz>`_. After downloading,
 untar the file in a terminal and add it to your path like so:
 
 .. code-block:: bash

+ 1 - 1
docs/language/expressions.rst

@@ -143,7 +143,7 @@ an bitwise XOR of all function selectors in the interface. This makes it possibl
 an interface at runtime, which can be used to write a `supportsInterface()` function as described
 in the EIP.
 
-The contract code for a contract, i.e. the binary WebAssembly or BPF, can be retrieved using the
+The contract code for a contract, i.e. the binary WebAssembly or Solana SBF, can be retrieved using the
 ``type(c).creationCode`` and ``type(c).runtimeCode`` fields, as ``bytes``. On EVM,
 the constructor code is in the ``creationCode`` and all the functions are in
 the ``runtimeCode``. Parity Substrate and Solana use the same

+ 2 - 2
docs/language/introduction.rst

@@ -17,8 +17,8 @@ As with any new project, bugs are possible. Please report any issues you may fin
 Differences:
 
 - libraries are always statically linked into the contract code
-- Solang generates WebAssembly or BPF rather than EVM.
-- Packed encoded uses little endian encoding, as WASM and BPF are little endian
+- Solang generates WebAssembly or Solana SBF rather than EVM.
+- Packed encoded uses little endian encoding, as WASM and SBF are little endian
   virtual machines.
 
 Unique features to Solang:

+ 1 - 1
docs/language/types.rst

@@ -63,7 +63,7 @@ The largest value an ``uint8`` can hold is (2 :superscript:`8`) - 1 = 255. So, t
   for such large types, and any EVM virtual machine implementation has to do bigint
   calculations, which are expensive.
 
-  WebAssembly or BPF do not support this. As a result that Solang has to emulate larger types with
+  WebAssembly or Solana SBF do not support this. As a result that Solang has to emulate larger types with
   many instructions, resulting in larger contract code and higher gas cost or compute units.
 
 Fixed Length byte arrays

+ 1 - 1
docs/running.rst

@@ -3,7 +3,7 @@ Using Solang on the command line
 
 The Solang compiler is run on the command line. The solidity source file
 names are provided as command line arguments; the output is an optimized
-wasm or bpf file which is ready for deployment on a chain, and an metadata
+WebAssembly or Solana SBF file which is ready for deployment on a chain, and an metadata
 file (also known as the abi).
 
 The following targets are supported right now:

+ 1 - 1
docs/targets/solana.rst

@@ -91,7 +91,7 @@ ______________________________
   solang compile --target solana flipper.sol -v
 
 This will produce two files called ``flipper.json`` and ``flipper.so``. The former is an Anchor style IDL file and the latter is
-the ELF BPF shared object containing the program. For each contract in the source code, Solang will create both an IDL file
+the Solana ELF shared object containing the program. For each contract in the source code, Solang will create both an IDL file
 and a binary file.
 
 Each program will need to be deployed to a program_id. Usually, the program_id is a well-known account which is specified

+ 23 - 6
src/emit/binary.rs

@@ -53,6 +53,8 @@ pub struct Binary<'a> {
     pub(crate) scratch: Option<GlobalValue<'a>>,
     pub(crate) parameters: Option<PointerValue<'a>>,
     pub(crate) return_values: HashMap<ReturnCode, IntValue<'a>>,
+    /// No initializer for vector_new
+    pub(crate) vector_init_empty: PointerValue<'a>,
 }
 
 impl<'a> Binary<'a> {
@@ -193,7 +195,22 @@ impl<'a> Binary<'a> {
     ) -> Self {
         LLVM_INIT.get_or_init(|| {
             inkwell::targets::Target::initialize_webassembly(&Default::default());
-            inkwell::targets::Target::initialize_bpf(&Default::default());
+
+            extern "C" {
+                fn LLVMInitializeSBFTarget();
+                fn LLVMInitializeSBFTargetInfo();
+                fn LLVMInitializeSBFAsmPrinter();
+                fn LLVMInitializeSBFDisassembler();
+                fn LLVMInitializeSBFTargetMC();
+            }
+
+            unsafe {
+                LLVMInitializeSBFTarget();
+                LLVMInitializeSBFTargetInfo();
+                LLVMInitializeSBFAsmPrinter();
+                LLVMInitializeSBFDisassembler();
+                LLVMInitializeSBFTargetMC();
+            }
         });
 
         let triple = target.llvm_target_triple();
@@ -278,6 +295,10 @@ impl<'a> Binary<'a> {
             scratch_len: None,
             parameters: None,
             return_values,
+            vector_init_empty: context
+                .i8_type()
+                .ptr_type(AddressSpace::default())
+                .const_null(),
         }
     }
 
@@ -856,11 +877,7 @@ impl<'a> Binary<'a> {
         }
 
         let init = match init {
-            None => self.builder.build_int_to_ptr(
-                self.context.i32_type().const_all_ones(),
-                self.context.i8_type().ptr_type(AddressSpace::default()),
-                "invalid",
-            ),
+            None => self.vector_init_empty,
             Some(s) => self.emit_global_string("const_string", s, true),
         };
 

+ 2 - 2
src/emit/mod.rs

@@ -343,7 +343,7 @@ impl Target {
     /// LLVM Target name
     fn llvm_target_name(&self) -> &'static str {
         if *self == Target::Solana {
-            "bpfel"
+            "sbf"
         } else {
             "wasm32"
         }
@@ -352,7 +352,7 @@ impl Target {
     /// LLVM Target triple
     fn llvm_target_triple(&self) -> TargetTriple {
         TargetTriple::create(if *self == Target::Solana {
-            "bpfel-unknown-unknown"
+            "sbf-unknown-unknown"
         } else {
             "wasm32-unknown-unknown-wasm"
         })

+ 1 - 1
src/emit/solana/mod.rs

@@ -58,7 +58,7 @@ impl SolanaTarget {
         );
         binary.return_values.insert(
             ReturnCode::InvalidDataError,
-            context.i32_type().const_int(2, false),
+            context.i64_type().const_int(2, false),
         );
         binary.return_values.insert(
             ReturnCode::AccountDataTooSmall,

+ 5 - 0
src/emit/substrate/mod.rs

@@ -117,6 +117,11 @@ impl SubstrateTarget {
             None,
         );
 
+        binary.vector_init_empty = binary.builder.build_int_to_ptr(
+            binary.context.i32_type().const_all_ones(),
+            binary.context.i8_type().ptr_type(AddressSpace::default()),
+            "empty_vector",
+        );
         binary.set_early_value_aborts(contract, ns);
 
         let scratch_len = binary.module.add_global(

+ 2 - 2
stdlib/Makefile

@@ -10,10 +10,10 @@ WASM=$(addprefix wasm/,ripemd160.bc stdlib.bc bigint.bc format.bc heap.bc)
 
 all: $(SOLANA) $(WASM)
 
-$(SOLANA): TARGET_FLAGS=--target=sbf -march=bpfel+solana
+$(SOLANA): TARGET_FLAGS=--target=sbf
 $(WASM): TARGET_FLAGS=--target=wasm32
 
 bpf/solana.bc: solana.c solana_sdk.h
 
 clean:
-	rm -r bpf/* wasm/*
+	rm -r bpf/* wasm/*

BIN
stdlib/bpf/bigint.bc


BIN
stdlib/bpf/format.bc


BIN
stdlib/bpf/heap.bc


BIN
stdlib/bpf/ripemd160.bc


BIN
stdlib/bpf/solana.bc


BIN
stdlib/bpf/stdlib.bc


+ 7 - 1
stdlib/stdlib.c

@@ -126,6 +126,12 @@ void __leNtobeN(uint8_t *from, uint8_t *to, uint32_t length)
 	} while (--length);
 }
 
+#ifdef __wasm__
+#define VECTOR_EMPTY ((uint8_t *)~0l)
+#else
+#define VECTOR_EMPTY ((uint8_t *)0l)
+#endif
+
 // Create a new vector. If initial is -1 then clear the data. This is done since a null pointer valid in wasm
 struct vector *vector_new(uint32_t members, uint32_t size, uint8_t *initial)
 {
@@ -138,7 +144,7 @@ struct vector *vector_new(uint32_t members, uint32_t size, uint8_t *initial)
 
 	uint8_t *data = v->data;
 
-	if ((int)initial != -1)
+	if (initial != VECTOR_EMPTY)
 	{
 		while (size_array--)
 		{

BIN
stdlib/wasm/stdlib.bc