summaryrefslogtreecommitdiffstats
path: root/Tools
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2024-07-23 13:12:06 (GMT)
committerGitHub <noreply@github.com>2024-07-23 13:12:06 (GMT)
commit624bda76386efd8eecf73c4ad06f997b9b25f07f (patch)
tree890768b024f1240a627dcb6f6071dc6f517bd0e1 /Tools
parent498cb6dff10f97fa3d348a4c0ad9374d14af3312 (diff)
downloadcpython-624bda76386efd8eecf73c4ad06f997b9b25f07f.zip
cpython-624bda76386efd8eecf73c4ad06f997b9b25f07f.tar.gz
cpython-624bda76386efd8eecf73c4ad06f997b9b25f07f.tar.bz2
GH-122155: Fix cases generator to correctly compute 'peek' offset for error handling (GH-122158)
Diffstat (limited to 'Tools')
-rw-r--r--Tools/cases_generator/analyzer.py6
-rw-r--r--Tools/cases_generator/generators_common.py2
-rw-r--r--Tools/cases_generator/stack.py15
3 files changed, 17 insertions, 6 deletions
diff --git a/Tools/cases_generator/analyzer.py b/Tools/cases_generator/analyzer.py
index c6f044e..f5cf4fa 100644
--- a/Tools/cases_generator/analyzer.py
+++ b/Tools/cases_generator/analyzer.py
@@ -317,9 +317,13 @@ def analyze_stack(op: parser.InstDef | parser.Pseudo, replace_op_arg_1: str | No
convert_stack_item(i, replace_op_arg_1) for i in op.inputs if isinstance(i, parser.StackEffect)
]
outputs: list[StackItem] = [convert_stack_item(i, replace_op_arg_1) for i in op.outputs]
+ # Mark variables with matching names at the base of the stack as "peek"
+ modified = False
for input, output in zip(inputs, outputs):
- if input.name == output.name:
+ if input.name == output.name and not modified:
input.peek = output.peek = True
+ else:
+ modified = True
if isinstance(op, parser.InstDef):
output_names = [out.name for out in outputs]
for input in inputs:
diff --git a/Tools/cases_generator/generators_common.py b/Tools/cases_generator/generators_common.py
index 9314bb9..587dc0d 100644
--- a/Tools/cases_generator/generators_common.py
+++ b/Tools/cases_generator/generators_common.py
@@ -92,7 +92,7 @@ def replace_error(
next(tkn_iter) # RPAREN
next(tkn_iter) # Semi colon
out.emit(") ")
- c_offset = stack.peek_offset.to_c()
+ c_offset = stack.peek_offset()
try:
offset = -int(c_offset)
close = ";\n"
diff --git a/Tools/cases_generator/stack.py b/Tools/cases_generator/stack.py
index f497fa3..61dcfd3 100644
--- a/Tools/cases_generator/stack.py
+++ b/Tools/cases_generator/stack.py
@@ -49,6 +49,9 @@ class StackOffset:
def empty() -> "StackOffset":
return StackOffset([], [])
+ def copy(self) -> "StackOffset":
+ return StackOffset(self.popped[:], self.pushed[:])
+
def pop(self, item: StackItem) -> None:
self.popped.append(var_size(item))
@@ -122,14 +125,11 @@ class Stack:
def __init__(self) -> None:
self.top_offset = StackOffset.empty()
self.base_offset = StackOffset.empty()
- self.peek_offset = StackOffset.empty()
self.variables: list[StackItem] = []
self.defined: set[str] = set()
def pop(self, var: StackItem, extract_bits: bool = False) -> str:
self.top_offset.pop(var)
- if not var.peek:
- self.peek_offset.pop(var)
indirect = "&" if var.is_array() else ""
if self.variables:
popped = self.variables.pop()
@@ -210,9 +210,16 @@ class Stack:
self.variables = []
self.base_offset.clear()
self.top_offset.clear()
- self.peek_offset.clear()
out.start_line()
+ def peek_offset(self) -> str:
+ peek = self.base_offset.copy()
+ for var in self.variables:
+ if not var.peek:
+ break
+ peek.push(var)
+ return peek.to_c()
+
def as_comment(self) -> str:
return f"/* Variables: {[v.name for v in self.variables]}. Base offset: {self.base_offset.to_c()}. Top offset: {self.top_offset.to_c()} */"