Commit 01f08e83 authored by Vitja Makarov's avatar Vitja Makarov

Remove generators hack

parent 0ede0ca5
...@@ -1301,7 +1301,6 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1301,7 +1301,6 @@ class FuncDefNode(StatNode, BlockNode):
init)) init))
tempvardecl_code = code.insertion_point() tempvardecl_code = code.insertion_point()
code.put_declare_refcount_context() code.put_declare_refcount_context()
if not self.is_generator_body:
self.generate_keyword_list(code) self.generate_keyword_list(code)
if profile: if profile:
code.put_trace_declarations() code.put_trace_declarations()
...@@ -1321,14 +1320,7 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1321,14 +1320,7 @@ class FuncDefNode(StatNode, BlockNode):
if is_getbuffer_slot: if is_getbuffer_slot:
self.getbuffer_init(code) self.getbuffer_init(code)
# ----- Create closure scope object # ----- Create closure scope object
if self.is_generator_body: if self.needs_closure:
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:
code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % ( code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
Naming.cur_scope_cname, Naming.cur_scope_cname,
lenv.scope_class.type.declaration_code(''), lenv.scope_class.type.declaration_code(''),
...@@ -1345,7 +1337,7 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1345,7 +1337,7 @@ class FuncDefNode(StatNode, BlockNode):
code.putln("}") code.putln("}")
code.put_gotref(Naming.cur_scope_cname) code.put_gotref(Naming.cur_scope_cname)
# Note that it is unsafe to decref the scope at this point. # 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;" % ( code.putln("%s = (%s)%s;" % (
outer_scope_cname, outer_scope_cname,
cenv.scope_class.type.declaration_code(''), cenv.scope_class.type.declaration_code(''),
...@@ -1363,22 +1355,11 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1363,22 +1355,11 @@ class FuncDefNode(StatNode, BlockNode):
code.put_trace_call(self.entry.name, self.pos) code.put_trace_call(self.entry.name, self.pos)
# ----- Fetch arguments # ----- Fetch arguments
self.generate_preamble(env, code) 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 ----- # ----- Function body -----
# ------------------------- # -------------------------
self.generate_function_body(env, code) 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 # ----- Default return value
code.putln("") code.putln("")
if self.return_type.is_pyobject: if self.return_type.is_pyobject:
...@@ -1464,10 +1445,8 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1464,10 +1445,8 @@ class FuncDefNode(StatNode, BlockNode):
if entry.type.is_pyobject: if entry.type.is_pyobject:
if (acquire_gil or entry.assignments) and not entry.in_closure: if (acquire_gil or entry.assignments) and not entry.in_closure:
code.put_var_decref(entry) 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) 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 # ----- Return
# This code is duplicated in ModuleNode.generate_module_init_func # This code is duplicated in ModuleNode.generate_module_init_func
...@@ -1505,17 +1484,9 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1505,17 +1484,9 @@ class FuncDefNode(StatNode, BlockNode):
if preprocessor_guard: if preprocessor_guard:
code.putln("#endif /*!(%s)*/" % preprocessor_guard) code.putln("#endif /*!(%s)*/" % preprocessor_guard)
# ----- Go back and insert temp variable declarations # ----- Go back and insert temp variable declarations
tempvardecl_code.put_temp_declarations(code.funcstate) 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 # ----- Python version
code.exit_cfunc_scope() code.exit_cfunc_scope()
if self.py_func: if self.py_func:
...@@ -1902,61 +1873,6 @@ class DecoratorNode(Node): ...@@ -1902,61 +1873,6 @@ class DecoratorNode(Node):
child_attrs = ['decorator'] 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): class DefNode(FuncDefNode):
# A Python function definition. # A Python function definition.
# #
...@@ -2250,10 +2166,6 @@ class DefNode(FuncDefNode): ...@@ -2250,10 +2166,6 @@ class DefNode(FuncDefNode):
Naming.pyfunc_prefix + prefix + name Naming.pyfunc_prefix + prefix + name
entry.pymethdef_cname = \ entry.pymethdef_cname = \
Naming.pymethdef_prefix + prefix + name 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: if Options.docstrings:
entry.doc = embed_position(self.pos, self.doc) entry.doc = embed_position(self.pos, self.doc)
entry.doc_cname = \ entry.doc_cname = \
...@@ -2401,14 +2313,6 @@ class DefNode(FuncDefNode): ...@@ -2401,14 +2313,6 @@ class DefNode(FuncDefNode):
"static PyMethodDef %s = " % "static PyMethodDef %s = " %
self.entry.pymethdef_cname) self.entry.pymethdef_cname)
code.put_pymethoddef(self.entry, ";", allow_skip=False) 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): def generate_argument_declarations(self, env, code):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment