Skip to content

Commit

Permalink
Extract lists into a standalone test
Browse files Browse the repository at this point in the history
  • Loading branch information
alexcrichton committed Sep 23, 2021
1 parent 23f0591 commit 61b20c5
Show file tree
Hide file tree
Showing 22 changed files with 950 additions and 829 deletions.
1 change: 0 additions & 1 deletion crates/test-helpers/build.rs
Expand Up @@ -46,7 +46,6 @@ fn main() {
}

if cfg!(feature = "wasm-c") {
println!("cargo:rerun-if-changed=../../tests/runtime");
for test_dir in fs::read_dir("../../tests/runtime").unwrap() {
let test_dir = test_dir.unwrap().path();
let c_impl = test_dir.join("wasm.c");
Expand Down
4 changes: 4 additions & 0 deletions crates/test-rust-wasm/Cargo.toml
Expand Up @@ -26,3 +26,7 @@ test = false
[[bin]]
name = "variants"
test = false

[[bin]]
name = "lists"
test = false
3 changes: 3 additions & 0 deletions crates/test-rust-wasm/src/bin/lists.rs
@@ -0,0 +1,3 @@
include!("../../../../tests/runtime/lists/wasm.rs");

fn main() {}
47 changes: 47 additions & 0 deletions crates/test-rust-wasm/src/lib.rs
@@ -0,0 +1,47 @@
//! A small global allocator implementation which is intended to keep track of
//! the number of allocated bytes to ensure that all our integration glue indeed
//! manages memory correctly and doesn't leak anything.

use std::alloc::{GlobalAlloc, Layout, System};
use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};

#[global_allocator]
static ALLOC: A = A;

static ALLOC_AMT: AtomicUsize = AtomicUsize::new(0);

struct A;

unsafe impl GlobalAlloc for A {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
let ptr = System.alloc(layout);
if !ptr.is_null() {
ALLOC_AMT.fetch_add(layout.size(), SeqCst);
}
return ptr;
}

unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
// Poison all deallocations to try to catch any use-after-free in the
// bindings as early as possible.
std::ptr::write_bytes(ptr, 0xde, layout.size());
ALLOC_AMT.fetch_sub(layout.size(), SeqCst);
System.dealloc(ptr, layout)
}
}

pub fn get() -> usize {
ALLOC_AMT.load(SeqCst)
}

pub fn guard() -> impl Drop {
struct A(usize);

impl Drop for A {
fn drop(&mut self) {
assert_eq!(get(), self.0);
}
}

A(get())
}
25 changes: 0 additions & 25 deletions tests/host.witx
@@ -1,28 +1,3 @@
// ===========================================
// lists
// ===========================================

list_param: function(a: list<u8>)
list_param2: function(a: string)
list_param3: function(a: list<string>)
list_param4: function(a: list<list<string>>)
list_result: function() -> list<u8>
list_result2: function() -> string
list_result3: function() -> list<string>

list_minmax8: function(a: list<u8>, b: list<s8>) -> (list<u8>, list<s8>)
list_minmax16: function(a: list<u16>, b: list<s16>) -> (list<u16>, list<s16>)
list_minmax32: function(a: list<u32>, b: list<s32>) -> (list<u32>, list<s32>)
list_minmax64: function(a: list<u64>, b: list<s64>) -> (list<u64>, list<s64>)
list_minmax_float: function(a: list<f32>, b: list<f64>) -> (list<f32>, list<f64>)

string_roundtrip: function(a: string) -> string

unaligned_roundtrip1: function(a: list<u16>, b: list<u32>, c: list<u64>, d: list<flag32>, e: list<flag64>)

record unaligned_record { a: u32, b: u64 }
unaligned_roundtrip2: function(a: list<unaligned_record>, b: list<f32>, c: list<f64>, d: list<string>, e: list<list<u8>>)

