Introduced code.globalstate and renamed code.func to code.funcstate
authorDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Fri, 1 Aug 2008 09:51:00 +0000 (11:51 +0200)
committerDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Fri, 1 Aug 2008 09:51:00 +0000 (11:51 +0200)
global is a reserved word...

Cython/Compiler/Buffer.py
Cython/Compiler/Code.py
Cython/Compiler/ExprNodes.py
Cython/Compiler/ModuleNode.py
Cython/Compiler/Nodes.py

index 3e8f5ac454e0ed00f6a30e6ddc218111a91c3eba..894494cc884f319051304234b8c5363ee5b4b90b 100644 (file)
@@ -209,7 +209,7 @@ def put_assign_to_buffer(lhs_cname, rhs_cname, buffer_aux, buffer_type,
             lhs_cname, bufstruct))
         code.end_block()
         # Acquire
-        retcode_cname = code.func.allocate_temp(PyrexTypes.c_int_type)
+        retcode_cname = code.funcstate.allocate_temp(PyrexTypes.c_int_type)
         code.putln("%s = %s;" % (retcode_cname, getbuffer % rhs_cname))
         code.putln('if (%s) ' % (code.unlikely("%s < 0" % retcode_cname)))
         # If acquisition failed, attempt to reacquire the old buffer
