def _getsetitem_gen(getset): _dunder_meth = "__%s__" % getset op = getattr(operator, getset) @templates.infer_global(op) class GetSetItem(templates.AbstractTemplate): def generic(self, args, kws): instance = args[0] if ( isinstance(instance, types.ClassInstanceType) and _dunder_meth in instance.jitmethods ): meth = instance.jitmethods[_dunder_meth] disp_type = types.Dispatcher(meth) sig = disp_type.get_call_type(self.context, args, kws) return sig # lower both {g,s}etitem and __{g,s}etitem__ to catch the calls # from python and numba imputils.lower_builtin( (types.ClassInstanceType, _dunder_meth), types.ClassInstanceType, types.VarArg(types.Any), )(get_imp()) imputils.lower_builtin( op, types.ClassInstanceType, types.VarArg(types.Any) )(get_imp())
def _implement_method(self, registry, attr): # create a separate instance of imp method to avoid closure clashing def get_imp(): def imp(context, builder, sig, args): instance_type = sig.args[0] if attr in instance_type.jit_methods: method = instance_type.jit_methods[attr] elif attr in instance_type.jit_static_methods: method = instance_type.jit_static_methods[attr] # imp gets called as a method, where the first argument is # self. We drop this for a static method. sig = sig.replace(args=sig.args[1:]) args = args[1:] disp_type = types.Dispatcher(method) call = context.get_function(disp_type, sig) out = call(builder, args) _add_linking_libs(context, call) return imputils.impl_ret_new_ref(context, builder, sig.return_type, out) return imp def _getsetitem_gen(getset): _dunder_meth = "__%s__" % getset op = getattr(operator, getset) @templates.infer_global(op) class GetSetItem(templates.AbstractTemplate): def generic(self, args, kws): instance = args[0] if isinstance(instance, types.ClassInstanceType) and \ _dunder_meth in instance.jit_methods: meth = instance.jit_methods[_dunder_meth] disp_type = types.Dispatcher(meth) sig = disp_type.get_call_type(self.context, args, kws) return sig # lower both {g,s}etitem and __{g,s}etitem__ to catch the calls # from python and numba imputils.lower_builtin((types.ClassInstanceType, _dunder_meth), types.ClassInstanceType, types.VarArg(types.Any))(get_imp()) imputils.lower_builtin(op, types.ClassInstanceType, types.VarArg(types.Any))(get_imp()) dunder_stripped = attr.strip('_') if dunder_stripped in ("getitem", "setitem"): _getsetitem_gen(dunder_stripped) else: registry.lower( (types.ClassInstanceType, attr), types.ClassInstanceType, types.VarArg(types.Any))(get_imp())
def do_class_init(cls): """ Register generic method implementation. """ from numba.core.imputils import lower_builtin attr = cls._attr @lower_builtin((cls.key, attr), cls.key, types.VarArg(types.Any)) def method_impl(context, builder, sig, args): typ = sig.args[0] typing_context = context.typing_context fnty = cls._get_function_type(typing_context, typ) sig = cls._get_signature(typing_context, fnty, sig.args, {}) call = context.get_function(fnty, sig) # Link dependent library context.add_linking_libs(getattr(call, 'libs', ())) return call(builder, args)
def do_class_init(cls): """ Register generic method implementation. """ # this line is changed for __call__ @numba.extending.lower_builtin(cls.key, cls.key, types.VarArg(types.Any)) def method_impl(context, builder, sig, args): typ = sig.args[0] typing_context = context.typing_context fnty = cls._get_function_type(typing_context, typ) sig = cls._get_signature(typing_context, fnty, sig.args, {}) call = context.get_function(fnty, sig) # Link dependent library context.add_linking_libs(getattr(call, 'libs', ())) return call(builder, args)
def _init_once(self): """ Overriding parent definition """ attr = self._attr try: registry = self._get_target_registry('method') except InternalTargetMismatchError: # Target mismatch. Do not register attribute lookup here. pass else: lower_builtin = registry.lower @lower_builtin((self.key, attr), self.key, types.VarArg(types.Any)) def method_impl(context, builder, sig, args): typ = sig.args[0] typing_context = context.typing_context fnty = self._get_function_type(typing_context, typ) sig = self._get_signature(typing_context, fnty, sig.args, {}) call = context.get_function(fnty, sig) # Link dependent library context.add_linking_libs(getattr(call, 'libs', ())) return call(builder, args)
res = builder.select(pred, v, acc) return ty, res typvals = zip(argtys, args) resty, resval = reduce(binary_minmax, typvals) return resval @lower_builtin(max, types.BaseTuple) def max_iterable(context, builder, sig, args): argtys = list(sig.args[0]) args = cgutils.unpack_tuple(builder, args[0]) return do_minmax(context, builder, argtys, args, operator.gt) @lower_builtin(max, types.VarArg(types.Any)) def max_vararg(context, builder, sig, args): return do_minmax(context, builder, sig.args, args, operator.gt) @lower_builtin(min, types.BaseTuple) def min_iterable(context, builder, sig, args): argtys = list(sig.args[0]) args = cgutils.unpack_tuple(builder, args[0]) return do_minmax(context, builder, argtys, args, operator.lt) @lower_builtin(min, types.VarArg(types.Any)) def min_vararg(context, builder, sig, args): return do_minmax(context, builder, sig.args, args, operator.lt)
likely=True) as (if_ok, if_error): with if_ok: pyapi.print_object(obj) pyapi.decref(obj) with if_error: cstr = context.insert_const_string(builder.module, "the print() function") strobj = pyapi.string_from_string(cstr) pyapi.err_write_unraisable(strobj) pyapi.decref(strobj) res = context.get_dummy_value() return impl_ret_untracked(context, builder, sig.return_type, res) @lower(print, types.VarArg(types.Any)) def print_varargs_impl(context, builder, sig, args): """ A entire print() call. """ pyapi = context.get_python_api(builder) gil = pyapi.gil_ensure() for i, (argtype, argval) in enumerate(zip(sig.args, args)): signature = typing.signature(types.none, argtype) imp = context.get_function("print_item", signature) imp(builder, [argval]) if i < len(args) - 1: pyapi.print_string(' ') pyapi.print_string('\n')
alloc_fe_type = instance_type.get_data_type() alloc_type = context.get_value_type(alloc_fe_type) ptr = builder.bitcast(dtor_fn.args[0], alloc_type.as_pointer()) data = context.make_helper(builder, alloc_fe_type, ref=ptr) context.nrt.decref(builder, alloc_fe_type, data._getvalue()) builder.ret_void() return dtor_fn @ClassBuilder.class_impl_registry.lower(types.ClassType, types.VarArg(types.Any)) def ctor_impl(context, builder, sig, args): """ Generic constructor (__new__) for jitclasses. """ # Allocate the instance inst_typ = sig.return_type alloc_type = context.get_data_type(inst_typ.get_data_type()) alloc_size = context.get_abi_sizeof(alloc_type) meminfo = context.nrt.meminfo_alloc_dtor( builder, context.get_constant(types.uintp, alloc_size), imp_dtor(context, builder.module, inst_typ), ) data_pointer = context.nrt.meminfo_data(builder, meminfo)
srcres = call_iternext(context, builder, enumty.source_type, enum.iter) is_valid = srcres.is_valid() result.set_valid(is_valid) with builder.if_then(is_valid): srcval = srcres.yielded_value() result.yield_( context.make_tuple(builder, enumty.yield_type, [count, srcval])) #------------------------------------------------------------------------------- # builtin `zip` implementation @lower_builtin(zip, types.VarArg(types.Any)) def make_zip_object(context, builder, sig, args): zip_type = sig.return_type assert len(args) == len(zip_type.source_types) zipobj = context.make_helper(builder, zip_type) for i, (arg, srcty) in enumerate(zip(args, sig.args)): zipobj[i] = call_getiter(context, builder, srcty, arg) res = zipobj._getvalue() return impl_ret_new_ref(context, builder, sig.return_type, res) @lower_builtin('iternext', types.ZipType)
def get_defaults(context): """ Get the default values for a slice's members: (start for positive step, start for negative step, stop for positive step, stop for negative step, step) """ maxint = (1 << (context.address_size - 1)) - 1 return (0, maxint, maxint, -maxint - 1, 1) #--------------------------------------------------------------------------- # The slice structure @lower_builtin(slice, types.VarArg(types.Any)) def slice_constructor_impl(context, builder, sig, args): ( default_start_pos, default_start_neg, default_stop_pos, default_stop_neg, default_step, ) = [context.get_constant(types.intp, x) for x in get_defaults(context)] slice_args = [None] * 3 # Fetch non-None arguments if len(args) == 1 and sig.args[0] is not types.none: slice_args[1] = args[0] else:
Implementation of tuple objects """ from llvmlite import ir import llvmlite.llvmpy.core as lc import operator from numba.core.imputils import (lower_builtin, lower_getattr_generic, lower_cast, lower_constant, iternext_impl, impl_ret_borrowed, impl_ret_untracked, RefType) from numba.core import typing, types, cgutils from numba.core.extending import overload_method, overload, intrinsic @lower_builtin(types.NamedTupleClass, types.VarArg(types.Any)) def namedtuple_constructor(context, builder, sig, args): # A namedtuple has the same representation as a regular tuple # the arguments need casting (lower_cast) from the types in the ctor args # to those in the ctor return type, this is to handle cases such as a # literal present in the args, but a type present in the return type. newargs = [] for i, arg in enumerate(args): casted = context.cast(builder, arg, sig.args[i], sig.return_type[i]) newargs.append(casted) res = context.make_tuple(builder, sig.return_type, tuple(newargs)) # The tuple's contents are borrowed return impl_ret_borrowed(context, builder, sig.return_type, res) @lower_builtin(operator.add, types.BaseTuple, types.BaseTuple) def tuple_add(context, builder, sig, args):
builder = llvmir.IRBuilder(dtor_fn.append_basic_block()) alloc_fe_type = instance_type.get_data_type() alloc_type = context.get_value_type(alloc_fe_type) ptr = builder.bitcast(dtor_fn.args[0], alloc_type.as_pointer()) data = context.make_helper(builder, alloc_fe_type, ref=ptr) context.nrt.decref(builder, alloc_fe_type, data._getvalue()) builder.ret_void() return dtor_fn @ClassBuilder.class_impl_registry.lower(types.ClassType, types.VarArg(types.Any)) def ctor_impl(context, builder, sig, args): """ Generic constructor (__new__) for jitclasses. """ # Allocate the instance inst_typ = sig.return_type alloc_type = context.get_data_type(inst_typ.get_data_type()) alloc_size = context.get_abi_sizeof(alloc_type) meminfo = context.nrt.meminfo_alloc_dtor( builder, context.get_constant(types.uintp, alloc_size), imp_dtor(context, builder.module, inst_typ), ) data_pointer = context.nrt.meminfo_data(builder, meminfo)