// ===========================================
// handles
// ===========================================
Expand Down
112 changes: 0 additions & 112 deletions tests/runtime/exports.c
Expand Up @@ -5,118 +5,6 @@
#include <string.h>
#include <wasm.h>

// "custom allocator" which just keeps track of allocated bytes

static size_t ALLOCATED_BYTES = 0;

__attribute__((export_name("canonical_abi_realloc")))
void *canonical_abi_realloc( void *ptr, size_t orig_size, size_t orig_align, size_t new_size) {
void *ret = realloc(ptr, new_size);
if (!ret)
abort();
ALLOCATED_BYTES -= orig_size;
ALLOCATED_BYTES += new_size;
return ret;
}

__attribute__((export_name("canonical_abi_free")))
void canonical_abi_free(void *ptr, size_t size, size_t align) {
if (size > 0) {
ALLOCATED_BYTES -= size;
free(ptr);
}
}

uint32_t wasm_allocated_bytes(void) {
return ALLOCATED_BYTES;
}


void wasm_list_param(wasm_list_u8_t *a) {
assert(a->len == 4);
assert(a->ptr[0] == 1);
assert(a->ptr[1] == 2);
assert(a->ptr[2] == 3);
assert(a->ptr[3] == 4);
wasm_list_u8_free(a);
}

void wasm_list_param2(wasm_string_t *a) {
assert(a->len == 3);
assert(a->ptr[0] == 'f');
assert(a->ptr[1] == 'o');
assert(a->ptr[2] == 'o');
wasm_string_free(a);
}

void wasm_list_param3(wasm_list_string_t *a) {
assert(a->len == 3);
assert(a->ptr[0].len == 3);
assert(a->ptr[0].ptr[0] == 'f');
assert(a->ptr[0].ptr[1] == 'o');
assert(a->ptr[0].ptr[2] == 'o');

assert(a->ptr[1].len == 3);
assert(a->ptr[1].ptr[0] == 'b');
assert(a->ptr[1].ptr[1] == 'a');
assert(a->ptr[1].ptr[2] == 'r');

assert(a->ptr[2].len == 3);
assert(a->ptr[2].ptr[0] == 'b');
assert(a->ptr[2].ptr[1] == 'a');
assert(a->ptr[2].ptr[2] == 'z');

wasm_list_string_free(a);
}

void wasm_list_param4(wasm_list_list_string_t *a) {
assert(a->len == 2);
assert(a->ptr[0].len == 2);
assert(a->ptr[1].len == 1);

assert(a->ptr[0].ptr[0].len == 3);
assert(a->ptr[0].ptr[0].ptr[0] == 'f');
assert(a->ptr[0].ptr[0].ptr[1] == 'o');
assert(a->ptr[0].ptr[0].ptr[2] == 'o');

assert(a->ptr[0].ptr[1].len == 3);
assert(a->ptr[0].ptr[1].ptr[0] == 'b');
assert(a->ptr[0].ptr[1].ptr[1] == 'a');
assert(a->ptr[0].ptr[1].ptr[2] == 'r');

assert(a->ptr[1].ptr[0].len == 3);
assert(a->ptr[1].ptr[0].ptr[0] == 'b');
assert(a->ptr[1].ptr[0].ptr[1] == 'a');
assert(a->ptr[1].ptr[0].ptr[2] == 'z');

wasm_list_list_string_free(a);
}

void wasm_list_result(wasm_list_u8_t *ret0) {
ret0->ptr = canonical_abi_realloc(NULL, 0, 1, 5);
ret0->len = 5;
ret0->ptr[0] = 1;
ret0->ptr[1] = 2;
ret0->ptr[2] = 3;
ret0->ptr[3] = 4;
ret0->ptr[4] = 5;
}

void wasm_list_result2(wasm_string_t *ret0) {
wasm_string_dup(ret0, "hello!");
}

