# 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'")
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():