-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathopcode.c
More file actions
127 lines (113 loc) · 2.18 KB
/
opcode.c
File metadata and controls
127 lines (113 loc) · 2.18 KB
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
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "compiler.h"
#include "opcode.h"
#include "compiler.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(const cb_instruction instruction)
{
union cb_op_encoding op;
op.as_size_t = instruction;
assert(op.unary.op < OP_MAX);
switch (op.unary.op) {
case OP_LOAD_CONST:
case OP_CONST_TRUE:
case OP_CONST_FALSE:
case OP_CONST_NULL:
case OP_CONST_STRING:
case OP_JUMP:
case OP_DUP:
case OP_LOAD_LOCAL:
case OP_LOAD_UPVALUE:
case OP_LOAD_GLOBAL:
case OP_LOAD_STRUCT:
case OP_LOAD_FROM_MODULE:
case OP_CATCH:
case OP_LOAD_THIS:
case OP_LOAD_METHOD:
return 1;
case OP_DUP_2:
return 2;
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_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_RETURN:
case OP_JUMP_IF_TRUE:
case OP_JUMP_IF_FALSE:
case OP_STORE_STRUCT:
case OP_ADD_STRUCT_FIELD:
case OP_THROW:
case OP_SET_METHOD:
return -1;
case OP_ARRAY_SET:
return -2;
case OP_HALT:
case OP_NOT:
case OP_BITWISE_NOT:
case OP_NEG:
case OP_NEW_STRUCT:
case OP_ROT_2:
case OP_ROT_3:
case OP_ROT_4:
case OP_STORE_LOCAL:
case OP_MAX:
case OP_BIND_LOCAL:
case OP_BIND_UPVALUE:
case OP_STORE_UPVALUE:
case OP_DECLARE_GLOBAL:
case OP_STORE_GLOBAL:
case OP_APPLY_DEFAULT_ARG:
case OP_IMPORT_MODULE:
case OP_PUSH_TRY:
case OP_POP_TRY:
case OP_INC:
case OP_DEC:
return 0;
case OP_ALLOCATE_LOCALS:
return op.unary.arg;
case OP_NEW_ARRAY_WITH_VALUES:
return -op.unary.arg + 1;
case OP_CALL:
case OP_CALL_METHOD:
return -op.unary.arg;
default:
fprintf(stderr, "getting stack effect of unknown opcode %d\n",
op.unary.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();
}
}