void wasm_list_result3(wasm_list_string_t *ret0) {
ret0->len = 2;
ret0->ptr = canonical_abi_realloc(NULL, 0, alignof(wasm_string_t), 2 * sizeof(wasm_string_t));

wasm_string_dup(&ret0->ptr[0], "hello,");
wasm_string_dup(&ret0->ptr[1], "world!");
}

void wasm_string_roundtrip(wasm_string_t *a, wasm_string_t *ret0) {
*ret0 = *a;
}

wasm_wasm_state_t wasm_wasm_state_create(void) {
return wasm_wasm_state_new((void*) 100);
Expand Down
166 changes: 0 additions & 166 deletions tests/runtime/imports.c
Expand Up @@ -7,172 +7,6 @@
#include <string.h>
#include <wasm.h>

static void test_lists() {
{
uint8_t list[] = {1, 2, 3, 4};
host_list_u8_t a;
a.ptr = list;
a.len = 4;
host_list_param(&a);
}

{
host_string_t a;
host_string_set(&a, "foo");
host_list_param2(&a);
}

{
host_string_t list[3];
host_string_set(&list[0], "foo");
host_string_set(&list[1], "bar");
host_string_set(&list[2], "baz");
host_list_string_t a;
a.ptr = list;
a.len = 3;
host_list_param3(&a);
}

{
host_string_t list1[2];
host_string_t list2[1];
host_string_set(&list1[0], "foo");
host_string_set(&list1[1], "bar");
host_string_set(&list2[0], "baz");
host_list_list_string_t a;
a.ptr[0].len = 2;
a.ptr[0].ptr = list1;
a.ptr[1].len = 1;
a.ptr[1].ptr = list2;
a.len = 2;
host_list_param4(&a);
}

{
host_list_u8_t a;
host_list_result(&a);
assert(a.len == 5);
assert(memcmp(a.ptr, "\x01\x02\x03\x04\x05", 5) == 0);
host_list_u8_free(&a);
}

{
host_string_t a;
host_list_result2(&a);
assert(a.len == 6);
assert(memcmp(a.ptr, "hello!", 6) == 0);
host_string_free(&a);
}

{
host_list_string_t a;
host_list_result3(&a);
assert(a.len == 2);
assert(a.ptr[0].len == 6);
assert(a.ptr[1].len == 6);
assert(memcmp(a.ptr[0].ptr, "hello,", 6) == 0);
assert(memcmp(a.ptr[1].ptr, "world!", 6) == 0);
host_list_string_free(&a);
}

{
host_string_t a, b;
host_string_set(&a, "x");
host_string_roundtrip(&a, &b);
assert(b.len == a.len);
assert(memcmp(b.ptr, a.ptr, a.len) == 0);
host_string_free(&b);

host_string_set(&a, "");
host_string_roundtrip(&a, &b);
assert(b.len == a.len);
host_string_free(&b);

host_string_set(&a, "hello");
host_string_roundtrip(&a, &b);
assert(b.len == a.len);
assert(memcmp(b.ptr, a.ptr, a.len) == 0);
host_string_free(&b);

host_string_set(&a, "hello ⚑ world");
host_string_roundtrip(&a, &b);
assert(b.len == a.len);
assert(memcmp(b.ptr, a.ptr, a.len) == 0);
host_string_free(&b);
}

{
uint8_t u8[2] = {0, UCHAR_MAX};
int8_t s8[2] = {SCHAR_MIN, SCHAR_MAX};
host_list_u8_t list_u8 = { u8, 2 };
host_list_s8_t list_s8 = { s8, 2 };
host_list_u8_t list_u8_out;
host_list_s8_t list_s8_out;
host_list_minmax8(&list_u8, &list_s8, &list_u8_out, &list_s8_out);
assert(list_u8_out.len == 2 && list_u8_out.ptr[0] == 0 && list_u8_out.ptr[1] == UCHAR_MAX);
assert(list_s8_out.len == 2 && list_s8_out.ptr[0] == SCHAR_MIN && list_s8_out.ptr[1] == SCHAR_MAX);
host_list_u8_free(&list_u8_out);
host_list_s8_free(&list_s8_out);
}

{
uint16_t u16[2] = {0, USHRT_MAX};
int16_t s16[2] = {SHRT_MIN, SHRT_MAX};
host_list_u16_t list_u16 = { u16, 2 };
host_list_s16_t list_s16 = { s16, 2 };
host_list_u16_t list_u16_out;
host_list_s16_t list_s16_out;
host_list_minmax16(&list_u16, &list_s16, &list_u16_out, &list_s16_out);
assert(list_u16_out.len == 2 && list_u16_out.ptr[0] == 0 && list_u16_out.ptr[1] == USHRT_MAX);
assert(list_s16_out.len == 2 && list_s16_out.ptr[0] == SHRT_MIN && list_s16_out.ptr[1] == SHRT_MAX);
host_list_u16_free(&list_u16_out);
host_list_s16_free(&list_s16_out);
}

{
uint32_t u32[2] = {0, UINT_MAX};
int32_t s32[2] = {INT_MIN, INT_MAX};
host_list_u32_t list_u32 = { u32, 2 };
host_list_s32_t list_s32 = { s32, 2 };
host_list_u32_t list_u32_out;
host_list_s32_t list_s32_out;
host_list_minmax32(&list_u32, &list_s32, &list_u32_out, &list_s32_out);
assert(list_u32_out.len == 2 && list_u32_out.ptr[0] == 0 && list_u32_out.ptr[1] == UINT_MAX);
assert(list_s32_out.len == 2 && list_s32_out.ptr[0] == INT_MIN && list_s32_out.ptr[1] == INT_MAX);
host_list_u32_free(&list_u32_out);
host_list_s32_free(&list_s32_out);
}

{
uint64_t u64[2] = {0, ULLONG_MAX};
int64_t s64[2] = {LLONG_MIN, LLONG_MAX};
host_list_u64_t list_u64 = { u64, 2 };
host_list_s64_t list_s64 = { s64, 2 };
host_list_u64_t list_u64_out;
host_list_s64_t list_s64_out;
host_list_minmax64(&list_u64, &list_s64, &list_u64_out, &list_s64_out);
assert(list_u64_out.len == 2 && list_u64_out.ptr[0] == 0 && list_u64_out.ptr[1] == ULLONG_MAX);
assert(list_s64_out.len == 2 && list_s64_out.ptr[0] == LLONG_MIN && list_s64_out.ptr[1] == LLONG_MAX);
host_list_u64_free(&list_u64_out);
host_list_s64_free(&list_s64_out);
}

{
float f32[4] = {-FLT_MAX, FLT_MAX, -INFINITY, INFINITY};
double f64[4] = {-DBL_MAX, DBL_MAX, -INFINITY, INFINITY};
host_list_f32_t list_f32 = { f32, 4 };
host_list_f64_t list_f64 = { f64, 4 };
host_list_f32_t list_f32_out;
host_list_f64_t list_f64_out;
host_list_minmax_float(&list_f32, &list_f64, &list_f32_out, &list_f64_out);
assert(list_f32_out.len == 4 && list_f32_out.ptr[0] == -FLT_MAX && list_f32_out.ptr[1] == FLT_MAX);
assert(list_f32_out.ptr[2] == -INFINITY && list_f32_out.ptr[3] == INFINITY);
assert(list_f64_out.len == 4 && list_f64_out.ptr[0] == -DBL_MAX && list_f64_out.ptr[1] == DBL_MAX);
assert(list_f64_out.ptr[2] == -INFINITY && list_f64_out.ptr[3] == INFINITY);
host_list_f32_free(&list_f32_out);
host_list_f64_free(&list_f64_out);
}
}

static void test_flavorful() {
{
Expand Down

0 comments on commit 61b20c5

Please sign in to comment.