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