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