1 /* 2 * Copyright 2018 WebAssembly Community Group participants 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef WASM_RT_H_ 18 #define WASM_RT_H_ 19 20 #include <stdint.h> 21 22 #ifdef __cplusplus 23 extern "C" { 24 #endif 25 26 /** Maximum stack depth before trapping. This can be configured by defining 27 * this symbol before including wasm-rt when building the generated c files, 28 * for example: 29 * 30 * ``` 31 * cc -c -DWASM_RT_MAX_CALL_STACK_DEPTH=100 my_module.c -o my_module.o 32 * ``` 33 * */ 34 #ifndef WASM_RT_MAX_CALL_STACK_DEPTH 35 #define WASM_RT_MAX_CALL_STACK_DEPTH 500 36 #endif 37 38 /** Reason a trap occurred. Provide this to `wasm_rt_trap`. */ 39 typedef enum { 40 WASM_RT_TRAP_NONE, /** No error. */ 41 WASM_RT_TRAP_OOB, /** Out-of-bounds access in linear memory. */ 42 WASM_RT_TRAP_INT_OVERFLOW, /** Integer overflow on divide or truncation. */ 43 WASM_RT_TRAP_DIV_BY_ZERO, /** Integer divide by zero. */ 44 WASM_RT_TRAP_INVALID_CONVERSION, /** Conversion from NaN to integer. */ 45 WASM_RT_TRAP_UNREACHABLE, /** Unreachable instruction executed. */ 46 WASM_RT_TRAP_CALL_INDIRECT, /** Invalid call_indirect, for any reason. */ 47 WASM_RT_TRAP_EXHAUSTION, /** Call stack exhausted. */ 48 } wasm_rt_trap_t; 49 50 /** Value types. Used to define function signatures. */ 51 typedef enum { 52 WASM_RT_I32, 53 WASM_RT_I64, 54 WASM_RT_F32, 55 WASM_RT_F64, 56 } wasm_rt_type_t; 57 58 /** A function type for all `anyfunc` functions in a Table. All functions are 59 * stored in this canonical form, but must be cast to their proper signature to 60 * call. */ 61 typedef void (*wasm_rt_anyfunc_t)(void); 62 63 /** A single element of a Table. */ 64 typedef struct { 65 /** The index as returned from `wasm_rt_register_func_type`. */ 66 uint32_t func_type; 67 /** The function. The embedder must know the actual C signature of the 68 * function and cast to it before calling. */ 69 wasm_rt_anyfunc_t func; 70 } wasm_rt_elem_t; 71 72 /** A Memory object. */ 73 typedef struct { 74 /** The linear memory data, with a byte length of `size`. */ 75 uint8_t* data; 76 /** The current and maximum page count for this Memory object. If there is no 77 * maximum, `max_pages` is 0xffffffffu (i.e. UINT32_MAX). */ 78 uint32_t pages, max_pages; 79 /** The current size of the linear memory, in bytes. */ 80 uint32_t size; 81 } wasm_rt_memory_t; 82 83 /** A Table object. */ 84 typedef struct { 85 /** The table element data, with an element count of `size`. */ 86 wasm_rt_elem_t* data; 87 /** The maximum element count of this Table object. If there is no maximum, 88 * `max_size` is 0xffffffffu (i.e. UINT32_MAX). */ 89 uint32_t max_size; 90 /** The current element count of the table. */ 91 uint32_t size; 92 } wasm_rt_table_t; 93 94 /** Stop execution immediately and jump back to the call to `wasm_rt_try`. 95 * The result of `wasm_rt_try` will be the provided trap reason. 96 * 97 * This is typically called by the generated code, and not the embedder. */ 98 extern void wasm_rt_trap(wasm_rt_trap_t) __attribute__((noreturn)); 99 100 /** Register a function type with the given signature. The returned function 101 * index is guaranteed to be the same for all calls with the same signature. 102 * The following varargs must all be of type `wasm_rt_type_t`, first the 103 * params` and then the `results`. 104 * 105 * ``` 106 * // Register (func (param i32 f32) (result i64)). 107 * wasm_rt_register_func_type(2, 1, WASM_RT_I32, WASM_RT_F32, WASM_RT_I64); 108 * => returns 1 109 * 110 * // Register (func (result i64)). 111 * wasm_rt_register_func_type(0, 1, WASM_RT_I32); 112 * => returns 2 113 * 114 * // Register (func (param i32 f32) (result i64)) again. 115 * wasm_rt_register_func_type(2, 1, WASM_RT_I32, WASM_RT_F32, WASM_RT_I64); 116 * => returns 1 117 * ``` */ 118 extern uint32_t wasm_rt_register_func_type(uint32_t params, 119 uint32_t results, 120 ...); 121 122 /** Initialize a Memory object with an initial page size of `initial_pages` and 123 * a maximum page size of `max_pages`. 124 * 125 * ``` 126 * wasm_rt_memory_t my_memory; 127 * // 1 initial page (65536 bytes), and a maximum of 2 pages. 128 * wasm_rt_allocate_memory(&my_memory, 1, 2); 129 * ``` */ 130 extern void wasm_rt_allocate_memory(wasm_rt_memory_t*, 131 uint32_t initial_pages, 132 uint32_t max_pages); 133 134 /** Grow a Memory object by `pages`, and return the previous page count. If 135 * this new page count is greater than the maximum page count, the grow fails 136 * and 0xffffffffu (UINT32_MAX) is returned instead. 137 * 138 * ``` 139 * wasm_rt_memory_t my_memory; 140 * ... 141 * // Grow memory by 10 pages. 142 * uint32_t old_page_size = wasm_rt_grow_memory(&my_memory, 10); 143 * if (old_page_size == UINT32_MAX) { 144 * // Failed to grow memory. 145 * } 146 * ``` */ 147 extern uint32_t wasm_rt_grow_memory(wasm_rt_memory_t*, uint32_t pages); 148 149 /** Initialize a Table object with an element count of `elements` and a maximum 150 * page size of `max_elements`. 151 * 152 * ``` 153 * wasm_rt_table_t my_table; 154 * // 5 elemnets and a maximum of 10 elements. 155 * wasm_rt_allocate_table(&my_table, 5, 10); 156 * ``` */ 157 extern void wasm_rt_allocate_table(wasm_rt_table_t*, 158 uint32_t elements, 159 uint32_t max_elements); 160 161 /** Current call stack depth. */ 162 extern uint32_t wasm_rt_call_stack_depth; 163 164 #ifdef __cplusplus 165 } 166 #endif 167 168 #endif /* WASM_RT_H_ */ 169