From: Vitja Makarov Date: Tue, 28 Dec 2010 18:50:58 +0000 (+0300) Subject: Merge remote branch 'upstream/master' X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=7f630812e3ac8fe8ba01531c8a958b90efc516d2;p=cython.git Merge remote branch 'upstream/master' Conflicts: Cython/Compiler/Nodes.py --- 7f630812e3ac8fe8ba01531c8a958b90efc516d2 diff --cc Cython/Compiler/Nodes.py index e441ec52,92c051ac..07cdfdbc --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@@ -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 @@@ -1519,38 -1513,6 +1519,39 @@@ self.py_func.generate_function_definitions(env, code) self.generate_wrapper_functions(code) + 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 entry.assignments and not entry.in_closure: ++ 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():