Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 07ebd46

Browse files
authored
pythongh-112519: Make it possible to specify instruction flags for pseudo instructions in bytecodes.c (python#112520)
1 parent 7eeea13 commit 07ebd46

File tree

6 files changed

+76
-12
lines changed

6 files changed

+76
-12
lines changed

Include/internal/pycore_opcode_metadata.h

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/test/test_generated_cases.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,44 @@ def test_macro_instruction(self):
466466
"""
467467
self.run_cases_test(input, output)
468468

469+
def test_pseudo_instruction_no_flags(self):
470+
input = """
471+
pseudo(OP) = {
472+
OP1,
473+
};
474+
475+
inst(OP1, (--)) {
476+
}
477+
"""
478+
output = """
479+
TARGET(OP1) {
480+
frame->instr_ptr = next_instr;
481+
next_instr += 1;
482+
INSTRUCTION_STATS(OP1);
483+
DISPATCH();
484+
}
485+
"""
486+
self.run_cases_test(input, output)
487+
488+
def test_pseudo_instruction_with_flags(self):
489+
input = """
490+
pseudo(OP, (HAS_ARG, HAS_JUMP)) = {
491+
OP1,
492+
};
493+
494+
inst(OP1, (--)) {
495+
}
496+
"""
497+
output = """
498+
TARGET(OP1) {
499+
frame->instr_ptr = next_instr;
500+
next_instr += 1;
501+
INSTRUCTION_STATS(OP1);
502+
DISPATCH();
503+
}
504+
"""
505+
self.run_cases_test(input, output)
506+
469507
def test_array_input(self):
470508
input = """
471509
inst(OP, (below, values[oparg*2], above --)) {

Python/bytecodes.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2831,15 +2831,15 @@ dummy_func(
28312831
ERROR_IF(res == NULL, error);
28322832
}
28332833

2834-
pseudo(SETUP_FINALLY) = {
2834+
pseudo(SETUP_FINALLY, (HAS_ARG)) = {
28352835
NOP,
28362836
};
28372837

2838-
pseudo(SETUP_CLEANUP) = {
2838+
pseudo(SETUP_CLEANUP, (HAS_ARG)) = {
28392839
NOP,
28402840
};
28412841

2842-
pseudo(SETUP_WITH) = {
2842+
pseudo(SETUP_WITH, (HAS_ARG)) = {
28432843
NOP,
28442844
};
28452845

Python/flowgraph.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ static const jump_target_label NO_LABEL = {-1};
9797
static inline int
9898
is_block_push(cfg_instr *i)
9999
{
100+
assert(OPCODE_HAS_ARG(i->i_opcode) || !IS_BLOCK_PUSH_OPCODE(i->i_opcode));
100101
return IS_BLOCK_PUSH_OPCODE(i->i_opcode);
101102
}
102103

@@ -2239,7 +2240,6 @@ convert_pseudo_ops(basicblock *entryblock)
22392240
for (int i = 0; i < b->b_iused; i++) {
22402241
cfg_instr *instr = &b->b_instr[i];
22412242
if (is_block_push(instr) || instr->i_opcode == POP_BLOCK) {
2242-
assert(SAME_OPCODE_METADATA(instr->i_opcode, NOP));
22432243
INSTR_SET_OP0(instr, NOP);
22442244
}
22452245
else if (instr->i_opcode == LOAD_CLOSURE) {

Tools/cases_generator/analysis.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -390,9 +390,14 @@ def analyze_pseudo(self, pseudo: parsing.Pseudo) -> PseudoInstruction:
390390
else:
391391
targets.append(self.macro_instrs[target_name])
392392
assert targets
393-
ignored_flags = {"HAS_EVAL_BREAK_FLAG", "HAS_DEOPT_FLAG", "HAS_ERROR_FLAG", "HAS_ESCAPES_FLAG"}
393+
ignored_flags = {"HAS_EVAL_BREAK_FLAG", "HAS_DEOPT_FLAG", "HAS_ERROR_FLAG",
394+
"HAS_ESCAPES_FLAG"}
394395
assert len({t.instr_flags.bitmap(ignore=ignored_flags) for t in targets}) == 1
395-
return PseudoInstruction(pseudo.name, targets, targets[0].instr_flags)
396+
397+
flags = InstructionFlags(**{f"{f}_FLAG" : True for f in pseudo.flags})
398+
for t in targets:
399+
flags.add(t.instr_flags)
400+
return PseudoInstruction(pseudo.name, targets, flags)
396401

397402
def analyze_instruction(
398403
self, instr: Instruction, offset: int

Tools/cases_generator/parsing.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,8 @@ class Family(Node):
138138
@dataclass
139139
class Pseudo(Node):
140140
name: str
141-
targets: list[str] # opcodes this can be replaced by
141+
flags: list[str] # instr flags to set on the pseudo instruction
142+
targets: list[str] # opcodes this can be replaced by
142143

143144

144145
class Parser(PLexer):
@@ -374,19 +375,39 @@ def family_def(self) -> Family | None:
374375
)
375376
return None
376377

378+
def flags(self) -> list[str]:
379+
here = self.getpos()
380+
if self.expect(lx.LPAREN):
381+
if tkn := self.expect(lx.IDENTIFIER):
382+
flags = [tkn.text]
383+
while self.expect(lx.COMMA):
384+
if tkn := self.expect(lx.IDENTIFIER):
385+
flags.append(tkn.text)
386+
else:
387+
break
388+
if not self.expect(lx.RPAREN):
389+
raise self.make_syntax_error("Expected comma or right paren")
390+
return flags
391+
self.setpos(here)
392+
return []
393+
377394
@contextual
378395
def pseudo_def(self) -> Pseudo | None:
379396
if (tkn := self.expect(lx.IDENTIFIER)) and tkn.text == "pseudo":
380397
size = None
381398
if self.expect(lx.LPAREN):
382399
if tkn := self.expect(lx.IDENTIFIER):
400+
if self.expect(lx.COMMA):
401+
flags = self.flags()
402+
else:
403+
flags = []
383404
if self.expect(lx.RPAREN):
384405
if self.expect(lx.EQUALS):
385406
if not self.expect(lx.LBRACE):
386407
raise self.make_syntax_error("Expected {")
387408
if members := self.members():
388409
if self.expect(lx.RBRACE) and self.expect(lx.SEMI):
389-
return Pseudo(tkn.text, members)
410+
return Pseudo(tkn.text, flags, members)
390411
return None
391412

392413
def members(self) -> list[str] | None:

0 commit comments

Comments
 (0)