Browse Source

Remove deduplication in stdlib functions

Signed-off-by: Sean Young <sean@mess.org>
Sean Young 4 years ago
parent
commit
22c9ab954c
7 changed files with 38 additions and 186 deletions
  1. 28 35
      src/emit/mod.rs
  2. 1 1
      stdlib/Makefile
  3. BIN
      stdlib/bpf/solana.bc
  4. BIN
      stdlib/bpf/stdlib.bc
  5. 0 142
      stdlib/solana.c
  6. 5 4
      stdlib/stdlib.c
  7. 4 4
      stdlib/stdlib.h

+ 28 - 35
src/emit/mod.rs

@@ -6066,61 +6066,54 @@ impl<'a> Contract<'a> {
     }
 }
 
-static STDLIB_IR: &[u8] = include_bytes!("../../stdlib/wasm/stdlib.bc");
+static BPF_IR: [&[u8]; 4] = [
+    include_bytes!("../../stdlib/bpf/stdlib.bc"),
+    include_bytes!("../../stdlib/bpf/bigint.bc"),
+    include_bytes!("../../stdlib/bpf/format.bc"),
+    include_bytes!("../../stdlib/bpf/solana.bc"),
+];
+
+static WASM_IR: [&[u8]; 4] = [
+    include_bytes!("../../stdlib/wasm/stdlib.bc"),
+    include_bytes!("../../stdlib/wasm/wasmheap.bc"),
+    include_bytes!("../../stdlib/wasm/bigint.bc"),
+    include_bytes!("../../stdlib/wasm/format.bc"),
+];
+
 static SHA3_IR: &[u8] = include_bytes!("../../stdlib/wasm/sha3.bc");
 static RIPEMD160_IR: &[u8] = include_bytes!("../../stdlib/wasm/ripemd160.bc");
 static SUBSTRATE_IR: &[u8] = include_bytes!("../../stdlib/wasm/substrate.bc");
-static WASMHEAP_IR: &[u8] = include_bytes!("../../stdlib/wasm/wasmheap.bc");
-static BIGINT_WASM_IR: &[u8] = include_bytes!("../../stdlib/wasm/bigint.bc");
-static BIGINT_BPF_IR: &[u8] = include_bytes!("../../stdlib/bpf/bigint.bc");
-static FORMAT_WASM_IR: &[u8] = include_bytes!("../../stdlib/wasm/format.bc");
-static FORMAT_BPF_IR: &[u8] = include_bytes!("../../stdlib/bpf/format.bc");
-static SOLANA_IR: &[u8] = include_bytes!("../../stdlib/bpf/solana.bc");
 
 /// Return the stdlib as parsed llvm module. The solidity standard library is hardcoded into
 /// the solang library
 fn load_stdlib<'a>(context: &'a Context, target: &Target) -> Module<'a> {
     if *target == Target::Solana {
-        let memory = MemoryBuffer::create_from_memory_range(SOLANA_IR, "solana");
+        let memory = MemoryBuffer::create_from_memory_range(&BPF_IR[0], "bpf_bc");
 
         let module = Module::parse_bitcode_from_buffer(&memory, context).unwrap();
 
-        let memory = MemoryBuffer::create_from_memory_range(BIGINT_BPF_IR, "bigint");
-
-        module
-            .link_in_module(Module::parse_bitcode_from_buffer(&memory, context).unwrap())
-            .unwrap();
-
-        let memory = MemoryBuffer::create_from_memory_range(FORMAT_BPF_IR, "format");
+        for bc in BPF_IR.iter().skip(1) {
+            let memory = MemoryBuffer::create_from_memory_range(bc, "bpf_bc");
 
-        module
-            .link_in_module(Module::parse_bitcode_from_buffer(&memory, context).unwrap())
-            .unwrap();
+            module
+                .link_in_module(Module::parse_bitcode_from_buffer(&memory, context).unwrap())
+                .unwrap();
+        }
 
         return module;
     }
 
-    let memory = MemoryBuffer::create_from_memory_range(STDLIB_IR, "stdlib");
+    let memory = MemoryBuffer::create_from_memory_range(&WASM_IR[0], "wasm_bc");
 
     let module = Module::parse_bitcode_from_buffer(&memory, context).unwrap();
 
-    let memory = MemoryBuffer::create_from_memory_range(BIGINT_WASM_IR, "bigint");
+    for bc in WASM_IR.iter().skip(1) {
+        let memory = MemoryBuffer::create_from_memory_range(bc, "wasm_bc");
 
-    module
-        .link_in_module(Module::parse_bitcode_from_buffer(&memory, context).unwrap())
-        .unwrap();
-
-    let memory = MemoryBuffer::create_from_memory_range(FORMAT_WASM_IR, "format");
-
-    module
-        .link_in_module(Module::parse_bitcode_from_buffer(&memory, context).unwrap())
-        .unwrap();
-
-    let memory = MemoryBuffer::create_from_memory_range(WASMHEAP_IR, "wasmheap");
-
-    module
-        .link_in_module(Module::parse_bitcode_from_buffer(&memory, context).unwrap())
-        .unwrap();
+        module
+            .link_in_module(Module::parse_bitcode_from_buffer(&memory, context).unwrap())
+            .unwrap();
+    }
 
     if Target::Substrate == *target {
         let memory = MemoryBuffer::create_from_memory_range(SUBSTRATE_IR, "substrate");

+ 1 - 1
stdlib/Makefile

@@ -4,7 +4,7 @@ CFLAGS=--target=$(TARGET) -emit-llvm -O3 -ffreestanding -fno-builtin -Wall -Wno-
 bpf/%.bc wasm/%.bc: %.c
 	$(CC) -c $(CFLAGS) $< -o $@
 
-SOLANA=$(addprefix bpf/,solana.bc bigint.bc format.bc)
+SOLANA=$(addprefix bpf/,solana.bc bigint.bc format.bc stdlib.bc)
 WASM=$(addprefix wasm/,ripemd160.bc sha3.bc stdlib.bc substrate.bc bigint.bc format.bc wasmheap.bc)
 
 all: $(SOLANA) $(WASM)

BIN
stdlib/bpf/solana.bc


BIN
stdlib/bpf/stdlib.bc


+ 0 - 142
stdlib/solana.c

@@ -19,149 +19,7 @@ entrypoint(const uint8_t *input)
     return solang_dispatch(params.data, params.data_len, ka);
 }
 
