Skip to content

Commit

Permalink
simplify
Browse files Browse the repository at this point in the history
  • Loading branch information
sbc100 committed Mar 9, 2022
1 parent 54794dc commit 3693ed4
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 549 deletions.
19 changes: 5 additions & 14 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
#

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 @@ -362,19 +361,11 @@ set(WABT_LIBRARY_SRC

add_library(wabt STATIC ${WABT_LIBRARY_SRC})

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 (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 ()

if (BUILD_FUZZ_TOOLS)
set(FUZZ_FLAGS "-fsanitize=fuzzer,address")
Expand Down
8 changes: 6 additions & 2 deletions test/run-spec-wasm2c.py
Original file line number Diff line number Diff line change
Expand Up @@ -471,14 +471,18 @@ def main(args):
o_filenames.append(Compile(cc, c_filename, out_dir, includes, defines))

if options.compile:
# Compile wasm-rt-impl.
wasm_rt_impl_c = os.path.join(options.wasmrt_dir, 'wasm-rt-impl.c')
o_filenames.append(Compile(cc, wasm_rt_impl_c, out_dir, includes))

# Compile and link -main test run entry point
o_filenames.append(Compile(cc, main_filename, out_dir, includes))
if IS_WINDOWS:
exe_ext = '.exe'
libs = ['/libpath:' + options.bindir, 'wasm-rt-impl.lib']
libs = []
else:
exe_ext = ''
libs = ['-L' + options.bindir, '-lwasm-rt-impl', '-lm']
libs = ['-lm']
main_exe = utils.ChangeExt(json_file_path, exe_ext)
Link(cc, o_filenames, main_exe, *libs)

Expand Down
2 changes: 1 addition & 1 deletion wasm2c/examples/fac/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ all: fac
clean:
rm -rf fac fac.wasm fac.c *.o

fac: main.o fac.o ../../wasm-rt-impl.o ../../wasm-rt-os-unix.o -lm
fac: main.o fac.o ../../wasm-rt-impl.o -lm

fac.wasm: fac.wat ../../../bin/wat2wasm
../../../bin/wat2wasm $< -o $@
Expand Down
127 changes: 101 additions & 26 deletions wasm2c/examples/fac/fac.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
#include <string.h>

#include "fac.h"
#define UNLIKELY(x) __builtin_expect(!!(x), 0)
#define LIKELY(x) __builtin_expect(!!(x), 1)

#define TRAP(x) (wasm_rt_trap(WASM_RT_TRAP_##x), 0)

Expand All @@ -22,13 +20,13 @@
|| TRAP(CALL_INDIRECT) \
, ((t)table.data[x].func)(__VA_ARGS__))

#define RANGE_CHECK(mem, a, t) \
if (UNLIKELY((a) + sizeof(t) > mem->size)) TRAP(OOB)
#define RANGE_CHECK(mem, offset, len) \
if (UNLIKELY(offset + (uint64_t)len > mem->size)) TRAP(OOB)

#if WASM_RT_MEMCHECK_SIGNAL_HANDLER
#define MEMCHECK(mem, a, t)
#else
#define MEMCHECK(mem, a, t) RANGE_CHECK(mem, a, t)
#define MEMCHECK(mem, a, t) RANGE_CHECK(mem, a, sizeof(t))
#endif

#if WABT_BIG_ENDIAN
Expand All @@ -42,45 +40,48 @@ static inline void load_data(void *dest, const void *src, size_t n) {
dest_chars[n - i - 1] = cursor;
}
}
#define LOAD_DATA(m, o, i, s) do { \
RANGE_CHECK((&m), m.size - o - s, char[s]); \
#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) \
static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \
MEMCHECK(mem, addr, t1); \
t1 result; \
__builtin_memcpy(&result, &mem->data[mem->size - addr - sizeof(t1)], sizeof(t1)); \
return (t3)(t2)result; \
#define DEFINE_LOAD(name, t1, t2, t3) \
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)); \
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; \
__builtin_memcpy(&mem->data[mem->size - addr - sizeof(t1)], &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->data[mem->size - addr - sizeof(t1)], &wrapped, \
sizeof(t1)); \
}
#else
static inline void load_data(void *dest, const void *src, size_t n) {
memcpy(dest, src, n);
}
#define LOAD_DATA(m, o, i, s) do { \
RANGE_CHECK((&m), o, char[s]); \
RANGE_CHECK((&m), o, s); \
load_data(&(m.data[o]), i, s); \
} while (0)
#define DEFINE_LOAD(name, t1, t2, t3) \
static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \
MEMCHECK(mem, addr, t1); \
t1 result; \
__builtin_memcpy(&result, &mem->data[addr], sizeof(t1)); \
return (t3)(t2)result; \
#define DEFINE_LOAD(name, t1, t2, t3) \
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)); \
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; \
__builtin_memcpy(&mem->data[addr], &wrapped, sizeof(t1)); \
wasm_rt_memcpy(&mem->data[addr], &wrapped, sizeof(t1)); \
}
#endif

