def test_multi_module_linking(self): # generate external library module m = Module.new('external-library-module') fnty = Type.function(Type.int(), [Type.int(), Type.int()]) libfname = 'myadd' func = m.add_function(fnty, libfname) bb = func.append_basic_block('') bldr = Builder.new(bb) bldr.ret(bldr.add(*func.args)) func.verify() # JIT the lib module and bind dynamic symbol libengine = EngineBuilder.new(m).mcjit(True).create() myadd_ptr = libengine.get_pointer_to_function(func) le.dylib_add_symbol(libfname, myadd_ptr) # reference external library m = Module.new('user') fnty = Type.function(Type.int(), [Type.int(), Type.int()]) func = m.add_function(fnty, 'foo') bb = func.append_basic_block('') bldr = Builder.new(bb) extadd = m.get_or_insert_function(fnty, name=libfname) bldr.ret(bldr.call(extadd, func.args)) func.verify() # JIT the user module engine = EngineBuilder.new(m).mcjit(True).create() ptr = engine.get_pointer_to_function(func) self.assertEqual(myadd_ptr, engine.get_pointer_to_named_function(libfname)) from ctypes import c_int, CFUNCTYPE callee = CFUNCTYPE(c_int, c_int, c_int)(ptr) self.assertEqual(321 + 123, callee(321, 123))
def _long_from_native_int(self, ival, func_name, native_int_type, signed): fnty = Type.function(self.pyobj, [native_int_type]) fn = self._get_function(fnty, name=func_name) resptr = cgutils.alloca_once(self.builder, self.pyobj) if PYVERSION < (3, 0): # Under Python 2, we try to return a PyInt object whenever # the given number fits in a C long. pyint_fnty = Type.function(self.pyobj, [self.long]) pyint_fn = self._get_function(pyint_fnty, name="PyInt_FromLong") long_max = Constant.int(native_int_type, _helperlib.long_max) if signed: long_min = Constant.int(native_int_type, _helperlib.long_min) use_pyint = self.builder.and_( self.builder.icmp(lc.ICMP_SGE, ival, long_min), self.builder.icmp(lc.ICMP_SLE, ival, long_max), ) else: use_pyint = self.builder.icmp(lc.ICMP_ULE, ival, long_max) with cgutils.ifelse(self.builder, use_pyint) as (then, otherwise): with then: downcast_ival = self.builder.trunc(ival, self.long) res = self.builder.call(pyint_fn, [downcast_ival]) self.builder.store(res, resptr) with otherwise: res = self.builder.call(fn, [ival]) self.builder.store(res, resptr) else: fn = self._get_function(fnty, name=func_name) self.builder.store(self.builder.call(fn, [ival]), resptr) return self.builder.load(resptr)
def dict_new(self, presize=0): if presize == 0: fnty = Type.function(self.pyobj, ()) fn = self._get_function(fnty, name="PyDict_New") return self.builder.call(fn, ()) else: fnty = Type.function(self.pyobj, [self.py_ssize_t]) fn = self._get_function(fnty, name="_PyDict_NewPresized") return self.builder.call(fn, [Constant.int(self.py_ssize_t, presize)])
def declare_runtime_library(self): self.runtime = {} self.runtime['_print_int'] = Function.new(self.module, Type.function(Type.void(), [int_type], False), "_print_int") self.runtime['_print_float'] = Function.new(self.module, Type.function(Type.void(), [float_type], False), "_print_float") self.runtime['_print_bool'] = Function.new(self.module, Type.function(Type.void(), [bool_type], False), "_print_bool")
def testCreateFunctionType(self): ty = Type.int8() ft = Type.function(ty, [ty], False) self.assertFalse(ft.is_function_vararg()) self.assertEqual(ty, ft.return_type()) self.assertEqual(1, ft.num_params()) self.assertEqual([ty], ft.param_types()) f2 = Type.function(ty, [ty], True) self.assertTrue(f2.is_function_vararg()) self.assertEqual([ty], f2.param_types()) self.assertEqual(1, f2.num_params())
def CodeGen(self): # Make the function type, ex: double(double, double). function_type = Type.function(Type.double(), [Type.double()] * len(self.args), False) function = Function.new(g_llvm_module, function_type, self.name) # If the name conflicts, already something with the same name # If it has a body, don't allow redefinition or re-extern if function.name != self.name: function.delete() function = g_llvm_module.get_function_named(self.name) # If the function already has a body, reject it if not function.is_declaration: raise RuntimeError('Redefinition of function.') # THIS IS ESSENTIALLY FUNCTION OVERLOADING, MAYBE CHANGE IN FUTURE # If function took different number of args, reject it if len(callee.args) != len(self.args): raise RuntimeError('Redeclaration of function with different' + ' number of args') # Set names for all args and add them to var symbol table for arg, arg_name in zip(function.args, self.args): arg.name = arg_name # add args to variable symbol table g_named_values[arg_name] = arg return function
def complex128_power_impl(context, builder, sig, args): [ca, cb] = args a = Complex128(context, builder, value=ca) b = Complex128(context, builder, value=cb) c = Complex128(context, builder) module = cgutils.get_module(builder) pa = a._getpointer() pb = b._getpointer() pc = c._getpointer() # Optimize for square because cpow looses a lot of precsiion TWO = context.get_constant(types.float64, 2) ZERO = context.get_constant(types.float64, 0) b_real_is_two = builder.fcmp(lc.FCMP_OEQ, b.real, TWO) b_imag_is_zero = builder.fcmp(lc.FCMP_OEQ, b.imag, ZERO) b_is_two = builder.and_(b_real_is_two, b_imag_is_zero) with cgutils.ifelse(builder, b_is_two) as (then, otherwise): with then: # Lower as multiplication res = complex_mul_impl(context, builder, sig, (ca, ca)) cres = Complex128(context, builder, value=res) c.real = cres.real c.imag = cres.imag with otherwise: # Lower with call to external function fnty = Type.function(Type.void(), [pa.type] * 3) cpow = module.get_or_insert_function(fnty, name="numba.math.cpow") builder.call(cpow, (pa, pb, pc)) return builder.load(pc)
def test_uses(self): m = Module.new("a") t = Type.int() ft = Type.function(t, [t, t, t]) f = m.add_function(ft, "func") b = f.append_basic_block("entry") bld = Builder.new(b) tmp1 = bld.add(Constant.int(t, 100), f.args[0], "tmp1") tmp2 = bld.add(tmp1, f.args[1], "tmp2") tmp3 = bld.add(tmp1, f.args[2], "tmp3") bld.ret(tmp3) # Testing use count self.assertEqual(f.args[0].use_count, 1) self.assertEqual(f.args[1].use_count, 1) self.assertEqual(f.args[2].use_count, 1) self.assertEqual(tmp1.use_count, 2) self.assertEqual(tmp2.use_count, 0) self.assertEqual(tmp3.use_count, 1) # Testing uses self.assert_(f.args[0].uses[0] is tmp1) self.assertEqual(len(f.args[0].uses), 1) self.assert_(f.args[1].uses[0] is tmp2) self.assertEqual(len(f.args[1].uses), 1) self.assert_(f.args[2].uses[0] is tmp3) self.assertEqual(len(f.args[2].uses), 1) self.assertEqual(len(tmp1.uses), 2) self.assertEqual(len(tmp2.uses), 0) self.assertEqual(len(tmp3.uses), 1)
def test_bswap(self): # setup a function and a builder mod = Module.new("test") functy = Type.function(Type.int(), []) func = mod.add_function(functy, "showme") block = func.append_basic_block("entry") b = Builder.new(block) # let's do bswap on a 32-bit integer using llvm.bswap val = Constant.int(Type.int(), 0x42) bswap = Function.intrinsic(mod, lc.INTR_BSWAP, [Type.int()]) bswap_res = b.call(bswap, [val]) b.ret(bswap_res) # logging.debug(mod) # the output is: # # ; ModuleID = 'test' # # define void @showme() { # entry: # %0 = call i32 @llvm.bswap.i32(i32 42) # ret i32 %0 # } # let's run the function ee = le.ExecutionEngine.new(mod) retval = ee.run_function(func, []) self.assertEqual(retval.as_int(), 0x42000000)
def f_abs(mod): '''libc: compute the absolute value of an integer''' ret = Type.int() args = [Type.int()] type_ = Type.function(ret, args) return mod.get_or_insert_function(type_, "abs")
def f_roundf(mod): '''libc: round to nearest integer, away from zero''' ret = Type.float() args = [Type.float()] type_ = Type.function(ret, args) return mod.get_or_insert_function(type_, "roundf")
def f_sqrtf(mod): '''libc: square root function''' ret = Type.float() args = [Type.float()] type_ = Type.function(ret, args) return mod.get_or_insert_function(type_, "sqrtf")
def f_powf(mod): '''libc: power function''' ret = Type.float() args = [Type.float(), Type.float()] type_ = Type.function(ret, args) return mod.get_or_insert_function(type_, "powf")
def test_issue100(self): m = Module.new('a') pm = FunctionPassManager.new(m) ee = ExecutionEngine.new(m) pm.add(ee.target_data) ti = Type.int() tf = Type.function(ti, []) f = m.add_function(tf, "func1") bb = f.append_basic_block('entry') b = Builder.new(bb) b.ret(Constant.int(ti, 0)) f.verify() pm.run(f) assert ee.run_function(f, []).as_int() == 0
def code_gen(self, from_definition=False): top_context = self.context.parent_context func_name_with_tag = self.func_name_token.word + "()" return_type = Helper.get_type(self.ret_type.word) arg_types = [Helper.get_type(arg[1]) for arg in self.args if True] func_type = Type.function(return_type, arg_types, False) if not func_name_with_tag in top_context.type_table: function = Function.new(g_llvm_module, func_type, self.func_name_token.word) top_context.type_table[func_name_with_tag] = func_type for arg in self.args: self.context.type_table[arg[0]] = Helper.get_type(arg[1]) return [function, self.context] else: old_func_type = top_context.type_table[func_name_with_tag] if old_func_type == func_type: if from_definition: for arg in self.args: self.context.type_table[arg[0]] = Helper.get_type( arg[1]) return [ g_llvm_module.get_function_named( self.func_name_token.word), self.context ] else: raise cmexception.RedefineException( self.func_name_token, 'function') else: raise cmexception.RedefineException(self.func_name_token, 'function')
def test_atomic_ldst(self): mod = Module.new('mod') functype = Type.function(Type.void(), []) func = mod.add_function(functype, name='foo') bb = func.append_basic_block('entry') bldr = Builder.new(bb) ptr = bldr.alloca(Type.int()) val = Constant.int(Type.int(), 1234) for ordering in self.orderings: loaded = bldr.atomic_load(ptr, ordering) self.assert_('load atomic' in str(loaded)) self.assertEqual(ordering, str(loaded).strip().split(' ')[-3].rstrip(',')) self.assert_('align 1' in str(loaded)) stored = bldr.atomic_store(loaded, ptr, ordering) self.assert_('store atomic' in str(stored)) self.assertEqual(ordering, str(stored).strip().split(' ')[-3].rstrip(',')) self.assert_('align 1' in str(stored)) fenced = bldr.fence(ordering) self.assertEqual(['fence', ordering], str(fenced).strip().split(' '))
def f_fabs(mod): '''libc: absolute value of floating-point number''' ret = Type.double() args = [Type.double()] type_ = Type.function(ret, args) return mod.get_or_insert_function(type_, "fabs")
def test_atomic_rmw(self): mod = Module.new("mod") functype = Type.function(Type.void(), []) func = mod.add_function(functype, name="foo") bb = func.append_basic_block("entry") bldr = Builder.new(bb) ptr = bldr.alloca(Type.int()) old = bldr.load(ptr) val = Constant.int(Type.int(), 1234) for ordering in self.orderings: inst = bldr.atomic_rmw("xchg", ptr, val, ordering) self.assertEqual(ordering, str(inst).split(" ")[-1]) for op in self.atomic_op: inst = bldr.atomic_rmw(op, ptr, val, ordering) self.assertEqual(op, str(inst).strip().split(" ")[3]) inst = bldr.atomic_rmw("xchg", ptr, val, ordering, crossthread=False) self.assertEqual("singlethread", str(inst).strip().split(" ")[-2]) for op in self.atomic_op: atomic_op = getattr(bldr, "atomic_%s" % op) inst = atomic_op(ptr, val, ordering) self.assertEqual(op, str(inst).strip().split(" ")[3])
def f_exit(mod): '''libc: cause normal process termination''' ret = Type.void() args = [Type.int(32)] type_ = Type.function(ret, args) return mod.get_or_insert_function(type_, "exit")
def testAppendBasicBlock(self): mod = Module.CreateWithName('module') ty = Type.int8(context=mod.context) ft = Type.function(ty, [ty], False) f = mod.add_function('timestwo', ft) bb = f.append_basic_block('body') self.assertEqual('body', bb.name)
def f_atoi(mod): '''libc: convert a string to an integer''' ret = Type.int(32) args = [Type.pointer(Type.int(8))] type_ = Type.function(ret, args) return mod.get_or_insert_function(type_, "atoi")
def dict_getitem_string(self, dic, name): """Returns a borrowed reference """ fnty = Type.function(self.pyobj, [self.pyobj, self.cstring]) fn = self._get_function(fnty, name="PyDict_GetItemString") cstr = self.context.insert_const_string(self.module, name) return self.builder.call(fn, [dic, cstr])
def tuple_pack(self, items): fnty = Type.function(self.pyobj, [self.py_ssize_t], var_arg=True) fn = self._get_function(fnty, name="PyTuple_Pack") n = self.context.get_constant(types.intp, len(items)) args = [n] args.extend(items) return self.builder.call(fn, args)
def f_main(mod): '''main function''' argc = Type.int(32) argv = Type.pointer(Type.pointer(Type.int(8))) type_ = Type.function(Type.void(), [argc, argv]) return mod.get_or_insert_function(type_, "main")
def __init__(self, fundef, llvm_cxt=llvm_context.global_context): self.parakeet_fundef = fundef if config.opt_stack_allocation: self.may_escape = may_escape(fundef) else: self.may_escape = None self.llvm_context = llvm_cxt self.vars = {} self.initialized = set([]) # Initializes the variables dictionary and returns a builder object llvm_input_types = map(llvm_ref_type, fundef.input_types) llvm_output_type = llvm_ref_type(fundef.return_type) llvm_fn_t = lltype.function(llvm_output_type, llvm_input_types) self.llvm_fn = self.llvm_context.module.add_function( llvm_fn_t, fundef.name) for arg in self.llvm_fn.args: if not llvm_types.is_scalar(arg.type): arg.add_attribute(ATTR_NO_CAPTURE) self.llvm_fn.does_not_throw = True self.entry_block, self.entry_builder = self.new_block("entry") self._init_vars(self.parakeet_fundef, self.entry_builder)
def create_cumsum_module(): mod = Module.CreateWithName('module') ty = Type.int8(context=mod.context) ft = Type.function(ty, [ty], False) f = mod.add_function('cumsum', ft) bb1 = f.append_basic_block('body') bb_hdr = f.append_basic_block('hdr') bb_loop = f.append_basic_block('loop') bb_exit = f.append_basic_block('exit') bldr = Builder.create(mod.context) bldr.position_at_end(bb1) bldr.branch(bb_hdr) bldr.position_at_end(bb_hdr) i = bldr.phi(ty, 'i') s = bldr.phi(ty, 's') zero = Value.const_int(ty, 0, True) c = bldr.int_signed_lt(zero, i, 'comp') bldr.conditional_branch(c, bb_loop, bb_exit) bldr.position_at_end(bb_loop) s1 = bldr.add(s, i, 's1') i1 = bldr.sub(i, Value.const_int(ty, 1, True), 'i1') bldr.branch(bb_hdr) i.add_incoming([f.get_param(0), i1], [bb1, bb_loop]) s.add_incoming([Value.const_int(ty, 0, True), s1], [bb1, bb_loop]) bldr.position_at_end(bb_exit) bldr.ret(s) return (mod, f)
def _build_module(self, float): mod = Module.new('test') functy = Type.function(float, [float]) func = mod.add_function(functy, "mytest%s" % float) block = func.append_basic_block("entry") b = Builder.new(block) return mod, func, b
def call_function_pointer(self, builder, funcptr, signature, args): retty = self.get_value_type(signature.return_type) fnty = Type.function(retty, [a.type for a in args]) fnptrty = Type.pointer(fnty) addr = self.get_constant(types.intp, funcptr) ptr = builder.inttoptr(addr, fnptrty) return builder.call(ptr, args)
def create_abs_module(): mod = Module.CreateWithName('module') ty = Type.int8(context=mod.context) ft = Type.function(ty, [ty], False) f = mod.add_function('abs', ft) bb1 = f.append_basic_block('body') bbt = f.append_basic_block('true') bbf = f.append_basic_block('false') bbm = f.append_basic_block('merge') bldr = Builder.create(mod.context) bldr.position_at_end(bb1) x = f.get_param(0) zero = Value.const_int(ty, 0, True) c = bldr.int_signed_lt(x, zero, 'comp') bldr.conditional_branch(c, bbt, bbf) # True branch bldr.position_at_end(bbt) y_t = bldr.neg(x, 'neg_x') bldr.branch(bbm) # False branch bldr.position_at_end(bbf) bldr.branch(bbm) bldr.position_at_end(bbm) y = bldr.phi(ty, 'y') y.add_incoming([y_t, x], [bbt, bbf]) bldr.ret(y) return (mod, f)
def get_external_function_type(self, fndesc): argtypes = [self.get_argument_type(aty) for aty in fndesc.argtypes] # don't wrap in pointer restype = self.get_argument_type(fndesc.restype) fnty = Type.function(restype, argtypes) return fnty
def test_bswap(self): # setup a function and a builder mod = Module.new('test') functy = Type.function(Type.int(), []) func = mod.add_function(functy, "showme") block = func.append_basic_block("entry") b = Builder.new(block) # let's do bswap on a 32-bit integer using llvm.bswap val = Constant.int(Type.int(), 0x42) bswap = Function.intrinsic(mod, lc.INTR_BSWAP, [Type.int()]) bswap_res = b.call(bswap, [val]) b.ret(bswap_res) # logging.debug(mod) # the output is: # # ; ModuleID = 'test' # # define void @showme() { # entry: # %0 = call i32 @llvm.bswap.i32(i32 42) # ret i32 %0 # } # let's run the function ee = le.ExecutionEngine.new(mod) retval = ee.run_function(func, []) self.assertEqual(retval.as_int(), 0x42000000)
def build(self): wrapname = "wrapper.%s" % self.func.name # This is the signature of PyCFunctionWithKeywords # (see CPython's methodobject.h) pyobj = self.context.get_argument_type(types.pyobject) wrapty = Type.function(pyobj, [pyobj, pyobj, pyobj]) wrapper = self.module.add_function(wrapty, name=wrapname) builder = Builder.new(wrapper.append_basic_block('entry')) # - `closure` will receive the `self` pointer stored in the # PyCFunction object (see _dynfunc.c) # - `args` and `kws` will receive the tuple and dict objects # of positional and keyword arguments, respectively. closure, args, kws = wrapper.args closure.name = 'py_closure' args.name = 'py_args' kws.name = 'py_kws' api = self.context.get_python_api(builder) self.build_wrapper(api, builder, closure, args, kws) wrapper.verify() return wrapper, api
def test_uses(self): m = Module.new('a') t = Type.int() ft = Type.function(t, [t, t, t]) f = m.add_function(ft, "func") b = f.append_basic_block('entry') bld = Builder.new(b) tmp1 = bld.add(Constant.int(t, 100), f.args[0], "tmp1") tmp2 = bld.add(tmp1, f.args[1], "tmp2") tmp3 = bld.add(tmp1, f.args[2], "tmp3") bld.ret(tmp3) # Testing use count self.assertEqual(f.args[0].use_count, 1) self.assertEqual(f.args[1].use_count, 1) self.assertEqual(f.args[2].use_count, 1) self.assertEqual(tmp1.use_count, 2) self.assertEqual(tmp2.use_count, 0) self.assertEqual(tmp3.use_count, 1) # Testing uses self.assert_(f.args[0].uses[0] is tmp1) self.assertEqual(len(f.args[0].uses), 1) self.assert_(f.args[1].uses[0] is tmp2) self.assertEqual(len(f.args[1].uses), 1) self.assert_(f.args[2].uses[0] is tmp3) self.assertEqual(len(f.args[2].uses), 1) self.assertEqual(len(tmp1.uses), 2) self.assertEqual(len(tmp2.uses), 0) self.assertEqual(len(tmp3.uses), 1)
def CodeGen(self): # Make the function type, eg. double(double,double). funct_type = Type.function(Type.double(), [Type.double()] * len(self.args), False) function = Function.new(g_llvm_module, funct_type, self.name) # If the name conflicted, there was already something with the same name. # If it has a body, don't allow redefinition or reextern. if function.name != self.name: function.delete() function = g_llvm_module.get_function_named(self.name) # If the function already has a body, reject this. if not function.is_declaration: raise RuntimeError('Redefinition of function.') # If the function took a different number of args, reject. if len(function.args) != len(self.args): raise RuntimeError('Redeclaration of a function with different number of args.') # Set names for all arguments and add them to the variables symbol table. for arg, arg_name in zip(function.args, self.args): arg.name = arg_name return function
def test_atomic_rmw(self): mod = Module.new('mod') functype = Type.function(Type.void(), []) func = mod.add_function(functype, name='foo') bb = func.append_basic_block('entry') bldr = Builder.new(bb) ptr = bldr.alloca(Type.int()) old = bldr.load(ptr) val = Constant.int(Type.int(), 1234) for ordering in self.orderings: inst = bldr.atomic_rmw('xchg', ptr, val, ordering) self.assertEqual(ordering, str(inst).split(' ')[-1]) for op in self.atomic_op: inst = bldr.atomic_rmw(op, ptr, val, ordering) self.assertEqual(op, str(inst).strip().split(' ')[3]) inst = bldr.atomic_rmw('xchg', ptr, val, ordering, crossthread=False) self.assertEqual('singlethread', str(inst).strip().split(' ')[-2]) for op in self.atomic_op: atomic_op = getattr(bldr, 'atomic_%s' % op) inst = atomic_op(ptr, val, ordering) self.assertEqual(op, str(inst).strip().split(' ')[3])
def numba_array_adaptor(self, ary, ptr): voidptr = Type.pointer(Type.int(8)) fnty = Type.function(Type.int(), [self.pyobj, voidptr]) fn = self._get_function(fnty, name="numba_adapt_ndarray") fn.args[0].add_attribute(lc.ATTR_NO_CAPTURE) fn.args[1].add_attribute(lc.ATTR_NO_CAPTURE) return self.builder.call(fn, (ary, ptr))
def parse_tuple_and_keywords(self, args, kws, fmt, keywords, *objs): charptr = Type.pointer(Type.int(8)) charptrary = Type.pointer(charptr) argtypes = [self.pyobj, self.pyobj, charptr, charptrary] fnty = Type.function(Type.int(), argtypes, var_arg=True) fn = self._get_function(fnty, name="PyArg_ParseTupleAndKeywords") return self.builder.call(fn, [args, kws, fmt, keywords] + list(objs))
def object_dump(self, obj): """ Dump a Python object on C stderr. For debugging purposes. """ fnty = Type.function(Type.void(), [self.pyobj]) fn = self._get_function(fnty, name="_PyObject_Dump") return self.builder.call(fn, (obj, ))
def object_dump(self, obj): """ Dump a Python object on C stderr. For debugging purposes. """ fnty = Type.function(Type.void(), [self.pyobj]) fn = self._get_function(fnty, name="_PyObject_Dump") return self.builder.call(fn, (obj,))
def create_instance(mod, spec, ctx): # Spine # | # # T ... = A .. | B .. | C .. # # | # Values lvals = [] instances = [] # Values # ====== for value in spec.values: tys = [ctx[id] for id in value.params] lvals += [(value.name, Type.struct(tys, value.name))] # Spine # ====== spine = Type.struct([a[1] for a in lvals], 'maybe') for i, (name, value) in enumerate(lvals): fn_spec = Type.function(void, value.elements) F = mod.add_function(fn_spec, value.name) instances += [F] build_constructor(F, value, spine, 1) return spine, instances
def numba_array_adaptor(self, ary, ptr): voidptr = Type.pointer(Type.int(8)) fnty = Type.function(Type.int(), [self.pyobj, voidptr]) fn = self._get_function(fnty, name="NumbaArrayAdaptor") fn.args[0].add_attribute(lc.ATTR_NO_CAPTURE) fn.args[1].add_attribute(lc.ATTR_NO_CAPTURE) return self.builder.call(fn, (ary, ptr))
def list_setitem(self, seq, idx, val): """ Warning: Steals reference to ``val`` """ fnty = Type.function(Type.int(), [self.pyobj, self.py_ssize_t, self.pyobj]) fn = self._get_function(fnty, name="PyList_SetItem") return self.builder.call(fn, [seq, idx, val])
def string_as_string(self, strobj): fnty = Type.function(self.cstring, [self.pyobj]) if PYVERSION >= (3, 0): fname = "PyUnicode_AsUTF8" else: fname = "PyString_AsString" fn = self._get_function(fnty, name=fname) return self.builder.call(fn, [strobj])
def tuple_setitem(self, tuple_val, index, item): """ Steals a reference to `item`. """ fnty = Type.function(Type.int(), [self.pyobj, Type.int(), self.pyobj]) setitem_fn = self._get_function(fnty, name='PyTuple_SetItem') index = self.context.get_constant(types.int32, index) self.builder.call(setitem_fn, [tuple_val, index, item])
def tuple_getitem(self, tup, idx): """ Borrow reference """ fnty = Type.function(self.pyobj, [self.pyobj, self.py_ssize_t]) fn = self._get_function(fnty, name="PyTuple_GetItem") idx = self.context.get_constant(types.intp, idx) return self.builder.call(fn, [tup, idx])
def bytes_from_string_and_size(self, string, size): fnty = Type.function(self.pyobj, [self.cstring, self.py_ssize_t]) if PYVERSION >= (3, 0): fname = "PyBytes_FromStringAndSize" else: fname = "PyString_FromStringAndSize" fn = self._get_function(fnty, name=fname) return self.builder.call(fn, [string, size])