-/*
- * Vector is used for dynamic array
- */
-struct vector
-{
-    uint32_t len;
-    uint32_t size;
-    uint8_t data[];
-};
-
 void *__malloc(uint32_t size)
 {
     return sol_alloc_free_(size, NULL);
 }
-
-/*
- * Fast-ish clear, 8 bytes at a time.
- */
-void __bzero8(void *_dest, uint32_t length)
-{
-    uint64_t *dest = _dest;
-
-    while (length--)
-    {
-        *dest++ = 0;
-    }
-}
-
-void __memset8(void *_dest, uint64_t val, uint32_t length)
-{
-    uint64_t *dest = _dest;
-
-    do
-    {
-        *dest++ = val;
-    } while (--length);
-}
-
-void __memcpy(void *_dest, const void *_src, uint32_t length)
-{
-    uint8_t *dest = _dest;
-    const uint8_t *src = _src;
-
-    while (length--)
-    {
-        *dest++ = *src++;
-    }
-}
-
-// 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;
-    uint32_t size_array = members * size;
-
-    v = __malloc(sizeof(*v) + size_array);
-    v->len = members;
-    v->size = members;
-
-    uint8_t *data = v->data;
-
-    if ((int)initial != -1)
-    {
-        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)
-{
-    uint32_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;
-
-    while (left_len--)
-    {
-        *data++ = *left++;
-    }
-
-    while (right_len--)
-    {
-        *data++ = *right++;
-    }
-
-    return v;
-}
-
-// This function is used for abi decoding integers.
-// ABI encoding is big endian, and can have integers of 8 to 256 bits
-// (1 to 32 bytes). This function copies length bytes and reverses the
-// order since wasm is little endian.
-void __be32toleN(uint8_t *from, uint8_t *to, uint32_t length)
-{
-    from += 31;
-
-    do
-    {
-        *to++ = *from--;
-    } while (--length);
-}
-
-void __beNtoleN(uint8_t *from, uint8_t *to, uint32_t length)
-{
-    from += length;
-
-    do
-    {
-        *to++ = *--from;
-    } while (--length);
-}
-
-void __leNtobeN(uint8_t *from, uint8_t *to, uint32_t length)
-{
-    to += 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;
-
-    do
-    {
-        *to-- = *from++;
-    } while (--length);
-}

+ 5 - 4
stdlib/stdlib.c

@@ -7,7 +7,7 @@
 
 /*
  */
-void __memset8(void *_dest, uint64_t val, size_t length)
+void __memset8(void *_dest, uint64_t val, uint32_t length)
 {
 	uint64_t *dest = _dest;
 
@@ -26,11 +26,12 @@ void __memset(void *_dest, uint8_t val, size_t length)
 		*dest++ = val;
 	} while (--length);
 }
+
 /*
  * Our memcpy can only deal with multiples of 8 bytes. This is enough for
  * simple allocator below.
  */
-void __memcpy8(void *_dest, void *_src, size_t length)
+void __memcpy8(void *_dest, void *_src, uint32_t length)
 {
 	uint64_t *dest = _dest;
 	uint64_t *src = _src;
@@ -41,7 +42,7 @@ void __memcpy8(void *_dest, void *_src, size_t length)
 	} while (--length);
 }
 
-void __memcpy(void *_dest, const void *_src, size_t length)
+void __memcpy(void *_dest, const void *_src, uint32_t length)
 {
 	uint8_t *dest = _dest;
 	const uint8_t *src = _src;
@@ -55,7 +56,7 @@ void __memcpy(void *_dest, const void *_src, size_t length)
 /*
  * Fast-ish clear, 8 bytes at a time.
  */
-void __bzero8(void *_dest, size_t length)
+void __bzero8(void *_dest, uint32_t length)
 {
 	uint64_t *dest = _dest;
 

+ 4 - 4
stdlib/stdlib.h

@@ -8,7 +8,7 @@ struct vector
     uint8_t data[];
 };
 
-void *__malloc(size_t size);
-void __memset(void *dest, uint8_t val, size_t length);
-void __memcpy(void *dest, const void *src, size_t length);
-void __memcpy8(void *_dest, void *_src, size_t length);
+extern void *__malloc(size_t size);
+extern void __memset(void *dest, uint8_t val, size_t length);
+extern void __memcpy(void *dest, const void *src, uint32_t length);
+extern void __memcpy8(void *_dest, void *_src, uint32_t length);