-
Notifications
You must be signed in to change notification settings - Fork 46
/
Copy pathwa.h
179 lines (146 loc) · 5.23 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
#ifndef WAC_H
#define WAC_H
#include <stdint.h>
#include <stdbool.h>
#define WA_MAGIC 0x6d736100
#define WA_VERSION 0x01
#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
#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_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)
char *import_module; // function only (imported)
char *import_field; // function only (imported)
void *(*func_ptr)(); // 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
char *export_name; // when exported
} Memory;
typedef struct Export {
uint32_t external_kind;
char *export_name;
void *value;
} Export;
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 {
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
uint32_t export_count; // number of exports
Export *exports;
// 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
} Module;
//
// Function declarations (Public API)
//
extern char exception[];
uint64_t get_type_mask(Type *type);
char *value_repr(StackValue *v);
void (*setup_thunk_in(uint32_t fidx))();
void setup_call(Module *m, uint32_t fidx);
bool interpret(Module *m);
void *get_export(Module *m, char *name, uint32_t kind);
Module *load_module(uint8_t *bytes, uint32_t byte_count, Options options);
bool invoke(Module *m, uint32_t fidx);
#endif // of WAC_H