1 #include <stdbool.h>
2
3 #include "Python.h"
4 #include "pycore_code.h" // write_location_entry_start()
5 #include "pycore_compile.h"
6 #include "pycore_instruction_sequence.h"
7 #include "pycore_opcode_utils.h" // IS_BACKWARDS_JUMP_OPCODE
8 #include "pycore_opcode_metadata.h" // is_pseudo_target, _PyOpcode_Caches
9 #include "pycore_symtable.h" // _Py_SourceLocation
10
11
12 #define DEFAULT_CODE_SIZE 128
13 #define DEFAULT_LNOTAB_SIZE 16
14 #define DEFAULT_CNOTAB_SIZE 32
15
16 #undef SUCCESS
17 #undef ERROR
18 #define SUCCESS 0
19 #define ERROR -1
20
21 #define RETURN_IF_ERROR(X) \
22 if ((X) < 0) { \
23 return ERROR; \
24 }
25
26 typedef _Py_SourceLocation location;
27 typedef _PyInstruction instruction;
28 typedef _PyInstructionSequence instr_sequence;
29
30 static inline bool
same_location(location a,location b)31 same_location(location a, location b)
32 {
33 return a.lineno == b.lineno &&
34 a.end_lineno == b.end_lineno &&
35 a.col_offset == b.col_offset &&
36 a.end_col_offset == b.end_col_offset;
37 }
38
39 static int
instr_size(instruction * instr)40 instr_size(instruction *instr)
41 {
42 int opcode = instr->i_opcode;
43 int oparg = instr->i_oparg;
44 assert(!IS_PSEUDO_INSTR(opcode));
45 assert(OPCODE_HAS_ARG(opcode) || oparg == 0);
46 int extended_args = (0xFFFFFF < oparg) + (0xFFFF < oparg) + (0xFF < oparg);
47 int caches = _PyOpcode_Caches[opcode];
48 return extended_args + 1 + caches;
49 }
50
51 struct assembler {
52 PyObject *a_bytecode; /* bytes containing bytecode */
53 int a_offset; /* offset into bytecode */
54 PyObject *a_except_table; /* bytes containing exception table */
55 int a_except_table_off; /* offset into exception table */
56 /* Location Info */
57 int a_lineno; /* lineno of last emitted instruction */
58 PyObject* a_linetable; /* bytes containing location info */
59 int a_location_off; /* offset of last written location info frame */
60 };
61
62 static int
assemble_init(struct assembler * a,int firstlineno)63 assemble_init(struct assembler *a, int firstlineno)
64 {
65 memset(a, 0, sizeof(struct assembler));
66 a->a_lineno = firstlineno;
67 a->a_linetable = NULL;
68 a->a_location_off = 0;
69 a->a_except_table = NULL;
70 a->a_bytecode = PyBytes_FromStringAndSize(NULL, DEFAULT_CODE_SIZE);
71 if (a->a_bytecode == NULL) {
72 goto error;
73 }
74 a->a_linetable = PyBytes_FromStringAndSize(NULL, DEFAULT_CNOTAB_SIZE);
75 if (a->a_linetable == NULL) {
76 goto error;
77 }
78 a->a_except_table = PyBytes_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE);
79 if (a->a_except_table == NULL) {
80 goto error;
81 }
82 return SUCCESS;
83 error:
84 Py_XDECREF(a->a_bytecode);
85 Py_XDECREF(a->a_linetable);
86 Py_XDECREF(a->a_except_table);
87 return ERROR;
88 }
89
90 static void
assemble_free(struct assembler * a)91 assemble_free(struct assembler *a)
92 {
93 Py_XDECREF(a->a_bytecode);
94 Py_XDECREF(a->a_linetable);
95 Py_XDECREF(a->a_except_table);
96 }
97
98 static inline void
write_except_byte(struct assembler * a,int byte)99 write_except_byte(struct assembler *a, int byte) {
100 unsigned char *p = (unsigned char *) PyBytes_AS_STRING(a->a_except_table);
101 p[a->a_except_table_off++] = byte;
102 }
103
104 #define CONTINUATION_BIT 64
105
106 static void
assemble_emit_exception_table_item(struct assembler * a,int value,int msb)107 assemble_emit_exception_table_item(struct assembler *a, int value, int msb)
108 {
109 assert ((msb | 128) == 128);
110 assert(value >= 0 && value < (1 << 30));
111 if (value >= 1 << 24) {
112 write_except_byte(a, (value >> 24) | CONTINUATION_BIT | msb);
113 msb = 0;
114 }
115 if (value >= 1 << 18) {
116 write_except_byte(a, ((value >> 18)&0x3f) | CONTINUATION_BIT | msb);
117 msb = 0;
118 }
119 if (value >= 1 << 12) {
120 write_except_byte(a, ((value >> 12)&0x3f) | CONTINUATION_BIT | msb);
121 msb = 0;
122 }
123 if (value >= 1 << 6) {
124 write_except_byte(a, ((value >> 6)&0x3f) | CONTINUATION_BIT | msb);
125 msb = 0;
126 }
127 write_except_byte(a, (value&0x3f) | msb);
128 }
129
130 /* See Objects/exception_handling_notes.txt for details of layout */
131 #define MAX_SIZE_OF_ENTRY 20
132
133 static int
assemble_emit_exception_table_entry(struct assembler * a,int start,int end,int handler_offset,_PyExceptHandlerInfo * handler)134 assemble_emit_exception_table_entry(struct assembler *a, int start, int end,
135 int handler_offset,
136 _PyExceptHandlerInfo *handler)
137 {
138 Py_ssize_t len = PyBytes_GET_SIZE(a->a_except_table);
139 if (a->a_except_table_off + MAX_SIZE_OF_ENTRY >= len) {
140 RETURN_IF_ERROR(_PyBytes_Resize(&a->a_except_table, len * 2));
141 }
142 int size = end-start;
143 assert(end > start);
144 int target = handler_offset;
145 int depth = handler->h_startdepth - 1;
146 if (handler->h_preserve_lasti > 0) {
147 depth -= 1;
148 }
149 assert(depth >= 0);
150 int depth_lasti = (depth<<1) | handler->h_preserve_lasti;
151 assemble_emit_exception_table_item(a, start, (1<<7));
152 assemble_emit_exception_table_item(a, size, 0);
153 assemble_emit_exception_table_item(a, target, 0);
154 assemble_emit_exception_table_item(a, depth_lasti, 0);
155 return SUCCESS;
156 }
157
158 static int
assemble_exception_table(struct assembler * a,instr_sequence * instrs)159 assemble_exception_table(struct assembler *a, instr_sequence *instrs)
160 {
161 int ioffset = 0;
162 _PyExceptHandlerInfo handler;
163 handler.h_label = -1;
164 handler.h_startdepth = -1;
165 handler.h_preserve_lasti = -1;
166 int start = -1;
167 for (int i = 0; i < instrs->s_used; i++) {
168 instruction *instr = &instrs->s_instrs[i];
169 if (instr->i_except_handler_info.h_label != handler.h_label) {
170 if (handler.h_label >= 0) {
171 int handler_offset = instrs->s_instrs[handler.h_label].i_offset;
172 RETURN_IF_ERROR(
173 assemble_emit_exception_table_entry(a, start, ioffset,
174 handler_offset,
175 &handler));
176 }
177 start = ioffset;
178 handler = instr->i_except_handler_info;
179 }
180 ioffset += instr_size(instr);
181 }
182 if (handler.h_label >= 0) {
183 int handler_offset = instrs->s_instrs[handler.h_label].i_offset;
184 RETURN_IF_ERROR(assemble_emit_exception_table_entry(a, start, ioffset,
185 handler_offset,
186 &handler));
187 }
188 return SUCCESS;
189 }
190
191
192 /* Code location emitting code. See locations.md for a description of the format. */
193
194 #define MSB 0x80
195
196 static void
write_location_byte(struct assembler * a,int val)197 write_location_byte(struct assembler* a, int val)
198 {
199 PyBytes_AS_STRING(a->a_linetable)[a->a_location_off] = val&255;
200 a->a_location_off++;
201 }
202
203
204 static uint8_t *
location_pointer(struct assembler * a)205 location_pointer(struct assembler* a)
206 {
207 return (uint8_t *)PyBytes_AS_STRING(a->a_linetable) +
208 a->a_location_off;
209 }
210
211 static void
write_location_first_byte(struct assembler * a,int code,int length)212 write_location_first_byte(struct assembler* a, int code, int length)
213 {
214 a->a_location_off += write_location_entry_start(
215 location_pointer(a), code, length);
216 }
217
218 static void
write_location_varint(struct assembler * a,unsigned int val)219 write_location_varint(struct assembler* a, unsigned int val)
220 {
221 uint8_t *ptr = location_pointer(a);
222 a->a_location_off += write_varint(ptr, val);
223 }
224
225
226 static void
write_location_signed_varint(struct assembler * a,int val)227 write_location_signed_varint(struct assembler* a, int val)
228 {
229 uint8_t *ptr = location_pointer(a);
230 a->a_location_off += write_signed_varint(ptr, val);
231 }
232
233 static void
write_location_info_short_form(struct assembler * a,int length,int column,int end_column)234 write_location_info_short_form(struct assembler* a, int length, int column, int end_column)
235 {
236 assert(length > 0 && length <= 8);
237 int column_low_bits = column & 7;
238 int column_group = column >> 3;
239 assert(column < 80);
240 assert(end_column >= column);
241 assert(end_column - column < 16);
242 write_location_first_byte(a, PY_CODE_LOCATION_INFO_SHORT0 + column_group, length);
243 write_location_byte(a, (column_low_bits << 4) | (end_column - column));
244 }
245
246 static void
write_location_info_oneline_form(struct assembler * a,int length,int line_delta,int column,int end_column)247 write_location_info_oneline_form(struct assembler* a, int length, int line_delta, int column, int end_column)
248 {
249 assert(length > 0 && length <= 8);
250 assert(line_delta >= 0 && line_delta < 3);
251 assert(column < 128);
252 assert(end_column < 128);
253 write_location_first_byte(a, PY_CODE_LOCATION_INFO_ONE_LINE0 + line_delta, length);
254 write_location_byte(a, column);
255 write_location_byte(a, end_column);
256 }
257
258 static void
write_location_info_long_form(struct assembler * a,location loc,int length)259 write_location_info_long_form(struct assembler* a, location loc, int length)
260 {
261 assert(length > 0 && length <= 8);
262 write_location_first_byte(a, PY_CODE_LOCATION_INFO_LONG, length);
263 write_location_signed_varint(a, loc.lineno - a->a_lineno);
264 assert(loc.end_lineno >= loc.lineno);
265 write_location_varint(a, loc.end_lineno - loc.lineno);
266 write_location_varint(a, loc.col_offset + 1);
267 write_location_varint(a, loc.end_col_offset + 1);
268 }
269
270 static void
write_location_info_none(struct assembler * a,int length)271 write_location_info_none(struct assembler* a, int length)
272 {
273 write_location_first_byte(a, PY_CODE_LOCATION_INFO_NONE, length);
274 }
275
276 static void
write_location_info_no_column(struct assembler * a,int length,int line_delta)277 write_location_info_no_column(struct assembler* a, int length, int line_delta)
278 {
279 write_location_first_byte(a, PY_CODE_LOCATION_INFO_NO_COLUMNS, length);
280 write_location_signed_varint(a, line_delta);
281 }
282
283 #define THEORETICAL_MAX_ENTRY_SIZE 25 /* 1 + 6 + 6 + 6 + 6 */
284
285
286 static int
write_location_info_entry(struct assembler * a,location loc,int isize)287 write_location_info_entry(struct assembler* a, location loc, int isize)
288 {
289 Py_ssize_t len = PyBytes_GET_SIZE(a->a_linetable);
290 if (a->a_location_off + THEORETICAL_MAX_ENTRY_SIZE >= len) {
291 assert(len > THEORETICAL_MAX_ENTRY_SIZE);
292 RETURN_IF_ERROR(_PyBytes_Resize(&a->a_linetable, len*2));
293 }
294 if (loc.lineno < 0) {
295 write_location_info_none(a, isize);
296 return SUCCESS;
297 }
298 int line_delta = loc.lineno - a->a_lineno;
299 int column = loc.col_offset;
300 int end_column = loc.end_col_offset;
301 assert(column >= -1);
302 assert(end_column >= -1);
303 if (column < 0 || end_column < 0) {
304 if (loc.end_lineno == loc.lineno || loc.end_lineno == -1) {
305 write_location_info_no_column(a, isize, line_delta);
306 a->a_lineno = loc.lineno;
307 return SUCCESS;
308 }
309 }
310 else if (loc.end_lineno == loc.lineno) {
311 if (line_delta == 0 && column < 80 && end_column - column < 16 && end_column >= column) {
312 write_location_info_short_form(a, isize, column, end_column);
313 return SUCCESS;
314 }
315 if (line_delta >= 0 && line_delta < 3 && column < 128 && end_column < 128) {
316 write_location_info_oneline_form(a, isize, line_delta, column, end_column);
317 a->a_lineno = loc.lineno;
318 return SUCCESS;
319 }
320 }
321 write_location_info_long_form(a, loc, isize);
322 a->a_lineno = loc.lineno;
323 return SUCCESS;
324 }
325
326 static int
assemble_emit_location(struct assembler * a,location loc,int isize)327 assemble_emit_location(struct assembler* a, location loc, int isize)
328 {
329 if (isize == 0) {
330 return SUCCESS;
331 }
332 while (isize > 8) {
333 RETURN_IF_ERROR(write_location_info_entry(a, loc, 8));
334 isize -= 8;
335 }
336 return write_location_info_entry(a, loc, isize);
337 }
338
339 static int
assemble_location_info(struct assembler * a,instr_sequence * instrs,int firstlineno)340 assemble_location_info(struct assembler *a, instr_sequence *instrs,
341 int firstlineno)
342 {
343 a->a_lineno = firstlineno;
344 location loc = NO_LOCATION;
345 int size = 0;
346 for (int i = 0; i < instrs->s_used; i++) {
347 instruction *instr = &instrs->s_instrs[i];
348 if (!same_location(loc, instr->i_loc)) {
349 RETURN_IF_ERROR(assemble_emit_location(a, loc, size));
350 loc = instr->i_loc;
351 size = 0;
352 }
353 size += instr_size(instr);
354 }
355 RETURN_IF_ERROR(assemble_emit_location(a, loc, size));
356 return SUCCESS;
357 }
358
359 static void
write_instr(_Py_CODEUNIT * codestr,instruction * instr,int ilen)360 write_instr(_Py_CODEUNIT *codestr, instruction *instr, int ilen)
361 {
362 int opcode = instr->i_opcode;
363 assert(!IS_PSEUDO_INSTR(opcode));
364 int oparg = instr->i_oparg;
365 assert(OPCODE_HAS_ARG(opcode) || oparg == 0);
366 int caches = _PyOpcode_Caches[opcode];
367 switch (ilen - caches) {
368 case 4:
369 codestr->op.code = EXTENDED_ARG;
370 codestr->op.arg = (oparg >> 24) & 0xFF;
371 codestr++;
372 /* fall through */
373 case 3:
374 codestr->op.code = EXTENDED_ARG;
375 codestr->op.arg = (oparg >> 16) & 0xFF;
376 codestr++;
377 /* fall through */
378 case 2:
379 codestr->op.code = EXTENDED_ARG;
380 codestr->op.arg = (oparg >> 8) & 0xFF;
381 codestr++;
382 /* fall through */
383 case 1:
384 codestr->op.code = opcode;
385 codestr->op.arg = oparg & 0xFF;
386 codestr++;
387 break;
388 default:
389 Py_UNREACHABLE();
390 }
391 while (caches--) {
392 codestr->op.code = CACHE;
393 codestr->op.arg = 0;
394 codestr++;
395 }
396 }
397
398 /* assemble_emit_instr()
399 Extend the bytecode with a new instruction.
400 Update lnotab if necessary.
401 */
402
403 static int
assemble_emit_instr(struct assembler * a,instruction * instr)404 assemble_emit_instr(struct assembler *a, instruction *instr)
405 {
406 Py_ssize_t len = PyBytes_GET_SIZE(a->a_bytecode);
407 _Py_CODEUNIT *code;
408
409 int size = instr_size(instr);
410 if (a->a_offset + size >= len / (int)sizeof(_Py_CODEUNIT)) {
411 if (len > PY_SSIZE_T_MAX / 2) {
412 return ERROR;
413 }
414 RETURN_IF_ERROR(_PyBytes_Resize(&a->a_bytecode, len * 2));
415 }
416 code = (_Py_CODEUNIT *)PyBytes_AS_STRING(a->a_bytecode) + a->a_offset;
417 a->a_offset += size;
418 write_instr(code, instr, size);
419 return SUCCESS;
420 }
421
422 static int
assemble_emit(struct assembler * a,instr_sequence * instrs,int first_lineno,PyObject * const_cache)423 assemble_emit(struct assembler *a, instr_sequence *instrs,
424 int first_lineno, PyObject *const_cache)
425 {
426 RETURN_IF_ERROR(assemble_init(a, first_lineno));
427
428 for (int i = 0; i < instrs->s_used; i++) {
429 instruction *instr = &instrs->s_instrs[i];
430 RETURN_IF_ERROR(assemble_emit_instr(a, instr));
431 }
432
433 RETURN_IF_ERROR(assemble_location_info(a, instrs, a->a_lineno));
434
435 RETURN_IF_ERROR(assemble_exception_table(a, instrs));
436
437 RETURN_IF_ERROR(_PyBytes_Resize(&a->a_except_table, a->a_except_table_off));
438 RETURN_IF_ERROR(_PyCompile_ConstCacheMergeOne(const_cache, &a->a_except_table));
439
440 RETURN_IF_ERROR(_PyBytes_Resize(&a->a_linetable, a->a_location_off));
441 RETURN_IF_ERROR(_PyCompile_ConstCacheMergeOne(const_cache, &a->a_linetable));
442
443 RETURN_IF_ERROR(_PyBytes_Resize(&a->a_bytecode, a->a_offset * sizeof(_Py_CODEUNIT)));
444 RETURN_IF_ERROR(_PyCompile_ConstCacheMergeOne(const_cache, &a->a_bytecode));
445 return SUCCESS;
446 }
447
448 static PyObject *
dict_keys_inorder(PyObject * dict,Py_ssize_t offset)449 dict_keys_inorder(PyObject *dict, Py_ssize_t offset)
450 {
451 PyObject *tuple, *k, *v;
452 Py_ssize_t pos = 0, size = PyDict_GET_SIZE(dict);
453
454 tuple = PyTuple_New(size);
455 if (tuple == NULL)
456 return NULL;
457 while (PyDict_Next(dict, &pos, &k, &v)) {
458 Py_ssize_t i = PyLong_AsSsize_t(v);
459 if (i == -1 && PyErr_Occurred()) {
460 Py_DECREF(tuple);
461 return NULL;
462 }
463 assert((i - offset) < size);
464 assert((i - offset) >= 0);
465 PyTuple_SET_ITEM(tuple, i - offset, Py_NewRef(k));
466 }
467 return tuple;
468 }
469
470 // This is in codeobject.c.
471 extern void _Py_set_localsplus_info(int, PyObject *, unsigned char,
472 PyObject *, PyObject *);
473
474 static int
compute_localsplus_info(_PyCompile_CodeUnitMetadata * umd,int nlocalsplus,PyObject * names,PyObject * kinds)475 compute_localsplus_info(_PyCompile_CodeUnitMetadata *umd, int nlocalsplus,
476 PyObject *names, PyObject *kinds)
477 {
478 PyObject *k, *v;
479 Py_ssize_t pos = 0;
480 while (PyDict_Next(umd->u_varnames, &pos, &k, &v)) {
481 int offset = PyLong_AsInt(v);
482 if (offset == -1 && PyErr_Occurred()) {
483 return ERROR;
484 }
485 assert(offset >= 0);
486 assert(offset < nlocalsplus);
487
488 // For now we do not distinguish arg kinds.
489 _PyLocals_Kind kind = CO_FAST_LOCAL;
490 int has_key = PyDict_Contains(umd->u_fasthidden, k);
491 RETURN_IF_ERROR(has_key);
492 if (has_key) {
493 kind |= CO_FAST_HIDDEN;
494 }
495
496 has_key = PyDict_Contains(umd->u_cellvars, k);
497 RETURN_IF_ERROR(has_key);
498 if (has_key) {
499 kind |= CO_FAST_CELL;
500 }
501
502 _Py_set_localsplus_info(offset, k, kind, names, kinds);
503 }
504 int nlocals = (int)PyDict_GET_SIZE(umd->u_varnames);
505
506 // This counter mirrors the fix done in fix_cell_offsets().
507 int numdropped = 0;
508 pos = 0;
509 while (PyDict_Next(umd->u_cellvars, &pos, &k, &v)) {
510 int has_name = PyDict_Contains(umd->u_varnames, k);
511 RETURN_IF_ERROR(has_name);
512 if (has_name) {
513 // Skip cells that are already covered by locals.
514 numdropped += 1;
515 continue;
516 }
517
518 int offset = PyLong_AsInt(v);
519 if (offset == -1 && PyErr_Occurred()) {
520 return ERROR;
521 }
522 assert(offset >= 0);
523 offset += nlocals - numdropped;
524 assert(offset < nlocalsplus);
525 _Py_set_localsplus_info(offset, k, CO_FAST_CELL, names, kinds);
526 }
527
528 pos = 0;
529 while (PyDict_Next(umd->u_freevars, &pos, &k, &v)) {
530 int offset = PyLong_AsInt(v);
531 if (offset == -1 && PyErr_Occurred()) {
532 return ERROR;
533 }
534 assert(offset >= 0);
535 offset += nlocals - numdropped;
536 assert(offset < nlocalsplus);
537 _Py_set_localsplus_info(offset, k, CO_FAST_FREE, names, kinds);
538 }
539 return SUCCESS;
540 }
541
542 static PyCodeObject *
makecode(_PyCompile_CodeUnitMetadata * umd,struct assembler * a,PyObject * const_cache,PyObject * constslist,int maxdepth,int nlocalsplus,int code_flags,PyObject * filename)543 makecode(_PyCompile_CodeUnitMetadata *umd, struct assembler *a, PyObject *const_cache,
544 PyObject *constslist, int maxdepth, int nlocalsplus, int code_flags,
545 PyObject *filename)
546 {
547 PyCodeObject *co = NULL;
548 PyObject *names = NULL;
549 PyObject *consts = NULL;
550 PyObject *localsplusnames = NULL;
551 PyObject *localspluskinds = NULL;
552 names = dict_keys_inorder(umd->u_names, 0);
553 if (!names) {
554 goto error;
555 }
556 if (_PyCompile_ConstCacheMergeOne(const_cache, &names) < 0) {
557 goto error;
558 }
559
560 consts = PyList_AsTuple(constslist); /* PyCode_New requires a tuple */
561 if (consts == NULL) {
562 goto error;
563 }
564 if (_PyCompile_ConstCacheMergeOne(const_cache, &consts) < 0) {
565 goto error;
566 }
567
568 assert(umd->u_posonlyargcount < INT_MAX);
569 assert(umd->u_argcount < INT_MAX);
570 assert(umd->u_kwonlyargcount < INT_MAX);
571 int posonlyargcount = (int)umd->u_posonlyargcount;
572 int posorkwargcount = (int)umd->u_argcount;
573 assert(INT_MAX - posonlyargcount - posorkwargcount > 0);
574 int kwonlyargcount = (int)umd->u_kwonlyargcount;
575
576 localsplusnames = PyTuple_New(nlocalsplus);
577 if (localsplusnames == NULL) {
578 goto error;
579 }
580 localspluskinds = PyBytes_FromStringAndSize(NULL, nlocalsplus);
581 if (localspluskinds == NULL) {
582 goto error;
583 }
584 if (compute_localsplus_info(umd, nlocalsplus,
585 localsplusnames, localspluskinds) == ERROR) {
586 goto error;
587 }
588
589 struct _PyCodeConstructor con = {
590 .filename = filename,
591 .name = umd->u_name,
592 .qualname = umd->u_qualname ? umd->u_qualname : umd->u_name,
593 .flags = code_flags,
594
595 .code = a->a_bytecode,
596 .firstlineno = umd->u_firstlineno,
597 .linetable = a->a_linetable,
598
599 .consts = consts,
600 .names = names,
601
602 .localsplusnames = localsplusnames,
603 .localspluskinds = localspluskinds,
604
605 .argcount = posonlyargcount + posorkwargcount,
606 .posonlyargcount = posonlyargcount,
607 .kwonlyargcount = kwonlyargcount,
608
609 .stacksize = maxdepth,
610
611 .exceptiontable = a->a_except_table,
612 };
613
614 if (_PyCode_Validate(&con) < 0) {
615 goto error;
616 }
617
618 if (_PyCompile_ConstCacheMergeOne(const_cache, &localsplusnames) < 0) {
619 goto error;
620 }
621 con.localsplusnames = localsplusnames;
622
623 co = _PyCode_New(&con);
624 if (co == NULL) {
625 goto error;
626 }
627
628 error:
629 Py_XDECREF(names);
630 Py_XDECREF(consts);
631 Py_XDECREF(localsplusnames);
632 Py_XDECREF(localspluskinds);
633 return co;
634 }
635
636 static int
resolve_jump_offsets(instr_sequence * instrs)637 resolve_jump_offsets(instr_sequence *instrs)
638 {
639 /* Compute the size of each instruction and fixup jump args.
640 * Replace instruction index with position in bytecode.
641 */
642
643 for (int i = 0; i < instrs->s_used; i++) {
644 instruction *instr = &instrs->s_instrs[i];
645 if (OPCODE_HAS_JUMP(instr->i_opcode)) {
646 instr->i_target = instr->i_oparg;
647 }
648 }
649
650 int extended_arg_recompile;
651
652 do {
653 int totsize = 0;
654 for (int i = 0; i < instrs->s_used; i++) {
655 instruction *instr = &instrs->s_instrs[i];
656 instr->i_offset = totsize;
657 int isize = instr_size(instr);
658 totsize += isize;
659 }
660 extended_arg_recompile = 0;
661
662 int offset = 0;
663 for (int i = 0; i < instrs->s_used; i++) {
664 instruction *instr = &instrs->s_instrs[i];
665 int isize = instr_size(instr);
666 /* jump offsets are computed relative to
667 * the instruction pointer after fetching
668 * the jump instruction.
669 */
670 offset += isize;
671 if (OPCODE_HAS_JUMP(instr->i_opcode)) {
672 instruction *target = &instrs->s_instrs[instr->i_target];
673 instr->i_oparg = target->i_offset;
674 if (instr->i_oparg < offset) {
675 assert(IS_BACKWARDS_JUMP_OPCODE(instr->i_opcode));
676 instr->i_oparg = offset - instr->i_oparg;
677 }
678 else {
679 assert(!IS_BACKWARDS_JUMP_OPCODE(instr->i_opcode));
680 instr->i_oparg = instr->i_oparg - offset;
681 }
682 if (instr_size(instr) != isize) {
683 extended_arg_recompile = 1;
684 }
685 }
686 }
687 /* XXX: This is an awful hack that could hurt performance, but
688 on the bright side it should work until we come up
689 with a better solution.
690
691 The issue is that in the first loop instr_size() is
692 called, and it requires i_oparg be set appropriately.
693 There is a bootstrap problem because i_oparg is
694 calculated in the second loop above.
695
696 So we loop until we stop seeing new EXTENDED_ARGs.
697 The only EXTENDED_ARGs that could be popping up are
698 ones in jump instructions. So this should converge
699 fairly quickly.
700 */
701 } while (extended_arg_recompile);
702 return SUCCESS;
703 }
704
705 static int
resolve_unconditional_jumps(instr_sequence * instrs)706 resolve_unconditional_jumps(instr_sequence *instrs)
707 {
708 /* Resolve directions of unconditional jumps */
709
710 for (int i = 0; i < instrs->s_used; i++) {
711 instruction *instr = &instrs->s_instrs[i];
712 bool is_forward = (instr->i_oparg > i);
713 switch(instr->i_opcode) {
714 case JUMP:
715 assert(is_pseudo_target(JUMP, JUMP_FORWARD));
716 assert(is_pseudo_target(JUMP, JUMP_BACKWARD));
717 instr->i_opcode = is_forward ? JUMP_FORWARD : JUMP_BACKWARD;
718 break;
719 case JUMP_NO_INTERRUPT:
720 assert(is_pseudo_target(JUMP_NO_INTERRUPT, JUMP_FORWARD));
721 assert(is_pseudo_target(JUMP_NO_INTERRUPT, JUMP_BACKWARD_NO_INTERRUPT));
722 instr->i_opcode = is_forward ?
723 JUMP_FORWARD : JUMP_BACKWARD_NO_INTERRUPT;
724 break;
725 default:
726 if (OPCODE_HAS_JUMP(instr->i_opcode) &&
727 IS_PSEUDO_INSTR(instr->i_opcode)) {
728 Py_UNREACHABLE();
729 }
730 }
731 }
732 return SUCCESS;
733 }
734
735 PyCodeObject *
_PyAssemble_MakeCodeObject(_PyCompile_CodeUnitMetadata * umd,PyObject * const_cache,PyObject * consts,int maxdepth,instr_sequence * instrs,int nlocalsplus,int code_flags,PyObject * filename)736 _PyAssemble_MakeCodeObject(_PyCompile_CodeUnitMetadata *umd, PyObject *const_cache,
737 PyObject *consts, int maxdepth, instr_sequence *instrs,
738 int nlocalsplus, int code_flags, PyObject *filename)
739 {
740 if (_PyInstructionSequence_ApplyLabelMap(instrs) < 0) {
741 return NULL;
742 }
743 if (resolve_unconditional_jumps(instrs) < 0) {
744 return NULL;
745 }
746 if (resolve_jump_offsets(instrs) < 0) {
747 return NULL;
748 }
749 PyCodeObject *co = NULL;
750
751 struct assembler a;
752 int res = assemble_emit(&a, instrs, umd->u_firstlineno, const_cache);
753 if (res == SUCCESS) {
754 co = makecode(umd, &a, const_cache, consts, maxdepth, nlocalsplus,
755 code_flags, filename);
756 }
757 assemble_free(&a);
758 return co;
759 }
760