summaryrefslogtreecommitdiff
path: root/wasm2c/wasm-rt-mem-impl.c
diff options
context:
space:
mode:
Diffstat (limited to 'wasm2c/wasm-rt-mem-impl.c')
-rw-r--r--wasm2c/wasm-rt-mem-impl.c178
1 files changed, 178 insertions, 0 deletions
diff --git a/wasm2c/wasm-rt-mem-impl.c b/wasm2c/wasm-rt-mem-impl.c
new file mode 100644
index 00000000..d29aadad
--- /dev/null
+++ b/wasm2c/wasm-rt-mem-impl.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2018 WebAssembly Community Group participants
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wasm-rt-impl.h"
+
+#include <assert.h>
+#include <stdio.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <sys/mman.h>
+#endif
+
+#define PAGE_SIZE 65536
+
+#ifdef WASM_RT_GROW_FAILED_HANDLER
+extern void WASM_RT_GROW_FAILED_HANDLER();
+#endif
+
+#define C11_MEMORY_LOCK_VAR_INIT(name) \
+ if (mtx_init(&(name), mtx_plain) != thrd_success) { \
+ fprintf(stderr, "Lock init failed\n"); \
+ abort(); \
+ }
+#define C11_MEMORY_LOCK_AQUIRE(name) \
+ if (mtx_lock(&(name)) != thrd_success) { \
+ fprintf(stderr, "Lock acquire failed\n"); \
+ abort(); \
+ }
+#define C11_MEMORY_LOCK_RELEASE(name) \
+ if (mtx_unlock(&(name)) != thrd_success) { \
+ fprintf(stderr, "Lock release failed\n"); \
+ abort(); \
+ }
+
+#define PTHREAD_MEMORY_LOCK_VAR_INIT(name) \
+ if (pthread_mutex_init(&(name), NULL) != 0) { \
+ fprintf(stderr, "Lock init failed\n"); \
+ abort(); \
+ }
+#define PTHREAD_MEMORY_LOCK_AQUIRE(name) \
+ if (pthread_mutex_lock(&(name)) != 0) { \
+ fprintf(stderr, "Lock acquire failed\n"); \
+ abort(); \
+ }
+#define PTHREAD_MEMORY_LOCK_RELEASE(name) \
+ if (pthread_mutex_unlock(&(name)) != 0) { \
+ fprintf(stderr, "Lock release failed\n"); \
+ abort(); \
+ }
+
+#define WIN_MEMORY_LOCK_VAR_INIT(name) InitializeCriticalSection(&(name))
+#define WIN_MEMORY_LOCK_AQUIRE(name) EnterCriticalSection(&(name))
+#define WIN_MEMORY_LOCK_RELEASE(name) LeaveCriticalSection(&(name))
+
+#if WASM_RT_USE_MMAP
+
+#ifdef _WIN32
+static void* os_mmap(size_t size) {
+ void* ret = VirtualAlloc(NULL, size, MEM_RESERVE, PAGE_NOACCESS);
+ return ret;
+}
+
+static int os_munmap(void* addr, size_t size) {
+ // Windows can only unmap the whole mapping
+ (void)size; /* unused */
+ BOOL succeeded = VirtualFree(addr, 0, MEM_RELEASE);
+ return succeeded ? 0 : -1;
+}
+
+static int os_mprotect(void* addr, size_t size) {
+ if (size == 0) {
+ return 0;
+ }
+ void* ret = VirtualAlloc(addr, size, MEM_COMMIT, PAGE_READWRITE);
+ if (ret == addr) {
+ return 0;
+ }
+ VirtualFree(addr, 0, MEM_RELEASE);
+ return -1;
+}
+
+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;
+ 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_munmap(void* addr, size_t size) {
+ return munmap(addr, size);
+}
+
+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
+
+static uint64_t get_alloc_size_for_mmap(uint64_t max_pages, bool is64) {
+ assert(!is64 && "memory64 is not yet compatible with WASM_RT_USE_MMAP");
+#if WASM_RT_MEMCHECK_GUARD_PAGES
+ /* Reserve 8GiB. */
+ const uint64_t max_size = 0x200000000ul;
+ return max_size;
+#else
+ if (max_pages != 0) {
+ const uint64_t max_size = max_pages * PAGE_SIZE;
+ return max_size;
+ }
+
+ /* Reserve 4GiB. */
+ const uint64_t max_size = 0x100000000ul;
+ return max_size;
+#endif
+}
+
+#endif
+
+// Include operations for memory
+#define WASM_RT_MEM_OPS
+#include "wasm-rt-mem-impl-helper.inc"
+#undef WASM_RT_MEM_OPS
+
+// Include operations for shared memory
+#define WASM_RT_MEM_OPS_SHARED
+#include "wasm-rt-mem-impl-helper.inc"
+#undef WASM_RT_MEM_OPS_SHARED
+
+#undef C11_MEMORY_LOCK_VAR_INIT
+#undef C11_MEMORY_LOCK_AQUIRE
+#undef C11_MEMORY_LOCK_RELEASE
+#undef PTHREAD_MEMORY_LOCK_VAR_INIT
+#undef PTHREAD_MEMORY_LOCK_AQUIRE
+#undef PTHREAD_MEMORY_LOCK_RELEASE
+#undef WIN_MEMORY_LOCK_VAR_INIT
+#undef WIN_MEMORY_LOCK_AQUIRE
+#undef WIN_MEMORY_LOCK_RELEASE
+#undef PAGE_SIZE