Expand Down Expand Up @@ -108,13 +109,87 @@ DEFINE_STORE(i64_store8, u8, u64)
DEFINE_STORE(i64_store16, u16, u64)
DEFINE_STORE(i64_store32, u32, u64)

#if defined(_MSC_VER)

#include <intrin.h>

// Adapted from https://github.com/nemequ/portable-snippets/blob/master/builtin/builtin.h

static inline int I64_CLZ(unsigned long long v) {
unsigned long r = 0;
#if defined(_M_AMD64) || defined(_M_ARM)
if (_BitScanReverse64(&r, v)) {
return 63 - r;
}
#else
if (_BitScanReverse(&r, (unsigned long) (v >> 32))) {
return 31 - r;
} else if (_BitScanReverse(&r, (unsigned long) v)) {
return 63 - r;
}
#endif
return 64;
}

static inline int I32_CLZ(unsigned long v) {
unsigned long r = 0;
if (_BitScanReverse(&r, v)) {
return 31 - r;
}
return 32;
}

static inline int I64_CTZ(unsigned long long v) {
if (!v) {
return 64;
}
unsigned long r = 0;
#if defined(_M_AMD64) || defined(_M_ARM)
_BitScanForward64(&r, v);
return (int) r;
#else
if (_BitScanForward(&r, (unsigned int) (v))) {
return (int) (r);
}

_BitScanForward(&r, (unsigned int) (v >> 32));
return (int) (r + 32);
#endif
}

static inline int I32_CTZ(unsigned long v) {
if (!v) {
return 32;
}
unsigned long r = 0;
_BitScanForward(&r, v);
return (int) r;
}

#define POPCOUNT_DEFINE_PORTABLE(f_n, T) \
static inline u32 f_n(T x) { \
x = x - ((x >> 1) & (T)~(T)0/3); \
x = (x & (T)~(T)0/15*3) + ((x >> 2) & (T)~(T)0/15*3); \
x = (x + (x >> 4)) & (T)~(T)0/255*15; \
return (T)(x * ((T)~(T)0/255)) >> (sizeof(T) - 1) * 8; \
}

POPCOUNT_DEFINE_PORTABLE(I32_POPCNT, u32)
POPCOUNT_DEFINE_PORTABLE(I64_POPCNT, u64)

#undef POPCOUNT_DEFINE_PORTABLE

#else

#define I32_CLZ(x) ((x) ? __builtin_clz(x) : 32)
#define I64_CLZ(x) ((x) ? __builtin_clzll(x) : 64)
#define I32_CTZ(x) ((x) ? __builtin_ctz(x) : 32)
#define I64_CTZ(x) ((x) ? __builtin_ctzll(x) : 64)
#define I32_POPCNT(x) (__builtin_popcount(x))
#define I64_POPCNT(x) (__builtin_popcountll(x))

#endif

