init))
tempvardecl_code = code.insertion_point()
code.put_declare_refcount_context()
- if not self.is_generator_body:
- self.generate_keyword_list(code)
+ self.generate_keyword_list(code)
if profile:
code.put_trace_declarations()
# ----- Extern library function declarations
if is_getbuffer_slot:
self.getbuffer_init(code)
# ----- Create closure scope object
- if self.is_generator_body:
- code.putln("%s = (%s) %s;" % (
- Naming.cur_scope_cname,
- lenv.scope_class.type.declaration_code(''),
- Naming.self_cname))
- gotref_code = code.insertion_point()
-
- elif self.needs_closure:
+ if self.needs_closure:
code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
Naming.cur_scope_cname,
lenv.scope_class.type.declaration_code(''),
code.putln("}")
code.put_gotref(Naming.cur_scope_cname)
# Note that it is unsafe to decref the scope at this point.
- if self.needs_outer_scope and not self.is_generator_body:
+ if self.needs_outer_scope:
code.putln("%s = (%s)%s;" % (
outer_scope_cname,
cenv.scope_class.type.declaration_code(''),
code.put_trace_call(self.entry.name, self.pos)
# ----- Fetch arguments
self.generate_preamble(env, code)
- if self.is_generator_body:
- code.funcstate.init_closure_temps(lenv.scope_class.type.scope)
- resume_code = code.insertion_point()
- first_run_label = code.new_label('first_run')
- code.use_label(first_run_label)
- code.put_label(first_run_label)
- code.putln('%s' %
- (code.error_goto_if_null(Naming.sent_value_cname, self.pos)))
# -------------------------
# ----- Function body -----
# -------------------------
self.generate_function_body(env, code)
- if self.is_generator_body:
- code.putln('PyErr_SetNone(PyExc_StopIteration); %s' % code.error_goto(self.pos))
-
# ----- Default return value
code.putln("")
if self.return_type.is_pyobject:
if entry.type.is_pyobject:
if (acquire_gil or entry.assignments) and not entry.in_closure:
code.put_var_decref(entry)
- if self.needs_closure and not self.is_generator_body:
+ if self.needs_closure:
code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
- if self.is_generator_body:
- 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
if preprocessor_guard:
code.putln("#endif /*!(%s)*/" % preprocessor_guard)
+
# ----- Go back and insert temp variable declarations
tempvardecl_code.put_temp_declarations(code.funcstate)
- # ----- Generator resume code
- if self.is_generator_body:
- resume_code.putln("switch (%s->%s.resume_label) {" % (Naming.cur_scope_cname, Naming.obj_base_cname));
- resume_code.putln("case 0: goto %s;" % first_run_label)
- for yield_expr in self.yields:
- resume_code.putln("case %d: goto %s;" % (yield_expr.label_num, yield_expr.label_name));
- resume_code.putln("default: /* CPython raises the right error here */");
- resume_code.putln("return NULL;");
- resume_code.putln("}");
# ----- Python version
code.exit_cfunc_scope()
if self.py_func:
child_attrs = ['decorator']
-class GeneratorWrapperNode(object):
- # Wrapper
- def __init__(self, def_node, func_cname=None, body_cname=None, header=None):
- self.def_node = def_node
- self.func_cname = func_cname
- self.body_cname = body_cname
- self.header = header
-
- def generate_function_body(self, env, code):
- code.mark_pos(self.def_node.pos)
- cenv = env.outer_scope # XXX: correct?
- while cenv.is_py_class_scope or cenv.is_c_class_scope:
- cenv = cenv.outer_scope
- lenv = self.def_node.local_scope
- code.enter_cfunc_scope()
- code.putln()
- code.putln('%s {' % self.header)
- code.put_declare_refcount_context()
- self.def_node.generate_keyword_list(code)
- code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
- code.putln(";")
- code.put_setup_refcount_context(self.def_node.entry.name)
- code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
- Naming.cur_scope_cname,
- lenv.scope_class.type.declaration_code(''),
- lenv.scope_class.type.typeptr_cname,
- lenv.scope_class.type.typeptr_cname,
- Naming.empty_tuple))
- code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname)
- code.put_finish_refcount_context()
- code.putln("return NULL;");
- code.putln("}");
- code.put_gotref(Naming.cur_scope_cname)
-
- if self.def_node.needs_outer_scope:
- outer_scope_cname = '%s->%s' % (Naming.cur_scope_cname, Naming.outer_scope_cname)
- code.putln("%s = (%s)%s;" % (
- outer_scope_cname,
- cenv.scope_class.type.declaration_code(''),
- Naming.self_cname))
- code.put_incref(outer_scope_cname, cenv.scope_class.type)
- code.put_giveref(outer_scope_cname)
-
- self.def_node.generate_preamble(env, code)
-
- generator_cname = '%s->%s' % (Naming.cur_scope_cname, Naming.obj_base_cname)
-
- code.putln('%s.resume_label = 0;' % generator_cname)
- code.putln('%s.body = %s;' % (generator_cname, self.body_cname))
- code.put_giveref(Naming.cur_scope_cname)
- code.put_finish_refcount_context()
- code.putln("return (PyObject *) %s;" % Naming.cur_scope_cname);
- code.putln('}\n')
- code.exit_cfunc_scope()
-
class DefNode(FuncDefNode):
# A Python function definition.
#
Naming.pyfunc_prefix + prefix + name
entry.pymethdef_cname = \
Naming.pymethdef_prefix + prefix + name
-
- if self.is_generator_body:
- self.generator_body_cname = Naming.genbody_prefix + env.next_id(env.scope_prefix) + name
-
if Options.docstrings:
entry.doc = embed_position(self.pos, self.doc)
entry.doc_cname = \
"static PyMethodDef %s = " %
self.entry.pymethdef_cname)
code.put_pymethoddef(self.entry, ";", allow_skip=False)
- if self.is_generator_body:
- 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)
+ code.putln("%s {" % header)
def generate_argument_declarations(self, env, code):
for arg in self.args: