-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwa.h
184 lines (154 loc) · 5.21 KB
/
wa.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#ifndef WAC_H
#define WAC_H
#ifdef __cplusplus
extern "C" {
#endif
#include "fixes.h"
#include "wa_result.h"
#define WA_MAGIC 0x6d736100
#define WA_VERSION 0x01
#ifdef LOW_MEMORY_CONFIG
#define PAGE_SIZE \
16 * 1024 // WARN: is it ok to change page size (other than 64kB) ?
#define STACK_SIZE 4 * 1024
#define BLOCKSTACK_SIZE 4 * 1024
#define CALLSTACK_SIZE 1024
#define BR_TABLE_SIZE 4 * 1024
#else
#define PAGE_SIZE 0x10000 // 65536
#define STACK_SIZE 0x10000 // 65536
#define BLOCKSTACK_SIZE 0x1000 // 4096
#define CALLSTACK_SIZE 0x1000 // 4096
#define BR_TABLE_SIZE 0x10000 // 65536
#endif
#define I32 0x7f // -0x01
#define I64 0x7e // -0x02
#define F32 0x7d // -0x03
#define F64 0x7c // -0x04
#define ANYFUNC 0x70 // -0x10
#define FUNC 0x60 // -0x20
#define BLOCK 0x40 // -0x40
#define KIND_FUNCTION 0
#define KIND_TABLE 1
#define KIND_MEMORY 2
#define KIND_GLOBAL 3
typedef struct Type {
uint8_t form;
uint32_t param_count;
uint32_t* params;
uint32_t result_count;
uint32_t* results;
uint64_t mask; // unique mask value for each type
} Type;
typedef union FuncPtr {
void (*void_void)(void);
void (*void_i32)(uint32_t);
void (*void_i64)(uint64_t);
void (*void_f32)(float);
void (*void_f64)(double);
double (*f64_f64)(double);
} FuncPtr;
// A block or function
typedef struct Block {
uint8_t block_type; // 0x00: function, 0x01: init_exp
// 0x02: block, 0x03: loop, 0x04: if
uint32_t fidx; // function only (index)
Type* type; // params/results type
uint32_t local_count; // function only
uint32_t* locals; // function only
uint32_t start_addr;
uint32_t end_addr;
uint32_t else_addr; // if block only
uint32_t br_addr; // blocks only
char* export_name; // function only (exported)
size_t name_len; // size of name buffer in bytes
char* import_module; // function only (imported)
char* import_field; // function only (imported)
void* (*func_ptr)(void); // function only (imported)
} Block;
typedef struct StackValue {
uint8_t value_type;
union {
uint32_t uint32;
int32_t int32;
uint64_t uint64;
int64_t int64;
float f32;
double f64;
} value;
} StackValue;
typedef struct Frame {
Block* block;
// Saved state
int sp;
int fp;
uint32_t ra;
} Frame;
typedef struct Table {
uint8_t elem_type; // type of entries (only ANYFUNC in MVP)
uint32_t initial; // initial table size
uint32_t maximum; // maximum table size
uint32_t size; // current table size
uint32_t* entries;
} Table;
typedef struct Memory {
uint32_t initial; // initial size (64K pages)
uint32_t maximum; // maximum size (64K pages)
uint32_t pages; // current size (64K pages)
uint8_t* bytes; // memory area
} Memory;
typedef struct Options {
// when true: host memory addresses will be outside allocated memory area
// so do not do bounds checking
bool disable_memory_bounds;
// when true, table entries are accessed like this:
// m->table.entries[m->table.entries-index]
// when false, table entires are accessed like this:
// m->table.entries[index]
bool mangle_table_index;
bool dlsym_trim_underscore;
} Options;
typedef struct Module {
// Runtime state
uint32_t pc; // program counter
int sp; // operand stack pointer
int fp; // current frame pointer into stack
StackValue stack[STACK_SIZE]; // main operand stack
int csp; // callstack pointer
Frame callstack[CALLSTACK_SIZE]; // callstack
uint32_t br_table[BR_TABLE_SIZE]; // br_table branch indexes
char* path; // file path of the wasm module
Options options; // Config options
uint32_t byte_count; // number of bytes in the module
uint8_t* bytes; // module content/bytes
uint32_t type_count; // number of function types
Type* types; // function types
uint32_t import_count; // number of leading imports in functions
uint32_t function_count; // number of function (including imports)
Block* functions; // imported and locally defined functions
Block** block_lookup; // map of module byte position to Blocks
// same length as byte_count
uint32_t start_function; // function to run on module load
Table table;
Memory memory;
uint32_t global_count; // number of globals
StackValue* globals; // globals
} Module;
//
// Function declarations (Public API)
//
char* value_repr(StackValue* v);
void (*setup_thunk_in(uint32_t fidx))(void);
void setup_call(Module* m, uint32_t fidx);
result_t interpret(Module* m);
extern uint32_t get_export_fidx(Module* m, char* name, uint32_t name_sz);
extern Module* load_module(uint8_t* bytes,
uint32_t byte_count,
Options options);
extern result_t invoke(Module* m, uint32_t fidx);
extern Module* snapshot(Module* m);
extern void snapshot_destroy(Module* m);
#ifdef __cplusplus
}
#endif
#endif // of WAC_H