Commit daf7dcec authored by Stefan Behnel's avatar Stefan Behnel

clean up and improve static type declarations in FlowControl.py a bit

parent cb2b3432
cimport cython
from Cython.Compiler.Visitor cimport CythonTransform, TreeVisitor
cdef class ControlBlock:
cdef public set children
cdef public set parents
......@@ -39,6 +41,9 @@ cdef class AssignmentList:
cdef public object mask
cdef public list stats
cdef class AssignmentCollector(TreeVisitor):
cdef list assignments
cdef class ControlFlow:
cdef public set blocks
cdef public set entries
......@@ -51,9 +56,10 @@ cdef class ControlFlow:
cdef public dict assmts
cpdef newblock(self, parent=*)
cpdef nextblock(self, parent=*)
cpdef newblock(self, ControlBlock parent=*)
cpdef nextblock(self, ControlBlock parent=*)
cpdef bint is_tracked(self, entry)
cpdef bint is_statically_assigned(self, entry)
cpdef mark_position(self, node)
cpdef mark_assignment(self, lhs, rhs, entry)
cpdef mark_argument(self, lhs, rhs, entry)
......@@ -74,5 +80,20 @@ cdef class ControlFlow:
cdef class Uninitialized:
pass
cdef class Unknown:
pass
@cython.locals(dirty=bint, block=ControlBlock, parent=ControlBlock)
cdef check_definitions(ControlFlow flow, dict compiler_directives)
cdef class ControlFlowAnalysis(CythonTransform):
cdef object gv_ctx
cdef set reductions
cdef list env_stack
cdef list stack
cdef object env
cdef ControlFlow flow
cdef bint in_inplace_assignment
cpdef mark_assignment(self, lhs, rhs=*)
cpdef mark_position(self, node)
import cython
cython.declare(PyrexTypes=object, Naming=object, ExprNodes=object, Nodes=object,
Options=object, UtilNodes=object, ModuleNode=object,
LetNode=object, LetRefNode=object, TreeFragment=object,
TemplateTransform=object, EncodedString=object,
error=object, warning=object, copy=object)
cython.declare(PyrexTypes=object, ExprNodes=object, Nodes=object,
Builtin=object, InternalError=object,
error=object, warning=object,
py_object_type=object, unspecified_type=object,
object_expr=object, object_expr_not_none=object,
fake_rhs_expr=object, TypedExprNode=object)
import Builtin
import ExprNodes
......@@ -17,7 +18,7 @@ from Errors import error, warning, InternalError
class TypedExprNode(ExprNodes.ExprNode):
# Used for declaring assignments of a specified type without a known entry.
def __init__(self, type, may_be_none=None, pos=None):
self.pos = pos
super(TypedExprNode, self).__init__(pos)
self.type = type
self._may_be_none = may_be_none
......@@ -640,7 +641,7 @@ class AssignmentCollector(TreeVisitor):
self.assignments = []
def visit_Node(self):
self.visitchildren(self)
self._visitchildren(self, None)
def visit_SingleAssignmentNode(self, node):
self.assignments.append((node.lhs, node.rhs))
......@@ -651,7 +652,6 @@ class AssignmentCollector(TreeVisitor):
class ControlFlowAnalysis(CythonTransform):
in_inplace_assignment = False
def visit_ModuleNode(self, node):
self.gv_ctx = GVContext()
......@@ -659,6 +659,7 @@ class ControlFlowAnalysis(CythonTransform):
# Set of NameNode reductions
self.reductions = set()
self.in_inplace_assignment = False
self.env_stack = []
self.env = node.scope
self.stack = []
......@@ -681,7 +682,7 @@ class ControlFlowAnalysis(CythonTransform):
for arg in node.args:
if arg.default:
self.visitchildren(arg)
self.visitchildren(node, attrs=('decorators',))
self.visitchildren(node, ('decorators',))
self.env_stack.append(self.env)
self.env = node.local_scope
self.stack.append(self.flow)
......@@ -697,7 +698,7 @@ class ControlFlowAnalysis(CythonTransform):
self.flow.nextblock()
for arg in node.args:
self.visit(arg)
self._visit(arg)
if node.star_arg:
self.flow.mark_argument(node.star_arg,
TypedExprNode(Builtin.tuple_type,
......@@ -708,10 +709,10 @@ class ControlFlowAnalysis(CythonTransform):
TypedExprNode(Builtin.dict_type,
may_be_none=False),
node.starstar_arg.entry)
self.visit(node.body)
self._visit(node.body)
# Workaround for generators
if node.is_generator:
self.visit(node.gbody.body)
self._visit(node.gbody.body)
# Exit point
if self.flow.block:
......@@ -760,7 +761,7 @@ class ControlFlowAnalysis(CythonTransform):
for arg in lhs.args:
self.mark_assignment(arg)
else:
self.visit(lhs)
self._visit(lhs)
if self.flow.exceptions:
exc_descr = self.flow.exceptions[-1]
......@@ -783,12 +784,12 @@ class ControlFlowAnalysis(CythonTransform):
raise InternalError, "Unhandled assignment node"
def visit_SingleAssignmentNode(self, node):
self.visit(node.rhs)
self._visit(node.rhs)
self.mark_assignment(node.lhs, node.rhs)
return node
def visit_CascadedAssignmentNode(self, node):
self.visit(node.rhs)
self._visit(node.rhs)
for lhs in node.lhs_list:
self.mark_assignment(lhs, node.rhs)
return node
......@@ -797,7 +798,7 @@ class ControlFlowAnalysis(CythonTransform):
collector = AssignmentCollector()
collector.visitchildren(node)
for lhs, rhs in collector.assignments:
self.visit(rhs)
self._visit(rhs)
for lhs, rhs in collector.assignments:
self.mark_assignment(lhs, rhs)
return node
......@@ -818,7 +819,7 @@ class ControlFlowAnalysis(CythonTransform):
"can not delete variable '%s' "
"referenced in nested scope" % entry.name)
# Mark reference
self.visit(arg)
self._visit(arg)
self.flow.mark_deletion(arg, entry)
return node
......@@ -845,7 +846,7 @@ class ControlFlowAnalysis(CythonTransform):
def visit_StatListNode(self, node):
if self.flow.block:
for stat in node.stats:
self.visit(stat)
self._visit(stat)
if not self.flow.block:
stat.is_terminator = True
break
......@@ -862,15 +863,15 @@ class ControlFlowAnalysis(CythonTransform):
# If clauses
for clause in node.if_clauses:
parent = self.flow.nextblock(parent)
self.visit(clause.condition)
self._visit(clause.condition)
self.flow.nextblock()
self.visit(clause.body)
self._visit(clause.body)
if self.flow.block:
self.flow.block.add_child(next_block)
# Else clause
if node.else_clause:
self.flow.nextblock(parent=parent)
self.visit(node.else_clause)
self._visit(node.else_clause)
if self.flow.block:
self.flow.block.add_child(next_block)
else:
......@@ -887,10 +888,10 @@ class ControlFlowAnalysis(CythonTransform):
next_block = self.flow.newblock()
# Condition block
self.flow.loops.append(LoopDescr(next_block, condition_block))
self.visit(node.condition)
self._visit(node.condition)
# Body block
self.flow.nextblock()
self.visit(node.body)
self._visit(node.body)
self.flow.loops.pop()
# Loop it
if self.flow.block:
......@@ -899,7 +900,7 @@ class ControlFlowAnalysis(CythonTransform):
# Else clause
if node.else_clause:
self.flow.nextblock(parent=condition_block)
self.visit(node.else_clause)
self._visit(node.else_clause)
if self.flow.block:
self.flow.block.add_child(next_block)
else:
......@@ -967,7 +968,7 @@ class ControlFlowAnalysis(CythonTransform):
next_block = self.flow.newblock()
# Condition with iterator
self.flow.loops.append(LoopDescr(next_block, condition_block))
self.visit(node.iterator)
self._visit(node.iterator)
# Target assignment
self.flow.nextblock()
......@@ -982,7 +983,7 @@ class ControlFlowAnalysis(CythonTransform):
self._delete_privates(node, exclude=node.target.entry)
self.flow.nextblock()
self.visit(node.body)
self._visit(node.body)
self.flow.loops.pop()
# Loop it
......@@ -991,7 +992,7 @@ class ControlFlowAnalysis(CythonTransform):
# Else clause
if node.else_clause:
self.flow.nextblock(parent=condition_block)
self.visit(node.else_clause)
self._visit(node.else_clause)
if self.flow.block:
self.flow.block.add_child(next_block)
else:
......@@ -1042,10 +1043,10 @@ class ControlFlowAnalysis(CythonTransform):
next_block = self.flow.newblock()
# Condition with iterator
self.flow.loops.append(LoopDescr(next_block, condition_block))
self.visit(node.bound1)
self.visit(node.bound2)
self._visit(node.bound1)
self._visit(node.bound2)
if node.step is not None:
self.visit(node.step)
self._visit(node.step)
# Target assignment
self.flow.nextblock()
self.mark_assignment(node.target, node.bound1)
......@@ -1055,7 +1056,7 @@ class ControlFlowAnalysis(CythonTransform):
node.bound1, node.step))
# Body block
self.flow.nextblock()
self.visit(node.body)
self._visit(node.body)
self.flow.loops.pop()
# Loop it
if self.flow.block:
......@@ -1063,7 +1064,7 @@ class ControlFlowAnalysis(CythonTransform):
# Else clause
if node.else_clause:
self.flow.nextblock(parent=condition_block)
self.visit(node.else_clause)
self._visit(node.else_clause)
if self.flow.block:
self.flow.block.add_child(next_block)
else:
......@@ -1083,9 +1084,9 @@ class ControlFlowAnalysis(CythonTransform):
return node
def visit_WithStatNode(self, node):
self.visit(node.manager)
self.visit(node.enter_call)
self.visit(node.body)
self._visit(node.manager)
self._visit(node.enter_call)
self._visit(node.body)
return node
def visit_TryExceptStatNode(self, node):
......@@ -1100,14 +1101,14 @@ class ControlFlowAnalysis(CythonTransform):
## XXX: links to exception handling point should be added by
## XXX: children nodes
self.flow.block.add_child(entry_point)
self.visit(node.body)
self._visit(node.body)
self.flow.exceptions.pop()
# After exception
if self.flow.block:
if node.else_clause:
self.flow.nextblock()
self.visit(node.else_clause)
self._visit(node.else_clause)
if self.flow.block:
self.flow.block.add_child(next_block)
......@@ -1115,7 +1116,7 @@ class ControlFlowAnalysis(CythonTransform):
self.flow.block = entry_point
if clause.pattern:
for pattern in clause.pattern:
self.visit(pattern)
self._visit(pattern)
else:
# TODO: handle * pattern
pass
......@@ -1123,7 +1124,7 @@ class ControlFlowAnalysis(CythonTransform):
self.flow.nextblock()
if clause.target:
self.mark_assignment(clause.target)
self.visit(clause.body)
self._visit(clause.body)
if self.flow.block:
self.flow.block.add_child(next_block)
......@@ -1142,7 +1143,7 @@ class ControlFlowAnalysis(CythonTransform):
# Exception entry point
entry_point = self.flow.newblock()
self.flow.block = entry_point
self.visit(node.finally_clause)
self._visit(node.finally_clause)
if self.flow.block and self.flow.exceptions:
self.flow.block.add_child(self.flow.exceptions[-1].entry_point)
......@@ -1150,7 +1151,7 @@ class ControlFlowAnalysis(CythonTransform):
# Normal execution
finally_enter = self.flow.newblock()
self.flow.block = finally_enter
self.visit(node.finally_clause)
self._visit(node.finally_clause)
finally_exit = self.flow.block
descr = ExceptionDescr(entry_point, finally_enter, finally_exit)
......@@ -1160,7 +1161,7 @@ class ControlFlowAnalysis(CythonTransform):
self.flow.block = body_block
## XXX: Is it still required
body_block.add_child(entry_point)
self.visit(node.body)
self._visit(node.body)
self.flow.exceptions.pop()
if self.flow.loops:
self.flow.loops[-1].exceptions.pop()
......@@ -1243,8 +1244,8 @@ class ControlFlowAnalysis(CythonTransform):
self.env_stack.append(self.env)
self.env = node.expr_scope
# Skip append node here
self.visit(node.target)
self.visit(node.loop)
self._visit(node.target)
self._visit(node.loop)
if node.expr_scope:
self.env = self.env_stack.pop()
return node
......@@ -1259,14 +1260,14 @@ class ControlFlowAnalysis(CythonTransform):
return node
def visit_PyClassDefNode(self, node):
self.visitchildren(node, attrs=('dict', 'metaclass',
'mkw', 'bases', 'class_result'))
self.visitchildren(node, ('dict', 'metaclass',
'mkw', 'bases', 'class_result'))
self.flow.mark_assignment(node.target, object_expr_not_none,
self.env.lookup(node.name))
self.env_stack.append(self.env)
self.env = node.scope
self.flow.nextblock()
self.visitchildren(node, attrs=('body',))
self.visitchildren(node, ('body',))
self.flow.nextblock()
self.env = self.env_stack.pop()
return node
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment