summaryrefslogtreecommitdiffstats
path: root/Tools/cases_generator
diff options
context:
space:
mode:
authorIrit Katriel <1055913+iritkatriel@users.noreply.github.com>2024-09-25 14:51:25 (GMT)
committerGitHub <noreply@github.com>2024-09-25 14:51:25 (GMT)
commit78aeb38f7d880a340295214abc4f7e77ffdad509 (patch)
tree8944d52302e56f98bef775d2599c6eee3c4db3b6 /Tools/cases_generator
parentc58c572a65eb5b93d054e779df289e975a0b9864 (diff)
downloadcpython-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.py2
-rw-r--r--Tools/cases_generator/opcode_metadata_generator.py4
-rw-r--r--Tools/cases_generator/parsing.py25
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