mirror of
https://github.com/remko/waforth
synced 2025-01-15 15:41:17 +01:00
169 lines
5.7 KiB
C
169 lines
5.7 KiB
C
|
/*
|
||
|
* 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 <stdint.h>
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
extern "C" {
|
||
|
#endif
|
||
|
|
||
|
/** Maximum stack depth before trapping. This 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
|
||
|
|
||
|
/** 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. */
|
||
|
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_EXHAUSTION, /** Call stack exhausted. */
|
||
|
} 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_type_t;
|
||
|
|
||
|
/** A function type for all `anyfunc` functions in a Table. All functions are
|
||
|
* stored in this canonical form, but must be cast to their proper signature to
|
||
|
* call. */
|
||
|
typedef void (*wasm_rt_anyfunc_t)(void);
|
||
|
|
||
|
/** A single element of a Table. */
|
||
|
typedef struct {
|
||
|
/** The index as returned from `wasm_rt_register_func_type`. */
|
||
|
uint32_t func_type;
|
||
|
/** The function. The embedder must know the actual C signature of the
|
||
|
* function and cast to it before calling. */
|
||
|
wasm_rt_anyfunc_t func;
|
||
|
} wasm_rt_elem_t;
|
||
|
|
||
|
/** 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). */
|
||
|
uint32_t pages, max_pages;
|
||
|
/** The current size of the linear memory, in bytes. */
|
||
|
uint32_t size;
|
||
|
} wasm_rt_memory_t;
|
||
|
|
||
|
/** A Table object. */
|
||
|
typedef struct {
|
||
|
/** The table element data, with an element count of `size`. */
|
||
|
wasm_rt_elem_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_table_t;
|
||
|
|
||
|
/** Stop execution immediately and jump back to the call to `wasm_rt_try`.
|
||
|
* The result of `wasm_rt_try` will be the provided trap reason.
|
||
|
*
|
||
|
* This is typically called by the generated code, and not the embedder. */
|
||
|
extern void wasm_rt_trap(wasm_rt_trap_t) __attribute__((noreturn));
|
||
|
|
||
|
/** Register a function type with the given signature. The returned function
|
||
|
* index is guaranteed to be the same for all calls with the same signature.
|
||
|
* The following varargs must all be of type `wasm_rt_type_t`, first the
|
||
|
* params` and then the `results`.
|
||
|
*
|
||
|
* ```
|
||
|
* // Register (func (param i32 f32) (result i64)).
|
||
|
* wasm_rt_register_func_type(2, 1, WASM_RT_I32, WASM_RT_F32, WASM_RT_I64);
|
||
|
* => returns 1
|
||
|
*
|
||
|
* // Register (func (result i64)).
|
||
|
* wasm_rt_register_func_type(0, 1, WASM_RT_I32);
|
||
|
* => returns 2
|
||
|
*
|
||
|
* // Register (func (param i32 f32) (result i64)) again.
|
||
|
* wasm_rt_register_func_type(2, 1, WASM_RT_I32, WASM_RT_F32, WASM_RT_I64);
|
||
|
* => returns 1
|
||
|
* ``` */
|
||
|
extern uint32_t wasm_rt_register_func_type(uint32_t params,
|
||
|
uint32_t results,
|
||
|
...);
|
||
|
|
||
|
/** Initialize a Memory object with an initial page size of `initial_pages` and
|
||
|
* a maximum page size of `max_pages`.
|
||
|
*
|
||
|
* ```
|
||
|
* wasm_rt_memory_t my_memory;
|
||
|
* // 1 initial page (65536 bytes), and a maximum of 2 pages.
|
||
|
* wasm_rt_allocate_memory(&my_memory, 1, 2);
|
||
|
* ``` */
|
||
|
extern void wasm_rt_allocate_memory(wasm_rt_memory_t*,
|
||
|
uint32_t initial_pages,
|
||
|
uint32_t max_pages);
|
||
|
|
||
|
/** 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.
|
||
|
* }
|
||
|
* ``` */
|
||
|
extern uint32_t wasm_rt_grow_memory(wasm_rt_memory_t*, uint32_t pages);
|
||
|
|
||
|
/** Initialize a Table object with an element count of `elements` and a maximum
|
||
|
* page size of `max_elements`.
|
||
|
*
|
||
|
* ```
|
||
|
* wasm_rt_table_t my_table;
|
||
|
* // 5 elemnets and a maximum of 10 elements.
|
||
|
* wasm_rt_allocate_table(&my_table, 5, 10);
|
||
|
* ``` */
|
||
|
extern void wasm_rt_allocate_table(wasm_rt_table_t*,
|
||
|
uint32_t elements,
|
||
|
uint32_t max_elements);
|
||
|
|
||
|
/** Current call stack depth. */
|
||
|
extern uint32_t wasm_rt_call_stack_depth;
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#endif /* WASM_RT_H_ */
|