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 sequence_del_slice(self, start, end, step): if step is None: tmp_inst = CIntegerLL(None, self.v) tmp_inst.declare_tmp(name='_rv_slice') if start is None: _start = c.Constant('integer', 0) else: _start = c.ID(start.as_ssize().name) if end is None: _end = c.Constant('integer', CIntegerLL.MAX) else: _end = c.ID(end.as_ssize().name) self.v.ctx.add(c.Assignment('=', c.ID(tmp_inst.name), c.FuncCall(c.ID('PySequence_DelSlice'), c.ExprList(c.ID(self.name), _start, _end)))) self.fail_if_nonzero(tmp_inst.name) tmp_inst.decref() else: slice_inst = PySliceLL(None, self.v) slice_inst.declare_tmp(name='_slice') if start is None: _start = self.v.none; _start.incref() else: _start = start.as_pyobject() if end is None: _end = self.v.none; _end.incref() else: _end = end.as_pyobject() _step = step.as_pyobject() slice_inst.new(_start, _end, _step) self.del_item(slice_inst) slice_inst.decref()
def add(self, val): out = CIntegerLL(None, self.v) out.declare_tmp(name='_set_add_rv') self.v.ctx.add(c.Assignment('=', c.ID(out.name), c.FuncCall(c.ID('PySet_Add'), c.ExprList( c.ID(self.name), c.ID(val.name))))) self.fail_if_nonzero(out.name) out.decref()
def sequence_set_slice(self, start, end, step, src_inst): '''Assign a sequence into a sliced sequence.''' # Case 0: no step means we can use the fast sequence SetSlice if step is None: tmp_inst = CIntegerLL(None, self.v) tmp_inst.declare_tmp(name='_rv_slice') if start is None: _start = c.Constant('integer', 0) else: _start = c.ID(start.as_ssize().name) if end is None: _end = c.Constant('integer', CIntegerLL.MAX) else: _end = c.ID(end.as_ssize().name) self.v.ctx.add(c.Assignment('=', c.ID(tmp_inst.name), c.FuncCall(c.ID('PySequence_SetSlice'), c.ExprList(c.ID(self.name), _start, _end, c.ID(src_inst.name))))) self.fail_if_negative(tmp_inst.name) tmp_inst.decref() else: slice_inst = PySliceLL(None, self.v) slice_inst.declare_tmp(name='_slice') if start is None: _start = self.v.none; _start.incref() else: _start = start.as_pyobject() if end is None: _end = self.v.none; _end.incref() else: _end = end.as_pyobject() _step = step.as_pyobject() slice_inst.new(_start, _end, _step) self.set_item(slice_inst, src_inst) slice_inst.decref()
def del_item(self, key): out = CIntegerLL(None, self.v) out.declare_tmp() self.v.ctx.add(c.Assignment('=', c.ID(out.name), c.FuncCall(c.ID('PyObject_DelItem'), c.ExprList( c.ID(self.name), c.ID(key.name))))) self.fail_if_nonzero(out.name) out.decref()
def del_attr_string(self, attrname): tmp = CIntegerLL(None, self.v) tmp.declare_tmp() self.v.ctx.add(c.Assignment('=', c.ID(tmp.name), c.FuncCall(c.ID('PyObject_DelAttrString'), c.ExprList( c.ID(self.name), c.Constant('string', attrname))))) self.fail_if_nonzero(tmp.name) tmp.decref()
def set_attr(self, attr, val): tmp = CIntegerLL(None, self.v) tmp.declare_tmp() self.v.ctx.add(c.Assignment('=', c.ID(tmp.name), c.FuncCall(c.ID('PyObject_SetAttr'), c.ExprList( c.ID(self.name), c.ID(attr.name), c.ID(val.name))))) self.fail_if_nonzero(tmp.name) tmp.decref()
def set_attr_string(self, attrname, attrval): tmp = CIntegerLL(None, self.v) tmp.declare_tmp(name="_setattr_rv") attrval = attrval.as_pyobject() self.v.ctx.add(c.Assignment('=', c.ID(tmp.name), c.FuncCall(c.ID('PyObject_SetAttrString'), c.ExprList( c.ID(self.name), c.Constant('string', attrname), c.ID(attrval.name))))) self.fail_if_nonzero(tmp.name) tmp.decref()
def set_item(self, key:PyObjectLL, val:PyObjectLL): tmp = CIntegerLL(None, self.v) tmp.declare_tmp(name='_set_rv') #key.incref() #val.incref() self.v.ctx.add(c.Assignment('=', c.ID(tmp.name), c.FuncCall(c.ID('PyDict_SetItem'), c.ExprList( c.ID(self.name), c.ID(key.name), c.ID(val.name))))) self.fail_if_nonzero(tmp.name) tmp.decref()
def set_item_string(self, name:str, var:PyObjectLL): tmp = CIntegerLL(None, self.v) tmp.declare_tmp(name='_set_str_rv') var = var.as_pyobject() #var.incref() self.v.ctx.add(c.Assignment('=', c.ID(tmp.name), c.FuncCall(c.ID('PyDict_SetItemString'), c.ExprList( c.ID(self.name), c.Constant('string', name), c.ID(var.name))))) self.fail_if_nonzero(tmp.name) tmp.decref()
def update(self, other:PyObjectLL): tmp = CIntegerLL(None, self.v) tmp.declare_tmp(name='_update_rv') self.v.ctx.add(c.Assignment('=', c.ID(tmp.name), c.FuncCall(c.ID('PyDict_Update'), c.ExprList(c.ID(self.name), c.ID(other.name))))) self.fail_if_nonzero(tmp.name) tmp.decref()