summaryrefslogtreecommitdiff
path: root/src/prebuilt/wasm2c_source_declarations.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/prebuilt/wasm2c_source_declarations.cc')
-rw-r--r--src/prebuilt/wasm2c_source_declarations.cc205
1 files changed, 147 insertions, 58 deletions
diff --git a/src/prebuilt/wasm2c_source_declarations.cc b/src/prebuilt/wasm2c_source_declarations.cc
index 87529c40..557bf67b 100644
--- a/src/prebuilt/wasm2c_source_declarations.cc
+++ b/src/prebuilt/wasm2c_source_declarations.cc
@@ -165,15 +165,32 @@ R"w2c_template( (CHECK_CALL_INDIRECT(table, ft, x), \
R"w2c_template( DO_CALL_INDIRECT(table, t, x, __VA_ARGS__))
)w2c_template"
R"w2c_template(
-#ifdef SUPPORT_MEMORY64
+static inline bool add_overflow(uint64_t a, uint64_t b, uint64_t* resptr) {
)w2c_template"
-R"w2c_template(#define RANGE_CHECK(mem, offset, len) \
+R"w2c_template(#if __has_builtin(__builtin_add_overflow)
+)w2c_template"
+R"w2c_template( return __builtin_add_overflow(a, b, resptr);
+)w2c_template"
+R"w2c_template(#elif defined(_MSC_VER)
+)w2c_template"
+R"w2c_template( return _addcarry_u64(0, a, b, resptr);
+)w2c_template"
+R"w2c_template(#else
+)w2c_template"
+R"w2c_template(#error "Missing implementation of __builtin_add_overflow or _addcarry_u64"
+)w2c_template"
+R"w2c_template(#endif
+)w2c_template"
+R"w2c_template(}
+)w2c_template"
+R"w2c_template(
+#define RANGE_CHECK(mem, offset, len) \
)w2c_template"
R"w2c_template( do { \
)w2c_template"
R"w2c_template( uint64_t res; \
)w2c_template"
-R"w2c_template( if (__builtin_add_overflow(offset, len, &res)) \
+R"w2c_template( if (UNLIKELY(add_overflow(offset, len, &res))) \
)w2c_template"
R"w2c_template( TRAP(OOB); \
)w2c_template"
@@ -183,16 +200,6 @@ R"w2c_template( TRAP(OOB); \
)w2c_template"
R"w2c_template( } while (0);
)w2c_template"
-R"w2c_template(#else
-)w2c_template"
-R"w2c_template(#define RANGE_CHECK(mem, offset, len) \
-)w2c_template"
-R"w2c_template( if (UNLIKELY(offset + (uint64_t)len > mem->size)) \
-)w2c_template"
-R"w2c_template( TRAP(OOB);
-)w2c_template"
-R"w2c_template(#endif
-)w2c_template"
R"w2c_template(
#if WASM_RT_USE_SEGUE_FOR_THIS_MODULE && WASM_RT_SANITY_CHECKS
)w2c_template"
@@ -215,21 +222,40 @@ R"w2c_template(#define WASM_RT_CHECK_BASE(mem)
R"w2c_template(#endif
)w2c_template"
R"w2c_template(
-#if WASM_RT_MEMCHECK_GUARD_PAGES
+// MEMCHECK_DEFAULT32 is an "accelerated" MEMCHECK used only for
+)w2c_template"
+R"w2c_template(// default-page-size, 32-bit memories. It may do nothing at all
+)w2c_template"
+R"w2c_template(// (if hardware bounds-checking is enabled via guard pages)
)w2c_template"
-R"w2c_template(#define MEMCHECK(mem, a, t) WASM_RT_CHECK_BASE(mem);
+R"w2c_template(// or it may do a slightly faster RANGE_CHECK.
+)w2c_template"
+R"w2c_template(#if WASM_RT_MEMCHECK_GUARD_PAGES
+)w2c_template"
+R"w2c_template(#define MEMCHECK_DEFAULT32(mem, a, t) WASM_RT_CHECK_BASE(mem);
)w2c_template"
R"w2c_template(#else
)w2c_template"
-R"w2c_template(#define MEMCHECK(mem, a, t) \
+R"w2c_template(#define MEMCHECK_DEFAULT32(mem, a, t) \
+)w2c_template"
+R"w2c_template( WASM_RT_CHECK_BASE(mem); \
)w2c_template"
-R"w2c_template( WASM_RT_CHECK_BASE(mem); \
+R"w2c_template( if (UNLIKELY(a + (uint64_t)sizeof(t) > mem->size)) \
)w2c_template"
-R"w2c_template( RANGE_CHECK(mem, a, sizeof(t))
+R"w2c_template( TRAP(OOB);
)w2c_template"
R"w2c_template(#endif
)w2c_template"
R"w2c_template(
+// MEMCHECK_GENERAL can be used for any memory
+)w2c_template"
+R"w2c_template(#define MEMCHECK_GENERAL(mem, a, t) \
+)w2c_template"
+R"w2c_template( WASM_RT_CHECK_BASE(mem); \
+)w2c_template"
+R"w2c_template( RANGE_CHECK(mem, a, sizeof(t));
+)w2c_template"
+R"w2c_template(
#ifdef __GNUC__
)w2c_template"
R"w2c_template(#define FORCE_READ_INT(var) __asm__("" ::"r"(var));
@@ -299,30 +325,103 @@ R"w2c_template( load_data(MEM_ADDR(&m, o, s), i, s); \
R"w2c_template( } while (0)
)w2c_template"
R"w2c_template(
-#define DEFINE_LOAD(name, t1, t2, t3, force_read) \
+#define DEF_MEM_CHECKS0(name, shared, mem_type, ret_kw, return_type) \
+)w2c_template"
+R"w2c_template( static inline return_type name##_default32(wasm_rt##shared##memory_t* mem, \
+)w2c_template"
+R"w2c_template( u64 addr) { \
+)w2c_template"
+R"w2c_template( MEMCHECK_DEFAULT32(mem, addr, mem_type); \
+)w2c_template"
+R"w2c_template( ret_kw name##_unchecked(mem, addr); \
+)w2c_template"
+R"w2c_template( } \
+)w2c_template"
+R"w2c_template( static inline return_type name(wasm_rt##shared##memory_t* mem, u64 addr) { \
+)w2c_template"
+R"w2c_template( MEMCHECK_GENERAL(mem, addr, mem_type); \
+)w2c_template"
+R"w2c_template( ret_kw name##_unchecked(mem, addr); \
+)w2c_template"
+R"w2c_template( }
+)w2c_template"
+R"w2c_template(
+#define DEF_MEM_CHECKS1(name, shared, mem_type, ret_kw, return_type, \
+)w2c_template"
+R"w2c_template( val_type1) \
+)w2c_template"
+R"w2c_template( static inline return_type name##_default32(wasm_rt##shared##memory_t* mem, \
+)w2c_template"
+R"w2c_template( u64 addr, val_type1 val1) { \
+)w2c_template"
+R"w2c_template( MEMCHECK_DEFAULT32(mem, addr, mem_type); \
+)w2c_template"
+R"w2c_template( ret_kw name##_unchecked(mem, addr, val1); \
+)w2c_template"
+R"w2c_template( } \
+)w2c_template"
+R"w2c_template( static inline return_type name(wasm_rt##shared##memory_t* mem, u64 addr, \
+)w2c_template"
+R"w2c_template( val_type1 val1) { \
+)w2c_template"
+R"w2c_template( MEMCHECK_GENERAL(mem, addr, mem_type); \
+)w2c_template"
+R"w2c_template( ret_kw name##_unchecked(mem, addr, val1); \
+)w2c_template"
+R"w2c_template( }
+)w2c_template"
+R"w2c_template(
+#define DEF_MEM_CHECKS2(name, shared, mem_type, ret_kw, return_type, \
+)w2c_template"
+R"w2c_template( val_type1, val_type2) \
+)w2c_template"
+R"w2c_template( static inline return_type name##_default32(wasm_rt##shared##memory_t* mem, \
+)w2c_template"
+R"w2c_template( u64 addr, val_type1 val1, \
+)w2c_template"
+R"w2c_template( val_type2 val2) { \
)w2c_template"
-R"w2c_template( static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \
+R"w2c_template( MEMCHECK_DEFAULT32(mem, addr, mem_type); \
)w2c_template"
-R"w2c_template( MEMCHECK(mem, addr, t1); \
+R"w2c_template( ret_kw name##_unchecked(mem, addr, val1, val2); \
)w2c_template"
-R"w2c_template( t1 result; \
+R"w2c_template( } \
)w2c_template"
-R"w2c_template( wasm_rt_memcpy(&result, MEM_ADDR_MEMOP(mem, addr, sizeof(t1)), \
+R"w2c_template( static inline return_type name(wasm_rt##shared##memory_t* mem, u64 addr, \
)w2c_template"
-R"w2c_template( sizeof(t1)); \
+R"w2c_template( val_type1 val1, val_type2 val2) { \
)w2c_template"
-R"w2c_template( force_read(result); \
+R"w2c_template( MEMCHECK_GENERAL(mem, addr, mem_type); \
)w2c_template"
-R"w2c_template( return (t3)(t2)result; \
+R"w2c_template( ret_kw name##_unchecked(mem, addr, val1, val2); \
)w2c_template"
R"w2c_template( }
)w2c_template"
R"w2c_template(
+#define DEFINE_LOAD(name, t1, t2, t3, force_read) \
+)w2c_template"
+R"w2c_template( static inline t3 name##_unchecked(wasm_rt_memory_t* mem, u64 addr) { \
+)w2c_template"
+R"w2c_template( t1 result; \
+)w2c_template"
+R"w2c_template( wasm_rt_memcpy(&result, MEM_ADDR_MEMOP(mem, 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( DEF_MEM_CHECKS0(name, _, t1, return, t3)
+)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) { \
+R"w2c_template( static inline void name##_unchecked(wasm_rt_memory_t* mem, u64 addr, \
)w2c_template"
-R"w2c_template( MEMCHECK(mem, addr, t1); \
+R"w2c_template( t2 value) { \
)w2c_template"
R"w2c_template( t1 wrapped = (t1)value; \
)w2c_template"
@@ -330,7 +429,9 @@ R"w2c_template( wasm_rt_memcpy(MEM_ADDR_MEMOP(mem, addr, sizeof(t1)), &wrappe
)w2c_template"
R"w2c_template( sizeof(t1)); \
)w2c_template"
-R"w2c_template( }
+R"w2c_template( } \
+)w2c_template"
+R"w2c_template( DEF_MEM_CHECKS1(name, _, t1, , void, t2)
)w2c_template"
R"w2c_template(
DEFINE_LOAD(i32_load, u32, u32, u32, FORCE_READ_INT)
@@ -976,7 +1077,7 @@ R"w2c_template( return sqrtf(x);
R"w2c_template(}
)w2c_template"
R"w2c_template(
-static inline void memory_fill(wasm_rt_memory_t* mem, u32 d, u32 val, u32 n) {
+static inline void memory_fill(wasm_rt_memory_t* mem, u64 d, u32 val, u64 n) {
)w2c_template"
R"w2c_template( RANGE_CHECK(mem, d, n);
)w2c_template"
@@ -989,11 +1090,11 @@ static inline void memory_copy(wasm_rt_memory_t* dest,
)w2c_template"
R"w2c_template( const wasm_rt_memory_t* src,
)w2c_template"
-R"w2c_template( u32 dest_addr,
+R"w2c_template( u64 dest_addr,
)w2c_template"
-R"w2c_template( u32 src_addr,
+R"w2c_template( u64 src_addr,
)w2c_template"
-R"w2c_template( u32 n) {
+R"w2c_template( u64 n) {
)w2c_template"
R"w2c_template( RANGE_CHECK(dest, dest_addr, n);
)w2c_template"
@@ -1010,7 +1111,7 @@ R"w2c_template( const u8* src,
)w2c_template"
R"w2c_template( u32 src_size,
)w2c_template"
-R"w2c_template( u32 dest_addr,
+R"w2c_template( u64 dest_addr,
)w2c_template"
R"w2c_template( u32 src_addr,
)w2c_template"
@@ -1046,7 +1147,7 @@ R"w2c_template( const wasm_elem_segment_exp
)w2c_template"
R"w2c_template( u32 src_size,
)w2c_template"
-R"w2c_template( u32 dest_addr,
+R"w2c_template( u64 dest_addr,
)w2c_template"
R"w2c_template( u32 src_addr,
)w2c_template"
@@ -1058,9 +1159,7 @@ R"w2c_template( if (UNLIKELY(src_addr + (uint64_t)n > src_size))
)w2c_template"
R"w2c_template( TRAP(OOB);
)w2c_template"
-R"w2c_template( if (UNLIKELY(dest_addr + (uint64_t)n > dest->size))
-)w2c_template"
-R"w2c_template( TRAP(OOB);
+R"w2c_template( RANGE_CHECK(dest, dest_addr, n);
)w2c_template"
R"w2c_template( for (u32 i = 0; i < n; i++) {
)w2c_template"
@@ -1107,7 +1206,7 @@ R"w2c_template(static inline void externref_table_init(wasm_rt_externref_table_t
)w2c_template"
R"w2c_template( u32 src_size,
)w2c_template"
-R"w2c_template( u32 dest_addr,
+R"w2c_template( u64 dest_addr,
)w2c_template"
R"w2c_template( u32 src_addr,
)w2c_template"
@@ -1117,9 +1216,7 @@ R"w2c_template( if (UNLIKELY(src_addr + (uint64_t)n > src_size))
)w2c_template"
R"w2c_template( TRAP(OOB);
)w2c_template"
-R"w2c_template( if (UNLIKELY(dest_addr + (uint64_t)n > dest->size))
-)w2c_template"
-R"w2c_template( TRAP(OOB);
+R"w2c_template( RANGE_CHECK(dest, dest_addr, n);
)w2c_template"
R"w2c_template( for (u32 i = 0; i < n; i++) {
)w2c_template"
@@ -1136,17 +1233,11 @@ R"w2c_template( static inline void type##_table_copy(wasm_rt_##type##_table_t*
)w2c_template"
R"w2c_template( const wasm_rt_##type##_table_t* src, \
)w2c_template"
-R"w2c_template( u32 dest_addr, u32 src_addr, u32 n) { \
+R"w2c_template( u64 dest_addr, u64 src_addr, u64 n) { \
)w2c_template"
-R"w2c_template( if (UNLIKELY(dest_addr + (uint64_t)n > dest->size)) \
+R"w2c_template( RANGE_CHECK(dest, dest_addr, n); \
)w2c_template"
-R"w2c_template( TRAP(OOB); \
-)w2c_template"
-R"w2c_template( if (UNLIKELY(src_addr + (uint64_t)n > src->size)) \
-)w2c_template"
-R"w2c_template( TRAP(OOB); \
-)w2c_template"
-R"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, \
)w2c_template"
@@ -1164,7 +1255,7 @@ R"w2c_template(
)w2c_template"
R"w2c_template( static inline wasm_rt_##type##_t type##_table_get( \
)w2c_template"
-R"w2c_template( const wasm_rt_##type##_table_t* table, u32 i) { \
+R"w2c_template( const wasm_rt_##type##_table_t* table, u64 i) { \
)w2c_template"
R"w2c_template( if (UNLIKELY(i >= table->size)) \
)w2c_template"
@@ -1184,7 +1275,7 @@ R"w2c_template(
)w2c_template"
R"w2c_template( static inline void type##_table_set(const wasm_rt_##type##_table_t* table, \
)w2c_template"
-R"w2c_template( u32 i, const wasm_rt_##type##_t val) { \
+R"w2c_template( u64 i, const wasm_rt_##type##_t val) { \
)w2c_template"
R"w2c_template( if (UNLIKELY(i >= table->size)) \
)w2c_template"
@@ -1204,13 +1295,11 @@ R"w2c_template(
)w2c_template"
R"w2c_template( static inline void type##_table_fill(const wasm_rt_##type##_table_t* table, \
)w2c_template"
-R"w2c_template( u32 d, const wasm_rt_##type##_t val, \
-)w2c_template"
-R"w2c_template( u32 n) { \
+R"w2c_template( u64 d, const wasm_rt_##type##_t val, \
)w2c_template"
-R"w2c_template( if (UNLIKELY((uint64_t)d + n > table->size)) \
+R"w2c_template( u64 n) { \
)w2c_template"
-R"w2c_template( TRAP(OOB); \
+R"w2c_template( RANGE_CHECK(table, d, n); \
)w2c_template"
R"w2c_template( for (uint32_t i = d; i < d + n; i++) { \
)w2c_template"