[Pyrex] Re: pyrex patch misses a few labels
David M. Cooke
cookedm at physics.mcmaster.ca
Mon Mar 13 09:47:47 CET 2006
[cc:ing the Pyrex list]
On Sun, Mar 12, 2006 at 08:03:17PM -0500, chris erway wrote:
> hi landon, david:
>
> last week the darwinports maintainer (landon) for Pyrex added your
> (david's) patch to suppress unused labels (patch-emit-only-used-
> labels) in Pyrex-generated code. i upgraded to the patched version
> today, and found it prevented me from building two Pyrex extensions
> used by the "democracy player" project (getdemocracy.com) -- a few
> errors about missing labels. maybe this patch should taken off the
> Pyrex Portfile?
>
> attached is an example Pyrex file from the democracy project, the
> working C code that Pyrex generates without the patch, and the code
> generated by the patch that fails compilation.
>
> -chris
I've found a minimal test case for this:
def testx():
for d in (1,2,3):
try:
pass
finally:
pass
The unpatched Pyrex generates a label just after the for, and the
finally will jump to that if a continue is used in the try: block. I've
updated the patches so that the label is generated at the end of the
for.
Updated patches that should apply cleanly to Pyrex 0.9.3.1 are available at
http://arbutus.mcmaster.ca/dmc/software/pyrex/
(this includes Elias Pschernig's patch (04) to not output declarations
for unused utility functions.)
I've attached the new 02-emit-only-used-labels patch for mail archive
goodness. There's still compiler warnings about unused labels due to the
finally: declaring more than needed, but that's less harmful than an
error ;-)
--
|>|\/|<
/--------------------------------------------------------------------------\
|David M. Cooke http://arbutus.physics.mcmaster.ca/dmc/
|cookedm at physics.mcmaster.ca
-------------- next part --------------
Mon Mar 13 03:27:55 EST 2006 David M. Cooke <cookedm at physics.mcmaster.ca>
* [02-emit-only-used-labels] Only emit labels if they've been used
diff -rN -u old-Pyrex--dmc2/Pyrex/Compiler/Code.py new-Pyrex--dmc2/Pyrex/Compiler/Code.py
--- old-Pyrex--dmc2/Pyrex/Compiler/Code.py 2006-03-13 03:34:04.000000000 -0500
+++ new-Pyrex--dmc2/Pyrex/Compiler/Code.py 2006-03-13 03:34:05.000000000 -0500
@@ -79,6 +79,7 @@
def init_labels(self):
self.label_counter = 0
+ self.used_labels = {}
self.return_label = self.new_label()
self.new_error_label()
self.continue_label = None
@@ -134,8 +135,16 @@
self.set_all_labels(new_labels)
return old_labels
+ def mark_label_used(self, lbl):
+ self.used_labels[lbl] = 1
+
def put_label(self, lbl):
- self.putln("%s:;" % lbl)
+ if lbl in self.used_labels:
+ self.putln("%s:;" % lbl)
+
+ def put_goto(self, lbl):
+ self.putln("goto %s;" % lbl)
+ self.mark_label_used(lbl)
def put_var_declarations(self, entries, static = 0, dll_linkage = None):
for entry in entries:
@@ -245,6 +254,7 @@
term))
def error_goto(self, pos):
+ self.mark_label_used(self.error_label)
return "{%s = %s[%s]; %s = %s; goto %s;}" % (
Naming.filename_cname,
Naming.filetable_cname,
diff -rN -u old-Pyrex--dmc2/Pyrex/Compiler/Nodes.py new-Pyrex--dmc2/Pyrex/Compiler/Nodes.py
--- old-Pyrex--dmc2/Pyrex/Compiler/Nodes.py 2006-03-13 03:34:04.000000000 -0500
+++ new-Pyrex--dmc2/Pyrex/Compiler/Nodes.py 2006-03-13 03:34:05.000000000 -0500
@@ -1707,7 +1707,7 @@
val = self.return_type.default_value
if val:
code.putln("%s = %s;" % (Naming.retval_cname, val))
- code.putln("goto %s;" % code.return_label)
+ code.put_goto(code.return_label)
# ----- Error cleanup
code.put_label(code.error_label)
code.put_var_xdecrefs(lenv.temp_entries)
@@ -2699,9 +2699,7 @@
if not code.break_label:
error(self.pos, "break statement not inside loop")
else:
- code.putln(
- "goto %s;" %
- code.break_label)
+ code.put_goto(code.break_label)
class ContinueStatNode(StatNode):
@@ -2715,9 +2713,7 @@
elif not code.continue_label:
error(self.pos, "continue statement not inside loop")
else:
- code.putln(
- "goto %s;" %
- code.continue_label)
+ code.put_goto(code.continue_label)
class ReturnStatNode(StatNode):
@@ -2776,9 +2772,7 @@
"%s = %s;" % (
Naming.retval_cname,
self.return_type.default_value))
- code.putln(
- "goto %s;" %
- code.return_label)
+ code.put_goto(code.return_label)
class RaiseStatNode(StatNode):
@@ -2940,9 +2934,7 @@
"if (%s) {" %
self.condition.result)
self.body.generate_execution_code(code)
- code.putln(
- "goto %s;" %
- end_label)
+ code.put_goto(end_label)
code.putln("}")
@@ -2971,12 +2963,12 @@
old_loop_labels = code.new_loop_labels()
code.putln(
"while (1) {")
- code.put_label(code.continue_label)
self.condition.generate_evaluation_code(code)
code.putln(
"if (!%s) break;" %
self.condition.result)
self.body.generate_execution_code(code)
+ code.put_label(code.continue_label)
code.putln("}")
break_label = code.break_label
code.set_loop_labels(old_loop_labels)
@@ -3024,10 +3016,10 @@
self.iterator.generate_evaluation_code(code)
code.putln(
"for (;;) {")
- code.put_label(code.continue_label)
self.item.generate_evaluation_code(code)
self.target.generate_assignment_code(self.item, code)
self.body.generate_execution_code(code)
+ code.put_label(code.continue_label)
code.putln(
"}")
break_label = code.break_label
@@ -3178,9 +3170,7 @@
self.else_clause.generate_execution_code(code)
code.putln(
"}")
- code.putln(
- "goto %s;" %
- end_label)
+ code.put_goto(end_label)
code.put_label(our_error_label)
code.put_var_xdecrefs_clear(self.cleanup_list)
default_clause_seen = 0
@@ -3192,9 +3182,7 @@
error(except_clause.pos, "Default except clause not last")
except_clause.generate_handling_code(code, end_label)
if not default_clause_seen:
- code.putln(
- "goto %s;" %
- code.error_label)
+ code.put_goto(code.error_label)
code.put_label(end_label)
@@ -3259,9 +3247,7 @@
else:
self.exc_value.generate_disposal_code(code)
self.body.generate_execution_code(code)
- code.putln(
- "goto %s;"
- % end_label)
+ code.put_goto(end_label)
code.putln(
"}")
@@ -3334,6 +3320,7 @@
code.putln(
"__pyx_why = 0; goto %s;" %
catch_label)
+ code.mark_label_used(catch_label)
for i in range(len(new_labels)):
if new_labels[i] and new_labels[i] <> "<try>":
if new_labels[i] == new_error_label:
@@ -3345,6 +3332,7 @@
new_labels[i],
i+1,
catch_label))
+ code.mark_label_used(catch_label)
code.put_label(catch_label)
code.set_all_labels(old_labels)
self.finally_clause.generate_execution_code(code)
@@ -3359,6 +3347,7 @@
"case %s: goto %s;" % (
i+1,
old_labels[i]))
+ code.mark_label_used(old_labels[i])
code.putln(
"}")
code.putln(
@@ -3378,9 +3367,7 @@
code.putln(
"%s = %s;" % (
self.lineno_var, Naming.lineno_cname))
- code.putln(
- "goto %s;" %
- catch_label)
+ code.put_goto(catch_label)
code.putln(
"}")
@@ -3398,9 +3385,7 @@
code.putln(
"%s = 0;" %
var)
- code.putln(
- "goto %s;" %
- error_label)
+ code.put_goto(error_label)
code.putln(
"}")
More information about the Pyrex
mailing list