Merge remote branch 'upstream/master'
authorVitja Makarov <vitja.makarov@gmail.com>
Sun, 19 Dec 2010 07:17:35 +0000 (10:17 +0300)
committerVitja Makarov <vitja.makarov@gmail.com>
Sun, 19 Dec 2010 07:22:16 +0000 (10:22 +0300)
Conflicts:
Cython/Compiler/ExprNodes.py
Cython/Compiler/Nodes.py
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/Symtab.py

1  2 
Cython/Compiler/Code.py
Cython/Compiler/ExprNodes.py
Cython/Compiler/ModuleNode.py
Cython/Compiler/Nodes.py
Cython/Compiler/Optimize.py
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/Parsing.py
Cython/Compiler/Scanning.py
Cython/Compiler/Symtab.py
Cython/Compiler/TypeInference.py
runtests.py

Simple merge
index 4bcee405e16a363c4da7b763569e6ca9005c7229,2ecddeb4356a0ad7db0a02fb39c8b2097509477a..2a744a0fc4c5316aed7e93d3aea0ad052fbb47cd
@@@ -492,13 -486,13 +492,13 @@@ class ExprNode(Node)
      def generate_subexpr_evaluation_code(self, code):
          for node in self.subexpr_nodes():
              node.generate_evaluation_code(code)
-     
      def generate_result_code(self, code):
          self.not_implemented("generate_result_code")
-     
      def generate_disposal_code(self, code):
          if self.is_temp:
 -            if self.type.is_pyobject:
 +            if self.type.is_pyobject and self.result():
                  code.put_decref_clear(self.result(), self.ctype())
          else:
              # Already done if self.is_temp
Simple merge
index 5ab4e598a39570e45885dd470f6a61f5f1ef6030,ff130a487d178785f7fd4e0acf850434eb58ae1f..c09a7d47b9c3fd316d7224407bd6c201cc847c67
@@@ -1166,9 -1166,8 +1166,9 @@@ class FuncDefNode(StatNode, BlockNode)
      assmt = None
      needs_closure = False
      needs_outer_scope = False
 +    is_generator = False
      modifiers = []
-     
      def analyse_default_values(self, env):
          genv = env.global_scope()
          default_seen = 0
              self.py_func.generate_function_definitions(env, code)
          self.generate_wrapper_functions(code)
  
-         # If an argument is assigned to in the body, we must 
 +        if self.is_generator:
 +            self.generator.generate_function_body(self.local_scope, code)
 +
 +    def generate_preamble(self, env, code):
 +        """Parse arguments and prepare scope"""
 +        import Buffer
 +
 +        lenv = self.local_scope
 +
 +        self.generate_argument_parsing_code(env, code)
-         # ----- Initialise local variables 
++        # If an argument is assigned to in the body, we must
 +        # incref it to properly keep track of refcounts.
 +        for entry in lenv.arg_entries:
 +            if entry.type.is_pyobject:
 +                if entry.assignments and not entry.in_closure:
 +                    code.put_var_incref(entry)
++        # ----- Initialise local variables
 +        for entry in lenv.var_entries:
 +            if entry.type.is_pyobject and entry.init_to_none and entry.used:
 +                code.put_init_var_to_py_none(entry)
 +        # ----- Initialise local buffer auxiliary variables
 +        for entry in lenv.var_entries + lenv.arg_entries:
 +            if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
 +                code.putln("%s.buf = NULL;" %
 +                           entry.buffer_aux.buffer_info_var.cname)
 +        # ----- Check and convert arguments
 +        self.generate_argument_type_tests(code)
 +        # ----- Acquire buffer arguments
 +        for entry in lenv.arg_entries:
 +            if entry.type.is_buffer:
 +                Buffer.put_acquire_arg_buffer(entry, code, self.pos)
 +
      def declare_argument(self, env, arg):
          if arg.type.is_void:
              error(arg.pos, "Invalid use of 'void'")
@@@ -2397,18 -2300,10 +2397,18 @@@ class DefNode(FuncDefNode)
                      "struct wrapperbase %s;" % self.entry.wrapperbase_cname)
          if with_pymethdef:
              code.put(
-                 "static PyMethodDef %s = " % 
+                 "static PyMethodDef %s = " %
                      self.entry.pymethdef_cname)
              code.put_pymethoddef(self.entry, ";", allow_skip=False)
 -        code.putln("%s {" % header)
 +        if self.is_generator:
 +            code.putln("static PyObject *%s(PyObject *%s, PyObject *%s) /* generator body */\n{" %
 +                       (self.generator_body_cname, Naming.self_cname, Naming.sent_value_cname))
 +            self.generator = GeneratorWrapperNode(self,
 +                                                  func_cname=self.entry.func_cname,
 +                                                  body_cname=self.generator_body_cname,
 +                                                  header=header)
 +        else:
 +            code.putln("%s {" % header)
  
      def generate_argument_declarations(self, env, code):
          for arg in self.args:
                      code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
              else:
                  error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
-     
      def generate_arg_xdecref(self, arg, code):
          if arg:
 -            code.put_var_xdecref(arg.entry)
 +            code.put_var_xdecref_clear(arg.entry)
-     
      def generate_arg_decref(self, arg, code):
          if arg:
 -            code.put_var_decref(arg.entry)
 +            code.put_var_decref_clear(arg.entry)
  
      def generate_stararg_copy_code(self, code):
          if not self.star_arg:
@@@ -3474,11 -3342,10 +3474,11 @@@ class ExprStatNode(StatNode)
                      else:
                          env.declare_var(var.value, type, var.pos, is_cdef = True)
                  self.__class__ = PassStatNode
-     
      def analyse_expressions(self, env):
 +        self.expr.result_is_used = False # hint that .result() may safely be left empty
          self.expr.analyse_expressions(env)
-     
      def generate_execution_code(self, code):
          self.expr.generate_evaluation_code(code)
          if not self.expr.is_temp and self.expr.result():
Simple merge
Simple merge
Simple merge
index 34b2d0d0ede410662e22e0e11538460b0cca5f74,c868349903cd79836129386050ed4feb50fad005..036c597e84d3348a260fc1b868a51fe00d14236a
@@@ -1272,16 -1298,6 +1298,16 @@@ class LocalScope(Scope)
              entry = self.global_scope().lookup_target(name)
              self.entries[name] = entry
  
-         
 +    def declare_nonlocal(self, name, pos):
 +        # Pull entry from outer scope into local scope
 +        orig_entry = self.lookup_here(name)
 +        if orig_entry and orig_entry.scope is self and not orig_entry.from_closure:
 +            error(pos, "'%s' redeclared as nonlocal" % name)
 +        else:
 +            entry = self.lookup(name)
 +            if entry is None or not entry.from_closure:
 +                error(pos, "no binding for nonlocal '%s' found" % name)
++
      def lookup(self, name):
          # Look up name in this scope or an enclosing one.
          # Return None if not found.
Simple merge
diff --cc runtests.py
Simple merge