@@ -217,7 +217,7 @@ def put_assign_to_buffer(lhs_cname, rhs_cname, buffer_aux, buffer_type,
         # will cause the reacquisition exception to be reported, one
         # can consider working around this later.
         code.begin_block()
-        type, value, tb = [code.func.allocate_temp(PyrexTypes.py_object_type)
+        type, value, tb = [code.funcstate.allocate_temp(PyrexTypes.py_object_type)
                            for i in range(3)]
         code.putln('PyErr_Fetch(&%s, &%s, &%s);' % (type, value, tb))
         code.put('if (%s) ' % code.unlikely("%s == -1" % (getbuffer % lhs_cname)))
@@ -227,13 +227,13 @@ def put_assign_to_buffer(lhs_cname, rhs_cname, buffer_aux, buffer_type,
         code.putln('} else {')
         code.putln('PyErr_Restore(%s, %s, %s);' % (type, value, tb))
         for t in (type, value, tb):
-            code.func.release_temp(t)
+            code.funcstate.release_temp(t)
         code.end_block()
         # Unpack indices
         code.end_block()
         put_unpack_buffer_aux_into_scope(buffer_aux, buffer_type.mode, code)
         code.putln(code.error_goto_if_neg(retcode_cname, pos))
-        code.func.release_temp(retcode_cname)
+        code.funcstate.release_temp(retcode_cname)
     else:
         # Our entry had no previous value, so set to None when acquisition fails.
         # In this case, auxiliary vars should be set up right in initialization to a zero-buffer,
@@ -261,7 +261,7 @@ def put_access(entry, index_signeds, index_cnames, pos, code):
     # Check bounds and fix negative indices
     boundscheck = True
     nonegs = True
-    tmp_cname = code.func.allocate_temp(PyrexTypes.c_int_type)
+    tmp_cname = code.funcstate.allocate_temp(PyrexTypes.c_int_type)
     if boundscheck:
         code.putln("%s = -1;" % tmp_cname)
     for idx, (signed, cname, shape) in enumerate(zip(index_signeds, index_cnames,
@@ -288,7 +288,7 @@ def put_access(entry, index_signeds, index_cnames, pos, code):
         code.putln('__Pyx_BufferIndexError(%s);' % tmp_cname)
         code.putln(code.error_goto(pos))
         code.end_block()
-    code.func.release_temp(tmp_cname)
+    code.funcstate.release_temp(tmp_cname)
 
     # Create buffer lookup and return it
     params = []
index 79aa5c2e579f18e37147d67f13e1b33087729d76..f5088e842b591d9d137214e7c95abb23040e3b30 100644 (file)
@@ -12,7 +12,16 @@ from Scanning import SourceDescriptor
 from Cython.StringIOTree import StringIOTree
 from sets import Set as set
 
-class FunctionContext(object):
+class FunctionState(object):
+    # return_label     string          function return point label
+    # error_label      string          error catch point label
+    # continue_label   string          loop continue point label
+    # break_label      string          loop break point label
+    # return_from_error_cleanup_label string
+    # label_counter    integer         counter for naming labels
+    # in_try_finally   boolean         inside try of try...finally
+    # exc_vars         (string * 3)    exception variables for reraise, or None
+
     # Not used for now, perhaps later
     def __init__(self, names_taken=set()):
         self.names_taken = names_taken
@@ -25,6 +34,9 @@ class FunctionContext(object):
         self.continue_label = None
         self.break_label = None
 
+        self.in_try_finally = 0
+        self.exc_vars = None
+
         self.temps_allocated = [] # of (name, type)
         self.temps_free = {} # type -> list of free vars
         self.temps_used_type = {} # name -> type
@@ -118,11 +130,44 @@ class FunctionContext(object):
             self.temps_free[type] = freelist
         freelist.append(name)
 
+class GlobalState(object):
+    # filename_table   {string : int}  for finding filename table indexes
+    # filename_list    [string]        filenames in filename table order
+    # input_file_contents dict         contents (=list of lines) of any file that was used as input
+    #                                  to create this output C code.  This is
+    #                                  used to annotate the comments.
+
+    def __init__(self):
+        self.filename_table = {}
+        self.filename_list = []
+        self.input_file_contents = {}
+
+    def lookup_filename(self, filename):
+        try:
+            index = self.filename_table[filename]
+        except KeyError:
+            index = len(self.filename_list)
+            self.filename_list.append(filename)
+            self.filename_table[filename] = index
+        return index
+
+    def commented_file_contents(self, source_desc):
+        try:
+            return self.input_file_contents[source_desc]
+        except KeyError:
+            F = [u' * ' + line.rstrip().replace(
+                    u'*/', u'*[inserted by cython to avoid comment closer]/'
+                    ).encode('ASCII', 'replace') # + Py2 auto-decode to unicode
+                 for line in source_desc.get_lines()]
+            self.input_file_contents[source_desc] = F
+            return F
+
+
 def funccontext_property(name):
     def get(self):
-        return getattr(self.func, name)
+        return getattr(self.funcstate, name)
     def set(self, value):
-        setattr(self.func, name, value)
+        setattr(self.funcstate, name, value)
     return property(get, set)
 
 class CCodeWriter(object):
@@ -148,47 +193,29 @@ class CCodeWriter(object):
     # level            int             indentation level
     # bol              bool            beginning of line?
     # marker           string          comment to emit before next line
-    # return_label     string          function return point label
-    # error_label      string          error catch point label
-    # continue_label   string          loop continue point label
-    # break_label      string          loop break point label
-    # return_from_error_cleanup_label string
-    # label_counter    integer         counter for naming labels
-    # in_try_finally   boolean         inside try of try...finally
-    # filename_table   {string : int}  for finding filename table indexes
-    # filename_list    [string]        filenames in filename table order
-    # exc_vars         (string * 3)    exception variables for reraise, or None
-    # input_file_contents dict         contents (=list of lines) of any file that was used as input
-    #                                  to create this output C code.  This is
-    #                                  used to annotate the comments.
-    # func             FunctionContext contains labels and temps context info
+    # funcstate        FunctionState   contains state local to a C function used for code
+    #                                  generation (labels and temps state etc.)
+    # globalstate      GlobalState     contains state global for a C file (input file info,
+    #                                  utility code, declared constants etc.)
    
-    in_try_finally = 0
-    
     def __init__(self, create_from=None, buffer=None):
         if buffer is None: buffer = StringIOTree()
         self.buffer = buffer
         self.marker = None
         self.last_marker_line = 0
-        self.func = None
+        
+        self.funcstate = None # always start with no function state
         if create_from is None:
             # Root CCodeWriter
             self.level = 0
             self.bol = 1
-            self.filename_table = {}
-            self.filename_list = []
-            self.exc_vars = None
-            self.input_file_contents = {}
+            self.globalstate = GlobalState()
         else:
+            # Use same global state
+            self.globalstate = create_from.globalstate
             # Clone formatting state
-            c = create_from
-            self.level = c.level
-            self.bol = c.bol
-            # Note: NOT copying but sharing instance
-            self.filename_table = c.filename_table
-            self.filename_list = []
-            self.input_file_contents = c.input_file_contents
-            # Leave other state alone
+            self.level = create_from.level
+            self.bol = create_from.bol
 
     def create_new(self, create_from, buffer):
         # polymorphic constructor -- very slightly more versatile
@@ -216,26 +243,26 @@ class CCodeWriter(object):
     labels_used = funccontext_property("labels_used")
     continue_label = funccontext_property("continue_label")
     break_label = funccontext_property("break_label")
-
+    return_from_error_cleanup_label = funccontext_property("return_from_error_cleanup_label")
 
     # Functions delegated to function scope
-    def new_label(self):               return self.func.new_label()
-    def new_error_label(self):         return self.func.new_error_label()
-    def get_loop_labels(self):         return self.func.get_loop_labels()
-    def set_loop_labels(self, labels): return self.func.set_loop_labels(labels)
-    def new_loop_labels(self):         return self.func.new_loop_labels()
-    def get_all_labels(self):          return self.func.get_all_labels()
-    def set_all_labels(self, labels):  return self.func.set_all_labels(labels)
-    def all_new_labels(self):          return self.func.all_new_labels()
-    def use_label(self, lbl):          return self.func.use_label(lbl)
-    def label_used(self, lbl):         return self.func.label_used(lbl)
+    def new_label(self):               return self.funcstate.new_label()
+    def new_error_label(self):         return self.funcstate.new_error_label()
+    def get_loop_labels(self):         return self.funcstate.get_loop_labels()
+    def set_loop_labels(self, labels): return self.funcstate.set_loop_labels(labels)
+    def new_loop_labels(self):         return self.funcstate.new_loop_labels()
+    def get_all_labels(self):          return self.funcstate.get_all_labels()
+    def set_all_labels(self, labels):  return self.funcstate.set_all_labels(labels)
+    def all_new_labels(self):          return self.funcstate.all_new_labels()
+    def use_label(self, lbl):          return self.funcstate.use_label(lbl)
+    def label_used(self, lbl):         return self.funcstate.label_used(lbl)
 
 
     def enter_cfunc_scope(self):
-        self.func = FunctionContext()
+        self.funcstate = FunctionState()
     
     def exit_cfunc_scope(self):
-        self.func = None
+        self.funcstate = None
 
     def putln(self, code = ""):
         if self.marker and self.bol:
@@ -287,17 +314,6 @@ class CCodeWriter(object):
     def get_py_version_hex(self, pyversion):
         return "0x%02X%02X%02X%02X" % (tuple(pyversion) + (0,0,0,0))[:4]
 
-    def commented_file_contents(self, source_desc):
-        try:
-            return self.input_file_contents[source_desc]
-        except KeyError:
-            F = [u' * ' + line.rstrip().replace(
-                    u'*/', u'*[inserted by cython to avoid comment closer]/'
-                    ).encode('ASCII', 'replace') # + Py2 auto-decode to unicode
-                 for line in source_desc.get_lines()]
-            self.input_file_contents[source_desc] = F
-            return F
-
     def mark_pos(self, pos):
         if pos is None:
             return
@@ -305,7 +321,7 @@ class CCodeWriter(object):
         if self.last_marker_line == line:
             return
         assert isinstance(source_desc, SourceDescriptor)
-        contents = self.commented_file_contents(source_desc)
+        contents = self.globalstate.commented_file_contents(source_desc)
 
         lines = contents[max(0,line-3):line] # line numbers start at 1
         lines[-1] += u'             # <<<<<<<<<<<<<<'
@@ -317,11 +333,11 @@ class CCodeWriter(object):
 
         
     def put_label(self, lbl):
-        if lbl in self.func.labels_used:
+        if lbl in self.funcstate.labels_used:
             self.putln("%s:;" % lbl)
     
     def put_goto(self, lbl):
-        self.func.use_label(lbl)
+        self.funcstate.use_label(lbl)
         self.putln("goto %s;" % lbl)
     
     def put_var_declarations(self, entries, static = 0, dll_linkage = None,
@@ -481,8 +497,8 @@ class CCodeWriter(object):
             return cond
         
     def error_goto(self, pos):
-        lbl = self.func.error_label
-        self.func.use_label(lbl)
+        lbl = self.funcstate.error_label
+        self.funcstate.use_label(lbl)
         if Options.c_line_in_traceback:
             cinfo = " %s = %s;" % (Naming.clineno_cname, Naming.line_c_macro)
         else:
@@ -509,13 +525,7 @@ class CCodeWriter(object):
         return self.error_goto_if("PyErr_Occurred()", pos)
     
     def lookup_filename(self, filename):
-        try:
-            index = self.filename_table[filename]
-        except KeyError:
-            index = len(self.filename_list)
-            self.filename_list.append(filename)
-            self.filename_table[filename] = index
-        return index
+        return self.globalstate.lookup_filename(filename)
 
 
 class PyrexCodeWriter:
index 699200d1faf708d6991ae0f1c92674f6b69fca3b..6fb5744d7598c7e9734e17739f03eda2bf39d8ba 100644 (file)
@@ -1065,7 +1065,7 @@ class NameNode(AtomicExprNode):
             rhs.generate_post_assignment_code(code)
 
     def generate_acquire_buffer(self, rhs, code):
-        rhstmp = code.func.allocate_temp(self.entry.type)
+        rhstmp = code.funcstate.allocate_temp(self.entry.type)
         buffer_aux = self.entry.buffer_aux
         bufstruct = buffer_aux.buffer_info_var.cname
         code.putln('%s = %s;' % (rhstmp, rhs.result_as(self.ctype())))
@@ -1075,7 +1075,7 @@ class NameNode(AtomicExprNode):
                                     is_initialized=not self.skip_assignment_decref,
                                     pos=self.pos, code=code)
         code.putln("%s = 0;" % rhstmp)
-        code.func.release_temp(rhstmp)
+        code.funcstate.release_temp(rhstmp)
     
     def generate_deletion_code(self, code):
         if self.entry is None:
@@ -1520,7 +1520,7 @@ class IndexNode(ExprNode):
 
     def buffer_access_code(self, code):
         # Assign indices to temps
-        index_temps = [code.func.allocate_temp(i.type) for i in self.indices]
+        index_temps = [code.funcstate.allocate_temp(i.type) for i in self.indices]
         for temp, index in zip(index_temps, self.indices):
             code.putln("%s = %s;" % (temp, index.result_code))
         # Generate buffer access code using these temps
index 26b778e3199f3ca9c7e2824953023a17d1e706ef..7c1b950c220cc984d954f45cced4336b9f782815 100644 (file)
@@ -529,8 +529,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
     def generate_filename_table(self, code):
         code.putln("")
         code.putln("static const char *%s[] = {" % Naming.filenames_cname)
-        if code.filename_list:
-            for source_desc in code.filename_list:
+        if code.globalstate.filename_list:
+            for source_desc in code.globalstate.filename_list:
                 filename = os.path.basename(source_desc.get_filenametable_entry())
                 escaped_filename = filename.replace("\\", "\\\\").replace('"', r'\"')
                 code.putln('"%s",' % 
@@ -1610,7 +1610,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         code.putln('}')
         
         tempdecl_code.put_var_declarations(env.temp_entries)
-        tempdecl_code.put_temp_declarations(code.func)
+        tempdecl_code.put_temp_declarations(code.funcstate)
 
         code.exit_cfunc_scope()
 
index 9911ae4bf67e0675d48cef0202059f3c87f5bfc8..861516431513aa5e07f6dd9ea990e7ed75da9228 100644 (file)
@@ -969,7 +969,7 @@ class FuncDefNode(StatNode, BlockNode):
         code.putln("}")
         # ----- Go back and insert temp variable declarations
         tempvardecl_code.put_var_declarations(lenv.temp_entries)
-        tempvardecl_code.put_temp_declarations(code.func)
+        tempvardecl_code.put_temp_declarations(code.funcstate)
         # ----- Python version
         code.exit_cfunc_scope()
         if self.py_func:
@@ -2634,7 +2634,7 @@ class ContinueStatNode(StatNode):
         pass
     
     def generate_execution_code(self, code):
-        if code.in_try_finally:
+        if code.funcstate.in_try_finally:
             error(self.pos, "continue statement inside try of try...finally")
         elif not code.continue_label:
             error(self.pos, "continue statement not inside loop")
@@ -2797,7 +2797,7 @@ class ReraiseStatNode(StatNode):
     gil_message = "Raising exception"
 
     def generate_execution_code(self, code):
-        vars = code.exc_vars
+        vars = code.funcstate.exc_vars
         if vars:
             code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
             code.putln(code.error_goto(self.pos))
@@ -3478,10 +3478,10 @@ class ExceptClauseNode(Node):
             self.excinfo_tuple.generate_evaluation_code(code)
             self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
 
-        old_exc_vars = code.exc_vars
-        code.exc_vars = self.exc_vars
+        old_exc_vars = code.funcstate.exc_vars
+        code.funcstate.exc_vars = self.exc_vars
         self.body.generate_execution_code(code)
-        code.exc_vars = old_exc_vars
+        code.funcstate.exc_vars = old_exc_vars
         for var in self.exc_vars:
             code.putln("Py_DECREF(%s); %s = 0;" % (var, var))
         code.put_goto(end_label)
@@ -3556,11 +3556,11 @@ class TryFinallyStatNode(StatNode):
         code.putln(
             "/*try:*/ {")
         if self.disallow_continue_in_try_finally:
-            was_in_try_finally = code.in_try_finally
-            code.in_try_finally = 1
+            was_in_try_finally = code.funcstate.in_try_finally
+            code.funcstate.in_try_finally = 1
         self.body.generate_execution_code(code)
         if self.disallow_continue_in_try_finally:
-            code.in_try_finally = was_in_try_finally
+            code.funcstate.in_try_finally = was_in_try_finally
         code.putln(
             "}")
         code.putln(