Merge remote branch 'upstream/master'
authorVitja Makarov <vitja.makarov@gmail.com>
Tue, 28 Dec 2010 18:50:58 +0000 (21:50 +0300)
committerVitja Makarov <vitja.makarov@gmail.com>
Tue, 28 Dec 2010 18:51:39 +0000 (21:51 +0300)
Conflicts:
Cython/Compiler/Nodes.py

1  2 
Cython/Compiler/ExprNodes.py
Cython/Compiler/Nodes.py

Simple merge
index e441ec52df7ec5d085a47be1981213eae7224ec0,92c051acf7fc422f2b0813b302f0f3d427399904..07cdfdbccbb30cab7e6f9aa531faf20591e4ede3
@@@ -1459,12 -1459,14 +1459,12 @@@ class FuncDefNode(StatNode, BlockNode)
          # Decref any increfed args
          for entry in lenv.arg_entries:
              if entry.type.is_pyobject:
-                 if entry.assignments and not entry.in_closure:
 -                if entry.in_closure:
 -                    code.put_var_giveref(entry)
 -                elif acquire_gil or entry.assignments:
++                if (acquire_gil or entry.assignments) and not entry.in_closure:
                      code.put_var_decref(entry)
 -        if self.needs_closure:
 +        if self.needs_closure and not self.is_generator:
              code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
 +        if self.is_generator:
 +            code.putln('%s->%s.resume_label = -1;' % (Naming.cur_scope_cname, Naming.obj_base_cname))
  
          # ----- Return
          # This code is duplicated in ModuleNode.generate_module_init_func
              self.py_func.generate_function_definitions(env, code)
          self.generate_wrapper_functions(code)
  
-                 if entry.assignments and not entry.in_closure:
 +        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
++        acquire_gil = self.acquire_gil
 +
 +        self.generate_argument_parsing_code(env, code)
 +        # 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 (acquire_gil or 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'")
@@@ -3476,9 -3344,14 +3477,15 @@@ class ExprStatNode(StatNode)
                  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 nogil_check(self, env):
+         if self.expr.type.is_pyobject and self.expr.is_temp:
+             self.gil_error()
+     gil_message = "Discarding owned Python object"
      def generate_execution_code(self, code):
          self.expr.generate_evaluation_code(code)
          if not self.expr.is_temp and self.expr.result():