def _dispatch_func_by_name_type(context, builder, sig, args, table, user_name):
    # for most cases the functions are homogeneous on all their types.
    # this code dispatches on the first argument type as it is the most useful
    # for our uses (all cases but ldexp are homogeneous in all types, and
    # dispatching on the first argument type works of ldexp as well)
    #
    # assumes that the function pointed by func_name has the type
    # signature sig (but needs translation to llvm types).

    ty = sig.args[0]
    try:
        func_name = table[ty]
    except KeyError as e:
        msg = "No {0} function for real type {1}".format(user_name, str(e))
        raise errors.LoweringError(msg)

    mod = builder.module
    if ty in types.complex_domain:
        # In numba struct types are always passed by pointer. So the call has to
        # be transformed from "result = func(ops...)" to "func(&result, ops...).
        # note that the result value pointer as first argument is the convention
        # used by numba.

        # First, prepare the return value
        out = context.make_complex(builder, ty)
        ptrargs = [cgutils.alloca_once_value(builder, arg)
                   for arg in args]
        call_args = [out._getpointer()] + ptrargs
        # get_value_as_argument for struct types like complex allocate stack space
        # and initialize with the value, the return value is the pointer to that
        # allocated space (ie: pointer to a copy of the value in the stack).
        # get_argument_type returns a pointer to the struct type in consonance.
        call_argtys = [ty] + list(sig.args)
        call_argltys = [context.get_value_type(ty).as_pointer()
                        for ty in call_argtys]
        fnty = lc.Type.function(lc.Type.void(), call_argltys)
        # Note: the function isn't pure here (it writes to its pointer args)
        fn = mod.get_or_insert_function(fnty, name=func_name)
        builder.call(fn, call_args)
        retval = builder.load(call_args[0])
    else:
        argtypes = [context.get_argument_type(aty) for aty in sig.args]
        restype = context.get_argument_type(sig.return_type)
        fnty = lc.Type.function(restype, argtypes)
        fn = cgutils.insert_pure_function(mod, fnty, name=func_name)
        retval = context.call_external_function(builder, fn, sig.args, args)
    return retval



########################################################################
# Division kernels inspired by NumPy loops.c.src code
#
# The builtins are not applicable as they rely on a test for zero in the
# denominator. If it is zero the appropriate exception is raised.
# In NumPy, a division by zero does not raise an exception, but instead
# generated a known value. Note that a division by zero in any of the
# operations of a vector may raise an exception or issue a warning
# depending on the numpy.seterr configuration. This is not supported
# right now (and in any case, it won't be handled by these functions
# either)
dataset/ETHPy150Open numba/numba/numba/targets/npyfuncs.py/_dispatch_func_by_name_type/original