Quellcode durchsuchen

Verify the heap

Signed-off-by: Sean Young <sean@mess.org>
Sean Young vor 5 Jahren
Ursprung
Commit
4ce77e93a5
5 geänderte Dateien mit 72 neuen und 3 gelöschten Zeilen
  1. 4 1
      src/emit/mod.rs
  2. BIN
      stdlib/stdlib.bc
  3. 1 1
      stdlib/stdlib.c
  4. 63 0
      tests/substrate.rs
  5. 4 1
      tests/substrate_builtins/mod.rs

+ 4 - 1
src/emit/mod.rs

@@ -1572,7 +1572,10 @@ impl<'a> Contract<'a> {
                 array.into()
             }
             Expression::AllocDynamicArray(_, ty, size, init) => {
-                let elem = ty.array_deref();
+                let elem = match ty {
+                    ast::Type::String | ast::Type::DynamicBytes => ast::Type::Bytes(1),
+                    _ => ty.array_deref(),
+                };
 
                 let size = self
                     .expression(size, vartab, function, runtime)

BIN
stdlib/stdlib.bc


+ 1 - 1
stdlib/stdlib.c

@@ -97,7 +97,7 @@ void __init_heap()
 	struct chunk *first = (struct chunk *)0x10000;
 	first->next = first->prev = NULL;
 	first->allocated = false;
-	first->length = (size_t)(__builtin_wasm_memory_size(0) -
+	first->length = (size_t)(__builtin_wasm_memory_size(0) * 0x10000 -
 							 (size_t)first - sizeof(struct chunk));
 }
 

+ 63 - 0
tests/substrate.rs

@@ -802,6 +802,69 @@ impl TestRuntime {
             }
         }
     }
+
+    pub fn heap_verify(&self) {
+        let memsize = self.vm.memory.current_size().0 as usize * 0x10000;
+        println!("memory size:{}", memsize);
+        let mut buf = Vec::new();
+        buf.resize(memsize, 0);
+
+        let mut current_elem = 0x10000;
+        let mut last_elem = 0u32;
+
+        loop {
+            let next: u32 = self.vm.memory.get_value(current_elem).unwrap();
+            let prev: u32 = self.vm.memory.get_value(current_elem + 4).unwrap();
+            let length: u32 = self.vm.memory.get_value(current_elem + 8).unwrap();
+            let allocated: u32 = self.vm.memory.get_value(current_elem + 12).unwrap();
+
+            println!(
+                "next:{:08x} prev:{:08x} length:{} allocated:{}",
+                next, prev, length, allocated
+            );
+
+            let buf = self
+                .vm
+                .memory
+                .get(current_elem + 16, length as usize)
+                .unwrap();
+
+            if allocated == 0 {
+                println!("{:08x} {} not allocated", current_elem + 16, length);
+            } else {
+                println!("{:08x} {} allocated", current_elem + 16, length);
+
+                assert_eq!(allocated & 0xffff, 1);
+
+                for offset in (0..buf.len()).step_by(16) {
+                    let mut hex = "\t".to_string();
+                    let mut chars = "\t".to_string();
+                    for i in 0..16 {
+                        if offset + i >= buf.len() {
+                            break;
+                        }
+                        let b = buf[offset + i];
+                        hex.push_str(&format!(" {:02x}", b));
+                        if b >= 0x20 && b <= 0x7e {
+                            chars.push_str(&format!("  {}", b as char));
+                        } else {
+                            chars.push_str("   ");
+                        }
+                    }
+                    println!("{}\n{}", hex, chars);
+                }
+            }
+
+            assert_eq!(last_elem, prev);
+
+            if next == 0 {
+                break;
+            }
+
+            last_elem = current_elem;
+            current_elem = next;
+        }
+    }
 }
 
 pub fn build_solidity(src: &'static str) -> TestRuntime {

+ 4 - 1
tests/substrate_builtins/mod.rs

@@ -123,7 +123,7 @@ fn abi_encode() {
                 string b = "foobar";
                 assert(abi.encode(b) == hex"18666f6f626172");
 
-                // BORKED assert(abi.encode("foobar") == hex"18666f6f626172");
+                assert(abi.encode("foobar") == hex"18666f6f626172");
             }
 
             function test3() public {
@@ -135,10 +135,13 @@ fn abi_encode() {
     );
 
     runtime.function("test", Vec::new());
+    runtime.heap_verify();
 
     runtime.function("test2", Vec::new());
+    runtime.heap_verify();
 
     runtime.function("test3", Vec::new());
+    runtime.heap_verify();
 }
 
 #[test]