blob: 1edd911ab6f9e97cef3b76c695f938eada739b9e [file] [log] [blame]
Damien429d7192013-10-04 19:53:11 +01001#include <stdint.h>
2#include <stdlib.h>
3#include <stdio.h>
4#include <string.h>
5#include <assert.h>
6
7#include "misc.h"
8#include "machine.h"
9#include "runtime.h"
10#include "bc.h"
11
12#define DECODE_UINT do { unum = *ip++; if (unum > 127) { unum = ((unum & 0x3f) << 8) | (*ip++); } } while (0)
13#define DECODE_QSTR do { qstr = *ip++; if (qstr > 127) { qstr = ((qstr & 0x3f) << 8) | (*ip++); } } while (0)
14#define PUSH(val) *--sp = (val)
15#define POP() (*sp++)
16
17py_obj_t py_execute_byte_code(byte *code, uint len, py_obj_t *args, uint n_args) {
18 byte *ip = code;
19 py_obj_t stack[10];
20 py_obj_t *sp = &stack[10]; // stack grows down, sp points to top of stack
21 machine_uint_t unum;
22 machine_int_t snum;
23 qstr qstr;
24 py_obj_t obj1, obj2;
25 py_obj_t fast0 = NULL, fast1 = NULL, fast2 = NULL, fastn[4] = {NULL, NULL, NULL, NULL};
26
27 // init args
28 for (int i = 0; i < n_args; i++) {
29 if (i == 0) {
30 fast0 = args[0];
31 } else if (i == 1) {
32 fast1 = args[1];
33 } else if (i == 2) {
34 fast2 = args[2];
35 } else {
36 assert(i - 3 < 4);
37 fastn[i - 3] = args[i];
38 }
39 }
40
41 // execute byte code
42 for (;;) {
43 int op = *ip++;
44 switch (op) {
45 case PYBC_LOAD_CONST_FALSE:
46 PUSH(py_const_false);
47 break;
48
49 case PYBC_LOAD_CONST_NONE:
50 PUSH(py_const_none);
51 break;
52
53 case PYBC_LOAD_CONST_TRUE:
54 PUSH(py_const_true);
55 break;
56
57 case PYBC_LOAD_CONST_SMALL_INT:
58 snum = ip[0] | (ip[1] << 8);
59 if (snum & 0x8000) {
60 snum |= ~0xffff;
61 }
62 ip += 2;
63 PUSH((py_obj_t)(snum << 1 | 1));
64 break;
65
66 case PYBC_LOAD_CONST_ID:
67 DECODE_QSTR;
68 PUSH(rt_load_const_str(qstr)); // TODO
69 break;
70
71 case PYBC_LOAD_CONST_STRING:
72 DECODE_QSTR;
73 PUSH(rt_load_const_str(qstr));
74 break;
75
76 case PYBC_LOAD_FAST_0:
77 PUSH(fast0);
78 break;
79
80 case PYBC_LOAD_FAST_1:
81 PUSH(fast1);
82 break;
83
84 case PYBC_LOAD_FAST_2:
85 PUSH(fast2);
86 break;
87
88 case PYBC_LOAD_FAST_N:
89 DECODE_UINT;
90 PUSH(fastn[unum - 3]);
91 break;
92
93 case PYBC_LOAD_NAME:
94 DECODE_QSTR;
95 PUSH(rt_load_name(qstr));
96 break;
97
98 case PYBC_LOAD_GLOBAL:
99 DECODE_QSTR;
100 PUSH(rt_load_global(qstr));
101 break;
102
103 case PYBC_LOAD_ATTR:
104 DECODE_QSTR;
105 *sp = rt_load_attr(*sp, qstr);
106 break;
107
108 case PYBC_LOAD_METHOD:
109 DECODE_QSTR;
110 sp -= 1;
111 rt_load_method(sp[1], qstr, sp);
112 break;
113
114 case PYBC_LOAD_BUILD_CLASS:
115 PUSH(rt_load_build_class());
116 break;
117
118 case PYBC_STORE_FAST_0:
119 fast0 = POP();
120 break;
121
122 case PYBC_STORE_FAST_1:
123 fast1 = POP();
124 break;
125
126 case PYBC_STORE_FAST_2:
127 fast2 = POP();
128 break;
129
130 case PYBC_STORE_FAST_N:
131 DECODE_UINT;
132 fastn[unum - 3] = POP();
133 break;
134
135 case PYBC_STORE_NAME:
136 DECODE_QSTR;
137 rt_store_name(qstr, POP());
138 break;
139
140 case PYBC_STORE_SUBSCR:
141 rt_store_subscr(sp[1], sp[0], sp[2]);
142 sp += 3;
143 break;
144
145 case PYBC_DUP_TOP:
146 obj1 = *sp;
147 PUSH(obj1);
148 break;
149
150 case PYBC_DUP_TOP_TWO:
151 sp -= 2;
152 sp[0] = sp[2];
153 sp[1] = sp[3];
154 break;
155
156 case PYBC_POP_TOP:
157 ++sp;
158 break;
159
160 case PYBC_ROT_THREE:
161 obj1 = sp[0];
162 sp[0] = sp[1];
163 sp[1] = sp[2];
164 sp[2] = obj1;
165 break;
166
167 case PYBC_JUMP:
168 DECODE_UINT;
169 ip = code + unum;
170 break;
171
172 case PYBC_POP_JUMP_IF_FALSE:
173 DECODE_UINT;
174 if (!rt_is_true(POP())) {
175 ip = code + unum;
176 }
177 break;
178
179 case PYBC_SETUP_LOOP:
180 DECODE_UINT;
181 break;
182
183 case PYBC_POP_BLOCK:
184 break;
185
186 case PYBC_BINARY_OP:
187 unum = *ip++;
188 obj2 = POP();
189 obj1 = *sp;
190 *sp = rt_binary_op(unum, obj1, obj2);
191 break;
192
193 case PYBC_COMPARE_OP:
194 unum = *ip++;
195 obj2 = POP();
196 obj1 = *sp;
197 *sp = rt_compare_op(unum, obj1, obj2);
198 break;
199
200 case PYBC_BUILD_LIST:
201 DECODE_UINT;
202 obj1 = rt_build_list(unum, sp);
203 sp += unum - 1;
204 *sp = obj1;
205 break;
206
207 case PYBC_BUILD_MAP:
208 DECODE_UINT;
209 PUSH(rt_build_map(unum));
210 break;
211
212 case PYBC_STORE_MAP:
213 sp += 2;
214 rt_store_map(sp[0], sp[-2], sp[-1]);
215 break;
216
217 case PYBC_BUILD_SET:
218 DECODE_UINT;
219 obj1 = rt_build_set(unum, sp);
220 sp += unum - 1;
221 *sp = obj1;
222 break;
223
224 case PYBC_MAKE_FUNCTION:
225 DECODE_UINT;
226 PUSH(rt_make_function_from_id(unum));
227 break;
228
229 case PYBC_CALL_FUNCTION:
230 DECODE_UINT;
231 assert((unum & 0xff00) == 0); // n_keyword
232 // switch on n_positional
233 if ((unum & 0xff) == 0) {
234 *sp = rt_call_function_0(*sp);
235 } else if ((unum & 0xff) == 1) {
236 obj1 = *sp++; // the single argument
237 *sp = rt_call_function_1(*sp, obj1);
238 } else if ((unum & 0xff) == 2) {
239 obj2 = *sp++; // the second argument
240 obj1 = *sp++; // the first argument
241 *sp = rt_call_function_2(*sp, obj1, obj2);
242 } else {
243 assert(0);
244 }
245 break;
246
247 case PYBC_CALL_METHOD:
248 DECODE_UINT;
249 assert((unum & 0xff00) == 0); // n_keyword
250 // switch on n_positional
251 if ((unum & 0xff) == 0) {
252 obj1 = *sp++; // the self object (or NULL)
253 *sp = rt_call_method_1(*sp, obj1);
254 } else if ((unum & 0xff) == 1) {
255 obj2 = *sp++; // the first argument
256 obj1 = *sp++; // the self object (or NULL)
257 *sp = rt_call_function_2(*sp, obj1, obj2);
258 } else {
259 assert(0);
260 }
261 break;
262
263 case PYBC_RETURN_VALUE:
264 return *sp;
265
266 default:
267 printf("code %p, offset %u, byte code 0x%02x not implemented\n", code, (uint)(ip - code), op);
268 assert(0);
269 return py_const_none;
270 }
271 }
272}