summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/prebuilt/wasm2c_atomicops_source_declarations.cc56
-rw-r--r--src/prebuilt/wasm2c_simd_source_declarations.cc8
-rw-r--r--src/prebuilt/wasm2c_source_declarations.cc150
-rw-r--r--src/template/wasm2c.declarations.c97
-rw-r--r--src/template/wasm2c_atomicops.declarations.c55
-rw-r--r--src/template/wasm2c_simd.declarations.c8
-rw-r--r--test/wasm2c/add.txt97
-rw-r--r--test/wasm2c/check-imports.txt97
-rw-r--r--test/wasm2c/export-names.txt97
-rw-r--r--test/wasm2c/hello.txt97
-rw-r--r--test/wasm2c/minimal.txt97
-rw-r--r--test/wasm2c/tail-calls.txt97
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,