-
Notifications
You must be signed in to change notification settings - Fork 0
/
vm.h
150 lines (127 loc) · 3.28 KB
/
vm.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
#ifndef VM_H_INCLUDED
#define VM_H_INCLUDED
#include "./type.h"
#include "./instruction.h"
#include "./constant.h"
#include "./function.h"
#include "./file.h"
#include <memory>
#include <cstdint>
#include <string>
#include <vector>
#include <variant>
namespace vm {
class VM {
private:
static const addr_t MIN_STACK_ADDR;
static const addr_t MAX_STACK_ADDR;
static const addr_t MAX_STACK_SIZE;
static const addr_t MIN_HEAP_ADDR;
static const addr_t MAX_HEAP_ADDR;
static const addr_t MAX_HEAP_SIZE;
private:
bool prepared;
File _file;
//std::vector<std::shared_ptr<Stack>> stacks;
std::unique_ptr<slot_t[]> _stack;
std::unique_ptr<slot_t[]> _heap;
std::vector<std::pair<addr_t, addr_t>> _heapRecord;
addr_t _sp;
addr_t _bp;
addr_t _ip;
int _counterInstruction;
// int _counterMicroIns;
struct Context {
addr_t prevPC;
addr_t prevSP;
addr_t prevBP;
addr_t BP;
int staticLink; // index in contexts
int functionIndex;
std::string functionName;
vm::u2 functionLevel;
};
std::vector<Context> _contexts;
std::vector<Instruction> _currentInstructions;
std::unordered_map<vm::u2, addr_t> _stringLiteralPool;
public:
VM(File) noexcept;
VM(const VM&) = delete;
VM(VM&&) = delete;
VM& operator=(VM) = delete;
public:
static std::unique_ptr<VM> make_vm(File file);
void start();
private:
void init() noexcept;
void buildStringLiteralPool();
void run();
void ensureStackRest(addr_t count);
void ensureStackUsed(addr_t count);
slot_t* checkAddr(addr_t addr, addr_t count);
slot_t* toHeapPtr(addr_t);
slot_t* toStackPtr(addr_t);
void printStackTrace(std::ostream&);
void DEC_SP(addr_t count);
void INC_SP(addr_t count);
addr_t NEW(addr_t count);
void DUP();
void DUP2();
template<typename T>
T POP();
template<typename T>
void PUSH(T val);
template<typename T>
T READ(addr_t addr);
template<typename T>
void WRITE(addr_t addr, T value);
void JUMP(u2 offset);
void CALL(u2 index);
void RET();
private:
void executeInstruction(const Instruction&);
void ipush(int_t value);
void popn(addr_t count);
void dup(); void dup2();
void loadc(u2 index);
void loada(u2 level_diff, addr_t offset);
void _new();
void snew(addr_t count);
template<typename T>
void Tload();
template<typename T>
void Taload();
template<typename T>
void Tstore();
template<typename T>
void Tastore();
template <typename T>
void Tadd();
template <typename T>
void Tsub();
template <typename T>
void Tmul();
template <typename T>
void Tdiv();
template <typename T>
void Tneg();
template <typename T>
void Tcmp();
template <typename T1, typename T2>
void T2T();
void jmp(u2 offset);
void je(u2 offset); void jne(u2 offset);
void jl(u2 offset); void jge(u2 offset);
void jg(u2 offset); void jle(u2 offset);
void call(u2 index);
template <typename T>
void Tret();
template <typename T>
void Tprint();
void sprint();
void printl();
template <typename T>
void Tscan();
};
}
#endif