diff options
author | Irit Katriel <1055913+iritkatriel@users.noreply.github.com> | 2024-09-25 14:51:25 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-25 14:51:25 (GMT) |
commit | 78aeb38f7d880a340295214abc4f7e77ffdad509 (patch) | |
tree | 8944d52302e56f98bef775d2599c6eee3c4db3b6 /Tools/cases_generator | |
parent | c58c572a65eb5b93d054e779df289e975a0b9864 (diff) | |
download | cpython-78aeb38f7d880a340295214abc4f7e77ffdad509.zip cpython-78aeb38f7d880a340295214abc4f7e77ffdad509.tar.gz cpython-78aeb38f7d880a340295214abc4f7e77ffdad509.tar.bz2 |
gh-124285: Fix bug where bool() is called multiple times for the same part of a boolean expression (#124394)
Diffstat (limited to 'Tools/cases_generator')
-rw-r--r-- | Tools/cases_generator/analyzer.py | 2 | ||||
-rw-r--r-- | Tools/cases_generator/opcode_metadata_generator.py | 4 | ||||
-rw-r--r-- | Tools/cases_generator/parsing.py | 25 |
3 files changed, 22 insertions, 9 deletions
diff --git a/Tools/cases_generator/analyzer.py b/Tools/cases_generator/analyzer.py index 0680c21..aabe205 100644 --- a/Tools/cases_generator/analyzer.py +++ b/Tools/cases_generator/analyzer.py @@ -248,6 +248,7 @@ class PseudoInstruction: name: str stack: StackEffect targets: list[Instruction] + as_sequence: bool flags: list[str] opcode: int = -1 @@ -852,6 +853,7 @@ def add_pseudo( pseudo.name, analyze_stack(pseudo), [instructions[target] for target in pseudo.targets], + pseudo.as_sequence, pseudo.flags, ) diff --git a/Tools/cases_generator/opcode_metadata_generator.py b/Tools/cases_generator/opcode_metadata_generator.py index 9b1bc98..2ad7604 100644 --- a/Tools/cases_generator/opcode_metadata_generator.py +++ b/Tools/cases_generator/opcode_metadata_generator.py @@ -305,6 +305,7 @@ def generate_pseudo_targets(analysis: Analysis, out: CWriter) -> None: table_size = len(analysis.pseudos) max_targets = max(len(pseudo.targets) for pseudo in analysis.pseudos.values()) out.emit("struct pseudo_targets {\n") + out.emit(f"uint8_t as_sequence;\n") out.emit(f"uint8_t targets[{max_targets + 1}];\n") out.emit("};\n") out.emit( @@ -315,10 +316,11 @@ def generate_pseudo_targets(analysis: Analysis, out: CWriter) -> None: f"const struct pseudo_targets _PyOpcode_PseudoTargets[{table_size}] = {{\n" ) for pseudo in analysis.pseudos.values(): + as_sequence = "1" if pseudo.as_sequence else "0" targets = ["0"] * (max_targets + 1) for i, target in enumerate(pseudo.targets): targets[i] = target.name - out.emit(f"[{pseudo.name}-256] = {{ {{ {', '.join(targets)} }} }},\n") + out.emit(f"[{pseudo.name}-256] = {{ {as_sequence}, {{ {', '.join(targets)} }} }},\n") out.emit("};\n\n") out.emit("#endif // NEED_OPCODE_METADATA\n") out.emit("static inline bool\n") diff --git a/Tools/cases_generator/parsing.py b/Tools/cases_generator/parsing.py index ab5444d..de31d9b 100644 --- a/Tools/cases_generator/parsing.py +++ b/Tools/cases_generator/parsing.py @@ -148,6 +148,7 @@ class Pseudo(Node): outputs: list[OutputEffect] flags: list[str] # instr flags to set on the pseudo instruction targets: list[str] # opcodes this can be replaced by + as_sequence: bool AstNode = InstDef | Macro | Pseudo | Family @@ -423,16 +424,22 @@ class Parser(PLexer): flags = [] if self.expect(lx.RPAREN): if self.expect(lx.EQUALS): - if not self.expect(lx.LBRACE): - raise self.make_syntax_error("Expected {") - if members := self.members(): - if self.expect(lx.RBRACE) and self.expect(lx.SEMI): + if self.expect(lx.LBRACE): + as_sequence = False + closing = lx.RBRACE + elif self.expect(lx.LBRACKET): + as_sequence = True + closing = lx.RBRACKET + else: + raise self.make_syntax_error("Expected { or [") + if members := self.members(allow_sequence=True): + if self.expect(closing) and self.expect(lx.SEMI): return Pseudo( - tkn.text, inp, outp, flags, members + tkn.text, inp, outp, flags, members, as_sequence ) return None - def members(self) -> list[str] | None: + def members(self, allow_sequence : bool=False) -> list[str] | None: here = self.getpos() if tkn := self.expect(lx.IDENTIFIER): members = [tkn.text] @@ -442,8 +449,10 @@ class Parser(PLexer): else: break peek = self.peek() - if not peek or peek.kind != lx.RBRACE: - raise self.make_syntax_error("Expected comma or right paren") + kinds = [lx.RBRACE, lx.RBRACKET] if allow_sequence else [lx.RBRACE] + if not peek or peek.kind not in kinds: + raise self.make_syntax_error( + f"Expected comma or right paren{'/bracket' if allow_sequence else ''}") return members self.setpos(here) return None |