Skip to content

Commit

Permalink
Add windows implementation of wasm2c runtime
Browse files Browse the repository at this point in the history
Split out from #1833
  • Loading branch information
sbc100 committed Mar 9, 2022
1 parent 720a7f2 commit ec759cc
Show file tree
Hide file tree
Showing 14 changed files with 921 additions and 110 deletions.
19 changes: 14 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#

cmake_minimum_required(VERSION 3.0.0)
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.11" CACHE STRING "Minimum OS X deployment version")
project(WABT LANGUAGES C CXX VERSION 1.0.27)
include(GNUInstallDirs)

Expand Down Expand Up @@ -361,11 +362,19 @@ set(WABT_LIBRARY_SRC

add_library(wabt STATIC ${WABT_LIBRARY_SRC})

IF (NOT WIN32)
add_library(wasm-rt-impl STATIC wasm2c/wasm-rt-impl.c wasm2c/wasm-rt-impl.h)
install(TARGETS wasm-rt-impl DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(FILES wasm2c/wasm-rt.h wasm2c/wasm-rt-impl.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
endif ()
add_library(wasm-rt-impl SHARED STATIC
wasm2c/wasm-rt-impl.c
wasm2c/wasm-rt-os-unix.c
wasm2c/wasm-rt-os-win.c)
set_property(TARGET wasm-rt-impl PROPERTY POSITION_INDEPENDENT_CODE ON)
install(TARGETS wasm-rt-impl DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(FILES wasm2c/wasm-rt.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

add_custom_target(wasm-rt-impl-copy-to-bin ALL
COMMAND ${CMAKE_COMMAND} -E make_directory ${WABT_SOURCE_DIR}/bin
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:wasm-rt-impl> ${WABT_SOURCE_DIR}/bin
DEPENDS wasm-rt-impl
)

if (BUILD_FUZZ_TOOLS)
set(FUZZ_FLAGS "-fsanitize=fuzzer,address")
Expand Down
12 changes: 6 additions & 6 deletions src/c-writer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2220,11 +2220,11 @@ void CWriter::Write(const UnaryExpr& expr) {
break;

case Opcode::F32Abs:
WriteSimpleUnaryExpr(expr.opcode, "fabsf");
WriteSimpleUnaryExpr(expr.opcode, "wasm_rt_fabsf");
break;

case Opcode::F64Abs:
WriteSimpleUnaryExpr(expr.opcode, "fabs");
WriteSimpleUnaryExpr(expr.opcode, "wasm_rt_fabs");
break;

case Opcode::F32Sqrt:
Expand Down Expand Up @@ -2252,19 +2252,19 @@ void CWriter::Write(const UnaryExpr& expr) {
break;

case Opcode::F32Trunc:
WriteSimpleUnaryExpr(expr.opcode, "truncf");
WriteSimpleUnaryExpr(expr.opcode, "wasm_rt_truncf");
break;

case Opcode::F64Trunc:
WriteSimpleUnaryExpr(expr.opcode, "trunc");
WriteSimpleUnaryExpr(expr.opcode, "wasm_rt_trunc");
break;

case Opcode::F32Nearest:
WriteSimpleUnaryExpr(expr.opcode, "nearbyintf");
WriteSimpleUnaryExpr(expr.opcode, "wasm_rt_nearbyintf");
break;

case Opcode::F64Nearest:
WriteSimpleUnaryExpr(expr.opcode, "nearbyint");
WriteSimpleUnaryExpr(expr.opcode, "wasm_rt_nearbyint");
break;

case Opcode::I32Extend8S:
Expand Down
127 changes: 101 additions & 26 deletions src/prebuilt/wasm2c.include.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ const char SECTION_NAME(includes)[] =
;

const char SECTION_NAME(declarations)[] =
"#define UNLIKELY(x) __builtin_expect(!!(x), 0)\n"
"#define LIKELY(x) __builtin_expect(!!(x), 1)\n"
"\n"
"#define TRAP(x) (wasm_rt_trap(WASM_RT_TRAP_##x), 0)\n"
"\n"
Expand All @@ -25,13 +23,13 @@ const char SECTION_NAME(declarations)[] =
" || TRAP(CALL_INDIRECT) \\\n"
" , ((t)table.data[x].func)(__VA_ARGS__))\n"
"\n"
"#define RANGE_CHECK(mem, a, t) \\\n"
" if (UNLIKELY((a) + sizeof(t) > mem->size)) TRAP(OOB)\n"
"#define RANGE_CHECK(mem, addr, len) \\\n"
" if (UNLIKELY((uint64_t)(addr) + len > mem->size)) TRAP(OOB)\n"
"\n"
"#if WASM_RT_MEMCHECK_SIGNAL_HANDLER\n"
"#define MEMCHECK(mem, a, t)\n"
"#else\n"
"#define MEMCHECK(mem, a, t) RANGE_CHECK(mem, a, t)\n"
"#define MEMCHECK(mem, a, t) RANGE_CHECK(mem, a, sizeof(t))\n"
"#endif\n"
"\n"
"#if WABT_BIG_ENDIAN\n"
Expand All @@ -45,45 +43,48 @@ const char SECTION_NAME(declarations)[] =
" dest_chars[n - i - 1] = cursor;\n"
" }\n"
"}\n"
"#define LOAD_DATA(m, o, i, s) do { \\\n"
" RANGE_CHECK((&m), m.size - o - s, char[s]); \\\n"
"#define LOAD_DATA(m, o, i, s) \\\n"
" do { \\\n"
" RANGE_CHECK((&m), m.size - o - s, s); \\\n"
" load_data(&(m.data[m.size - o - s]), i, s); \\\n"
" } while (0)\n"
"#define DEFINE_LOAD(name, t1, t2, t3) \\\n"
" static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \\\n"
" MEMCHECK(mem, addr, t1); \\\n"
" t1 result; \\\n"
" __builtin_memcpy(&result, &mem->data[mem->size - addr - sizeof(t1)], sizeof(t1)); \\\n"
" return (t3)(t2)result; \\\n"
"#define DEFINE_LOAD(name, t1, t2, t3) \\\n"
" static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \\\n"
" MEMCHECK(mem, addr, t1); \\\n"
" t1 result; \\\n"
" wasm_rt_memcpy(&result, &mem->data[mem->size - addr - sizeof(t1)], \\\n"
" sizeof(t1)); \\\n"
" return (t3)(t2)result; \\\n"
" }\n"
"\n"
"#define DEFINE_STORE(name, t1, t2) \\\n"
" static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \\\n"
" MEMCHECK(mem, addr, t1); \\\n"
" t1 wrapped = (t1)value; \\\n"
" __builtin_memcpy(&mem->data[mem->size - addr - sizeof(t1)], &wrapped, sizeof(t1)); \\\n"
"#define DEFINE_STORE(name, t1, t2) \\\n"
" static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \\\n"
" MEMCHECK(mem, addr, t1); \\\n"
" t1 wrapped = (t1)value; \\\n"
" wasm_rt_memcpy(&mem->data[mem->size - addr - sizeof(t1)], &wrapped, \\\n"
" sizeof(t1)); \\\n"
" }\n"
"#else\n"
"static inline void load_data(void *dest, const void *src, size_t n) {\n"
" memcpy(dest, src, n);\n"
"}\n"
"#define LOAD_DATA(m, o, i, s) do { \\\n"
" RANGE_CHECK((&m), o, char[s]); \\\n"
" RANGE_CHECK((&m), o, s); \\\n"
" load_data(&(m.data[o]), i, s); \\\n"
" } while (0)\n"
"#define DEFINE_LOAD(name, t1, t2, t3) \\\n"
" static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \\\n"
" MEMCHECK(mem, addr, t1); \\\n"
" t1 result; \\\n"
" __builtin_memcpy(&result, &mem->data[addr], sizeof(t1)); \\\n"
" return (t3)(t2)result; \\\n"
"#define DEFINE_LOAD(name, t1, t2, t3) \\\n"
" static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \\\n"
" MEMCHECK(mem, addr, t1); \\\n"
" t1 result; \\\n"
" wasm_rt_memcpy(&result, &mem->data[addr], sizeof(t1)); \\\n"
" return (t3)(t2)result; \\\n"
" }\n"
"\n"
"#define DEFINE_STORE(name, t1, t2) \\\n"
" static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \\\n"
" MEMCHECK(mem, addr, t1); \\\n"
" t1 wrapped = (t1)value; \\\n"
" __builtin_memcpy(&mem->data[addr], &wrapped, sizeof(t1)); \\\n"
" wasm_rt_memcpy(&mem->data[addr], &wrapped, sizeof(t1)); \\\n"
" }\n"
"#endif\n"
"\n"
Expand Down Expand Up @@ -111,13 +112,87 @@ const char SECTION_NAME(declarations)[] =
"DEFINE_STORE(i64_store16, u16, u64)\n"
"DEFINE_STORE(i64_store32, u32, u64)\n"
"\n"
"#if defined(_MSC_VER)\n"
"\n"
"#include <intrin.h>\n"
"\n"
"// Adapted from https://github.com/nemequ/portable-snippets/blob/master/builtin/builtin.h\n"
"\n"
"static inline int I64_CLZ(unsigned long long v) {\n"
" unsigned long r = 0;\n"
"#if defined(_M_AMD64) || defined(_M_ARM)\n"
" if (_BitScanReverse64(&r, v)) {\n"
" return 63 - r;\n"
" }\n"
"#else\n"
" if (_BitScanReverse(&r, (unsigned long) (v >> 32))) {\n"
" return 31 - r;\n"
" } else if (_BitScanReverse(&r, (unsigned long) v)) {\n"
" return 63 - r;\n"
" }\n"
"#endif\n"
" return 64;\n"
"}\n"
"\n"
"static inline int I32_CLZ(unsigned long v) {\n"
" unsigned long r = 0;\n"
" if (_BitScanReverse(&r, v)) {\n"
" return 31 - r;\n"
" }\n"
" return 32;\n"
"}\n"
"\n"
"static inline int I64_CTZ(unsigned long long v) {\n"
" if (!v) {\n"
" return 64;\n"
" }\n"
" unsigned long r = 0;\n"
"#if defined(_M_AMD64) || defined(_M_ARM)\n"
" _BitScanForward64(&r, v);\n"
" return (int) r;\n"
"#else\n"
" if (_BitScanForward(&r, (unsigned int) (v))) {\n"
" return (int) (r);\n"
" }\n"
"\n"
" _BitScanForward(&r, (unsigned int) (v >> 32));\n"
" return (int) (r + 32);\n"
"#endif\n"
"}\n"
"\n"
"static inline int I32_CTZ(unsigned long v) {\n"
" if (!v) {\n"
" return 32;\n"
" }\n"
" unsigned long r = 0;\n"
" _BitScanForward(&r, v);\n"
" return (int) r;\n"
"}\n"
"\n"
"#define POPCOUNT_DEFINE_PORTABLE(f_n, T) \\\n"
" static inline u32 f_n(T x) { \\\n"
" x = x - ((x >> 1) & (T)~(T)0/3); \\\n"
" x = (x & (T)~(T)0/15*3) + ((x >> 2) & (T)~(T)0/15*3); \\\n"
" x = (x + (x >> 4)) & (T)~(T)0/255*15; \\\n"
" return (T)(x * ((T)~(T)0/255)) >> (sizeof(T) - 1) * 8; \\\n"
" }\n"
"\n"
"POPCOUNT_DEFINE_PORTABLE(I32_POPCNT, u32)\n"
"POPCOUNT_DEFINE_PORTABLE(I64_POPCNT, u64)\n"
"\n"
"#undef POPCOUNT_DEFINE_PORTABLE\n"
"\n"
"#else\n"
"\n"
"#define I32_CLZ(x) ((x) ? __builtin_clz(x) : 32)\n"
"#define I64_CLZ(x) ((x) ? __builtin_clzll(x) : 64)\n"
"#define I32_CTZ(x) ((x) ? __builtin_ctz(x) : 32)\n"
"#define I64_CTZ(x) ((x) ? __builtin_ctzll(x) : 64)\n"
"#define I32_POPCNT(x) (__builtin_popcount(x))\n"
"#define I64_POPCNT(x) (__builtin_popcountll(x))\n"
"\n"
"#endif\n"
"\n"
"#define DIV_S(ut, min, x, y) \\\n"
" ((UNLIKELY((y) == 0)) ? TRAP(DIV_BY_ZERO) \\\n"
" : (UNLIKELY((x) == min && (y) == -1)) ? TRAP(INT_OVERFLOW) \\\n"
Expand Down
Loading

0 comments on commit ec759cc

Please sign in to comment.