summaryrefslogtreecommitdiffstats
path: root/third_party/wasm2c/wasm2c/wasm-rt.h
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/wasm2c/wasm2c/wasm-rt.h')
-rw-r--r--third_party/wasm2c/wasm2c/wasm-rt.h455
1 files changed, 455 insertions, 0 deletions
diff --git a/third_party/wasm2c/wasm2c/wasm-rt.h b/third_party/wasm2c/wasm2c/wasm-rt.h
new file mode 100644
index 0000000000..9fd12dee03
--- /dev/null
+++ b/third_party/wasm2c/wasm2c/wasm-rt.h
@@ -0,0 +1,455 @@
+/*
+ * 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.
+ */
+
+#ifndef WASM_RT_H_
+#define WASM_RT_H_
+
+#include <setjmp.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __has_builtin
+#define __has_builtin(x) 0 // Compatibility with non-clang compilers.
+#endif
+
+#if __has_builtin(__builtin_expect)
+#define UNLIKELY(x) __builtin_expect(!!(x), 0)
+#define LIKELY(x) __builtin_expect(!!(x), 1)
+#else
+#define UNLIKELY(x) (x)
+#define LIKELY(x) (x)
+#endif
+
+#if __has_builtin(__builtin_memcpy)
+#define wasm_rt_memcpy __builtin_memcpy
+#else
+#define wasm_rt_memcpy memcpy
+#endif
+
+#if __has_builtin(__builtin_unreachable)
+#define wasm_rt_unreachable __builtin_unreachable
+#else
+#define wasm_rt_unreachable abort
+#endif
+
+#ifdef _MSC_VER
+#define WASM_RT_THREAD_LOCAL __declspec(thread)
+#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
+#define WASM_RT_THREAD_LOCAL _Thread_local
+#else
+#define WASM_RT_THREAD_LOCAL
+#endif
+
+/**
+ * Backward compatibility: Convert the previously exposed
+ * WASM_RT_MEMCHECK_SIGNAL_HANDLER macro to the ALLOCATION and CHECK macros that
+ * are now used.
+ */
+#if defined(WASM_RT_MEMCHECK_SIGNAL_HANDLER)
+
+#if WASM_RT_MEMCHECK_SIGNAL_HANDLER
+#define WASM_RT_USE_MMAP 1
+#define WASM_RT_MEMCHECK_GUARD_PAGES 1
+#else
+#define WASM_RT_USE_MMAP 0
+#define WASM_RT_MEMCHECK_BOUNDS_CHECK 1
+#endif
+
+#warning \
+ "WASM_RT_MEMCHECK_SIGNAL_HANDLER has been deprecated in favor of WASM_RT_USE_MMAP and WASM_RT_MEMORY_CHECK_* macros"
+#endif
+
+/**
+ * Specify if we use OR mmap/mprotect (+ Windows equivalents) OR malloc/realloc
+ * for the Wasm memory allocation and growth. mmap/mprotect guarantees memory
+ * will grow without being moved, while malloc ensures the virtual memory is
+ * consumed only as needed, but may relocate the memory to handle memory
+ * fragmentation.
+ *
+ * This defaults to malloc on 32-bit platforms or if memory64 support is needed.
+ * It defaults to mmap on 64-bit platforms assuming memory64 support is not
+ * needed (so we can use the guard based range checks below).
+ */
+#ifndef WASM_RT_USE_MMAP
+#if UINTPTR_MAX > 0xffffffff && !SUPPORT_MEMORY64
+#define WASM_RT_USE_MMAP 1
+#else
+#define WASM_RT_USE_MMAP 0
+#endif
+#endif
+
+/**
+ * Set the range checking strategy for Wasm memories.
+ *
+ * GUARD_PAGES: memory accesses rely on unmapped pages/guard pages to trap
+ * out-of-bound accesses.
+ *
+ * BOUNDS_CHECK: memory accesses are checked with explicit bounds checks.
+ *
+ * This defaults to GUARD_PAGES as this is the fasest option, iff the
+ * requirements of GUARD_PAGES --- 64-bit platforms, MMAP allocation strategy,
+ * no 64-bit memories --- are met. This falls back to BOUNDS otherwise.
+ */
+
+// Check if Guard checks are supported
+#if UINTPTR_MAX > 0xffffffff && WASM_RT_USE_MMAP && !SUPPORT_MEMORY64
+#define WASM_RT_GUARD_PAGES_SUPPORTED 1
+#else
+#define WASM_RT_GUARD_PAGES_SUPPORTED 0
+#endif
+
+// Specify defaults for memory checks if unspecified
+#if !defined(WASM_RT_MEMCHECK_GUARD_PAGES) && \
+ !defined(WASM_RT_MEMCHECK_BOUNDS_CHECK)
+#if WASM_RT_GUARD_PAGES_SUPPORTED
+#define WASM_RT_MEMCHECK_GUARD_PAGES 1
+#else
+#define WASM_RT_MEMCHECK_BOUNDS_CHECK 1
+#endif
+#endif
+
+// Ensure the macros are defined
+#ifndef WASM_RT_MEMCHECK_GUARD_PAGES
+#define WASM_RT_MEMCHECK_GUARD_PAGES 0
+#endif
+#ifndef WASM_RT_MEMCHECK_BOUNDS_CHECK
+#define WASM_RT_MEMCHECK_BOUNDS_CHECK 0
+#endif
+
+// Sanity check the use of guard pages
+#if WASM_RT_MEMCHECK_GUARD_PAGES && !WASM_RT_GUARD_PAGES_SUPPORTED
+#error \
+ "WASM_RT_MEMCHECK_GUARD_PAGES not supported on this platform/configuration"
+#endif
+
+#if WASM_RT_MEMCHECK_GUARD_PAGES && WASM_RT_MEMCHECK_BOUNDS_CHECK
+#error \
+ "Cannot use both WASM_RT_MEMCHECK_GUARD_PAGES and WASM_RT_MEMCHECK_BOUNDS_CHECK"
+
+#elif !WASM_RT_MEMCHECK_GUARD_PAGES && !WASM_RT_MEMCHECK_BOUNDS_CHECK
+#error \
+ "Must choose at least one from WASM_RT_MEMCHECK_GUARD_PAGES and WASM_RT_MEMCHECK_BOUNDS_CHECK"
+#endif
+
+/**
+ * Some configurations above require the Wasm runtime to install a signal
+ * handler. However, this can be explicitly disallowed by the host using
+ * WASM_RT_SKIP_SIGNAL_RECOVERY. In this case, when the wasm code encounters an
+ * OOB access, it may either trap or abort.
+ */
+#ifndef WASM_RT_SKIP_SIGNAL_RECOVERY
+#define WASM_RT_SKIP_SIGNAL_RECOVERY 0
+#endif
+
+#if WASM_RT_MEMCHECK_GUARD_PAGES && !WASM_RT_SKIP_SIGNAL_RECOVERY
+#define WASM_RT_INSTALL_SIGNAL_HANDLER 1
+#else
+#define WASM_RT_INSTALL_SIGNAL_HANDLER 0
+#endif
+
+#ifndef WASM_RT_USE_STACK_DEPTH_COUNT
+/* The signal handler on POSIX can detect call stack overflows. On windows, or
+ * platforms without a signal handler, we use stack depth counting. */
+#if WASM_RT_INSTALL_SIGNAL_HANDLER && !defined(_WIN32)
+#define WASM_RT_USE_STACK_DEPTH_COUNT 0
+#else
+#define WASM_RT_USE_STACK_DEPTH_COUNT 1
+#endif
+#endif
+
+#if WASM_RT_USE_STACK_DEPTH_COUNT
+/**
+ * When the signal handler cannot be used to detect stack overflows, stack depth
+ * is limited explicitly. The maximum stack depth before trapping can be
+ * configured by defining this symbol before including wasm-rt when building the
+ * generated c files, for example:
+ *
+ * ```
+ * cc -c -DWASM_RT_MAX_CALL_STACK_DEPTH=100 my_module.c -o my_module.o
+ * ```
+ */
+#ifndef WASM_RT_MAX_CALL_STACK_DEPTH
+#define WASM_RT_MAX_CALL_STACK_DEPTH 500
+#endif
+
+/** Current call stack depth. */
+extern WASM_RT_THREAD_LOCAL uint32_t wasm_rt_call_stack_depth;
+
+#endif
+
+#if defined(_MSC_VER)
+#define WASM_RT_NO_RETURN __declspec(noreturn)
+#else
+#define WASM_RT_NO_RETURN __attribute__((noreturn))
+#endif
+
+#if defined(__APPLE__) && WASM_RT_INSTALL_SIGNAL_HANDLER
+#define WASM_RT_MERGED_OOB_AND_EXHAUSTION_TRAPS 1
+#else
+#define WASM_RT_MERGED_OOB_AND_EXHAUSTION_TRAPS 0
+#endif
+
+/** Reason a trap occurred. Provide this to `wasm_rt_trap`. */
+typedef enum {
+ WASM_RT_TRAP_NONE, /** No error. */
+ WASM_RT_TRAP_OOB, /** Out-of-bounds access in linear memory or a table. */
+ WASM_RT_TRAP_INT_OVERFLOW, /** Integer overflow on divide or truncation. */
+ WASM_RT_TRAP_DIV_BY_ZERO, /** Integer divide by zero. */
+ WASM_RT_TRAP_INVALID_CONVERSION, /** Conversion from NaN to integer. */
+ WASM_RT_TRAP_UNREACHABLE, /** Unreachable instruction executed. */
+ WASM_RT_TRAP_CALL_INDIRECT, /** Invalid call_indirect, for any reason. */
+ WASM_RT_TRAP_UNCAUGHT_EXCEPTION, /* Exception thrown and not caught */
+#if WASM_RT_MERGED_OOB_AND_EXHAUSTION_TRAPS
+ WASM_RT_TRAP_EXHAUSTION = WASM_RT_TRAP_OOB,
+#else
+ WASM_RT_TRAP_EXHAUSTION, /** Call stack exhausted. */
+#endif
+} wasm_rt_trap_t;
+
+/** Value types. Used to define function signatures. */
+typedef enum {
+ WASM_RT_I32,
+ WASM_RT_I64,
+ WASM_RT_F32,
+ WASM_RT_F64,
+ WASM_RT_V128,
+ WASM_RT_FUNCREF,
+ WASM_RT_EXTERNREF,
+} wasm_rt_type_t;
+
+/**
+ * A generic function pointer type, both for Wasm functions (`code`)
+ * and host functions (`hostcode`). All function pointers are stored
+ * in this canonical form, but must be cast to their proper signature
+ * to call.
+ */
+typedef void (*wasm_rt_function_ptr_t)(void);
+
+/**
+ * The type of a function (an arbitrary number of param and result types).
+ * This is represented as an opaque 256-bit ID.
+ */
+typedef const char* wasm_rt_func_type_t;
+
+/** A function instance (the runtime representation of a function).
+ * These can be stored in tables of type funcref, or used as values. */
+typedef struct {
+ /** The function's type. */
+ wasm_rt_func_type_t func_type;
+ /** The function. The embedder must know the actual C signature of the
+ * function and cast to it before calling. */
+ wasm_rt_function_ptr_t func;
+ /** A function instance is a closure of the function over an instance
+ * of the originating module. The module_instance element will be passed into
+ * the function at runtime. */
+ void* module_instance;
+} wasm_rt_funcref_t;
+
+/** Default (null) value of a funcref */
+static const wasm_rt_funcref_t wasm_rt_funcref_null_value = {NULL, NULL, NULL};
+
+/** The type of an external reference (opaque to WebAssembly). */
+typedef void* wasm_rt_externref_t;
+
+/** Default (null) value of an externref */
+static const wasm_rt_externref_t wasm_rt_externref_null_value = NULL;
+
+/** A Memory object. */
+typedef struct {
+ /** The linear memory data, with a byte length of `size`. */
+ uint8_t* data;
+ /** The current and maximum page count for this Memory object. If there is no
+ * maximum, `max_pages` is 0xffffffffu (i.e. UINT32_MAX). */
+ uint64_t pages, max_pages;
+ /** The current size of the linear memory, in bytes. */
+ uint64_t size;
+ /** Is this memory indexed by u64 (as opposed to default u32) */
+ bool is64;
+} wasm_rt_memory_t;
+
+/** A Table of type funcref. */
+typedef struct {
+ /** The table element data, with an element count of `size`. */
+ wasm_rt_funcref_t* data;
+ /** The maximum element count of this Table object. If there is no maximum,
+ * `max_size` is 0xffffffffu (i.e. UINT32_MAX). */
+ uint32_t max_size;
+ /** The current element count of the table. */
+ uint32_t size;
+} wasm_rt_funcref_table_t;
+
+/** A Table of type externref. */
+typedef struct {
+ /** The table element data, with an element count of `size`. */
+ wasm_rt_externref_t* data;
+ /** The maximum element count of this Table object. If there is no maximum,
+ * `max_size` is 0xffffffffu (i.e. UINT32_MAX). */
+ uint32_t max_size;
+ /** The current element count of the table. */
+ uint32_t size;
+} wasm_rt_externref_table_t;
+
+/** Initialize the runtime. */
+void wasm_rt_init(void);
+
+/** Is the runtime initialized? */
+bool wasm_rt_is_initialized(void);
+
+/** Free the runtime's state. */
+void wasm_rt_free(void);
+
+/**
+ * A hardened jmp_buf that allows checking for initialization before use
+ */
+typedef struct {
+ /* Is the jmp buf intialized? */
+ bool initialized;
+ /* jmp_buf contents */
+ jmp_buf buffer;
+} wasm_rt_jmp_buf;
+
+#if WASM_RT_INSTALL_SIGNAL_HANDLER && !defined(_WIN32)
+#define WASM_RT_SETJMP_SETBUF(buf) sigsetjmp(buf, 1)
+#else
+#define WASM_RT_SETJMP_SETBUF(buf) setjmp(buf)
+#endif
+
+#define WASM_RT_SETJMP(buf) \
+ ((buf).initialized = true, WASM_RT_SETJMP_SETBUF((buf).buffer))
+
+#if WASM_RT_INSTALL_SIGNAL_HANDLER && !defined(_WIN32)
+#define WASM_RT_LONGJMP_UNCHECKED(buf, val) siglongjmp(buf, val)
+#else
+#define WASM_RT_LONGJMP_UNCHECKED(buf, val) longjmp(buf, val)
+#endif
+
+#define WASM_RT_LONGJMP(buf, val) \
+ /* Abort on failure as this may be called in the trap handler */ \
+ if (!((buf).initialized)) \
+ abort(); \
+ (buf).initialized = false; \
+ WASM_RT_LONGJMP_UNCHECKED((buf).buffer, val)
+
+/**
+ * Stop execution immediately and jump back to the call to `wasm_rt_impl_try`.
+ * The result of `wasm_rt_impl_try` will be the provided trap reason.
+ *
+ * This is typically called by the generated code, and not the embedder.
+ */
+WASM_RT_NO_RETURN void wasm_rt_trap(wasm_rt_trap_t);
+
+/**
+ * Return a human readable error string based on a trap type.
+ */
+const char* wasm_rt_strerror(wasm_rt_trap_t trap);
+
+#define wasm_rt_try(target) WASM_RT_SETJMP(target)
+
+/**
+ * Initialize a Memory object with an initial page size of `initial_pages` and
+ * a maximum page size of `max_pages`, indexed with an i32 or i64.
+ *
+ * ```
+ * wasm_rt_memory_t my_memory;
+ * // 1 initial page (65536 bytes), and a maximum of 2 pages,
+ * // indexed with an i32
+ * wasm_rt_allocate_memory(&my_memory, 1, 2, false);
+ * ```
+ */
+void wasm_rt_allocate_memory(wasm_rt_memory_t*,
+ uint64_t initial_pages,
+ uint64_t max_pages,
+ bool is64);
+
+/**
+ * Grow a Memory object by `pages`, and return the previous page count. If
+ * this new page count is greater than the maximum page count, the grow fails
+ * and 0xffffffffu (UINT32_MAX) is returned instead.
+ *
+ * ```
+ * wasm_rt_memory_t my_memory;
+ * ...
+ * // Grow memory by 10 pages.
+ * uint32_t old_page_size = wasm_rt_grow_memory(&my_memory, 10);
+ * if (old_page_size == UINT32_MAX) {
+ * // Failed to grow memory.
+ * }
+ * ```
+ */
+uint64_t wasm_rt_grow_memory(wasm_rt_memory_t*, uint64_t pages);
+
+/**
+ * Free a Memory object.
+ */
+void wasm_rt_free_memory(wasm_rt_memory_t*);
+
+/**
+ * Initialize a funcref Table object with an element count of `elements` and a
+ * maximum size of `max_elements`.
+ *
+ * ```
+ * wasm_rt_funcref_table_t my_table;
+ * // 5 elements and a maximum of 10 elements.
+ * wasm_rt_allocate_funcref_table(&my_table, 5, 10);
+ * ```
+ */
+void wasm_rt_allocate_funcref_table(wasm_rt_funcref_table_t*,
+ uint32_t elements,
+ uint32_t max_elements);
+
+/**
+ * Free a funcref Table object.
+ */
+void wasm_rt_free_funcref_table(wasm_rt_funcref_table_t*);
+
+/**
+ * Initialize an externref Table object with an element count
+ * of `elements` and a maximum size of `max_elements`.
+ * Usage as per wasm_rt_allocate_funcref_table.
+ */
+void wasm_rt_allocate_externref_table(wasm_rt_externref_table_t*,
+ uint32_t elements,
+ uint32_t max_elements);
+
+/**
+ * Free an externref Table object.
+ */
+void wasm_rt_free_externref_table(wasm_rt_externref_table_t*);
+
+/**
+ * Grow a Table object by `delta` elements (giving the new elements the value
+ * `init`), and return the previous element count. If this new element count is
+ * greater than the maximum element count, the grow fails and 0xffffffffu
+ * (UINT32_MAX) is returned instead.
+ */
+uint32_t wasm_rt_grow_funcref_table(wasm_rt_funcref_table_t*,
+ uint32_t delta,
+ wasm_rt_funcref_t init);
+uint32_t wasm_rt_grow_externref_table(wasm_rt_externref_table_t*,
+ uint32_t delta,
+ wasm_rt_externref_t init);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* WASM_RT_H_ */