-
Notifications
You must be signed in to change notification settings - Fork 2
/
opcode.c
178 lines (168 loc) · 3.23 KB
/
opcode.c
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
#include <stdio.h>
#include <stdlib.h>
#include "compiler.h"
#include "opcode.h"
const char *cb_opcode_name(enum cb_opcode op)
{
#define CASE(O) case O: return #O;
switch (op) {
CB_OPCODE_LIST(CASE)
default:
return "";
}
#undef CASE
}
int cb_opcode_stack_effect(enum cb_opcode op, cb_instruction *args)
{
switch (op) {
case OP_HALT:
case OP_JUMP:
case OP_STORE_LOCAL:
case OP_DECLARE_GLOBAL:
case OP_STORE_GLOBAL:
case OP_BIND_LOCAL:
case OP_BIND_UPVALUE:
case OP_STORE_UPVALUE:
case OP_BITWISE_NOT:
case OP_NOT:
case OP_NEG:
case OP_INIT_MODULE:
case OP_END_MODULE:
case OP_ENTER_MODULE:
case OP_EXIT_MODULE:
case OP_NEW_STRUCT:
case OP_LOAD_STRUCT:
case OP_ROT_2:
case OP_MAX:
return 0;
case OP_CONST_INT:
case OP_CONST_DOUBLE:
case OP_CONST_STRING:
case OP_CONST_CHAR:
case OP_CONST_TRUE:
case OP_CONST_FALSE:
case OP_CONST_NULL:
case OP_LOAD_LOCAL:
case OP_LOAD_GLOBAL:
case OP_NEW_FUNCTION:
case OP_LOAD_UPVALUE:
case OP_LOAD_FROM_MODULE:
case OP_DUP:
case OP_NEW_STRUCT_SPEC:
return 1;
case OP_CALL:
return -args[0];
case OP_NEW_ARRAY_WITH_VALUES:
return 1 - args[0];
case OP_ADD:
case OP_SUB:
case OP_MUL:
case OP_DIV:
case OP_MOD:
case OP_EXP:
case OP_JUMP_IF_TRUE:
case OP_JUMP_IF_FALSE:
case OP_RETURN:
case OP_POP:
case OP_ARRAY_GET:
case OP_EQUAL:
case OP_NOT_EQUAL:
case OP_LESS_THAN:
case OP_LESS_THAN_EQUAL:
case OP_GREATER_THAN:
case OP_GREATER_THAN_EQUAL:
case OP_BITWISE_AND:
case OP_BITWISE_OR:
case OP_BITWISE_XOR:
case OP_STORE_STRUCT:
case OP_ADD_STRUCT_FIELD:
return -1;
case OP_ARRAY_SET:
return -2;
default:
fprintf(stderr, "Unknown opcode: %d\n", op);
abort();
}
}
unsigned cb_opcode_nargs(enum cb_opcode op, cb_instruction *args)
{
switch (op) {
case OP_MAX:
case OP_HALT:
case OP_CONST_TRUE:
case OP_CONST_FALSE:
case OP_CONST_NULL:
case OP_ADD:
case OP_SUB:
case OP_MUL:
case OP_DIV:
case OP_MOD:
case OP_EXP:
case OP_POP:
case OP_ARRAY_GET:
case OP_ARRAY_SET:
case OP_EQUAL:
case OP_NOT_EQUAL:
case OP_LESS_THAN:
case OP_LESS_THAN_EQUAL:
case OP_GREATER_THAN:
case OP_GREATER_THAN_EQUAL:
case OP_BITWISE_OR:
case OP_BITWISE_AND:
case OP_BITWISE_XOR:
case OP_BITWISE_NOT:
case OP_NOT:
case OP_NEG:
case OP_END_MODULE:
case OP_DUP:
case OP_RETURN:
case OP_EXIT_MODULE:
case OP_NEW_STRUCT:
case OP_ROT_2:
return 0;
case OP_CONST_INT:
case OP_CONST_DOUBLE:
case OP_CONST_STRING:
case OP_CONST_CHAR:
case OP_JUMP:
case OP_JUMP_IF_TRUE:
case OP_JUMP_IF_FALSE:
case OP_LOAD_LOCAL:
case OP_STORE_LOCAL:
case OP_BIND_LOCAL:
case OP_BIND_UPVALUE:
case OP_LOAD_UPVALUE:
case OP_STORE_UPVALUE:
case OP_INIT_MODULE:
case OP_ENTER_MODULE:
case OP_NEW_ARRAY_WITH_VALUES:
case OP_CALL:
case OP_LOAD_GLOBAL:
case OP_DECLARE_GLOBAL:
case OP_STORE_GLOBAL:
case OP_LOAD_STRUCT:
case OP_STORE_STRUCT:
case OP_ADD_STRUCT_FIELD:
return 1;
case OP_NEW_FUNCTION:
return 6 + args[5];
case OP_LOAD_FROM_MODULE:
return 2;
case OP_NEW_STRUCT_SPEC:
return 2 + args[1];
default:
fprintf(stderr, "Unknown opcode: %d\n", op);
abort();
}
}
enum cb_opcode cb_opcode_assert(size_t n)
{
switch (n) {
#define CASE(OP) case OP: return OP;
CB_OPCODE_LIST(CASE)
#undef CASE
default:
fprintf(stderr, "Invalid opcode: %zu\n", n);
abort();
}
}