diff options
-rw-r--r-- | src/prebuilt/wasm2c_atomicops_source_declarations.cc | 56 | ||||
-rw-r--r-- | src/prebuilt/wasm2c_simd_source_declarations.cc | 8 | ||||
-rw-r--r-- | src/prebuilt/wasm2c_source_declarations.cc | 150 | ||||
-rw-r--r-- | src/template/wasm2c.declarations.c | 97 | ||||
-rw-r--r-- | src/template/wasm2c_atomicops.declarations.c | 55 | ||||
-rw-r--r-- | src/template/wasm2c_simd.declarations.c | 8 | ||||
-rw-r--r-- | test/wasm2c/add.txt | 97 | ||||
-rw-r--r-- | test/wasm2c/check-imports.txt | 97 | ||||
-rw-r--r-- | test/wasm2c/export-names.txt | 97 | ||||
-rw-r--r-- | test/wasm2c/hello.txt | 97 | ||||
-rw-r--r-- | test/wasm2c/minimal.txt | 97 | ||||
-rw-r--r-- | test/wasm2c/tail-calls.txt | 97 |
12 files changed, 447 insertions, 509 deletions
diff --git a/src/prebuilt/wasm2c_atomicops_source_declarations.cc b/src/prebuilt/wasm2c_atomicops_source_declarations.cc index 91b6929e..5e82c15b 100644 --- a/src/prebuilt/wasm2c_atomicops_source_declarations.cc +++ b/src/prebuilt/wasm2c_atomicops_source_declarations.cc @@ -225,23 +225,23 @@ R"w2c_template( TRAP(UNALIGNED); \ R"w2c_template( } )w2c_template" R"w2c_template( -#define DEFINE_ATOMIC_LOAD(name, t1, t2, t3, force_read) \ +#define DEFINE_ATOMIC_LOAD(name, t1, t2, t3, force_read) \ )w2c_template" -R"w2c_template( static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \ +R"w2c_template( static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \ )w2c_template" -R"w2c_template( MEMCHECK(mem, addr, t1); \ +R"w2c_template( MEMCHECK(mem, addr, t1); \ )w2c_template" -R"w2c_template( ATOMIC_ALIGNMENT_CHECK(addr, t1); \ +R"w2c_template( ATOMIC_ALIGNMENT_CHECK(addr, t1); \ )w2c_template" -R"w2c_template( t1 result; \ +R"w2c_template( t1 result; \ )w2c_template" -R"w2c_template( wasm_rt_memcpy(&result, &mem->data[addr], sizeof(t1)); \ +R"w2c_template( wasm_rt_memcpy(&result, MEM_ADDR(mem, addr, sizeof(t1)), sizeof(t1)); \ )w2c_template" -R"w2c_template( result = atomic_load_##t1(&mem->data[addr]); \ +R"w2c_template( result = atomic_load_##t1(MEM_ADDR(mem, addr, sizeof(t1))); \ )w2c_template" -R"w2c_template( force_read(result); \ +R"w2c_template( force_read(result); \ )w2c_template" -R"w2c_template( return (t3)(t2)result; \ +R"w2c_template( return (t3)(t2)result; \ )w2c_template" R"w2c_template( } )w2c_template" @@ -271,7 +271,7 @@ R"w2c_template( ATOMIC_ALIGNMENT_CHECK(addr, t1); )w2c_template" R"w2c_template( t1 wrapped = (t1)value; \ )w2c_template" -R"w2c_template( atomic_store_##t1(&mem->data[addr], wrapped); \ +R"w2c_template( atomic_store_##t1(MEM_ADDR(mem, addr, sizeof(t1)), wrapped); \ )w2c_template" R"w2c_template( } )w2c_template" @@ -291,19 +291,19 @@ R"w2c_template(DEFINE_ATOMIC_STORE(i64_atomic_store16, u16, u64) R"w2c_template(DEFINE_ATOMIC_STORE(i64_atomic_store32, u32, u64) )w2c_template" R"w2c_template( -#define DEFINE_ATOMIC_RMW(name, op, t1, t2) \ +#define DEFINE_ATOMIC_RMW(name, op, t1, t2) \ )w2c_template" -R"w2c_template( static inline t2 name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \ +R"w2c_template( static inline t2 name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \ )w2c_template" -R"w2c_template( MEMCHECK(mem, addr, t1); \ +R"w2c_template( MEMCHECK(mem, addr, t1); \ )w2c_template" -R"w2c_template( ATOMIC_ALIGNMENT_CHECK(addr, t1); \ +R"w2c_template( ATOMIC_ALIGNMENT_CHECK(addr, t1); \ )w2c_template" -R"w2c_template( t1 wrapped = (t1)value; \ +R"w2c_template( t1 wrapped = (t1)value; \ )w2c_template" -R"w2c_template( t1 ret = atomic_##op##_##t1(&mem->data[addr], wrapped); \ +R"w2c_template( t1 ret = atomic_##op##_##t1(MEM_ADDR(mem, addr, sizeof(t1)), wrapped); \ )w2c_template" -R"w2c_template( return (t2)ret; \ +R"w2c_template( return (t2)ret; \ )w2c_template" R"w2c_template( } )w2c_template" @@ -398,25 +398,27 @@ R"w2c_template(DEFINE_ATOMIC_RMW(i64_atomic_rmw32_xchg_u, exchange, u32, u64) R"w2c_template(DEFINE_ATOMIC_RMW(i64_atomic_rmw_xchg, exchange, u64, u64) )w2c_template" R"w2c_template( -#define DEFINE_ATOMIC_CMP_XCHG(name, t1, t2) \ +#define DEFINE_ATOMIC_CMP_XCHG(name, t1, t2) \ )w2c_template" -R"w2c_template( static inline t1 name(wasm_rt_memory_t* mem, u64 addr, t1 expected, \ +R"w2c_template( static inline t1 name(wasm_rt_memory_t* mem, u64 addr, t1 expected, \ )w2c_template" -R"w2c_template( t1 replacement) { \ +R"w2c_template( t1 replacement) { \ )w2c_template" -R"w2c_template( MEMCHECK(mem, addr, t2); \ +R"w2c_template( MEMCHECK(mem, addr, t2); \ )w2c_template" -R"w2c_template( ATOMIC_ALIGNMENT_CHECK(addr, t2); \ +R"w2c_template( ATOMIC_ALIGNMENT_CHECK(addr, t2); \ )w2c_template" -R"w2c_template( t2 expected_wrapped = (t2)expected; \ +R"w2c_template( t2 expected_wrapped = (t2)expected; \ )w2c_template" -R"w2c_template( t2 replacement_wrapped = (t2)replacement; \ +R"w2c_template( t2 replacement_wrapped = (t2)replacement; \ )w2c_template" -R"w2c_template( t2 old = atomic_compare_exchange_##t2(&mem->data[addr], &expected_wrapped, \ +R"w2c_template( t2 old = \ )w2c_template" -R"w2c_template( replacement_wrapped); \ +R"w2c_template( atomic_compare_exchange_##t2(MEM_ADDR(mem, addr, sizeof(t2)), \ )w2c_template" -R"w2c_template( return (t1)old; \ +R"w2c_template( &expected_wrapped, replacement_wrapped); \ +)w2c_template" +R"w2c_template( return (t1)old; \ )w2c_template" R"w2c_template( } )w2c_template" diff --git a/src/prebuilt/wasm2c_simd_source_declarations.cc b/src/prebuilt/wasm2c_simd_source_declarations.cc index bbd10ee5..07425377 100644 --- a/src/prebuilt/wasm2c_simd_source_declarations.cc +++ b/src/prebuilt/wasm2c_simd_source_declarations.cc @@ -17,7 +17,7 @@ R"w2c_template( static inline v128 name(wasm_rt_memory_t* mem, u64 addr) { \ )w2c_template" R"w2c_template( MEMCHECK(mem, addr, t); \ )w2c_template" -R"w2c_template( v128 result = func((v128*)&mem->data[addr]); \ +R"w2c_template( v128 result = func(MEM_ADDR(mem, addr, sizeof(t))); \ )w2c_template" R"w2c_template( SIMD_FORCE_READ(result); \ )w2c_template" @@ -32,7 +32,7 @@ R"w2c_template( static inline v128 name(wasm_rt_memory_t* mem, u64 addr, v128 v )w2c_template" R"w2c_template( MEMCHECK(mem, addr, t); \ )w2c_template" -R"w2c_template( v128 result = func((v128*)&mem->data[addr], vec, lane); \ +R"w2c_template( v128 result = func(MEM_ADDR(mem, addr, sizeof(t)), vec, lane); \ )w2c_template" R"w2c_template( SIMD_FORCE_READ(result); \ )w2c_template" @@ -47,7 +47,7 @@ R"w2c_template( static inline void name(wasm_rt_memory_t* mem, u64 addr, v128 v )w2c_template" R"w2c_template( MEMCHECK(mem, addr, t); \ )w2c_template" -R"w2c_template( simde_wasm_v128_store((v128*)&mem->data[addr], value); \ +R"w2c_template( simde_wasm_v128_store(MEM_ADDR(mem, addr, sizeof(t)), value); \ )w2c_template" R"w2c_template( } )w2c_template" @@ -58,7 +58,7 @@ R"w2c_template( static inline void name(wasm_rt_memory_t* mem, u64 addr, v128 v )w2c_template" R"w2c_template( MEMCHECK(mem, addr, t); \ )w2c_template" -R"w2c_template( func((v128*)&mem->data[addr], value, lane); \ +R"w2c_template( func(MEM_ADDR(mem, addr, sizeof(t)), value, lane); \ )w2c_template" R"w2c_template( } )w2c_template" diff --git a/src/prebuilt/wasm2c_source_declarations.cc b/src/prebuilt/wasm2c_source_declarations.cc index 414e6ef0..babb43e3 100644 --- a/src/prebuilt/wasm2c_source_declarations.cc +++ b/src/prebuilt/wasm2c_source_declarations.cc @@ -1,4 +1,45 @@ const char* s_source_declarations = R"w2c_template( +// Computes a pointer to an object of the given size in a little-endian memory. +)w2c_template" +R"w2c_template(// +)w2c_template" +R"w2c_template(// On a little-endian host, this is just &mem->data[addr] - the object's size is +)w2c_template" +R"w2c_template(// unused. On a big-endian host, it's &mem->data[mem->size - addr - n], where n +)w2c_template" +R"w2c_template(// is the object's size. +)w2c_template" +R"w2c_template(// +)w2c_template" +R"w2c_template(// Note that mem may be evaluated multiple times. +)w2c_template" +R"w2c_template(// +)w2c_template" +R"w2c_template(// Parameters: +)w2c_template" +R"w2c_template(// mem - The memory. +)w2c_template" +R"w2c_template(// addr - The address. +)w2c_template" +R"w2c_template(// n - The size of the object. +)w2c_template" +R"w2c_template(// +)w2c_template" +R"w2c_template(// Result: +)w2c_template" +R"w2c_template(// A pointer for an object of size n. +)w2c_template" +R"w2c_template(#if WABT_BIG_ENDIAN +)w2c_template" +R"w2c_template(#define MEM_ADDR(mem, addr, n) &(mem)->data[(mem)->size - (addr) - (n)] +)w2c_template" +R"w2c_template(#else +)w2c_template" +R"w2c_template(#define MEM_ADDR(mem, addr, n) &(mem)->data[addr] +)w2c_template" +R"w2c_template(#endif +)w2c_template" +R"w2c_template( #define TRAP(x) (wasm_rt_trap(WASM_RT_TRAP_##x), 0) )w2c_template" R"w2c_template( @@ -123,9 +164,7 @@ R"w2c_template(#define FORCE_READ_FLOAT(var) R"w2c_template(#endif )w2c_template" R"w2c_template( -#if WABT_BIG_ENDIAN -)w2c_template" -R"w2c_template(static inline void load_data(void* dest, const void* src, size_t n) { +static inline void load_data(void* dest, const void* src, size_t n) { )w2c_template" R"w2c_template( if (!n) { )w2c_template" @@ -133,13 +172,13 @@ R"w2c_template( return; )w2c_template" R"w2c_template( } )w2c_template" -R"w2c_template( size_t i = 0; +R"w2c_template( wasm_rt_memcpy(dest, src, n); )w2c_template" -R"w2c_template( u8* dest_chars = dest; +R"w2c_template(#if WABT_BIG_ENDIAN )w2c_template" -R"w2c_template( wasm_rt_memcpy(dest, src, n); +R"w2c_template( u8* dest_chars = dest; )w2c_template" -R"w2c_template( for (i = 0; i < (n >> 1); i++) { +R"w2c_template( for (size_t i = 0; i < (n >> 1); i++) { )w2c_template" R"w2c_template( u8 cursor = dest_chars[i]; )w2c_template" @@ -149,106 +188,51 @@ R"w2c_template( dest_chars[n - i - 1] = cursor; )w2c_template" R"w2c_template( } )w2c_template" -R"w2c_template(} -)w2c_template" -R"w2c_template(#define LOAD_DATA(m, o, i, s) \ -)w2c_template" -R"w2c_template( do { \ -)w2c_template" -R"w2c_template( RANGE_CHECK((&m), m.size - o - s, s); \ -)w2c_template" -R"w2c_template( load_data(&(m.data[m.size - o - s]), i, s); \ -)w2c_template" -R"w2c_template( } while (0) -)w2c_template" -R"w2c_template(#define DEFINE_LOAD(name, t1, t2, t3, force_read) \ -)w2c_template" -R"w2c_template( static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \ -)w2c_template" -R"w2c_template( MEMCHECK(mem, addr, t1); \ -)w2c_template" -R"w2c_template( t1 result; \ -)w2c_template" -R"w2c_template( wasm_rt_memcpy(&result, &mem->data[mem->size - addr - sizeof(t1)], \ -)w2c_template" -R"w2c_template( sizeof(t1)); \ -)w2c_template" -R"w2c_template( force_read(result); \ -)w2c_template" -R"w2c_template( return (t3)(t2)result; \ -)w2c_template" -R"w2c_template( } -)w2c_template" -R"w2c_template( -#define DEFINE_STORE(name, t1, t2) \ -)w2c_template" -R"w2c_template( static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \ -)w2c_template" -R"w2c_template( MEMCHECK(mem, addr, t1); \ -)w2c_template" -R"w2c_template( t1 wrapped = (t1)value; \ -)w2c_template" -R"w2c_template( wasm_rt_memcpy(&mem->data[mem->size - addr - sizeof(t1)], &wrapped, \ -)w2c_template" -R"w2c_template( sizeof(t1)); \ -)w2c_template" -R"w2c_template( } -)w2c_template" -R"w2c_template(#else -)w2c_template" -R"w2c_template(static inline void load_data(void* dest, const void* src, size_t n) { -)w2c_template" -R"w2c_template( if (!n) { -)w2c_template" -R"w2c_template( return; -)w2c_template" -R"w2c_template( } -)w2c_template" -R"w2c_template( wasm_rt_memcpy(dest, src, n); +R"w2c_template(#endif )w2c_template" R"w2c_template(} )w2c_template" -R"w2c_template(#define LOAD_DATA(m, o, i, s) \ +R"w2c_template( +#define LOAD_DATA(m, o, i, s) \ )w2c_template" -R"w2c_template( do { \ +R"w2c_template( do { \ )w2c_template" -R"w2c_template( RANGE_CHECK((&m), o, s); \ +R"w2c_template( RANGE_CHECK((&m), o, s); \ )w2c_template" -R"w2c_template( load_data(&(m.data[o]), i, s); \ +R"w2c_template( load_data(MEM_ADDR(&m, o, s), i, s); \ )w2c_template" R"w2c_template( } while (0) )w2c_template" -R"w2c_template(#define DEFINE_LOAD(name, t1, t2, t3, force_read) \ +R"w2c_template( +#define DEFINE_LOAD(name, t1, t2, t3, force_read) \ )w2c_template" -R"w2c_template( static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \ +R"w2c_template( static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \ )w2c_template" -R"w2c_template( MEMCHECK(mem, addr, t1); \ +R"w2c_template( MEMCHECK(mem, addr, t1); \ )w2c_template" -R"w2c_template( t1 result; \ +R"w2c_template( t1 result; \ )w2c_template" -R"w2c_template( wasm_rt_memcpy(&result, &mem->data[addr], sizeof(t1)); \ +R"w2c_template( wasm_rt_memcpy(&result, MEM_ADDR(mem, addr, sizeof(t1)), sizeof(t1)); \ )w2c_template" -R"w2c_template( force_read(result); \ +R"w2c_template( force_read(result); \ )w2c_template" -R"w2c_template( return (t3)(t2)result; \ +R"w2c_template( return (t3)(t2)result; \ )w2c_template" R"w2c_template( } )w2c_template" R"w2c_template( -#define DEFINE_STORE(name, t1, t2) \ +#define DEFINE_STORE(name, t1, t2) \ )w2c_template" -R"w2c_template( static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \ +R"w2c_template( static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \ )w2c_template" -R"w2c_template( MEMCHECK(mem, addr, t1); \ +R"w2c_template( MEMCHECK(mem, addr, t1); \ )w2c_template" -R"w2c_template( t1 wrapped = (t1)value; \ +R"w2c_template( t1 wrapped = (t1)value; \ )w2c_template" -R"w2c_template( wasm_rt_memcpy(&mem->data[addr], &wrapped, sizeof(t1)); \ +R"w2c_template( wasm_rt_memcpy(MEM_ADDR(mem, addr, sizeof(t1)), &wrapped, sizeof(t1)); \ )w2c_template" R"w2c_template( } )w2c_template" -R"w2c_template(#endif -)w2c_template" R"w2c_template( DEFINE_LOAD(i32_load, u32, u32, u32, FORCE_READ_INT) )w2c_template" @@ -897,7 +881,7 @@ static inline void memory_fill(wasm_rt_memory_t* mem, u32 d, u32 val, u32 n) { )w2c_template" R"w2c_template( RANGE_CHECK(mem, d, n); )w2c_template" -R"w2c_template( memset(mem->data + d, val, n); +R"w2c_template( memset(MEM_ADDR(mem, d, n), val, n); )w2c_template" R"w2c_template(} )w2c_template" @@ -916,7 +900,7 @@ R"w2c_template( RANGE_CHECK(dest, dest_addr, n); )w2c_template" R"w2c_template( RANGE_CHECK(src, src_addr, n); )w2c_template" -R"w2c_template( memmove(dest->data + dest_addr, src->data + src_addr, n); +R"w2c_template( memmove(MEM_ADDR(dest, dest_addr, n), MEM_ADDR(src, src_addr, n), n); )w2c_template" R"w2c_template(} )w2c_template" diff --git a/src/template/wasm2c.declarations.c b/src/template/wasm2c.declarations.c index c0a44707..40f07ed9 100644 --- a/src/template/wasm2c.declarations.c +++ b/src/template/wasm2c.declarations.c @@ -1,4 +1,25 @@ +// Computes a pointer to an object of the given size in a little-endian memory. +// +// On a little-endian host, this is just &mem->data[addr] - the object's size is +// unused. On a big-endian host, it's &mem->data[mem->size - addr - n], where n +// is the object's size. +// +// Note that mem may be evaluated multiple times. +// +// Parameters: +// mem - The memory. +// addr - The address. +// n - The size of the object. +// +// Result: +// A pointer for an object of size n. +#if WABT_BIG_ENDIAN +#define MEM_ADDR(mem, addr, n) &(mem)->data[(mem)->size - (addr) - (n)] +#else +#define MEM_ADDR(mem, addr, n) &(mem)->data[addr] +#endif + #define TRAP(x) (wasm_rt_trap(WASM_RT_TRAP_##x), 0) #if WASM_RT_USE_STACK_DEPTH_COUNT @@ -67,70 +88,42 @@ static inline bool func_types_eq(const wasm_rt_func_type_t a, #define FORCE_READ_FLOAT(var) #endif -#if WABT_BIG_ENDIAN static inline void load_data(void* dest, const void* src, size_t n) { if (!n) { return; } - size_t i = 0; - u8* dest_chars = dest; wasm_rt_memcpy(dest, src, n); - for (i = 0; i < (n >> 1); i++) { +#if WABT_BIG_ENDIAN + u8* dest_chars = dest; + for (size_t i = 0; i < (n >> 1); i++) { u8 cursor = dest_chars[i]; dest_chars[i] = dest_chars[n - i - 1]; dest_chars[n - i - 1] = cursor; } +#endif } -#define LOAD_DATA(m, o, i, s) \ - do { \ - RANGE_CHECK((&m), m.size - o - s, s); \ - load_data(&(m.data[m.size - o - s]), i, s); \ - } while (0) -#define DEFINE_LOAD(name, t1, t2, t3, force_read) \ - static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \ - MEMCHECK(mem, addr, t1); \ - t1 result; \ - wasm_rt_memcpy(&result, &mem->data[mem->size - addr - sizeof(t1)], \ - sizeof(t1)); \ - force_read(result); \ - return (t3)(t2)result; \ - } - -#define DEFINE_STORE(name, t1, t2) \ - static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \ - MEMCHECK(mem, addr, t1); \ - t1 wrapped = (t1)value; \ - wasm_rt_memcpy(&mem->data[mem->size - addr - sizeof(t1)], &wrapped, \ - sizeof(t1)); \ - } -#else -static inline void load_data(void* dest, const void* src, size_t n) { - if (!n) { - return; - } - wasm_rt_memcpy(dest, src, n); -} -#define LOAD_DATA(m, o, i, s) \ - do { \ - RANGE_CHECK((&m), o, s); \ - load_data(&(m.data[o]), i, s); \ + +#define LOAD_DATA(m, o, i, s) \ + do { \ + RANGE_CHECK((&m), o, s); \ + load_data(MEM_ADDR(&m, o, s), i, s); \ } while (0) -#define DEFINE_LOAD(name, t1, t2, t3, force_read) \ - static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \ - MEMCHECK(mem, addr, t1); \ - t1 result; \ - wasm_rt_memcpy(&result, &mem->data[addr], sizeof(t1)); \ - force_read(result); \ - return (t3)(t2)result; \ + +#define DEFINE_LOAD(name, t1, t2, t3, force_read) \ + static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \ + MEMCHECK(mem, addr, t1); \ + t1 result; \ + wasm_rt_memcpy(&result, MEM_ADDR(mem, addr, sizeof(t1)), sizeof(t1)); \ + force_read(result); \ + return (t3)(t2)result; \ } -#define DEFINE_STORE(name, t1, t2) \ - static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \ - MEMCHECK(mem, addr, t1); \ - t1 wrapped = (t1)value; \ - wasm_rt_memcpy(&mem->data[addr], &wrapped, sizeof(t1)); \ +#define DEFINE_STORE(name, t1, t2) \ + static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \ + MEMCHECK(mem, addr, t1); \ + t1 wrapped = (t1)value; \ + wasm_rt_memcpy(MEM_ADDR(mem, addr, sizeof(t1)), &wrapped, sizeof(t1)); \ } -#endif DEFINE_LOAD(i32_load, u32, u32, u32, FORCE_READ_INT) DEFINE_LOAD(i64_load, u64, u64, u64, FORCE_READ_INT) @@ -480,7 +473,7 @@ static float wasm_sqrtf(float x) { static inline void memory_fill(wasm_rt_memory_t* mem, u32 d, u32 val, u32 n) { RANGE_CHECK(mem, d, n); - memset(mem->data + d, val, n); + memset(MEM_ADDR(mem, d, n), val, n); } static inline void memory_copy(wasm_rt_memory_t* dest, @@ -490,7 +483,7 @@ static inline void memory_copy(wasm_rt_memory_t* dest, u32 n) { RANGE_CHECK(dest, dest_addr, n); RANGE_CHECK(src, src_addr, n); - memmove(dest->data + dest_addr, src->data + src_addr, n); + memmove(MEM_ADDR(dest, dest_addr, n), MEM_ADDR(src, src_addr, n), n); } static inline void memory_init(wasm_rt_memory_t* dest, diff --git a/src/template/wasm2c_atomicops.declarations.c b/src/template/wasm2c_atomicops.declarations.c index 78d9772e..976f7f95 100644 --- a/src/template/wasm2c_atomicops.declarations.c +++ b/src/template/wasm2c_atomicops.declarations.c @@ -125,15 +125,15 @@ TRAP(UNALIGNED); \ } -#define DEFINE_ATOMIC_LOAD(name, t1, t2, t3, force_read) \ - static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \ - MEMCHECK(mem, addr, t1); \ - ATOMIC_ALIGNMENT_CHECK(addr, t1); \ - t1 result; \ - wasm_rt_memcpy(&result, &mem->data[addr], sizeof(t1)); \ - result = atomic_load_##t1(&mem->data[addr]); \ - force_read(result); \ - return (t3)(t2)result; \ +#define DEFINE_ATOMIC_LOAD(name, t1, t2, t3, force_read) \ + static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \ + MEMCHECK(mem, addr, t1); \ + ATOMIC_ALIGNMENT_CHECK(addr, t1); \ + t1 result; \ + wasm_rt_memcpy(&result, MEM_ADDR(mem, addr, sizeof(t1)), sizeof(t1)); \ + result = atomic_load_##t1(MEM_ADDR(mem, addr, sizeof(t1))); \ + force_read(result); \ + return (t3)(t2)result; \ } DEFINE_ATOMIC_LOAD(i32_atomic_load, u32, u32, u32, FORCE_READ_INT) @@ -149,7 +149,7 @@ DEFINE_ATOMIC_LOAD(i64_atomic_load32_u, u32, u64, u64, FORCE_READ_INT) MEMCHECK(mem, addr, t1); \ ATOMIC_ALIGNMENT_CHECK(addr, t1); \ t1 wrapped = (t1)value; \ - atomic_store_##t1(&mem->data[addr], wrapped); \ + atomic_store_##t1(MEM_ADDR(mem, addr, sizeof(t1)), wrapped); \ } DEFINE_ATOMIC_STORE(i32_atomic_store, u32, u32) @@ -160,13 +160,13 @@ DEFINE_ATOMIC_STORE(i64_atomic_store8, u8, u64) DEFINE_ATOMIC_STORE(i64_atomic_store16, u16, u64) DEFINE_ATOMIC_STORE(i64_atomic_store32, u32, u64) -#define DEFINE_ATOMIC_RMW(name, op, t1, t2) \ - static inline t2 name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \ - MEMCHECK(mem, addr, t1); \ - ATOMIC_ALIGNMENT_CHECK(addr, t1); \ - t1 wrapped = (t1)value; \ - t1 ret = atomic_##op##_##t1(&mem->data[addr], wrapped); \ - return (t2)ret; \ +#define DEFINE_ATOMIC_RMW(name, op, t1, t2) \ + static inline t2 name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \ + MEMCHECK(mem, addr, t1); \ + ATOMIC_ALIGNMENT_CHECK(addr, t1); \ + t1 wrapped = (t1)value; \ + t1 ret = atomic_##op##_##t1(MEM_ADDR(mem, addr, sizeof(t1)), wrapped); \ + return (t2)ret; \ } DEFINE_ATOMIC_RMW(i32_atomic_rmw8_add_u, add, u8, u32) @@ -217,16 +217,17 @@ DEFINE_ATOMIC_RMW(i64_atomic_rmw16_xchg_u, exchange, u16, u64) DEFINE_ATOMIC_RMW(i64_atomic_rmw32_xchg_u, exchange, u32, u64) DEFINE_ATOMIC_RMW(i64_atomic_rmw_xchg, exchange, u64, u64) -#define DEFINE_ATOMIC_CMP_XCHG(name, t1, t2) \ - static inline t1 name(wasm_rt_memory_t* mem, u64 addr, t1 expected, \ - t1 replacement) { \ - MEMCHECK(mem, addr, t2); \ - ATOMIC_ALIGNMENT_CHECK(addr, t2); \ - t2 expected_wrapped = (t2)expected; \ - t2 replacement_wrapped = (t2)replacement; \ - t2 old = atomic_compare_exchange_##t2(&mem->data[addr], &expected_wrapped, \ - replacement_wrapped); \ - return (t1)old; \ +#define DEFINE_ATOMIC_CMP_XCHG(name, t1, t2) \ + static inline t1 name(wasm_rt_memory_t* mem, u64 addr, t1 expected, \ + t1 replacement) { \ + MEMCHECK(mem, addr, t2); \ + ATOMIC_ALIGNMENT_CHECK(addr, t2); \ + t2 expected_wrapped = (t2)expected; \ + t2 replacement_wrapped = (t2)replacement; \ + t2 old = \ + atomic_compare_exchange_##t2(MEM_ADDR(mem, addr, sizeof(t2)), \ + &expected_wrapped, replacement_wrapped); \ + return (t1)old; \ } DEFINE_ATOMIC_CMP_XCHG(i32_atomic_rmw8_cmpxchg_u, u32, u8); diff --git a/src/template/wasm2c_simd.declarations.c b/src/template/wasm2c_simd.declarations.c index aee5d600..cf397856 100644 --- a/src/template/wasm2c_simd.declarations.c +++ b/src/template/wasm2c_simd.declarations.c @@ -8,7 +8,7 @@ #define DEFINE_SIMD_LOAD_FUNC(name, func, t) \ static inline v128 name(wasm_rt_memory_t* mem, u64 addr) { \ MEMCHECK(mem, addr, t); \ - v128 result = func((v128*)&mem->data[addr]); \ + v128 result = func(MEM_ADDR(mem, addr, sizeof(t))); \ SIMD_FORCE_READ(result); \ return result; \ } @@ -16,7 +16,7 @@ #define DEFINE_SIMD_LOAD_LANE(name, func, t, lane) \ static inline v128 name(wasm_rt_memory_t* mem, u64 addr, v128 vec) { \ MEMCHECK(mem, addr, t); \ - v128 result = func((v128*)&mem->data[addr], vec, lane); \ + v128 result = func(MEM_ADDR(mem, addr, sizeof(t)), vec, lane); \ SIMD_FORCE_READ(result); \ return result; \ } @@ -24,13 +24,13 @@ #define DEFINE_SIMD_STORE(name, t) \ static inline void name(wasm_rt_memory_t* mem, u64 addr, v128 value) { \ MEMCHECK(mem, addr, t); \ - simde_wasm_v128_store((v128*)&mem->data[addr], value); \ + simde_wasm_v128_store(MEM_ADDR(mem, addr, sizeof(t)), value); \ } #define DEFINE_SIMD_STORE_LANE(name, func, t, lane) \ static inline void name(wasm_rt_memory_t* mem, u64 addr, v128 value) { \ MEMCHECK(mem, addr, t); \ - func((v128*)&mem->data[addr], value, lane); \ + func(MEM_ADDR(mem, addr, sizeof(t)), value, lane); \ } // clang-format off diff --git a/test/wasm2c/add.txt b/test/wasm2c/add.txt index b7ff8d9b..7fc570c0 100644 --- a/test/wasm2c/add.txt +++ b/test/wasm2c/add.txt @@ -66,6 +66,27 @@ u32 w2c_test_add(w2c_test*, u32, u32); #include "wasm.h" +// Computes a pointer to an object of the given size in a little-endian memory. +// +// On a little-endian host, this is just &mem->data[addr] - the object's size is +// unused. On a big-endian host, it's &mem->data[mem->size - addr - n], where n +// is the object's size. +// +// Note that mem may be evaluated multiple times. +// +// Parameters: +// mem - The memory. +// addr - The address. +// n - The size of the object. +// +// Result: +// A pointer for an object of size n. +#if WABT_BIG_ENDIAN +#define MEM_ADDR(mem, addr, n) &(mem)->data[(mem)->size - (addr) - (n)] +#else +#define MEM_ADDR(mem, addr, n) &(mem)->data[addr] +#endif + #define TRAP(x) (wasm_rt_trap(WASM_RT_TRAP_##x), 0) #if WASM_RT_USE_STACK_DEPTH_COUNT @@ -134,70 +155,42 @@ static inline bool func_types_eq(const wasm_rt_func_type_t a, #define FORCE_READ_FLOAT(var) #endif -#if WABT_BIG_ENDIAN static inline void load_data(void* dest, const void* src, size_t n) { if (!n) { return; } - size_t i = 0; - u8* dest_chars = dest; wasm_rt_memcpy(dest, src, n); - for (i = 0; i < (n >> 1); i++) { +#if WABT_BIG_ENDIAN + u8* dest_chars = dest; + for (size_t i = 0; i < (n >> 1); i++) { u8 cursor = dest_chars[i]; dest_chars[i] = dest_chars[n - i - 1]; dest_chars[n - i - 1] = cursor; } +#endif } -#define LOAD_DATA(m, o, i, s) \ - do { \ - RANGE_CHECK((&m), m.size - o - s, s); \ - load_data(&(m.data[m.size - o - s]), i, s); \ - } while (0) -#define DEFINE_LOAD(name, t1, t2, t3, force_read) \ - static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \ - MEMCHECK(mem, addr, t1); \ - t1 result; \ - wasm_rt_memcpy(&result, &mem->data[mem->size - addr - sizeof(t1)], \ - sizeof(t1)); \ - force_read(result); \ - return (t3)(t2)result; \ - } - -#define DEFINE_STORE(name, t1, t2) \ - static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \ - MEMCHECK(mem, addr, t1); \ - t1 wrapped = (t1)value; \ - wasm_rt_memcpy(&mem->data[mem->size - addr - sizeof(t1)], &wrapped, \ - sizeof(t1)); \ - } -#else -static inline void load_data(void* dest, const void* src, size_t n) { - if (!n) { - return; - } - wasm_rt_memcpy(dest, src, n); -} -#define LOAD_DATA(m, o, i, s) \ - do { \ - RANGE_CHECK((&m), o, s); \ - load_data(&(m.data[o]), i, s); \ + +#define LOAD_DATA(m, o, i, s) \ + do { \ + RANGE_CHECK((&m), o, s); \ + load_data(MEM_ADDR(&m, o, s), i, s); \ } while (0) -#define DEFINE_LOAD(name, t1, t2, t3, force_read) \ - static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \ - MEMCHECK(mem, addr, t1); \ - t1 result; \ - wasm_rt_memcpy(&result, &mem->data[addr], sizeof(t1)); \ - force_read(result); \ - return (t3)(t2)result; \ + +#define DEFINE_LOAD(name, t1, t2, t3, force_read) \ + static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \ + MEMCHECK(mem, addr, t1); \ + t1 result; \ + wasm_rt_memcpy(&result, MEM_ADDR(mem, addr, sizeof(t1)), sizeof(t1)); \ + force_read(result); \ + return (t3)(t2)result; \ } -#define DEFINE_STORE(name, t1, t2) \ - static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \ - MEMCHECK(mem, addr, t1); \ - t1 wrapped = (t1)value; \ - wasm_rt_memcpy(&mem->data[addr], &wrapped, sizeof(t1)); \ +#define DEFINE_STORE(name, t1, t2) \ + static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \ + MEMCHECK(mem, addr, t1); \ + t1 wrapped = (t1)value; \ + wasm_rt_memcpy(MEM_ADDR(mem, addr, sizeof(t1)), &wrapped, sizeof(t1)); \ } -#endif DEFINE_LOAD(i32_load, u32, u32, u32, FORCE_READ_INT) DEFINE_LOAD(i64_load, u64, u64, u64, FORCE_READ_INT) @@ -547,7 +540,7 @@ static float wasm_sqrtf(float x) { static inline void memory_fill(wasm_rt_memory_t* mem, u32 d, u32 val, u32 n) { RANGE_CHECK(mem, d, n); - memset(mem->data + d, val, n); + memset(MEM_ADDR(mem, d, n), val, n); } static inline void memory_copy(wasm_rt_memory_t* dest, @@ -557,7 +550,7 @@ static inline void memory_copy(wasm_rt_memory_t* dest, u32 n) { RANGE_CHECK(dest, dest_addr, n); RANGE_CHECK(src, src_addr, n); - memmove(dest->data + dest_addr, src->data + src_addr, n); + memmove(MEM_ADDR(dest, dest_addr, n), MEM_ADDR(src, src_addr, n), n); } static inline void memory_init(wasm_rt_memory_t* dest, diff --git a/test/wasm2c/check-imports.txt b/test/wasm2c/check-imports.txt index 60d38348..ce2469ed 100644 --- a/test/wasm2c/check-imports.txt +++ b/test/wasm2c/check-imports.txt @@ -89,6 +89,27 @@ extern const u8 wasm2c_test_is64_env_0x5F_linear_memory; #include "wasm.h" +// Computes a pointer to an object of the given size in a little-endian memory. +// +// On a little-endian host, this is just &mem->data[addr] - the object's size is +// unused. On a big-endian host, it's &mem->data[mem->size - addr - n], where n +// is the object's size. +// +// Note that mem may be evaluated multiple times. +// +// Parameters: +// mem - The memory. +// addr - The address. +// n - The size of the object. +// +// Result: +// A pointer for an object of size n. +#if WABT_BIG_ENDIAN +#define MEM_ADDR(mem, addr, n) &(mem)->data[(mem)->size - (addr) - (n)] +#else +#define MEM_ADDR(mem, addr, n) &(mem)->data[addr] +#endif + #define TRAP(x) (wasm_rt_trap(WASM_RT_TRAP_##x), 0) #if WASM_RT_USE_STACK_DEPTH_COUNT @@ -157,70 +178,42 @@ static inline bool func_types_eq(const wasm_rt_func_type_t a, #define FORCE_READ_FLOAT(var) #endif -#if WABT_BIG_ENDIAN static inline void load_data(void* dest, const void* src, size_t n) { if (!n) { return; } - size_t i = 0; - u8* dest_chars = dest; wasm_rt_memcpy(dest, src, n); - for (i = 0; i < (n >> 1); i++) { +#if WABT_BIG_ENDIAN + u8* dest_chars = dest; + for (size_t i = 0; i < (n >> 1); i++) { u8 cursor = dest_chars[i]; dest_chars[i] = dest_chars[n - i - 1]; dest_chars[n - i - 1] = cursor; } +#endif } -#define LOAD_DATA(m, o, i, s) \ - do { \ - RANGE_CHECK((&m), m.size - o - s, s); \ - load_data(&(m.data[m.size - o - s]), i, s); \ - } while (0) -#define DEFINE_LOAD(name, t1, t2, t3, force_read) \ - static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \ - MEMCHECK(mem, addr, t1); \ - t1 result; \ - wasm_rt_memcpy(&result, &mem->data[mem->size - addr - sizeof(t1)], \ - sizeof(t1)); \ - force_read(result); \ - return (t3)(t2)result; \ - } - -#define DEFINE_STORE(name, t1, t2) \ - static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \ - MEMCHECK(mem, addr, t1); \ - t1 wrapped = (t1)value; \ - wasm_rt_memcpy(&mem->data[mem->size - addr - sizeof(t1)], &wrapped, \ - sizeof(t1)); \ - } -#else -static inline void load_data(void* dest, const void* src, size_t n) { - if (!n) { - return; - } - wasm_rt_memcpy(dest, src, n); -} -#define LOAD_DATA(m, o, i, s) \ - do { \ - RANGE_CHECK((&m), o, s); \ - load_data(&(m.data[o]), i, s); \ + +#define LOAD_DATA(m, o, i, s) \ + do { \ + RANGE_CHECK((&m), o, s); \ + load_data(MEM_ADDR(&m, o, s), i, s); \ } while (0) -#define DEFINE_LOAD(name, t1, t2, t3, force_read) \ - static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \ - MEMCHECK(mem, addr, t1); \ - t1 result; \ - wasm_rt_memcpy(&result, &mem->data[addr], sizeof(t1)); \ - force_read(result); \ - return (t3)(t2)result; \ + +#define DEFINE_LOAD(name, t1, t2, t3, force_read) \ + static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \ + MEMCHECK(mem, addr, t1); \ + t1 result; \ + wasm_rt_memcpy(&result, MEM_ADDR(mem, addr, sizeof(t1)), sizeof(t1)); \ + force_read(result); \ + return (t3)(t2)result; \ } -#define DEFINE_STORE(name, t1, t2) \ - static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \ - MEMCHECK(mem, addr, t1); \ - t1 wrapped = (t1)value; \ - wasm_rt_memcpy(&mem->data[addr], &wrapped, sizeof(t1)); \ +#define DEFINE_STORE(name, t1, t2) \ + static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \ + MEMCHECK(mem, addr, t1); \ + t1 wrapped = (t1)value; \ + wasm_rt_memcpy(MEM_ADDR(mem, addr, sizeof(t1)), &wrapped, sizeof(t1)); \ } -#endif DEFINE_LOAD(i32_load, u32, u32, u32, FORCE_READ_INT) DEFINE_LOAD(i64_load, u64, u64, u64, FORCE_READ_INT) @@ -570,7 +563,7 @@ static float wasm_sqrtf(float x) { static inline void memory_fill(wasm_rt_memory_t* mem, u32 d, u32 val, u32 n) { RANGE_CHECK(mem, d, n); - memset(mem->data + d, val, n); + memset(MEM_ADDR(mem, d, n), val, n); } static inline void memory_copy(wasm_rt_memory_t* dest, @@ -580,7 +573,7 @@ static inline void memory_copy(wasm_rt_memory_t* dest, u32 n) { RANGE_CHECK(dest, dest_addr, n); RANGE_CHECK(src, src_addr, n); - memmove(dest->data + dest_addr, src->data + src_addr, n); + memmove(MEM_ADDR(dest, dest_addr, n), MEM_ADDR(src, src_addr, n), n); } static inline void memory_init(wasm_rt_memory_t* dest, diff --git a/test/wasm2c/export-names.txt b/test/wasm2c/export-names.txt index 89501325..73e8b598 100644 --- a/test/wasm2c/export-names.txt +++ b/test/wasm2c/export-names.txt @@ -89,6 +89,27 @@ void w2c_test_0xE20x9D0xA40xEF0xB80x8F(w2c_test*); #include "wasm.h" +// Computes a pointer to an object of the given size in a little-endian memory. +// +// On a little-endian host, this is just &mem->data[addr] - the object's size is +// unused. On a big-endian host, it's &mem->data[mem->size - addr - n], where n +// is the object's size. +// +// Note that mem may be evaluated multiple times. +// +// Parameters: +// mem - The memory. +// addr - The address. +// n - The size of the object. +// +// Result: +// A pointer for an object of size n. +#if WABT_BIG_ENDIAN +#define MEM_ADDR(mem, addr, n) &(mem)->data[(mem)->size - (addr) - (n)] +#else +#define MEM_ADDR(mem, addr, n) &(mem)->data[addr] +#endif + #define TRAP(x) (wasm_rt_trap(WASM_RT_TRAP_##x), 0) #if WASM_RT_USE_STACK_DEPTH_COUNT @@ -157,70 +178,42 @@ static inline bool func_types_eq(const wasm_rt_func_type_t a, #define FORCE_READ_FLOAT(var) #endif -#if WABT_BIG_ENDIAN static inline void load_data(void* dest, const void* src, size_t n) { if (!n) { return; } - size_t i = 0; - u8* dest_chars = dest; wasm_rt_memcpy(dest, src, n); - for (i = 0; i < (n >> 1); i++) { +#if WABT_BIG_ENDIAN + u8* dest_chars = dest; + for (size_t i = 0; i < (n >> 1); i++) { u8 cursor = dest_chars[i]; dest_chars[i] = dest_chars[n - i - 1]; dest_chars[n - i - 1] = cursor; } +#endif } -#define LOAD_DATA(m, o, i, s) \ - do { \ - RANGE_CHECK((&m), m.size - o - s, s); \ - load_data(&(m.data[m.size - o - s]), i, s); \ - } while (0) -#define DEFINE_LOAD(name, t1, t2, t3, force_read) \ - static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \ - MEMCHECK(mem, addr, t1); \ - t1 result; \ - wasm_rt_memcpy(&result, &mem->data[mem->size - addr - sizeof(t1)], \ - sizeof(t1)); \ - force_read(result); \ - return (t3)(t2)result; \ - } - -#define DEFINE_STORE(name, t1, t2) \ - static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \ - MEMCHECK(mem, addr, t1); \ - t1 wrapped = (t1)value; \ - wasm_rt_memcpy(&mem->data[mem->size - addr - sizeof(t1)], &wrapped, \ - sizeof(t1)); \ - } -#else -static inline void load_data(void* dest, const void* src, size_t n) { - if (!n) { - return; - } - wasm_rt_memcpy(dest, src, n); -} -#define LOAD_DATA(m, o, i, s) \ - do { \ - RANGE_CHECK((&m), o, s); \ - load_data(&(m.data[o]), i, s); \ + +#define LOAD_DATA(m, o, i, s) \ + do { \ + RANGE_CHECK((&m), o, s); \ + load_data(MEM_ADDR(&m, o, s), i, s); \ } while (0) -#define DEFINE_LOAD(name, t1, t2, t3, force_read) \ - static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \ - MEMCHECK(mem, addr, t1); \ - t1 result; \ - wasm_rt_memcpy(&result, &mem->data[addr], sizeof(t1)); \ - force_read(result); \ - return (t3)(t2)result; \ + +#define DEFINE_LOAD(name, t1, t2, t3, force_read) \ + static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \ + MEMCHECK(mem, addr, t1); \ + t1 result; \ + wasm_rt_memcpy(&result, MEM_ADDR(mem, addr, sizeof(t1)), sizeof(t1)); \ + force_read(result); \ + return (t3)(t2)result; \ } -#define DEFINE_STORE(name, t1, t2) \ - static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \ - MEMCHECK(mem, addr, t1); \ - t1 wrapped = (t1)value; \ - wasm_rt_memcpy(&mem->data[addr], &wrapped, sizeof(t1)); \ +#define DEFINE_STORE(name, t1, t2) \ + static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \ + MEMCHECK(mem, addr, t1); \ + t1 wrapped = (t1)value; \ + wasm_rt_memcpy(MEM_ADDR(mem, addr, sizeof(t1)), &wrapped, sizeof(t1)); \ } -#endif DEFINE_LOAD(i32_load, u32, u32, u32, FORCE_READ_INT) DEFINE_LOAD(i64_load, u64, u64, u64, FORCE_READ_INT) @@ -570,7 +563,7 @@ static float wasm_sqrtf(float x) { static inline void memory_fill(wasm_rt_memory_t* mem, u32 d, u32 val, u32 n) { RANGE_CHECK(mem, d, n); - memset(mem->data + d, val, n); + memset(MEM_ADDR(mem, d, n), val, n); } static inline void memory_copy(wasm_rt_memory_t* dest, @@ -580,7 +573,7 @@ static inline void memory_copy(wasm_rt_memory_t* dest, u32 n) { RANGE_CHECK(dest, dest_addr, n); RANGE_CHECK(src, src_addr, n); - memmove(dest->data + dest_addr, src->data + src_addr, n); + memmove(MEM_ADDR(dest, dest_addr, n), MEM_ADDR(src, src_addr, n), n); } static inline void memory_init(wasm_rt_memory_t* dest, diff --git a/test/wasm2c/hello.txt b/test/wasm2c/hello.txt index f11c9005..a38ebb11 100644 --- a/test/wasm2c/hello.txt +++ b/test/wasm2c/hello.txt @@ -97,6 +97,27 @@ void w2c_test_0x5Fstart(w2c_test*); #include "wasm.h" +// Computes a pointer to an object of the given size in a little-endian memory. +// +// On a little-endian host, this is just &mem->data[addr] - the object's size is +// unused. On a big-endian host, it's &mem->data[mem->size - addr - n], where n +// is the object's size. +// +// Note that mem may be evaluated multiple times. +// +// Parameters: +// mem - The memory. +// addr - The address. +// n - The size of the object. +// +// Result: +// A pointer for an object of size n. +#if WABT_BIG_ENDIAN +#define MEM_ADDR(mem, addr, n) &(mem)->data[(mem)->size - (addr) - (n)] +#else +#define MEM_ADDR(mem, addr, n) &(mem)->data[addr] +#endif + #define TRAP(x) (wasm_rt_trap(WASM_RT_TRAP_##x), 0) #if WASM_RT_USE_STACK_DEPTH_COUNT @@ -165,70 +186,42 @@ static inline bool func_types_eq(const wasm_rt_func_type_t a, #define FORCE_READ_FLOAT(var) #endif -#if WABT_BIG_ENDIAN static inline void load_data(void* dest, const void* src, size_t n) { if (!n) { return; } - size_t i = 0; - u8* dest_chars = dest; wasm_rt_memcpy(dest, src, n); - for (i = 0; i < (n >> 1); i++) { +#if WABT_BIG_ENDIAN + u8* dest_chars = dest; + for (size_t i = 0; i < (n >> 1); i++) { u8 cursor = dest_chars[i]; dest_chars[i] = dest_chars[n - i - 1]; dest_chars[n - i - 1] = cursor; } +#endif } -#define LOAD_DATA(m, o, i, s) \ - do { \ - RANGE_CHECK((&m), m.size - o - s, s); \ - load_data(&(m.data[m.size - o - s]), i, s); \ - } while (0) -#define DEFINE_LOAD(name, t1, t2, t3, force_read) \ - static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \ - MEMCHECK(mem, addr, t1); \ - t1 result; \ - wasm_rt_memcpy(&result, &mem->data[mem->size - addr - sizeof(t1)], \ - sizeof(t1)); \ - force_read(result); \ - return (t3)(t2)result; \ - } - -#define DEFINE_STORE(name, t1, t2) \ - static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \ - MEMCHECK(mem, addr, t1); \ - t1 wrapped = (t1)value; \ - wasm_rt_memcpy(&mem->data[mem->size - addr - sizeof(t1)], &wrapped, \ - sizeof(t1)); \ - } -#else -static inline void load_data(void* dest, const void* src, size_t n) { - if (!n) { - return; - } - wasm_rt_memcpy(dest, src, n); -} -#define LOAD_DATA(m, o, i, s) \ - do { \ - RANGE_CHECK((&m), o, s); \ - load_data(&(m.data[o]), i, s); \ + +#define LOAD_DATA(m, o, i, s) \ + do { \ + RANGE_CHECK((&m), o, s); \ + load_data(MEM_ADDR(&m, o, s), i, s); \ } while (0) -#define DEFINE_LOAD(name, t1, t2, t3, force_read) \ - static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \ - MEMCHECK(mem, addr, t1); \ - t1 result; \ - wasm_rt_memcpy(&result, &mem->data[addr], sizeof(t1)); \ - force_read(result); \ - return (t3)(t2)result; \ + +#define DEFINE_LOAD(name, t1, t2, t3, force_read) \ + static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \ + MEMCHECK(mem, addr, t1); \ + t1 result; \ + wasm_rt_memcpy(&result, MEM_ADDR(mem, addr, sizeof(t1)), sizeof(t1)); \ + force_read(result); \ + return (t3)(t2)result; \ } -#define DEFINE_STORE(name, t1, t2) \ - static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \ - MEMCHECK(mem, addr, t1); \ - t1 wrapped = (t1)value; \ - wasm_rt_memcpy(&mem->data[addr], &wrapped, sizeof(t1)); \ +#define DEFINE_STORE(name, t1, t2) \ + static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \ + MEMCHECK(mem, addr, t1); \ + t1 wrapped = (t1)value; \ + wasm_rt_memcpy(MEM_ADDR(mem, addr, sizeof(t1)), &wrapped, sizeof(t1)); \ } -#endif DEFINE_LOAD(i32_load, u32, u32, u32, FORCE_READ_INT) DEFINE_LOAD(i64_load, u64, u64, u64, FORCE_READ_INT) @@ -578,7 +571,7 @@ static float wasm_sqrtf(float x) { static inline void memory_fill(wasm_rt_memory_t* mem, u32 d, u32 val, u32 n) { RANGE_CHECK(mem, d, n); - memset(mem->data + d, val, n); + memset(MEM_ADDR(mem, d, n), val, n); } static inline void memory_copy(wasm_rt_memory_t* dest, @@ -588,7 +581,7 @@ static inline void memory_copy(wasm_rt_memory_t* dest, u32 n) { RANGE_CHECK(dest, dest_addr, n); RANGE_CHECK(src, src_addr, n); - memmove(dest->data + dest_addr, src->data + src_addr, n); + memmove(MEM_ADDR(dest, dest_addr, n), MEM_ADDR(src, src_addr, n), n); } static inline void memory_init(wasm_rt_memory_t* dest, diff --git a/test/wasm2c/minimal.txt b/test/wasm2c/minimal.txt index 71e641d9..d77a6573 100644 --- a/test/wasm2c/minimal.txt +++ b/test/wasm2c/minimal.txt @@ -60,6 +60,27 @@ wasm_rt_func_type_t wasm2c_test_get_func_type(uint32_t param_count, uint32_t res #include "wasm.h" +// Computes a pointer to an object of the given size in a little-endian memory. +// +// On a little-endian host, this is just &mem->data[addr] - the object's size is +// unused. On a big-endian host, it's &mem->data[mem->size - addr - n], where n +// is the object's size. +// +// Note that mem may be evaluated multiple times. +// +// Parameters: +// mem - The memory. +// addr - The address. +// n - The size of the object. +// +// Result: +// A pointer for an object of size n. +#if WABT_BIG_ENDIAN +#define MEM_ADDR(mem, addr, n) &(mem)->data[(mem)->size - (addr) - (n)] +#else +#define MEM_ADDR(mem, addr, n) &(mem)->data[addr] +#endif + #define TRAP(x) (wasm_rt_trap(WASM_RT_TRAP_##x), 0) #if WASM_RT_USE_STACK_DEPTH_COUNT @@ -128,70 +149,42 @@ static inline bool func_types_eq(const wasm_rt_func_type_t a, #define FORCE_READ_FLOAT(var) #endif -#if WABT_BIG_ENDIAN static inline void load_data(void* dest, const void* src, size_t n) { if (!n) { return; } - size_t i = 0; - u8* dest_chars = dest; wasm_rt_memcpy(dest, src, n); - for (i = 0; i < (n >> 1); i++) { +#if WABT_BIG_ENDIAN + u8* dest_chars = dest; + for (size_t i = 0; i < (n >> 1); i++) { u8 cursor = dest_chars[i]; dest_chars[i] = dest_chars[n - i - 1]; dest_chars[n - i - 1] = cursor; } +#endif } -#define LOAD_DATA(m, o, i, s) \ - do { \ - RANGE_CHECK((&m), m.size - o - s, s); \ - load_data(&(m.data[m.size - o - s]), i, s); \ - } while (0) -#define DEFINE_LOAD(name, t1, t2, t3, force_read) \ - static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \ - MEMCHECK(mem, addr, t1); \ - t1 result; \ - wasm_rt_memcpy(&result, &mem->data[mem->size - addr - sizeof(t1)], \ - sizeof(t1)); \ - force_read(result); \ - return (t3)(t2)result; \ - } - -#define DEFINE_STORE(name, t1, t2) \ - static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \ - MEMCHECK(mem, addr, t1); \ - t1 wrapped = (t1)value; \ - wasm_rt_memcpy(&mem->data[mem->size - addr - sizeof(t1)], &wrapped, \ - sizeof(t1)); \ - } -#else -static inline void load_data(void* dest, const void* src, size_t n) { - if (!n) { - return; - } - wasm_rt_memcpy(dest, src, n); -} -#define LOAD_DATA(m, o, i, s) \ - do { \ - RANGE_CHECK((&m), o, s); \ - load_data(&(m.data[o]), i, s); \ + +#define LOAD_DATA(m, o, i, s) \ + do { \ + RANGE_CHECK((&m), o, s); \ + load_data(MEM_ADDR(&m, o, s), i, s); \ } while (0) -#define DEFINE_LOAD(name, t1, t2, t3, force_read) \ - static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \ - MEMCHECK(mem, addr, t1); \ - t1 result; \ - wasm_rt_memcpy(&result, &mem->data[addr], sizeof(t1)); \ - force_read(result); \ - return (t3)(t2)result; \ + +#define DEFINE_LOAD(name, t1, t2, t3, force_read) \ + static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \ + MEMCHECK(mem, addr, t1); \ + t1 result; \ + wasm_rt_memcpy(&result, MEM_ADDR(mem, addr, sizeof(t1)), sizeof(t1)); \ + force_read(result); \ + return (t3)(t2)result; \ } -#define DEFINE_STORE(name, t1, t2) \ - static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \ - MEMCHECK(mem, addr, t1); \ - t1 wrapped = (t1)value; \ - wasm_rt_memcpy(&mem->data[addr], &wrapped, sizeof(t1)); \ +#define DEFINE_STORE(name, t1, t2) \ + static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \ + MEMCHECK(mem, addr, t1); \ + t1 wrapped = (t1)value; \ + wasm_rt_memcpy(MEM_ADDR(mem, addr, sizeof(t1)), &wrapped, sizeof(t1)); \ } -#endif DEFINE_LOAD(i32_load, u32, u32, u32, FORCE_READ_INT) DEFINE_LOAD(i64_load, u64, u64, u64, FORCE_READ_INT) @@ -541,7 +534,7 @@ static float wasm_sqrtf(float x) { static inline void memory_fill(wasm_rt_memory_t* mem, u32 d, u32 val, u32 n) { RANGE_CHECK(mem, d, n); - memset(mem->data + d, val, n); + memset(MEM_ADDR(mem, d, n), val, n); } static inline void memory_copy(wasm_rt_memory_t* dest, @@ -551,7 +544,7 @@ static inline void memory_copy(wasm_rt_memory_t* dest, u32 n) { RANGE_CHECK(dest, dest_addr, n); RANGE_CHECK(src, src_addr, n); - memmove(dest->data + dest_addr, src->data + src_addr, n); + memmove(MEM_ADDR(dest, dest_addr, n), MEM_ADDR(src, src_addr, n), n); } static inline void memory_init(wasm_rt_memory_t* dest, diff --git a/test/wasm2c/tail-calls.txt b/test/wasm2c/tail-calls.txt index 9bb317c5..5a30e45f 100644 --- a/test/wasm2c/tail-calls.txt +++ b/test/wasm2c/tail-calls.txt @@ -90,6 +90,27 @@ void wasm_tailcall_w2c_test_tailcaller(void **instance_ptr, void *tail_call_stac #include "wasm.h" +// Computes a pointer to an object of the given size in a little-endian memory. +// +// On a little-endian host, this is just &mem->data[addr] - the object's size is +// unused. On a big-endian host, it's &mem->data[mem->size - addr - n], where n +// is the object's size. +// +// Note that mem may be evaluated multiple times. +// +// Parameters: +// mem - The memory. +// addr - The address. +// n - The size of the object. +// +// Result: +// A pointer for an object of size n. +#if WABT_BIG_ENDIAN +#define MEM_ADDR(mem, addr, n) &(mem)->data[(mem)->size - (addr) - (n)] +#else +#define MEM_ADDR(mem, addr, n) &(mem)->data[addr] +#endif + #define TRAP(x) (wasm_rt_trap(WASM_RT_TRAP_##x), 0) #if WASM_RT_USE_STACK_DEPTH_COUNT @@ -158,70 +179,42 @@ static inline bool func_types_eq(const wasm_rt_func_type_t a, #define FORCE_READ_FLOAT(var) #endif -#if WABT_BIG_ENDIAN static inline void load_data(void* dest, const void* src, size_t n) { if (!n) { return; } - size_t i = 0; - u8* dest_chars = dest; wasm_rt_memcpy(dest, src, n); - for (i = 0; i < (n >> 1); i++) { +#if WABT_BIG_ENDIAN + u8* dest_chars = dest; + for (size_t i = 0; i < (n >> 1); i++) { u8 cursor = dest_chars[i]; dest_chars[i] = dest_chars[n - i - 1]; dest_chars[n - i - 1] = cursor; } +#endif } -#define LOAD_DATA(m, o, i, s) \ - do { \ - RANGE_CHECK((&m), m.size - o - s, s); \ - load_data(&(m.data[m.size - o - s]), i, s); \ - } while (0) -#define DEFINE_LOAD(name, t1, t2, t3, force_read) \ - static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \ - MEMCHECK(mem, addr, t1); \ - t1 result; \ - wasm_rt_memcpy(&result, &mem->data[mem->size - addr - sizeof(t1)], \ - sizeof(t1)); \ - force_read(result); \ - return (t3)(t2)result; \ - } - -#define DEFINE_STORE(name, t1, t2) \ - static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \ - MEMCHECK(mem, addr, t1); \ - t1 wrapped = (t1)value; \ - wasm_rt_memcpy(&mem->data[mem->size - addr - sizeof(t1)], &wrapped, \ - sizeof(t1)); \ - } -#else -static inline void load_data(void* dest, const void* src, size_t n) { - if (!n) { - return; - } - wasm_rt_memcpy(dest, src, n); -} -#define LOAD_DATA(m, o, i, s) \ - do { \ - RANGE_CHECK((&m), o, s); \ - load_data(&(m.data[o]), i, s); \ + +#define LOAD_DATA(m, o, i, s) \ + do { \ + RANGE_CHECK((&m), o, s); \ + load_data(MEM_ADDR(&m, o, s), i, s); \ } while (0) -#define DEFINE_LOAD(name, t1, t2, t3, force_read) \ - static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \ - MEMCHECK(mem, addr, t1); \ - t1 result; \ - wasm_rt_memcpy(&result, &mem->data[addr], sizeof(t1)); \ - force_read(result); \ - return (t3)(t2)result; \ + +#define DEFINE_LOAD(name, t1, t2, t3, force_read) \ + static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \ + MEMCHECK(mem, addr, t1); \ + t1 result; \ + wasm_rt_memcpy(&result, MEM_ADDR(mem, addr, sizeof(t1)), sizeof(t1)); \ + force_read(result); \ + return (t3)(t2)result; \ } -#define DEFINE_STORE(name, t1, t2) \ - static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \ - MEMCHECK(mem, addr, t1); \ - t1 wrapped = (t1)value; \ - wasm_rt_memcpy(&mem->data[addr], &wrapped, sizeof(t1)); \ +#define DEFINE_STORE(name, t1, t2) \ + static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \ + MEMCHECK(mem, addr, t1); \ + t1 wrapped = (t1)value; \ + wasm_rt_memcpy(MEM_ADDR(mem, addr, sizeof(t1)), &wrapped, sizeof(t1)); \ } -#endif DEFINE_LOAD(i32_load, u32, u32, u32, FORCE_READ_INT) DEFINE_LOAD(i64_load, u64, u64, u64, FORCE_READ_INT) @@ -571,7 +564,7 @@ static float wasm_sqrtf(float x) { static inline void memory_fill(wasm_rt_memory_t* mem, u32 d, u32 val, u32 n) { RANGE_CHECK(mem, d, n); - memset(mem->data + d, val, n); + memset(MEM_ADDR(mem, d, n), val, n); } static inline void memory_copy(wasm_rt_memory_t* dest, @@ -581,7 +574,7 @@ static inline void memory_copy(wasm_rt_memory_t* dest, u32 n) { RANGE_CHECK(dest, dest_addr, n); RANGE_CHECK(src, src_addr, n); - memmove(dest->data + dest_addr, src->data + src_addr, n); + memmove(MEM_ADDR(dest, dest_addr, n), MEM_ADDR(src, src_addr, n), n); } static inline void memory_init(wasm_rt_memory_t* dest, |