ClassNode to new temps
authorDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Sat, 28 Mar 2009 11:38:21 +0000 (12:38 +0100)
committerDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Sat, 28 Mar 2009 11:38:21 +0000 (12:38 +0100)
Cython/Compiler/Code.py
Cython/Compiler/ExprNodes.py
Cython/Compiler/Nodes.py

index 7e5350d4bf398348011c483a6866e25f97743191..195548396df598bd65d674f1e1e91b2df4421e38 100644 (file)
@@ -687,14 +687,18 @@ class CCodeWriter(object):
     #                                  generation (labels and temps state etc.)
     # globalstate      GlobalState     contains state global for a C file (input file info,
     #                                  utility code, declared constants etc.)
-    # emit_linenums    boolean         whether or not to write #line pragmas 
-    
+    # emit_linenums    boolean         whether or not to write #line pragmas
+    #
+    # pyclass_stack    list            used during recursive code generation to pass information
+    #                                  about the current class one is in
+
     def __init__(self, create_from=None, buffer=None, copy_formatting=False, emit_linenums=None):
         if buffer is None: buffer = StringIOTree()
         self.buffer = buffer
         self.marker = None
         self.last_marker_line = 0
         self.source_desc = ""
+        self.pyclass_stack = []
         
         self.funcstate = None
         self.level = 0
index 3b09f6fa0ef505ed42b0a0bd91f2df5a7f194dcb..de29d53fdbcc18613ec4000caec02f0ce2480355 100644 (file)
@@ -3567,7 +3567,7 @@ class DictItemNode(ExprNode):
         return iter([self.key, self.value])
 
 
-class ClassNode(ExprNode):
+class ClassNode(NewTempExprNode):
     #  Helper class used in the implementation of Python
     #  class definitions. Constructs a class object given
     #  a name, tuple of bases and class dictionary.
@@ -3615,7 +3615,6 @@ class UnboundMethodNode(NewTempExprNode):
     #  class definitions. Constructs an unbound method
     #  object from a class and a function.
     #
-    #  class_cname   string     C var holding the class object
     #  function      ExprNode   Function object
     
     subexprs = ['function']
@@ -3628,11 +3627,12 @@ class UnboundMethodNode(NewTempExprNode):
     gil_message = "Constructing an unbound method"
 
     def generate_result_code(self, code):
+        class_cname = code.pyclass_stack[-1].classobj.result()
         code.putln(
             "%s = PyMethod_New(%s, 0, %s); %s" % (
                 self.result(),
                 self.function.py_result(),
-                self.class_cname,
+                class_cname,
                 code.error_goto_if_null(self.result(), self.pos)))
         code.put_gotref(self.py_result())
 
index fef637dcf3b485416609a0224af23362bfebb15f..0f00ac4dc0932719e00a8bc8ce591a9fce7e35e9 100644 (file)
@@ -1781,13 +1781,12 @@ class DefNode(FuncDefNode):
         self.analyse_default_values(env)
         if env.is_py_class_scope:
             self.synthesize_assignment_node(env)
-    
+
     def synthesize_assignment_node(self, env):
         import ExprNodes
         self.assmt = SingleAssignmentNode(self.pos,
             lhs = ExprNodes.NameNode(self.pos, name = self.name),
             rhs = ExprNodes.UnboundMethodNode(self.pos, 
-                class_cname = env.class_obj_cname,
                 function = ExprNodes.PyCFunctionNode(self.pos,
                     pymethdef_cname = self.entry.pymethdef_cname)))
         self.assmt.analyse_declarations(env)
@@ -2530,8 +2529,7 @@ class PyClassDefNode(ClassDefNode):
         self.classobj.analyse_expressions(env)
         genv = env.global_scope()
         cenv = self.scope
-        cenv.class_dict_cname = self.dict.result()
-        cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
+        cenv.class_dict_cname = self.dict.result() # TODO newtemps -- move to code generation
         self.body.analyse_expressions(cenv)
         self.target.analyse_target_expression(env, self.classobj)
         self.dict.release_temp(env)
@@ -2542,12 +2540,16 @@ class PyClassDefNode(ClassDefNode):
         self.body.generate_function_definitions(self.scope, code)
     
     def generate_execution_code(self, code):
+        code.pyclass_stack.append(self)
+        cenv = self.scope
         self.dict.generate_evaluation_code(code)
         self.classobj.generate_evaluation_code(code)
+        cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
         self.body.generate_execution_code(code)
         self.target.generate_assignment_code(self.classobj, code)
         self.dict.generate_disposal_code(code)
         self.dict.free_temps(code)
+        code.pyclass_stack.pop()
 
 
 class CClassDefNode(ClassDefNode):