def transfer_to_runnerfunc(self, args, vararg, kwonlyargs, kwarg): ## PyObject **tmp = calloc(sizeof(PyObject*), <len(args)> + 2) #0: set to the function object #1: set to the generator object itself #2: used as a slot to communicate a yielded value #3+: args in canonical order argsname = self.v.scope.ctx.reserve_name('gen_argslist', self.v.tu) decl = c.Decl(argsname, c.PtrDecl(PyObjectLL.typedecl()), init=c.ID('NULL')) self.v.scope.ctx.add_variable(decl, False) self.v.ctx.add(c.Assignment('=', c.ID(argsname), c.FuncCall(c.ID('calloc'), c.ExprList(c.Constant('integer', self.N_EXTRA_PARAMS + len(self.stub_arg_insts)), c.FuncCall(c.ID('sizeof'), c.ExprList(PyObjectLL.typedecl())))))) self.fail_if_null(argsname) self.v.ctx.add(c.Assignment('=', c.ArrayRef(c.ID(argsname), c.Constant('integer', self.SELF_INDEX)), c.ID('self'))) self.v.ctx.add(c.Assignment('=', c.ArrayRef(c.ID(argsname), c.Constant('integer', self.GENERATOR_INDEX)), c.ID('NULL'))) self.v.ctx.add(c.Assignment('=', c.ArrayRef(c.ID(argsname), c.Constant('integer', self.RETURN_INDEX)), c.ID('NULL'))) for i, arg_inst in enumerate(self.stub_arg_insts, self.ARGS_INDEX): self.v.ctx.add(c.Assignment('=', c.ArrayRef(c.ID(argsname), c.Constant('integer', i)), c.ID(arg_inst.name))) self.v.ctx.add(c.FuncCall(c.ID('Py_XINCREF'), c.ExprList(c.ID(arg_inst.name)))) self.v.ctx.add(c.Assignment('=', c.ID('__return_value__'), c.FuncCall(c.ID('MpGenerator_New'), c.ExprList( c.FuncCall(c.ID('strdup'), c.ExprList(c.Constant('string', PyStringLL.name_to_c_string(self.hlnode.owner.name)))), c.ID(self.c_runner_func.decl.name), c.ID(argsname), c.Constant('integer', self.STACKSIZE) #FIXME: try to discover and set a good size for the stack )))) self.fail_if_null('__return_value__') self.v.ctx.add(c.Assignment('=', c.ArrayRef(c.ID(argsname), c.Constant('integer', self.GENERATOR_INDEX)), c.ID('__return_value__')))
def runner_intro(self): '''Set the generator context on the TLS so that we can get to it from generators we call into.''' self.v.ctx.add(c.Comment('cast args to PyObject**')) self.args_name = self.v.scope.ctx.reserve_name('__args__', self.v.tu) self.v.scope.ctx.add_variable(c.Decl(self.args_name, c.PtrDecl(c.PtrDecl(c.TypeDecl(self.args_name, c.IdentifierType('PyObject')))), init=c.ID('NULL')), False) self.v.ctx.add(c.Assignment('=', c.ID(self.args_name), c.Cast(c.PtrDecl(PyObjectLL.typedecl()), c.ID('gen_args')))) self.fail_if_null(self.args_name) #NOTE: we should _not_ incref our __self__ or __gen__ since this function _is_ us -- if we keep this ref and don't # fully drain, then we will never decref ourself and clean up the other references we're holding onto self.v.ctx.add(c.Comment('get function instance')) self.self_inst = PyObjectLL(None, self.v) self.self_inst.declare_tmp(name='__self__') self.v.ctx.add(c.Assignment('=', c.ID(self.self_inst.name), c.ArrayRef(c.ID(self.args_name), c.Constant('integer', self.SELF_INDEX)))) self.fail_if_null(self.self_inst.name) self.v.ctx.add(c.Comment('get generator instance')) self.gen_inst = PyObjectLL(None, self.v) self.gen_inst.declare_tmp(name='__gen__') self.v.ctx.add(c.Assignment('=', c.ID(self.gen_inst.name), c.ArrayRef(c.ID(self.args_name), c.Constant('integer', self.GENERATOR_INDEX)))) self.fail_if_null(self.gen_inst.name) super().runner_intro() self.v.ctx.add(c.Comment('mark us as in the generator')) tmp = CIntegerLL(None, self.v) tmp.declare_tmp() self.v.ctx.add(c.Assignment('=', c.ID(tmp.name), c.FuncCall(c.ID('MpGenerator_EnterContext'), c.ExprList(c.ID(self.gen_inst.name))))) self.fail_if_nonzero(tmp.name) tmp.decref()
def create_runnerfunc(self, args, vararg, kwonlyargs, kwarg): body = c.Compound() base_decl = c.Decl('__self__', c.PtrDecl(c.TypeDecl('__self__', c.IdentifierType('PyObject')))) arg_decls = [] for arg in args: ll_inst = self.v.create_ll_instance(arg.arg.hl) ll_inst.name = body.reserve_name(str(arg.arg), self.v.tu) arg_decls.append(c.Decl(ll_inst.name, c.PtrDecl(c.TypeDecl(ll_inst.name, c.IdentifierType('PyObject'))))) if vararg: ll_inst = self.v.create_ll_instance(vararg.hl) ll_inst.name = body.reserve_name(str(vararg), self.v.tu) arg_decls.append(c.Decl(ll_inst.name, c.PtrDecl(c.TypeDecl(ll_inst.name, c.IdentifierType('PyObject'))))) kw_decls = [] for arg in kwonlyargs: ll_inst = self.v.create_ll_instance(arg.arg.hl) ll_inst.name = body.reserve_name(str(arg.arg), self.v.tu) kw_decls.append(c.Decl(ll_inst.name, c.PtrDecl(c.TypeDecl(ll_inst.name, c.IdentifierType('PyObject'))))) if kwarg: ll_inst = self.v.create_ll_instance(kwarg.hl) ll_inst.name = body.reserve_name(str(kwarg), self.v.tu) kw_decls.append(c.Decl(ll_inst.name, c.PtrDecl(c.TypeDecl(ll_inst.name, c.IdentifierType('PyObject'))))) param_list = c.ParamList(base_decl, *(arg_decls + kw_decls)) self._create_runner_common(param_list, PyObjectLL.typedecl(), body)
def stub_intro(self): self.stub_self_inst = PyObjectLL(None, self.v) self.stub_self_inst.name = self.v.scope.ctx.reserve_name('self', self.v.tu) self.stub_args_tuple = PyTupleLL(None, self.v) self.stub_args_tuple.name = self.v.scope.ctx.reserve_name('args', self.v.tu) self.stub_kwargs_dict = PyDictLL(None, self.v) self.stub_kwargs_dict.name = self.v.scope.ctx.reserve_name('kwargs', self.v.tu) #FIXME: make this an instance and and inst self.v.scope.ctx.add_variable(c.Decl('__return_value__', PyObjectLL.typedecl('__return_value__'), init=c.ID('NULL')), False)
def intro(self, docstring, module_name): self.v.ctx.add_variable(c.Decl('__return_value__', PyObjectLL.typedecl('__return_value__')), False) # set the docstring ds = PyStringLL(None, self.v) ds.declare_tmp() if docstring: ds.new(docstring) else: ds.assign_none() self.c_namespace_dict.set_item_string('__doc__', ds) ds.decref() # set the module name ds = PyStringLL(None, self.v) ds.declare_tmp() if module_name: ds.new(module_name) self.c_namespace_dict.set_item_string('__module__', ds) ds.decref()
def runner_intro(self): self.v.ctx.add_variable(c.Decl('__return_value__', PyObjectLL.typedecl('__return_value__'), init=c.ID('NULL')), False)
def declare(self, *, quals=[], name=None): super().declare(quals=quals, name=name) self.v.scope.ctx.add_variable(c.Decl(self.name, PyObjectLL.typedecl(self.name), quals=quals, init=c.ID('NULL')), True)