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