#define DIV_S(ut, min, x, y) \
((UNLIKELY((y) == 0)) ? TRAP(DIV_BY_ZERO) \
: (UNLIKELY((x) == min && (y) == -1)) ? TRAP(INT_OVERFLOW) \
Expand Down
2 changes: 1 addition & 1 deletion wasm2c/examples/rot13/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ all: rot13
clean:
rm -rf rot13 rot13.wasm rot13.c *.o

rot13: main.o rot13.o ../../wasm-rt-impl.o ../../wasm-rt-os-unix.o -lm
rot13: main.o rot13.o ../../wasm-rt-impl.o -lm

rot13.wasm: rot13.wat ../../../bin/wat2wasm
../../../bin/wat2wasm $< -o $@
Expand Down
65 changes: 53 additions & 12 deletions wasm2c/wasm-rt-impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
*/

#include "wasm-rt-impl.h"
#include "wasm-rt-os.h"

#include <assert.h>
#include <math.h>
Expand Down Expand Up @@ -110,10 +109,55 @@ static void signal_handler(int sig, siginfo_t* si, void* unused) {
}
#endif

// Heap aligned to 4GB
#define WASM_HEAP_ALIGNMENT 0x100000000ull
#ifdef _WIN32
static void* os_mmap(size_t size) {
return VirtualAlloc(NULL, request_size, MEM_RESERVE | MEM_COMMIT, PAGE_NOACCESS);
}

static int os_mprotect(void* addr, size_t size) {
DWORD old;
BOOL succeeded = VirtualProtect((LPVOID)addr, size, PAGE_READWRITE, &old);
return succeeded ? 0 : -1;
}

bool wasm_rt_allocate_memory(wasm_rt_memory_t* memory,
static void os_print_last_error(const char* msg) {
DWORD errorMessageID = GetLastError();
if (errorMessageID != 0) {
LPSTR messageBuffer = 0;
// The api creates the buffer that holds the message
size_t size = FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR)&messageBuffer, 0, NULL);
(void)size;
// Copy the error message into a std::string.
printf("%s. %s\n", msg, messageBuffer);
LocalFree(messageBuffer);
} else {
printf("%s. No error code.\n", msg);
}
}
#else
static void* os_mmap(size_t size) {
int map_prot = PROT_NONE;
int map_flags = MAP_ANONYMOUS | MAP_PRIVATE;
uint8_t* addr = mmap(NULL, size, map_prot, map_flags, -1, 0);
if (addr == MAP_FAILED)
return NULL;
return addr;
}

static int os_mprotect(void* addr, size_t size) {
return mprotect(addr, size, PROT_READ | PROT_WRITE);
}

static void os_print_last_error(const char* msg) {
perror(msg);
}
#endif

void wasm_rt_allocate_memory(wasm_rt_memory_t* memory,
uint32_t initial_pages,
uint32_t max_pages) {
uint32_t byte_length = initial_pages * PAGE_SIZE;
Expand All @@ -134,17 +178,16 @@ bool wasm_rt_allocate_memory(wasm_rt_memory_t* memory,
}

/* Reserve 8GiB. */
void* addr =
os_mmap_aligned(NULL, 0x200000000ul, MMAP_PROT_NONE, MMAP_MAP_NONE,
WASM_HEAP_ALIGNMENT, /*alignment_offset=*/0);
void* addr = os_mmap(0x200000000ul);

if (addr == (void*)-1) {
os_print_last_error("os_mmap failed.");
abort();
}
int ret = os_mmap_commit(addr, byte_length, MMAP_PROT_READ | MMAP_PROT_WRITE);
int ret = os_mprotect(addr, byte_length);
if (ret != 0) {
return false;
os_print_last_error("os_mprotect failed.");
abort();
}
memory->data = addr;
#else
Expand All @@ -153,7 +196,6 @@ bool wasm_rt_allocate_memory(wasm_rt_memory_t* memory,
memory->size = byte_length;
memory->pages = initial_pages;
memory->max_pages = max_pages;
return true;
}

uint32_t wasm_rt_grow_memory(wasm_rt_memory_t* memory, uint32_t delta) {
Expand All @@ -170,8 +212,7 @@ uint32_t wasm_rt_grow_memory(wasm_rt_memory_t* memory, uint32_t delta) {
uint32_t delta_size = delta * PAGE_SIZE;
#if WASM_RT_MEMCHECK_SIGNAL_HANDLER_POSIX
uint8_t* new_data = memory->data;
int ret = os_mmap_commit(new_data + old_size, delta_size,
MMAP_PROT_READ | MMAP_PROT_WRITE);
int ret = os_mprotect(new_data + old_size, delta_size);
if (ret != 0) {
return (uint32_t)-1;
}
Expand Down
Loading

0 comments on commit 3693ed4

Please sign in to comment.