#define GET_AWAITABLE 131
#define MAKE_FUNCTION 132
#define BUILD_SLICE 133
-#define JUMP_NO_INTERRUPT 134
+#define JUMP_BACKWARD_NO_INTERRUPT 134
#define MAKE_CELL 135
#define LOAD_CLOSURE 136
#define LOAD_DEREF 137
0U,
536870912U,
134234112U,
- 4096U,
+ 4160U,
0U,
0U,
0U,
[IMPORT_STAR] = IMPORT_STAR,
[IS_OP] = IS_OP,
[JUMP_BACKWARD] = JUMP_BACKWARD,
+ [JUMP_BACKWARD_NO_INTERRUPT] = JUMP_BACKWARD_NO_INTERRUPT,
[JUMP_BACKWARD_QUICK] = JUMP_BACKWARD,
[JUMP_FORWARD] = JUMP_FORWARD,
[JUMP_IF_FALSE_OR_POP] = JUMP_IF_FALSE_OR_POP,
[JUMP_IF_TRUE_OR_POP] = JUMP_IF_TRUE_OR_POP,
- [JUMP_NO_INTERRUPT] = JUMP_NO_INTERRUPT,
[KW_NAMES] = KW_NAMES,
[LIST_APPEND] = LIST_APPEND,
[LIST_EXTEND] = LIST_EXTEND,
#define SETUP_WITH -3
#define POP_BLOCK -4
#define JUMP -5
+#define JUMP_NO_INTERRUPT -6
-#define MIN_VIRTUAL_OPCODE -5
+#define MIN_VIRTUAL_OPCODE -6
#define MAX_ALLOWED_OPCODE 254
#define IS_WITHIN_OPCODE_RANGE(opcode) \
#define IS_VIRTUAL_OPCODE(opcode) ((opcode) < 0)
+/* opcodes which are not emitted in codegen stage, only by the assembler */
+#define IS_ASSEMBLER_OPCODE(opcode) \
+ ((opcode) == JUMP_FORWARD || \
+ (opcode) == JUMP_BACKWARD || \
+ (opcode) == JUMP_BACKWARD_NO_INTERRUPT)
+
+
#define IS_TOP_LEVEL_AWAIT(c) ( \
(c->c_flags->cf_flags & PyCF_ALLOW_TOP_LEVEL_AWAIT) \
&& (c->u->u_ste->ste_type == ModuleBlock))
case JUMP_FORWARD:
case JUMP_BACKWARD:
case JUMP:
+ case JUMP_BACKWARD_NO_INTERRUPT:
case JUMP_NO_INTERRUPT:
return 0;
int end_line, int col_offset, int end_col_offset)
{
assert(IS_WITHIN_OPCODE_RANGE(opcode));
+ assert(!IS_ASSEMBLER_OPCODE(opcode));
assert(!HAS_ARG(opcode) || IS_ARTIFICIAL(opcode));
if (compiler_use_new_implicit_block_if_needed(c) < 0) {
EXTENDED_ARG is used for 16, 24, and 32-bit arguments. */
assert(IS_WITHIN_OPCODE_RANGE(opcode));
+ assert(!IS_ASSEMBLER_OPCODE(opcode));
assert(HAS_ARG(opcode));
assert(0 <= oparg && oparg <= 2147483647);
basicblock *target)
{
assert(IS_WITHIN_OPCODE_RANGE(opcode));
+ assert(!IS_ASSEMBLER_OPCODE(opcode));
assert(HAS_ARG(opcode) || IS_VIRTUAL_OPCODE(opcode));
assert(target != NULL);
stackdepth_push(&sp, instr->i_target, target_depth);
}
depth = new_depth;
- assert(instr->i_opcode != JUMP_FORWARD);
- assert(instr->i_opcode != JUMP_BACKWARD);
+ assert(!IS_ASSEMBLER_OPCODE(instr->i_opcode));
if (instr->i_opcode == JUMP_NO_INTERRUPT ||
instr->i_opcode == JUMP ||
instr->i_opcode == RETURN_VALUE ||
continue;
}
struct instr *last = &b->b_instr[b->b_iused-1];
- assert(last->i_opcode != JUMP_FORWARD);
- assert(last->i_opcode != JUMP_BACKWARD);
+ assert(!IS_ASSEMBLER_OPCODE(last->i_opcode));
if (last->i_opcode == JUMP) {
- if (last->i_target->b_visited == 0) {
- last->i_opcode = JUMP_FORWARD;
- }
- else {
- last->i_opcode = JUMP_BACKWARD;
- }
+ bool is_forward = last->i_target->b_visited == 0;
+ last->i_opcode = is_forward ? JUMP_FORWARD : JUMP_BACKWARD;
+ }
+ if (last->i_opcode == JUMP_NO_INTERRUPT) {
+ bool is_forward = last->i_target->b_visited == 0;
+ last->i_opcode = is_forward ?
+ JUMP_FORWARD : JUMP_BACKWARD_NO_INTERRUPT;
}
}
}
instr->i_oparg = instr->i_target->b_offset;
if (is_relative_jump(instr)) {
if (instr->i_oparg < bsize) {
- assert(instr->i_opcode == JUMP_BACKWARD);
+ assert(instr->i_opcode == JUMP_BACKWARD ||
+ instr->i_opcode == JUMP_BACKWARD_NO_INTERRUPT);
instr->i_oparg = bsize - instr->i_oparg;
}
else {
assert(instr->i_opcode != JUMP_BACKWARD);
+ assert(instr->i_opcode != JUMP_BACKWARD_NO_INTERRUPT);
instr->i_oparg -= bsize;
}
}
inst->i_target = inst->i_target->b_next;
}
target = &inst->i_target->b_instr[0];
- assert(target->i_opcode != JUMP_FORWARD);
- assert(target->i_opcode != JUMP_BACKWARD);
+ assert(!IS_ASSEMBLER_OPCODE(target->i_opcode));
}
else {
target = &nop;
}
- assert(inst->i_opcode != JUMP_FORWARD);
- assert(inst->i_opcode != JUMP_BACKWARD);
+ assert(!IS_ASSEMBLER_OPCODE(inst->i_opcode));
switch (inst->i_opcode) {
/* Remove LOAD_CONST const; conditional jump */
case LOAD_CONST:
/* Mark blocks as exit and/or nofallthrough.
Raise SystemError if CFG is malformed. */
for (int i = 0; i < bb->b_iused; i++) {
- assert(bb->b_instr[i].i_opcode != JUMP_FORWARD);
- assert(bb->b_instr[i].i_opcode != JUMP_BACKWARD);
+ assert(!IS_ASSEMBLER_OPCODE(bb->b_instr[i].i_opcode));
switch(bb->b_instr[i].i_opcode) {
case RETURN_VALUE:
case RAISE_VARARGS:
for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) {
if (b->b_iused > 0) {
struct instr *b_last_instr = &b->b_instr[b->b_iused - 1];
- assert(b_last_instr->i_opcode != JUMP_FORWARD);
- assert(b_last_instr->i_opcode != JUMP_BACKWARD);
+ assert(!IS_ASSEMBLER_OPCODE(b_last_instr->i_opcode));
if (b_last_instr->i_opcode == JUMP ||
b_last_instr->i_opcode == JUMP_NO_INTERRUPT) {
if (b_last_instr->i_target == b->b_next) {