forked from wasm3/wasm3
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathm3_compile.h
172 lines (122 loc) · 5.46 KB
/
m3_compile.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
//
// m3_compile.h
// M3: Massey Meta Machine
//
// Created by Steven Massey on 4/17/19.
// Copyright © 2019 Steven Massey. All rights reserved.
//
#ifndef m3_compile_h
#define m3_compile_h
#include "m3_env.h"
#include "m3_exec_defs.h"
/*
WebAssembly spec info
---------------------
2.3.2 Result Types
Note: In the current version of WebAssembly, at most one value is allowed as a result. However, this may be
generalized to sequences of values in future versions.
M3
--
*/
enum
{
c_waOp_block = 0x02,
c_waOp_loop = 0x03,
c_waOp_if = 0x04,
c_waOp_else = 0x05,
c_waOp_end = 0x0b,
c_waOp_branch = 0x0c,
c_waOp_branchIf = 0x0d,
c_waOp_getLocal = 0x20,
c_waOp_setLocal = 0x21,
c_waOp_teeLocal = 0x22,
};
//-----------------------------------------------------------------------------------------------------------------------------------
// since the end location of a block can be unknown when a branch is compiled, writing
// the actual address must deferred. A linked-list of patch locations is kept in
// M3CompilationScope. When the block compilation exits, it patches these addresses.
typedef struct M3BranchPatch
{
struct M3BranchPatch * next;
pc_t * location;
}
M3BranchPatch;
typedef M3BranchPatch * IM3BranchPatch;
typedef struct M3CompilationScope
{
struct M3CompilationScope * outer;
pc_t pc; // used by ContinueLoop's
IM3BranchPatch patches;
i32 depth;
i32 loopDepth;
i16 initStackIndex;
u8 type;
u8 opcode;
}
M3CompilationScope;
typedef M3CompilationScope * IM3CompilationScope;
static const u16 c_m3RegisterUnallocated = 0;
typedef struct
{
IM3Runtime runtime;
IM3Module module;
bytes_t wasm;
bytes_t wasmEnd;
M3CompilationScope block;
IM3Function function;
IM3CodePage page;
u32 numEmits;
u32 numOpcodes;
u16 firstSlotIndex; // numArgs + numLocals + numReservedConstants. the first mutable slot available to the compiler.
u16 stackIndex; // current stack index
u16 firstConstSlotIndex;
u16 constSlotIndex; // as const's are encountered during compilation this tracks their location in the "real" stack
u64 constants [c_m3MaxNumFunctionConstants];
// for args/locals this wasmStack tracks write counts. for the dynamic portion of the stack, the array holds slot locations
u16 wasmStack [c_m3MaxFunctionStackHeight];
u8 typeStack [c_m3MaxFunctionStackHeight];
// this array just contains single bit allocation flags. could be fused with the typeStack to conserve space
u8 m3Slots [c_m3MaxFunctionStackHeight];
u16 numAllocatedExecSlots;
u16 regStackIndexPlusOne [2];
//bool enableOptimizations; // no longer used. currently implementation is highly pre-optimized.
u8 previousOpcode;
}
M3Compilation;
typedef M3Compilation * IM3Compilation;
typedef M3Result (* M3Compiler) (IM3Compilation, u8);
//-----------------------------------------------------------------------------------------------------------------------------------
typedef struct M3OpInfo
{
#ifdef DEBUG
const char * const name;
#endif
i8 stackOffset;
u8 type;
IM3Operation operation_sr; // top operand in register
IM3Operation operation_rs; // top operand in stack
IM3Operation operation_ss; // both operands in stack
M3Compiler compiler;
}
M3OpInfo;
typedef const M3OpInfo * IM3OpInfo;
extern const M3OpInfo c_operations [];
#ifdef DEBUG
#define M3OP(...) { __VA_ARGS__ }
#define M3OP_RESERVED { "reserved" }
#else
#define M3OP(name, ...) { __VA_ARGS__ }
#define M3OP_RESERVED { 0 }
#endif
//-----------------------------------------------------------------------------------------------------------------------------------
M3Result EmitOp (IM3Compilation o, IM3Operation i_operation);
void EmitConstant (IM3Compilation o, const u64 immediate);
void Push (IM3Compilation o, u8 i_waType, i16 i_location);
void EmitPointer (IM3Compilation o, const void * const i_immediate);
M3Result CompileBlock (IM3Compilation io, u8 i_blockType, u8 i_blockOpcode);
M3Result Compile_ElseBlock (IM3Compilation io, pc_t * o_startPC, u8 i_blockType);
M3Result Compile_BlockStatements (IM3Compilation io);
M3Result Compile_Function (IM3Function io_function);
bool PeekNextOpcode (IM3Compilation o, u8 i_opcode);
//M3Result Optimize_ConstOp (IM3Compilation o, u64 i_word, u8 i_waType);
#endif /* m3_compile_h */