Example #1
0
	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__')))
Example #2
0
	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()
Example #3
0
	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)
Example #4
0
	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)
Example #5
0
	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()
Example #6
0
	def runner_intro(self):
		self.v.ctx.add_variable(c.Decl('__return_value__', PyObjectLL.typedecl('__return_value__'), init=c.ID('NULL')), False)
Example #7
0
	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)