Selaa lähdekoodia

Enable tests for stdlib (#1299)

* Enable tests for stdlib

Signed-off-by: Lucas Steuernagel <lucas.tnagel@gmail.com>
Lucas Steuernagel 2 vuotta sitten
vanhempi
sitoutus
200560e189

+ 16 - 0
.github/workflows/test.yml

@@ -366,3 +366,19 @@ jobs:
       working-directory: ./vscode
     - run: vsce package
       working-directory: ./vscode
+
+  std-lib-tests:
+    name: Stdlib
+    runs-on: solang-ubuntu-latest
+    steps:
+      - name: Checkout sources
+        uses: actions/checkout@v3
+      - name: Lints for stdlib
+        run: |
+          make lint
+        working-directory: ./stdlib
+      - name: Stdlib tests
+        run: |
+          make test
+          ./test
+        working-directory: ./stdlib

+ 5 - 0
build.rs

@@ -5,6 +5,11 @@ use std::process::Command;
 fn main() {
     #[cfg(feature = "llvm")]
     {
+        Command::new("make")
+            .args(["-C", "stdlib"])
+            .output()
+            .expect("Could not build stdlib");
+
         // compile our linker
         let cxxflags = Command::new("llvm-config")
             .args(["--cxxflags"])

+ 2 - 2
docs/installing.rst

@@ -197,7 +197,7 @@ And on Windows, assuming *installdir* was ``C:\Users\User\solang-llvm``:
 Step 2: Build Solang
 ____________________
 
-Once you have the correct LLVM version in your path, simply run:
+Once you have the correct LLVM version in your path, ensure you have GNU make installed and simply run:
 
 .. code-block:: bash
 
@@ -213,7 +213,7 @@ Alternative step 2: Build Solang from crates.io
 _______________________________________________
 
 The latest Solang release is  on `crates.io <https://crates.io/crates/solang>`_. Once you have the
-correct LLVM version in your path, simply run:
+correct LLVM version in your path, ensure you have GNU make installed and simply run:
 
 .. code-block:: bash
 

+ 3 - 0
stdlib/.clang-format

@@ -0,0 +1,3 @@
+ReflowComments: false
+BasedOnStyle: Microsoft
+SortIncludes: Never

+ 2 - 0
stdlib/.gitignore

@@ -0,0 +1,2 @@
+wasm/
+bpf/

+ 17 - 3
stdlib/Makefile

@@ -2,7 +2,10 @@ CC=clang
 BIT_INT_FLAGS=-Xclang -fexperimental-max-bitint-width=512
 CFLAGS=$(TARGET_FLAGS) -emit-llvm -O3 -ffreestanding -fno-builtin -Wall -Wno-unused-function $(BIT_INT_FLAGS)
 
-bpf/%.bc wasm/%.bc: %.c
+bpf/%.bc: %.c
+	$(CC) -c $(CFLAGS) $< -o $@
+
+wasm/%.bc: %.c
 	$(CC) -c $(CFLAGS) $< -o $@
 
 SOLANA=$(addprefix bpf/,solana.bc bigint.bc format.bc stdlib.bc ripemd160.bc heap.bc)
@@ -10,10 +13,21 @@ WASM=$(addprefix wasm/,ripemd160.bc stdlib.bc bigint.bc format.bc heap.bc)
 
 all: $(SOLANA) $(WASM)
 
+$(SOLANA) $(WASM): | outputs_dirs
+
 $(SOLANA): TARGET_FLAGS=--target=sbf
 $(WASM): TARGET_FLAGS=--target=wasm32
 
-bpf/solana.bc: solana.c solana_sdk.h
+bpf/solana.bc: solana.c solana_sdk.h | outputs_dirs
+
+outputs_dirs:
+	@mkdir -p bpf wasm
 
 clean:
-	rm -r bpf/* wasm/*
+	rm -rf bpf wasm
+
+test:
+	clang -DTEST -DSOL_TEST -O3 -Wall solana.c stdlib.c -o test
+
+lint:
+	clang-format *.c *.h --style=file --dry-run -Werror

+ 2 - 4
stdlib/bigint.c

@@ -120,8 +120,7 @@ bool __mul32_with_builtin_ovf(uint32_t left[], uint32_t right[], uint32_t out[],
 // Some compiler runtime builtins we need.
 
 // 128 bit shift left.
-typedef union
-{
+typedef union {
     __uint128_t all;
     struct
     {
@@ -131,8 +130,7 @@ typedef union
 } two64;
 
 // 128 bit shift left.
-typedef union
-{
+typedef union {
     __int128_t all;
     struct
     {

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


+ 6 - 6
stdlib/format.c

@@ -109,7 +109,8 @@ char *uint2dec(char *output, uint64_t val)
     return output;
 }
 
-extern int udivmod128(const __uint128_t *dividend, const __uint128_t *divisor, __uint128_t *remainder, __uint128_t *quotient);
+extern int udivmod128(const __uint128_t *dividend, const __uint128_t *divisor, __uint128_t *remainder,
+                      __uint128_t *quotient);
 
 char *uint128dec(char *output, __uint128_t val128)
 {
@@ -183,8 +184,7 @@ typedef unsigned _BitInt(256) uint256_t;
 
 extern int udivmod256(const uint256_t *dividend, const uint256_t *divisor, uint256_t *remainder, uint256_t *quotient);
 
-char *
-uint256dec(char *output, uint256_t *val256)
+char *uint256dec(char *output, uint256_t *val256)
 {
     // we want 1e19, how to declare such a constant in clang?
     const uint256_t n1e10 = 10000000000;
@@ -243,14 +243,14 @@ uint256dec(char *output, uint256_t *val256)
 static const char b58digits[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
 
 // https://github.com/bitcoin/libbase58/blob/b1dd03fa8d1be4be076bb6152325c6b5cf64f678/base58.c inspired this code.
-void base58_encode_solana_address(uint8_t * data, uint32_t data_len, uint8_t * output, uint32_t output_len)
+void base58_encode_solana_address(uint8_t *data, uint32_t data_len, uint8_t *output, uint32_t output_len)
 {
     uint32_t j, carry, zero_count = 0;
 
     while (zero_count < data_len && !data[zero_count])
         ++zero_count;
 
-    for (uint32_t i=zero_count, high = output_len - 1; i < data_len; i++, high = j)
+    for (uint32_t i = zero_count, high = output_len - 1; i < data_len; i++, high = j)
     {
         for (carry = data[i], j = output_len - 1; (j > high) || carry; --j)
         {
@@ -264,7 +264,7 @@ void base58_encode_solana_address(uint8_t * data, uint32_t data_len, uint8_t * o
         }
     }
 
-    for (j=0; j < output_len; j++)
+    for (j = 0; j < output_len; j++)
     {
         output[j] = b58digits[output[j]];
     }

+ 1 - 2
stdlib/heap.c

@@ -33,8 +33,7 @@ void __init_heap()
     struct chunk *first = HEAP_START;
     first->next = first->prev = NULL;
     first->allocated = false;
-    first->length = (size_t)(__builtin_wasm_memory_size(0) * 0x10000 -
-                             (size_t)first - sizeof(struct chunk));
+    first->length = (size_t)(__builtin_wasm_memory_size(0) * 0x10000 - (size_t)first - sizeof(struct chunk));
 }
 #else
 #define HEAP_START ((struct chunk *)0x300000000)

+ 119 - 67
stdlib/ripemd160.c

@@ -54,25 +54,25 @@
 #define RIPEMD160_DIGEST_SIZE 20
 #define BLOCK_SIZE 64
 
-typedef struct {
-    uint32_t h[5];      /* The current hash state */
-    uint64_t length;    /* Total number of _bits_ (not bytes) added to the
+typedef struct
+{
+    uint32_t h[5];   /* The current hash state */
+    uint64_t length; /* Total number of _bits_ (not bytes) added to the
                            hash.  This includes bits that have been buffered
                            but not not fed through the compression function yet. */
     union {
         uint32_t w[16];
         uint8_t b[64];
     } buf;
-    uint8_t bufpos;     /* number of bytes currently in the buffer */
+    uint8_t bufpos; /* number of bytes currently in the buffer */
 } ripemd160_state;
 
-
 /* cyclic left-shift the 32-bit word n left by s bits */
-#define ROL(s, n) (((n) << (s)) | ((n) >> (32-(s))))
+#define ROL(s, n) (((n) << (s)) | ((n) >> (32 - (s))))
 
 /* Initial values for the chaining variables.
  * This is just 0123456789ABCDEFFEDCBA9876543210F0E1D2C3 in little-endian. */
-static const uint32_t initial_h[5] = { 0x67452301u, 0xEFCDAB89u, 0x98BADCFEu, 0x10325476u, 0xC3D2E1F0u };
+static const uint32_t initial_h[5] = {0x67452301u, 0xEFCDAB89u, 0x98BADCFEu, 0x10325476u, 0xC3D2E1F0u};
 
 /* Ordering of message words.  Based on the permutations rho(i) and pi(i), defined as follows:
  *
@@ -88,20 +88,20 @@ static const uint32_t initial_h[5] = { 0x67452301u, 0xEFCDAB89u, 0x98BADCFEu, 0x
 
 /* Left line */
 static const uint8_t RL[5][16] = {
-    { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },   /* Round 1: id */
-    { 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8 },   /* Round 2: rho */
-    { 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12 },   /* Round 3: rho^2 */
-    { 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2 },   /* Round 4: rho^3 */
-    { 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 }    /* Round 5: rho^4 */
+    {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, /* Round 1: id */
+    {7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8}, /* Round 2: rho */
+    {3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12}, /* Round 3: rho^2 */
+    {1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2}, /* Round 4: rho^3 */
+    {4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13}  /* Round 5: rho^4 */
 };
 
 /* Right line */
 static const uint8_t RR[5][16] = {
-    { 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12 },   /* Round 1: pi */
-    { 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2 },   /* Round 2: rho pi */
-    { 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13 },   /* Round 3: rho^2 pi */
-    { 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14 },   /* Round 4: rho^3 pi */
-    { 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 }    /* Round 5: rho^4 pi */
+    {5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12}, /* Round 1: pi */
+    {6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2}, /* Round 2: rho pi */
+    {15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13}, /* Round 3: rho^2 pi */
+    {8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14}, /* Round 4: rho^3 pi */
+    {12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11}  /* Round 5: rho^4 pi */
 };
 
 /*
@@ -112,20 +112,20 @@ static const uint8_t RR[5][16] = {
 
 /* Shifts, left line */
 static const uint8_t SL[5][16] = {
-    { 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8 }, /* Round 1 */
-    { 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12 }, /* Round 2 */
-    { 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5 }, /* Round 3 */
-    { 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12 }, /* Round 4 */
-    { 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 }  /* Round 5 */
+    {11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8}, /* Round 1 */
+    {7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12}, /* Round 2 */
+    {11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5}, /* Round 3 */
+    {11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12}, /* Round 4 */
+    {9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6}  /* Round 5 */
 };
 
 /* Shifts, right line */
 static const uint8_t SR[5][16] = {
-    { 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6 }, /* Round 1 */
-    { 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11 }, /* Round 2 */
-    { 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5 }, /* Round 3 */
-    { 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8 }, /* Round 4 */
-    { 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 }  /* Round 5 */
+    {8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6}, /* Round 1 */
+    {9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11}, /* Round 2 */
+    {9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5}, /* Round 3 */
+    {15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8}, /* Round 4 */
+    {8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11}  /* Round 5 */
 };
 
 /* Boolean functions */
@@ -138,20 +138,20 @@ static const uint8_t SR[5][16] = {
 
 /* Round constants, left line */
 static const uint32_t KL[5] = {
-    0x00000000u,    /* Round 1: 0 */
-    0x5A827999u,    /* Round 2: floor(2**30 * sqrt(2)) */
-    0x6ED9EBA1u,    /* Round 3: floor(2**30 * sqrt(3)) */
-    0x8F1BBCDCu,    /* Round 4: floor(2**30 * sqrt(5)) */
-    0xA953FD4Eu     /* Round 5: floor(2**30 * sqrt(7)) */
+    0x00000000u, /* Round 1: 0 */
+    0x5A827999u, /* Round 2: floor(2**30 * sqrt(2)) */
+    0x6ED9EBA1u, /* Round 3: floor(2**30 * sqrt(3)) */
+    0x8F1BBCDCu, /* Round 4: floor(2**30 * sqrt(5)) */
+    0xA953FD4Eu  /* Round 5: floor(2**30 * sqrt(7)) */
 };
 
 /* Round constants, right line */
 static const uint32_t KR[5] = {
-    0x50A28BE6u,    /* Round 1: floor(2**30 * cubert(2)) */
-    0x5C4DD124u,    /* Round 2: floor(2**30 * cubert(3)) */
-    0x6D703EF3u,    /* Round 3: floor(2**30 * cubert(5)) */
-    0x7A6D76E9u,    /* Round 4: floor(2**30 * cubert(7)) */
-    0x00000000u     /* Round 5: 0 */
+    0x50A28BE6u, /* Round 1: floor(2**30 * cubert(2)) */
+    0x5C4DD124u, /* Round 2: floor(2**30 * cubert(3)) */
+    0x6D703EF3u, /* Round 3: floor(2**30 * cubert(5)) */
+    0x7A6D76E9u, /* Round 4: floor(2**30 * cubert(7)) */
+    0x00000000u  /* Round 5: 0 */
 };
 
 /* The RIPEMD160 compression function.  Operates on self->buf */
@@ -159,8 +159,8 @@ static void ripemd160_compress(ripemd160_state *self)
 {
     uint8_t w, round;
     uint32_t T;
-    uint32_t AL, BL, CL, DL, EL;    /* left line */
-    uint32_t AR, BR, CR, DR, ER;    /* right line */
+    uint32_t AL, BL, CL, DL, EL; /* left line */
+    uint32_t AR, BR, CR, DR, ER; /* right line */
 
     /* Load the left and right lines with the initial state */
     AL = AR = self->h[0];
@@ -171,57 +171,107 @@ static void ripemd160_compress(ripemd160_state *self)
 
     /* Round 1 */
     round = 0;
-    for (w = 0; w < 16; w++) { /* left line */
+    for (w = 0; w < 16; w++)
+    { /* left line */
         T = ROL(SL[round][w], AL + F1(BL, CL, DL) + self->buf.w[RL[round][w]] + KL[round]) + EL;
-        AL = EL; EL = DL; DL = ROL(10, CL); CL = BL; BL = T;
+        AL = EL;
+        EL = DL;
+        DL = ROL(10, CL);
+        CL = BL;
+        BL = T;
     }
-    for (w = 0; w < 16; w++) { /* right line */
+    for (w = 0; w < 16; w++)
+    { /* right line */
         T = ROL(SR[round][w], AR + F5(BR, CR, DR) + self->buf.w[RR[round][w]] + KR[round]) + ER;
-        AR = ER; ER = DR; DR = ROL(10, CR); CR = BR; BR = T;
+        AR = ER;
+        ER = DR;
+        DR = ROL(10, CR);
+        CR = BR;
+        BR = T;
     }
 
     /* Round 2 */
     round++;
-    for (w = 0; w < 16; w++) { /* left line */
+    for (w = 0; w < 16; w++)
+    { /* left line */
         T = ROL(SL[round][w], AL + F2(BL, CL, DL) + self->buf.w[RL[round][w]] + KL[round]) + EL;
-        AL = EL; EL = DL; DL = ROL(10, CL); CL = BL; BL = T;
+        AL = EL;
+        EL = DL;
+        DL = ROL(10, CL);
+        CL = BL;
+        BL = T;
     }
-    for (w = 0; w < 16; w++) { /* right line */
+    for (w = 0; w < 16; w++)
+    { /* right line */
         T = ROL(SR[round][w], AR + F4(BR, CR, DR) + self->buf.w[RR[round][w]] + KR[round]) + ER;
-        AR = ER; ER = DR; DR = ROL(10, CR); CR = BR; BR = T;
+        AR = ER;
+        ER = DR;
+        DR = ROL(10, CR);
+        CR = BR;
+        BR = T;
     }
 
     /* Round 3 */
     round++;
-    for (w = 0; w < 16; w++) { /* left line */
+    for (w = 0; w < 16; w++)
+    { /* left line */
         T = ROL(SL[round][w], AL + F3(BL, CL, DL) + self->buf.w[RL[round][w]] + KL[round]) + EL;
-        AL = EL; EL = DL; DL = ROL(10, CL); CL = BL; BL = T;
+        AL = EL;
+        EL = DL;
+        DL = ROL(10, CL);
+        CL = BL;
+        BL = T;
     }
-    for (w = 0; w < 16; w++) { /* right line */
+    for (w = 0; w < 16; w++)
+    { /* right line */
         T = ROL(SR[round][w], AR + F3(BR, CR, DR) + self->buf.w[RR[round][w]] + KR[round]) + ER;
-        AR = ER; ER = DR; DR = ROL(10, CR); CR = BR; BR = T;
+        AR = ER;
+        ER = DR;
+        DR = ROL(10, CR);
+        CR = BR;
+        BR = T;
     }
 
     /* Round 4 */
     round++;
-    for (w = 0; w < 16; w++) { /* left line */
+    for (w = 0; w < 16; w++)
+    { /* left line */
         T = ROL(SL[round][w], AL + F4(BL, CL, DL) + self->buf.w[RL[round][w]] + KL[round]) + EL;
-        AL = EL; EL = DL; DL = ROL(10, CL); CL = BL; BL = T;
+        AL = EL;
+        EL = DL;
+        DL = ROL(10, CL);
+        CL = BL;
+        BL = T;
     }
-    for (w = 0; w < 16; w++) { /* right line */
+    for (w = 0; w < 16; w++)
+    { /* right line */
         T = ROL(SR[round][w], AR + F2(BR, CR, DR) + self->buf.w[RR[round][w]] + KR[round]) + ER;
-        AR = ER; ER = DR; DR = ROL(10, CR); CR = BR; BR = T;
+        AR = ER;
+        ER = DR;
+        DR = ROL(10, CR);
+        CR = BR;
+        BR = T;
     }
 
     /* Round 5 */
     round++;
-    for (w = 0; w < 16; w++) { /* left line */
+    for (w = 0; w < 16; w++)
+    { /* left line */
         T = ROL(SL[round][w], AL + F5(BL, CL, DL) + self->buf.w[RL[round][w]] + KL[round]) + EL;
-        AL = EL; EL = DL; DL = ROL(10, CL); CL = BL; BL = T;
+        AL = EL;
+        EL = DL;
+        DL = ROL(10, CL);
+        CL = BL;
+        BL = T;
     }
-    for (w = 0; w < 16; w++) { /* right line */
+    for (w = 0; w < 16; w++)
+    { /* right line */
         T = ROL(SR[round][w], AR + F1(BR, CR, DR) + self->buf.w[RR[round][w]] + KR[round]) + ER;
-        AR = ER; ER = DR; DR = ROL(10, CR); CR = BR; BR = T;
+        AR = ER;
+        ER = DR;
+        DR = ROL(10, CR);
+        CR = BR;
+        BR = T;
     }
 
     /* Final mixing stage */
@@ -242,16 +292,18 @@ static void ripemd160_update(ripemd160_state *self, const unsigned char *p, int
 {
     unsigned int bytes_needed;
 
-    while (length > 0) {
+    while (length > 0)
+    {
         /* Figure out how many bytes we need to fill the internal buffer. */
         bytes_needed = 64 - self->bufpos;
 
-        if ((unsigned int) length >= bytes_needed) {
+        if ((unsigned int)length >= bytes_needed)
+        {
             /* We have enough bytes, so copy them into the internal buffer and run
              * the compression function. */
             __memcpy(&self->buf.b[self->bufpos], p, bytes_needed);
             self->bufpos += bytes_needed;
-            self->length += bytes_needed << 3;    /* length is in bits */
+            self->length += bytes_needed << 3; /* length is in bits */
             p += bytes_needed;
             ripemd160_compress(self);
             length -= bytes_needed;
@@ -262,7 +314,7 @@ static void ripemd160_update(ripemd160_state *self, const unsigned char *p, int
          * Copy what's there and return. */
         __memcpy(&self->buf.b[self->bufpos], p, length);
         self->bufpos += length;
-        self->length += length << 3;    /* length is in bits */
+        self->length += length << 3; /* length is in bits */
         return;
     }
 }
@@ -272,14 +324,15 @@ static void ripemd160_digest(ripemd160_state *self, unsigned char *out)
     /* Append the padding */
     self->buf.b[self->bufpos++] = 0x80;
 
-    if (self->bufpos > 56) {
+    if (self->bufpos > 56)
+    {
         self->bufpos = 64;
         ripemd160_compress(self);
     }
 
     /* Append the length */
-    self->buf.w[14] = (uint32_t) (self->length & 0xFFFFffffu);
-    self->buf.w[15] = (uint32_t) ((self->length >> 32) & 0xFFFFffffu);
+    self->buf.w[14] = (uint32_t)(self->length & 0xFFFFffffu);
+    self->buf.w[15] = (uint32_t)((self->length >> 32) & 0xFFFFffffu);
     self->bufpos = 64;
     ripemd160_compress(self);
 
@@ -287,7 +340,6 @@ static void ripemd160_digest(ripemd160_state *self, unsigned char *out)
     __memcpy(out, &self->h, RIPEMD160_DIGEST_SIZE);
 }
 
-
 void ripemd160(void *in, int inlen, void *out)
 {
     ripemd160_state state;

+ 46 - 29
stdlib/solana.c

@@ -9,14 +9,21 @@ extern uint64_t solang_dispatch(SolParameters *param);
 extern void __init_heap();
 
 // The address 'SysvarC1ock11111111111111111111111111111111' base58 decoded
-static const SolPubkey clock_address = {0x06, 0xa7, 0xd5, 0x17, 0x18, 0xc7, 0x74, 0xc9, 0x28, 0x56, 0x63, 0x98, 0x69, 0x1d, 0x5e, 0xb6, 0x8b, 0x5e, 0xb8, 0xa3, 0x9b, 0x4b, 0x6d, 0x5c, 0x73, 0x55, 0x5b, 0x21, 0x00, 0x00, 0x00, 0x00};
+static const SolPubkey clock_address = {0x06, 0xa7, 0xd5, 0x17, 0x18, 0xc7, 0x74, 0xc9, 0x28, 0x56, 0x63,
+                                        0x98, 0x69, 0x1d, 0x5e, 0xb6, 0x8b, 0x5e, 0xb8, 0xa3, 0x9b, 0x4b,
+                                        0x6d, 0x5c, 0x73, 0x55, 0x5b, 0x21, 0x00, 0x00, 0x00, 0x00};
 // The address 'Sysvar1nstructions1111111111111111111111111' base58 decoded
-static const SolPubkey instructions_address = {0x06, 0xa7, 0xd5, 0x17, 0x18, 0x7b, 0xd1, 0x66, 0x35, 0xda, 0xd4, 0x04, 0x55, 0xfd, 0xc2, 0xc0, 0xc1, 0x24, 0xc6, 0x8f, 0x21, 0x56, 0x75, 0xa5, 0xdb, 0xba, 0xcb, 0x5f, 0x08, 0x00, 0x00, 0x00};
+static const SolPubkey instructions_address = {0x06, 0xa7, 0xd5, 0x17, 0x18, 0x7b, 0xd1, 0x66, 0x35, 0xda, 0xd4,
+                                               0x04, 0x55, 0xfd, 0xc2, 0xc0, 0xc1, 0x24, 0xc6, 0x8f, 0x21, 0x56,
+                                               0x75, 0xa5, 0xdb, 0xba, 0xcb, 0x5f, 0x08, 0x00, 0x00, 0x00};
 // The address 'Ed25519SigVerify111111111111111111111111111' base58 decoded
-static const SolPubkey ed25519_address = {0x03, 0x7d, 0x46, 0xd6, 0x7c, 0x93, 0xfb, 0xbe, 0x12, 0xf9, 0x42, 0x8f, 0x83, 0x8d, 0x40, 0xff, 0x05, 0x70, 0x74, 0x49, 0x27, 0xf4, 0x8a, 0x64, 0xfc, 0xca, 0x70, 0x44, 0x80, 0x00, 0x00, 0x00};
+static const SolPubkey ed25519_address = {0x03, 0x7d, 0x46, 0xd6, 0x7c, 0x93, 0xfb, 0xbe, 0x12, 0xf9, 0x42,
+                                          0x8f, 0x83, 0x8d, 0x40, 0xff, 0x05, 0x70, 0x74, 0x49, 0x27, 0xf4,
+                                          0x8a, 0x64, 0xfc, 0xca, 0x70, 0x44, 0x80, 0x00, 0x00, 0x00};
 
-uint64_t
-entrypoint(const uint8_t *input)
+#ifndef TEST
+
+uint64_t entrypoint(const uint8_t *input)
 {
     SolParameters params;
 
@@ -48,19 +55,13 @@ entrypoint(const uint8_t *input)
     return solang_dispatch(&params);
 }
 
-uint64_t sol_invoke_signed_c(
-    const SolInstruction *instruction,
-    const SolAccountInfo *account_infos,
-    int account_infos_len,
-    const SolSignerSeeds *signers_seeds,
-    int signers_seeds_len);
-
+uint64_t sol_invoke_signed_c(const SolInstruction *instruction, const SolAccountInfo *account_infos,
+                             int account_infos_len, const SolSignerSeeds *signers_seeds, int signers_seeds_len);
 
 // 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)
+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 = {
@@ -129,9 +130,7 @@ uint64_t external_call(uint8_t *input, uint32_t input_len, SolPubkey *address,
     }
 }
 
-uint64_t *sol_account_lamport(
-    uint8_t *address,
-    SolParameters *params)
+uint64_t *sol_account_lamport(uint8_t *address, SolParameters *params)
 {
     SolPubkey *pubkey = (SolPubkey *)address;
 
@@ -192,6 +191,8 @@ bool sol_try_transfer(uint8_t *to_address, uint64_t lamports, SolParameters *par
     return true;
 }
 
+#endif
+
 uint64_t address_hash(uint8_t data[32])
 {
     uint64_t hash = 0;
@@ -274,8 +275,7 @@ uint64_t signature_verify(uint8_t *public_key, struct vector *message, struct ve
             {
                 struct ed25519_instruction_sig *sig = &ed25519->sig[sig_no];
 
-                if (sig->public_key_instruction_index != instr_no ||
-                    sig->signature_instruction_index != instr_no ||
+                if (sig->public_key_instruction_index != instr_no || sig->signature_instruction_index != instr_no ||
                     sig->message_instruction_index != instr_no)
                     continue;
 
@@ -693,10 +693,14 @@ uint64_t account_data_realloc(SolAccountInfo *ai, uint32_t offset, uint32_t size
 // To run the test:
 // clang -DTEST -DSOL_TEST -O3 -Wall solana.c stdlib.c -o test && ./test
 #include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
 
 void validate_heap(void *data, uint32_t offs[100], uint32_t lens[100])
 {
-    uint32_t offset = ((uint32_t *)data)[1];
+    struct account_data_header *hdr = data;
+    uint32_t offset = hdr->heap_offset;
 
     uint32_t last_offset = 0;
 
@@ -764,8 +768,9 @@ int main()
     uint32_t allocs = 0;
 
     memset(data, 0, sizeof(data));
-    ((uint32_t *)data)[0] = 0x41424344;
-    ((uint32_t *)data)[1] = 0x20;
+    struct account_data_header *hdr = data;
+    hdr->magic = 0x41424344;
+    hdr->heap_offset = 0x20;
 
     memset(offs, 0, sizeof(offs));
 
@@ -773,6 +778,9 @@ int main()
     printf("seed: %d\n", seed);
     srand(seed);
 
+    uint32_t new_offset;
+    uint64_t status;
+
     for (;;)
     {
         validate_heap(data, offs, lens);
@@ -781,25 +789,36 @@ int main()
         if (offs[n] == 0)
         {
             // printf("STEP: alloc %d\n", n);
-            offs[n] = account_data_alloc(&ai, 100);
+            status = account_data_alloc(&ai, 100, &new_offset);
+            assert(status == 0);
+            offs[n] = new_offset;
             memset(data + offs[n], n, 100);
             lens[n] = 100;
         }
         else if (rand() % 2)
         {
             // printf("STEP: free %d (0x%x)\n", n, offs[n]);
-            account_data_free(&ai, offs[n]);
+            account_data_free(ai.data, offs[n]);
             offs[n] = 0;
         }
         else
         {
+            // printf("STEP: realloc %d (0x%x)\n", n, offs[n]);
             int size = (rand() % 200) + 10;
-            int old_size = account_data_len(&ai, offs[n]);
-            offs[n] = account_data_realloc(&ai, offs[n], size);
+            int old_size = account_data_len(ai.data, offs[n]);
+            status = account_data_realloc(&ai, offs[n], size, &new_offset);
+            assert(status == 0);
+            offs[n] = new_offset;
             if (size > old_size)
                 memset(data + offs[n] + old_size, n, size - old_size);
             lens[n] = size;
         }
+
+        if (time(NULL) - seed > 120)
+        {
+            printf("No error found after running for two minutes\n");
+            break;
+        }
     }
 }
 
@@ -807,6 +826,4 @@ void sol_panic_(const char *s, uint64_t len, uint64_t line, uint64_t column)
 {
     printf("panic: %s line %lld", s, line);
 }
-
-int solang_dispatch(const uint8_t *input, uint64_t input_len, SolAccountInfo *ka) {}
 #endif

+ 204 - 233
stdlib/solana_sdk.h

@@ -79,7 +79,7 @@ void sol_log_64_(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t);
  */
 typedef struct
 {
-  uint8_t x[SIZE_PUBKEY];
+    uint8_t x[SIZE_PUBKEY];
 } SolPubkey;
 
 /**
@@ -91,14 +91,14 @@ typedef struct
  */
 static bool SolPubkey_same(const SolPubkey *one, const SolPubkey *two)
 {
-  for (int i = 0; i < sizeof(*one); i++)
-  {
-    if (one->x[i] != two->x[i])
+    for (int i = 0; i < sizeof(*one); i++)
     {
-      return false;
+        if (one->x[i] != two->x[i])
+        {
+            return false;
+        }
     }
-  }
-  return true;
+    return true;
 }
 
 /**
@@ -106,15 +106,15 @@ static bool SolPubkey_same(const SolPubkey *one, const SolPubkey *two)
  */
 typedef struct
 {
-  SolPubkey *key;      /** Public key of the account */
-  uint64_t *lamports;  /** Number of lamports owned by this account */
-  uint64_t data_len;   /** Length of data in bytes */
-  uint8_t *data;       /** On-chain data within this account */
-  SolPubkey *owner;    /** Program that owns this account */
-  uint64_t rent_epoch; /** The epoch at which this account will next owe rent */
-  bool is_signer;      /** Transaction was signed by this account's key? */
-  bool is_writable;    /** Is the account writable? */
-  bool executable;     /** This account's data contains a loaded program (and is now read-only) */
+    SolPubkey *key;      /** Public key of the account */
+    uint64_t *lamports;  /** Number of lamports owned by this account */
+    uint64_t data_len;   /** Length of data in bytes */
+    uint8_t *data;       /** On-chain data within this account */
+    SolPubkey *owner;    /** Program that owns this account */
+    uint64_t rent_epoch; /** The epoch at which this account will next owe rent */
+    bool is_signer;      /** Transaction was signed by this account's key? */
+    bool is_writable;    /** Is the account writable? */
+    bool executable;     /** This account's data contains a loaded program (and is now read-only) */
 } SolAccountInfo;
 
 /**
@@ -122,10 +122,10 @@ typedef struct
  */
 static void sol_memcpy(void *dst, const void *src, int len)
 {
-  for (int i = 0; i < len; i++)
-  {
-    *((uint8_t *)dst + i) = *((const uint8_t *)src + i);
-  }
+    for (int i = 0; i < len; i++)
+    {
+        *((uint8_t *)dst + i) = *((const uint8_t *)src + i);
+    }
 }
 
 /**
@@ -133,15 +133,15 @@ static void sol_memcpy(void *dst, const void *src, int len)
  */
 static int sol_memcmp(const void *s1, const void *s2, int n)
 {
-  for (int i = 0; i < n; i++)
-  {
-    uint8_t diff = *((uint8_t *)s1 + i) - *((const uint8_t *)s2 + i);
-    if (diff)
+    for (int i = 0; i < n; i++)
     {
-      return diff;
+        uint8_t diff = *((uint8_t *)s1 + i) - *((const uint8_t *)s2 + i);
+        if (diff)
+        {
+            return diff;
+        }
     }
-  }
-  return 0;
+    return 0;
 }
 
 /**
@@ -149,13 +149,13 @@ static int sol_memcmp(const void *s1, const void *s2, int n)
  */
 static void sol_memset(void *b, int c, size_t len)
 {
-  uint8_t *a = (uint8_t *)b;
-  while (len > 0)
-  {
-    *a = c;
-    a++;
-    len--;
-  }
+    uint8_t *a = (uint8_t *)b;
+    while (len > 0)
+    {
+        *a = c;
+        a++;
+        len--;
+    }
 }
 
 /**
@@ -163,13 +163,13 @@ static void sol_memset(void *b, int c, size_t len)
  */
 static size_t sol_strlen(const char *s)
 {
-  size_t len = 0;
-  while (*s)
-  {
-    len++;
-    s++;
-  }
-  return len;
+    size_t len = 0;
+    while (*s)
+    {
+        len++;
+        s++;
+    }
+    return len;
 }
 
 /**
@@ -189,19 +189,19 @@ void sol_panic_(const char *, uint64_t, uint64_t, uint64_t);
 /**
  * Asserts
  */
-#define sol_assert(expr) \
-  if (!(expr))           \
-  {                      \
-    sol_panic();         \
-  }
+#define sol_assert(expr)                                                                                               \
+    if (!(expr))                                                                                                       \
+    {                                                                                                                  \
+        sol_panic();                                                                                                   \
+    }
 
 /**
  * Seed used to create a program address or passed to sol_invoke_signed
  */
 typedef struct
 {
-  const uint8_t *addr; /** Seed bytes */
-  uint64_t len;        /** Length of the seed bytes */
+    const uint8_t *addr; /** Seed bytes */
+    uint64_t len;        /** Length of the seed bytes */
 } SolSignerSeed;
 
 /**
@@ -209,14 +209,14 @@ typedef struct
  */
 typedef struct
 {
-  SolAccountInfo ka[10]; /** Pointer to an array of SolAccountInfo, must already
+    SolAccountInfo ka[10]; /** Pointer to an array of SolAccountInfo, must already
                           point to an array of SolAccountInfos */
-  uint64_t ka_num;       /** Number of SolAccountInfo entries in `ka` */
-  const uint8_t *input;  /** pointer to the instruction data */
-  uint64_t input_len;    /** Length in bytes of the instruction data */
-  SolPubkey *program_id; /** program_id of the currently executing program */
-  const SolAccountInfo *ka_clock;
-  const SolAccountInfo *ka_instructions;
+    uint64_t ka_num;       /** Number of SolAccountInfo entries in `ka` */
+    const uint8_t *input;  /** pointer to the instruction data */
+    uint64_t input_len;    /** Length in bytes of the instruction data */
+    SolPubkey *program_id; /** program_id of the currently executing program */
+    const SolAccountInfo *ka_clock;
+    const SolAccountInfo *ka_instructions;
 } SolParameters;
 
 /**
@@ -238,108 +238,106 @@ typedef struct
  * @param params Pointer to a SolParameters structure
  * @return Boolean true if successful.
  */
-static uint64_t sol_deserialize(
-    const uint8_t *input,
-    SolParameters *params)
+static uint64_t sol_deserialize(const uint8_t *input, SolParameters *params)
 {
-  if (NULL == input || NULL == params)
-  {
-    return ERROR_INVALID_ARGUMENT;
-  }
-  params->ka_num = *(uint64_t *)input;
-  input += sizeof(uint64_t);
-
-  for (int i = 0; i < params->ka_num; i++)
-  {
-    uint8_t dup_info = input[0];
-    input += sizeof(uint8_t);
-
-    if (i >= SOL_ARRAY_SIZE(params->ka))
+    if (NULL == input || NULL == params)
     {
-      if (dup_info == UINT8_MAX)
-      {
-        input += sizeof(uint8_t);
-        input += sizeof(uint8_t);
-        input += sizeof(uint8_t);
-        input += 4; // padding
-        input += sizeof(SolPubkey);
-        input += sizeof(SolPubkey);
-        input += sizeof(uint64_t);
-        uint64_t data_len = *(uint64_t *)input;
-        input += sizeof(uint64_t);
-        input += data_len;
-        input += MAX_PERMITTED_DATA_INCREASE;
-        input = (uint8_t *)(((uint64_t)input + 8 - 1) & ~(8 - 1)); // padding
-        input += sizeof(uint64_t);
-      }
-      continue;
+        return ERROR_INVALID_ARGUMENT;
     }
-    if (dup_info == UINT8_MAX)
-    {
-      // is signer?
-      params->ka[i].is_signer = *(uint8_t *)input != 0;
-      input += sizeof(uint8_t);
-
-      // is writable?
-      params->ka[i].is_writable = *(uint8_t *)input != 0;
-      input += sizeof(uint8_t);
-
-      // executable?
-      params->ka[i].executable = *(uint8_t *)input;
-      input += sizeof(uint8_t);
-
-      input += 4; // padding
-
-      // key
-      params->ka[i].key = (SolPubkey *)input;
-      input += sizeof(SolPubkey);
-
-      // owner
-      params->ka[i].owner = (SolPubkey *)input;
-      input += sizeof(SolPubkey);
-
-      // lamports
-      params->ka[i].lamports = (uint64_t *)input;
-      input += sizeof(uint64_t);
-
-      // account data
-      params->ka[i].data_len = *(uint64_t *)input;
-      input += sizeof(uint64_t);
-      params->ka[i].data = (uint8_t *)input;
-      input += params->ka[i].data_len;
-      input += MAX_PERMITTED_DATA_INCREASE;
-      input = (uint8_t *)(((uint64_t)input + 8 - 1) & ~(8 - 1)); // padding
-
-      // rent epoch
-      params->ka[i].rent_epoch = *(uint64_t *)input;
-      input += sizeof(uint64_t);
-    }
-    else
+    params->ka_num = *(uint64_t *)input;
+    input += sizeof(uint64_t);
+
+    for (int i = 0; i < params->ka_num; i++)
     {
-      params->ka[i].is_signer = params->ka[dup_info].is_signer;
-      params->ka[i].is_writable = params->ka[dup_info].is_writable;
-      params->ka[i].executable = params->ka[dup_info].executable;
-      params->ka[i].key = params->ka[dup_info].key;
-      params->ka[i].owner = params->ka[dup_info].owner;
-      params->ka[i].lamports = params->ka[dup_info].lamports;
-      params->ka[i].data_len = params->ka[dup_info].data_len;
-      params->ka[i].data = params->ka[dup_info].data;
-      params->ka[i].rent_epoch = params->ka[dup_info].rent_epoch;
-      input += 7; // padding
+        uint8_t dup_info = input[0];
+        input += sizeof(uint8_t);
+
+        if (i >= SOL_ARRAY_SIZE(params->ka))
+        {
+            if (dup_info == UINT8_MAX)
+            {
+                input += sizeof(uint8_t);
+                input += sizeof(uint8_t);
+                input += sizeof(uint8_t);
+                input += 4; // padding
+                input += sizeof(SolPubkey);
+                input += sizeof(SolPubkey);
+                input += sizeof(uint64_t);
+                uint64_t data_len = *(uint64_t *)input;
+                input += sizeof(uint64_t);
+                input += data_len;
+                input += MAX_PERMITTED_DATA_INCREASE;
+                input = (uint8_t *)(((uint64_t)input + 8 - 1) & ~(8 - 1)); // padding
+                input += sizeof(uint64_t);
+            }
+            continue;
+        }
+        if (dup_info == UINT8_MAX)
+        {
+            // is signer?
+            params->ka[i].is_signer = *(uint8_t *)input != 0;
+            input += sizeof(uint8_t);
+
+            // is writable?
+            params->ka[i].is_writable = *(uint8_t *)input != 0;
+            input += sizeof(uint8_t);
+
+            // executable?
+            params->ka[i].executable = *(uint8_t *)input;
+            input += sizeof(uint8_t);
+
+            input += 4; // padding
+
+            // key
+            params->ka[i].key = (SolPubkey *)input;
+            input += sizeof(SolPubkey);
+
+            // owner
+            params->ka[i].owner = (SolPubkey *)input;
+            input += sizeof(SolPubkey);
+
+            // lamports
+            params->ka[i].lamports = (uint64_t *)input;
+            input += sizeof(uint64_t);
+
+            // account data
+            params->ka[i].data_len = *(uint64_t *)input;
+            input += sizeof(uint64_t);
+            params->ka[i].data = (uint8_t *)input;
+            input += params->ka[i].data_len;
+            input += MAX_PERMITTED_DATA_INCREASE;
+            input = (uint8_t *)(((uint64_t)input + 8 - 1) & ~(8 - 1)); // padding
+
+            // rent epoch
+            params->ka[i].rent_epoch = *(uint64_t *)input;
+            input += sizeof(uint64_t);
+        }
+        else
+        {
+            params->ka[i].is_signer = params->ka[dup_info].is_signer;
+            params->ka[i].is_writable = params->ka[dup_info].is_writable;
+            params->ka[i].executable = params->ka[dup_info].executable;
+            params->ka[i].key = params->ka[dup_info].key;
+            params->ka[i].owner = params->ka[dup_info].owner;
+            params->ka[i].lamports = params->ka[dup_info].lamports;
+            params->ka[i].data_len = params->ka[dup_info].data_len;
+            params->ka[i].data = params->ka[dup_info].data;
+            params->ka[i].rent_epoch = params->ka[dup_info].rent_epoch;
+            input += 7; // padding
+        }
     }
-  }
 
-  uint64_t data_len = *(uint64_t *)input;
-  input += sizeof(uint64_t);
+    uint64_t data_len = *(uint64_t *)input;
+    input += sizeof(uint64_t);
 
-  params->input_len = data_len;
-  params->input = input;
-  input += data_len;
+    params->input_len = data_len;
+    params->input = input;
+    input += data_len;
 
-  params->program_id = (SolPubkey *)input;
-  input += sizeof(SolPubkey);
+    params->program_id = (SolPubkey *)input;
+    input += sizeof(SolPubkey);
 
-  return 0;
+    return 0;
 }
 
 /**
@@ -347,8 +345,8 @@ static uint64_t sol_deserialize(
  */
 typedef struct
 {
-  const uint8_t *addr; /** bytes */
-  uint64_t len;        /** number of bytes*/
+    const uint8_t *addr; /** bytes */
+    uint64_t len;        /** number of bytes*/
 } SolBytes;
 
 /**
@@ -363,19 +361,16 @@ typedef struct
  * @param bytes_len Number of byte arrays
  * @param result 32 byte array to hold the result
  */
-static uint64_t sol_sha256(
-    const SolBytes *bytes,
-    int bytes_len,
-    const uint8_t *result);
+static uint64_t sol_sha256(const SolBytes *bytes, int bytes_len, const uint8_t *result);
 
 /**
  * Account Meta
  */
 typedef struct
 {
-  SolPubkey *pubkey; /** An account's public key */
-  bool is_writable;  /** True if the `pubkey` can be loaded as a read-write account */
-  bool is_signer;    /** True if an Instruction requires a Transaction signature matching `pubkey` */
+    SolPubkey *pubkey; /** An account's public key */
+    bool is_writable;  /** True if the `pubkey` can be loaded as a read-write account */
+    bool is_signer;    /** True if an Instruction requires a Transaction signature matching `pubkey` */
 } SolAccountMeta;
 
 /**
@@ -383,11 +378,11 @@ typedef struct
  */
 typedef struct
 {
-  SolPubkey *program_id;    /** Pubkey of the instruction processor that executes this instruction */
-  SolAccountMeta *accounts; /** Metadata for what accounts should be passed to the instruction processor */
-  uint64_t account_len;     /** Number of SolAccountMetas */
-  uint8_t *data;            /** Opaque data passed to the instruction processor */
-  uint64_t data_len;        /** Length of the data in bytes */
+    SolPubkey *program_id;    /** Pubkey of the instruction processor that executes this instruction */
+    SolAccountMeta *accounts; /** Metadata for what accounts should be passed to the instruction processor */
+    uint64_t account_len;     /** Number of SolAccountMetas */
+    uint8_t *data;            /** Opaque data passed to the instruction processor */
+    uint64_t data_len;        /** Length of the data in bytes */
 } SolInstruction;
 
 /**
@@ -396,8 +391,8 @@ typedef struct
  */
 typedef struct
 {
-  const SolSignerSeed *addr; /** An arry of a signer's seeds */
-  uint64_t len;              /** Number of seeds */
+    const SolSignerSeed *addr; /** An arry of a signer's seeds */
+    uint64_t len;              /** Number of seeds */
 } SolSignerSeeds;
 
 /**
@@ -408,11 +403,8 @@ typedef struct
  * @param Progam id of the signer
  * @param Program address created, filled on return
  */
-static uint64_t sol_create_program_address(
-    const SolSignerSeed *seeds,
-    int seeds_len,
-    const SolPubkey *program_id,
-    const SolPubkey *address);
+static uint64_t sol_create_program_address(const SolSignerSeed *seeds, int seeds_len, const SolPubkey *program_id,
+                                           const SolPubkey *address);
 
 /**
  * Cross-program invocation
@@ -428,26 +420,13 @@ static uint64_t sol_create_program_address(
  * @param seeds Seed bytes used to sign program accounts
  * @param seeds_len Length of the seeds array
  */
-static uint64_t sol_invoke_signed(
-    const SolInstruction *instruction,
-    const SolAccountInfo *account_infos,
-    int account_infos_len,
-    const SolSignerSeeds *signers_seeds,
-    int signers_seeds_len)
+static uint64_t sol_invoke_signed(const SolInstruction *instruction, const SolAccountInfo *account_infos,
+                                  int account_infos_len, const SolSignerSeeds *signers_seeds, int signers_seeds_len)
 {
-  uint64_t sol_invoke_signed_c(
-      const SolInstruction *instruction,
-      const SolAccountInfo *account_infos,
-      int account_infos_len,
-      const SolSignerSeeds *signers_seeds,
-      int signers_seeds_len);
-
-  return sol_invoke_signed_c(
-      instruction,
-      account_infos,
-      account_infos_len,
-      signers_seeds,
-      signers_seeds_len);
+    uint64_t sol_invoke_signed_c(const SolInstruction *instruction, const SolAccountInfo *account_infos,
+                                 int account_infos_len, const SolSignerSeeds *signers_seeds, int signers_seeds_len);
+
+    return sol_invoke_signed_c(instruction, account_infos, account_infos_len, signers_seeds, signers_seeds_len);
 }
 /**
  * Invoke another program
@@ -456,18 +435,11 @@ static uint64_t sol_invoke_signed(
  * @param account_infos Accounts used by instruction
  * @param account_infos_len Length of account_infos array
  */
-static uint64_t sol_invoke(
-    const SolInstruction *instruction,
-    const SolAccountInfo *account_infos,
-    int account_infos_len)
+static uint64_t sol_invoke(const SolInstruction *instruction, const SolAccountInfo *account_infos,
+                           int account_infos_len)
 {
-  const SolSignerSeeds signers_seeds[] = {{}};
-  return sol_invoke_signed(
-      instruction,
-      account_infos,
-      account_infos_len,
-      signers_seeds,
-      0);
+    const SolSignerSeeds signers_seeds[] = {{}};
+    return sol_invoke_signed(instruction, account_infos, account_infos_len, signers_seeds, 0);
 }
 
 /**@}*/
@@ -482,8 +454,7 @@ static uint64_t sol_invoke(
  *
  * @param key The public key to print
  */
-void sol_log_pubkey(
-    const SolPubkey *pubkey);
+void sol_log_pubkey(const SolPubkey *pubkey);
 
 /**
  * Prints the hexadecimal representation of an array
@@ -492,10 +463,10 @@ void sol_log_pubkey(
  */
 static void sol_log_array(const uint8_t *array, int len)
 {
-  for (int j = 0; j < len; j++)
-  {
-    sol_log_64(0, 0, 0, j, array[j]);
-  }
+    for (int j = 0; j < len; j++)
+    {
+        sol_log_64(0, 0, 0, j, array[j]);
+    }
 }
 
 /**
@@ -505,32 +476,32 @@ static void sol_log_array(const uint8_t *array, int len)
  */
 static void sol_log_params(const SolParameters *params)
 {
-  sol_log("- Program identifier:");
-  sol_log_pubkey(params->program_id);
-
-  sol_log("- Number of KeyedAccounts");
-  sol_log_64(0, 0, 0, 0, params->ka_num);
-  for (int i = 0; i < params->ka_num; i++)
-  {
-    sol_log("  - Is signer");
-    sol_log_64(0, 0, 0, 0, params->ka[i].is_signer);
-    sol_log("  - Is writable");
-    sol_log_64(0, 0, 0, 0, params->ka[i].is_writable);
-    sol_log("  - Key");
-    sol_log_pubkey(params->ka[i].key);
-    sol_log("  - Lamports");
-    sol_log_64(0, 0, 0, 0, *params->ka[i].lamports);
-    sol_log("  - data");
-    sol_log_array(params->ka[i].data, params->ka[i].data_len);
-    sol_log("  - Owner");
-    sol_log_pubkey(params->ka[i].owner);
-    sol_log("  - Executable");
-    sol_log_64(0, 0, 0, 0, params->ka[i].executable);
-    sol_log("  - Rent Epoch");
-    sol_log_64(0, 0, 0, 0, params->ka[i].rent_epoch);
-  }
-  sol_log("- Eth abi Instruction data\0");
-  sol_log_array(params->input, params->input_len);
+    sol_log("- Program identifier:");
+    sol_log_pubkey(params->program_id);
+
+    sol_log("- Number of KeyedAccounts");
+    sol_log_64(0, 0, 0, 0, params->ka_num);
+    for (int i = 0; i < params->ka_num; i++)
+    {
+        sol_log("  - Is signer");
+        sol_log_64(0, 0, 0, 0, params->ka[i].is_signer);
+        sol_log("  - Is writable");
+        sol_log_64(0, 0, 0, 0, params->ka[i].is_writable);
+        sol_log("  - Key");
+        sol_log_pubkey(params->ka[i].key);
+        sol_log("  - Lamports");
+        sol_log_64(0, 0, 0, 0, *params->ka[i].lamports);
+        sol_log("  - data");
+        sol_log_array(params->ka[i].data, params->ka[i].data_len);
+        sol_log("  - Owner");
+        sol_log_pubkey(params->ka[i].owner);
+        sol_log("  - Executable");
+        sol_log_64(0, 0, 0, 0, params->ka[i].executable);
+        sol_log("  - Rent Epoch");
+        sol_log_64(0, 0, 0, 0, params->ka[i].rent_epoch);
+    }
+    sol_log("- Eth abi Instruction data\0");
+    sol_log_array(params->input, params->input_len);
 }
 
 /**@}*/
@@ -550,11 +521,11 @@ uint64_t entrypoint(const uint8_t *input);
 #include <stdio.h>
 void sol_log_(const char *s, uint64_t len)
 {
-  printf("sol_log: %s\n", s);
+    printf("sol_log: %s\n", s);
 }
 void sol_log_64(uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5)
 {
-  printf("sol_log_64: %llu, %llu, %llu, %llu, %llu\n", arg1, arg2, arg3, arg4, arg5);
+    printf("sol_log_64: %llu, %llu, %llu, %llu, %llu\n", arg1, arg2, arg3, arg4, arg5);
 }
 #endif
 

+ 124 - 121
stdlib/stdlib.c

@@ -10,22 +10,22 @@
  */
 void __memset8(void *_dest, uint64_t val, uint32_t length)
 {
-	uint64_t *dest = _dest;
+    uint64_t *dest = _dest;
 
-	do
-	{
-		*dest++ = val;
-	} while (--length);
+    do
+    {
+        *dest++ = val;
+    } while (--length);
 }
 
 void __memset(void *_dest, uint8_t val, size_t length)
 {
-	uint8_t *dest = _dest;
+    uint8_t *dest = _dest;
 
-	do
-	{
-		*dest++ = val;
-	} while (--length);
+    do
+    {
+        *dest++ = val;
+    } while (--length);
 }
 
 /*
@@ -34,24 +34,24 @@ void __memset(void *_dest, uint8_t val, size_t length)
  */
 void __memcpy8(void *_dest, void *_src, uint32_t length)
 {
-	uint64_t *dest = _dest;
-	uint64_t *src = _src;
+    uint64_t *dest = _dest;
+    uint64_t *src = _src;
 
-	do
-	{
-		*dest++ = *src++;
-	} while (--length);
+    do
+    {
+        *dest++ = *src++;
+    } while (--length);
 }
 
 void __memcpy(void *_dest, const void *_src, uint32_t length)
 {
-	uint8_t *dest = _dest;
-	const uint8_t *src = _src;
+    uint8_t *dest = _dest;
+    const uint8_t *src = _src;
 
-	while (length--)
-	{
-		*dest++ = *src++;
-	}
+    while (length--)
+    {
+        *dest++ = *src++;
+    }
 }
 
 /*
@@ -59,25 +59,25 @@ void __memcpy(void *_dest, const void *_src, uint32_t length)
  */
 void __bzero8(void *_dest, uint32_t length)
 {
-	uint64_t *dest = _dest;
+    uint64_t *dest = _dest;
 
-	while (length--)
-	{
-		*dest++ = 0;
-	}
+    while (length--)
+    {
+        *dest++ = 0;
+    }
 }
 
 int __memcmp_ord(uint8_t *a, uint8_t *b, uint32_t len)
 {
-	do
-	{
-		int diff = (int)(*a++) - (int)(*b++);
+    do
+    {
+        int diff = (int)(*a++) - (int)(*b++);
 
-		if (diff)
-			return diff;
-	} while (--len);
+        if (diff)
+            return diff;
+    } while (--len);
 
-	return 0;
+    return 0;
 }
 
 // This function is used for abi decoding integers.
@@ -86,128 +86,131 @@ int __memcmp_ord(uint8_t *a, uint8_t *b, uint32_t len)
 // order since wasm is little endian.
 void __be32toleN(uint8_t *from, uint8_t *to, uint32_t length)
 {
-	from += 31;
+    from += 31;
 
-	do
-	{
-		*to++ = *from--;
-	} while (--length);
+    do
+    {
+        *to++ = *from--;
+    } while (--length);
 }
 
 void __beNtoleN(uint8_t *from, uint8_t *to, uint32_t length)
 {
-	from += length;
+    from += length;
 
-	do
-	{
-		*to++ = *--from;
-	} while (--length);
+    do
+    {
+        *to++ = *--from;
+    } while (--length);
 }
 
 // This function is for used for abi encoding integers
 // ABI encoding is big endian.
 void __leNtobe32(uint8_t *from, uint8_t *to, uint32_t length)
 {
-	to += 31;
+    to += 31;
 
-	do
-	{
-		*to-- = *from++;
-	} while (--length);
+    do
+    {
+        *to-- = *from++;
+    } while (--length);
 }
 
 void __leNtobeN(uint8_t *from, uint8_t *to, uint32_t length)
 {
-	to += length;
-
-	do
-	{
-		*--to = *from++;
-	} 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)
-{
-	struct vector *v;
-	size_t size_array = members * size;
-
-	v = __malloc(sizeof(*v) + size_array);
-	v->len = members;
-	v->size = members;
-
-	uint8_t *data = v->data;
-
-	if (initial != VECTOR_EMPTY)
-	{
-		while (size_array--)
-		{
-			*data++ = *initial++;
-		}
-	}
-	else
-	{
-		while (size_array--)
-		{
-			*data++ = 0;
-		}
-	}
-
-	return v;
+    to += length;
+    do
+    {
+        *--to = *from++;
+    } while (--length);
 }
 
 uint64_t vector_hash(struct vector *v)
 {
-	uint64_t hash = 0;
-	uint8_t *data = v->data;
-	uint32_t len = v->len;
+    uint64_t hash = 0;
+    uint8_t *data = v->data;
+    uint32_t len = v->len;
 
-	while (len--)
-	{
-		hash += *data;
-	}
+    while (len--)
+    {
+        hash += *data;
+    }
 
-	return hash;
+    return hash;
 }
 
 bool __memcmp(uint8_t *left, uint32_t left_len, uint8_t *right, uint32_t right_len)
 {
-	if (left_len != right_len)
-		return false;
+    if (left_len != right_len)
+        return false;
 
-	while (left_len--)
-	{
-		if (*left++ != *right++)
-			return false;
-	}
+    while (left_len--)
+    {
+        if (*left++ != *right++)
+            return false;
+    }
 
-	return true;
+    return true;
+}
+
+#ifndef TEST
+
+#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 is valid in Wasm
+struct vector *vector_new(uint32_t members, uint32_t size, uint8_t *initial)
+{
+    struct vector *v;
+    size_t size_array = members * size;
+
+    v = __malloc(sizeof(*v) + size_array);
+    v->len = members;
+    v->size = members;
+
+    uint8_t *data = v->data;
+
+    if (initial != VECTOR_EMPTY)
+    {
+        while (size_array--)
+        {
+            *data++ = *initial++;
+        }
+    }
+    else
+    {
+        while (size_array--)
+        {
+            *data++ = 0;
+        }
+    }
+
+    return v;
 }
 
 struct vector *concat(uint8_t *left, uint32_t left_len, uint8_t *right, uint32_t right_len)
 {
-	size_t size_array = left_len + right_len;
-	struct vector *v = __malloc(sizeof(*v) + size_array);
-	v->len = size_array;
-	v->size = size_array;
+    size_t size_array = left_len + right_len;
+    struct vector *v = __malloc(sizeof(*v) + size_array);
+    v->len = size_array;
+    v->size = size_array;
 
-	uint8_t *data = v->data;
+    uint8_t *data = v->data;
 
-	while (left_len--)
-	{
-		*data++ = *left++;
-	}
+    while (left_len--)
+    {
+        *data++ = *left++;
+    }
 
-	while (right_len--)
-	{
-		*data++ = *right++;
-	}
+    while (right_len--)
+    {
+        *data++ = *right++;
+    }
 
-	return v;
+    return v;
 }
+
+#endif

BIN
stdlib/test


BIN
stdlib/wasm/bigint.bc


BIN
stdlib/wasm/format.bc


BIN
stdlib/wasm/heap.bc


BIN
stdlib/wasm/ripemd160.bc


BIN
stdlib/wasm/stdlib.bc