Exemple #1
0
    def generic_resolve(self, instance, attr):
        if attr in instance.struct:
            # It's a struct field => the type is well-known
            return instance.struct[attr]

        elif attr in instance.jitmethods:
            # It's a jitted method => typeinfer it
            meth = instance.jitmethods[attr]
            disp_type = types.Dispatcher(meth)

            class MethodTemplate(templates.AbstractTemplate):
                key = (self.key, attr)

                def generic(self, args, kws):
                    args = (instance, ) + tuple(args)
                    sig = disp_type.get_call_type(self.context, args, kws)
                    return sig.as_method()

            return types.BoundFunction(MethodTemplate, instance)

        elif attr in instance.jitprops:
            # It's a jitted property => typeinfer its getter
            impdct = instance.jitprops[attr]
            getter = impdct['get']
            disp_type = types.Dispatcher(getter)
            sig = disp_type.get_call_type(self.context, (instance, ), {})
            return sig.return_type
Exemple #2
0
 def imp(context, builder, sig, args):
     instance_type = sig.args[0]
     method = instance_type.jitmethods[attr]
     disp_type = types.Dispatcher(method)
     call = context.get_function(types.Dispatcher(method), sig)
     out = call(builder, args)
     return imputils.impl_ret_new_ref(context, builder, sig.return_type,
                                      out)
Exemple #3
0
    def __init__(self, py_func, locals={}, targetoptions={}, impl_kind='direct'):
        """
        Parameters
        ----------
        py_func: function object to be compiled
        locals: dict, optional
            Mapping of local variable names to Numba types.  Used to override
            the types deduced by the type inference engine.
        targetoptions: dict, optional
            Target-specific config options.
        """
        self.typingctx = self.targetdescr.typing_context
        self.targetctx = self.targetdescr.target_context

        pysig = utils.pysignature(py_func)
        arg_count = len(pysig.parameters)
        can_fallback = not targetoptions.get('nopython', False)
        _DispatcherBase.__init__(self, arg_count, py_func, pysig, can_fallback)

        functools.update_wrapper(self, py_func)

        self.targetoptions = targetoptions
        self.locals = locals
        self._cache = NullCache()
        compiler_class = self._impl_kinds[impl_kind]
        self._impl_kind = impl_kind
        self._compiler = compiler_class(py_func, self.targetdescr,
                                        targetoptions, locals)
        self._cache_hits = collections.Counter()
        self._cache_misses = collections.Counter()

        self._type = types.Dispatcher(self)
        self.typingctx.insert_global(self, self._type)
Exemple #4
0
    def typeof_global(self, inst, target, gvar):
        typ = self.context.resolve_value_type(gvar.value)

        if (typ is None and gvar.name == self.py_func.__name__
                and gvar.name in _temporary_dispatcher_map):
            # Self-recursion case where the dispatcher is not (yet?) known
            # as a global variable
            typ = types.Dispatcher(_temporary_dispatcher_map[gvar.name])

        if isinstance(typ, types.Dispatcher) and typ.dispatcher.is_compiling:
            # Recursive call
            if typ.dispatcher.py_func is self.py_func:
                typ = types.RecursiveCall(typ)
            else:
                raise NotImplementedError(
                    "call to %s: mutual recursion not supported" %
                    typ.dispatcher)

        if isinstance(typ, types.Array):
            # Global array in nopython mode is constant
            # XXX why layout='C'?
            typ = typ.copy(layout='C', readonly=True)

        if typ is not None:
            self.sentry_modified_builtin(inst, gvar)
            self.lock_type(target.name, typ, loc=inst.loc)
            self.assumed_immutables.add(inst)
        else:
            raise TypingError("Untyped global name '%s'" % gvar.name,
                              loc=inst.loc)
Exemple #5
0
    def typeof_global(self, inst, target, gvar):
        try:
            typ = self.resolve_value_type(inst, gvar.value)
        except TypingError as e:
            if (gvar.name == self.func_id.func_name
                    and gvar.name in _temporary_dispatcher_map):
                # Self-recursion case where the dispatcher is not (yet?) known
                # as a global variable
                typ = types.Dispatcher(_temporary_dispatcher_map[gvar.name])
            else:
                e.patch_message("Untyped global name '%s': %s" %
                                (gvar.name, e))
                raise

        if isinstance(typ, types.Dispatcher) and typ.dispatcher.is_compiling:
            # Recursive call
            callframe = self.context.callstack.findfirst(
                typ.dispatcher.py_func)
            if callframe is not None:
                typ = types.RecursiveCall(typ)
            else:
                raise NotImplementedError("call to %s: unsupported recursion" %
                                          typ.dispatcher)

        if isinstance(typ, types.Array):
            # Global array in nopython mode is constant
            typ = typ.copy(readonly=True)

        self.sentry_modified_builtin(inst, gvar)
        self.lock_type(target.name, typ, loc=inst.loc)
        self.assumed_immutables.add(inst)
Exemple #6
0
def attr_impl(context, builder, typ, value, attr):
    """
    Generic getattr() for @jitclass instances.
    """
    if attr in typ.struct:
        # It's a struct field
        inst = context.make_helper(builder, typ, value=value)
        data_pointer = inst.data
        data = context.make_data_helper(builder,
                                        typ.get_data_type(),
                                        ref=data_pointer)
        return imputils.impl_ret_borrowed(context, builder, typ.struct[attr],
                                          getattr(data, _mangle_attr(attr)))
    elif attr in typ.jitprops:
        # It's a jitted property
        getter = typ.jitprops[attr]['get']
        sig = templates.signature(None, typ)
        dispatcher = types.Dispatcher(getter)
        sig = dispatcher.get_call_type(context.typing_context, [typ], {})
        call = context.get_function(dispatcher, sig)
        out = call(builder, [value])
        return imputils.impl_ret_new_ref(context, builder, sig.return_type,
                                         out)

    raise NotImplementedError('attribute {0!r} not implemented'.format(attr))
Exemple #7
0
 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
Exemple #8
0
 def test_weaktype(self):
     d = Dummy()
     e = Dummy()
     a = types.Dispatcher(d)
     b = types.Dispatcher(d)
     c = types.Dispatcher(e)
     self.assertIs(a.dispatcher, d)
     self.assertIs(b.dispatcher, d)
     self.assertIs(c.dispatcher, e)
     # Equality of alive references
     self.assertTrue(a == b)
     self.assertFalse(a != b)
     self.assertTrue(a != c)
     self.assertFalse(a == c)
     z = types.int8
     self.assertFalse(a == z)
     self.assertFalse(b == z)
     self.assertFalse(c == z)
     self.assertTrue(a != z)
     self.assertTrue(b != z)
     self.assertTrue(c != z)
     # Hashing and mappings
     s = set([a, b, c])
     self.assertEqual(len(s), 2)
     self.assertIn(a, s)
     self.assertIn(b, s)
     self.assertIn(c, s)
     # Kill the references
     d = e = None
     gc.collect()
     with self.assertRaises(ReferenceError):
         a.dispatcher
     with self.assertRaises(ReferenceError):
         b.dispatcher
     with self.assertRaises(ReferenceError):
         c.dispatcher
     # Dead references are always unequal
     self.assertFalse(a == b)
     self.assertFalse(a == c)
     self.assertFalse(b == c)
     self.assertFalse(a == z)
     self.assertTrue(a != b)
     self.assertTrue(a != c)
     self.assertTrue(b != c)
     self.assertTrue(a != z)
Exemple #9
0
 def generic(self, args, kws):
     # Redirect resolution to __init__
     instance_type = self.key.instance_type
     ctor = instance_type.jitmethods['__init__']
     boundargs = (instance_type.get_reference_type(), ) + args
     disp_type = types.Dispatcher(ctor)
     sig = disp_type.get_call_type(self.context, boundargs, kws)
     # Actual constructor returns an instance value (not None)
     out = templates.signature(instance_type, *sig.args[1:])
     return out
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)
    data_pointer = builder.bitcast(data_pointer,
                                   alloc_type.as_pointer())

    # Nullify all data
    builder.store(cgutils.get_null_value(alloc_type),
                  data_pointer)

    inst_struct = context.make_helper(builder, inst_typ)
    inst_struct.meminfo = meminfo
    inst_struct.data = data_pointer

    # Call the jitted __init__
    # TODO: extract the following into a common util
    init_sig = (sig.return_type,) + sig.args

    init = inst_typ.jitmethods['__init__']
    disp_type = types.Dispatcher(init)
    call = context.get_function(disp_type, types.void(*init_sig))
    _add_linking_libs(context, call)
    realargs = [inst_struct._getvalue()] + list(args)
    call(builder, realargs)

    # Prepare return value
    ret = inst_struct._getvalue()

    return imputils.impl_ret_new_ref(context, builder, inst_typ, ret)
Exemple #11
0
def attr_impl(context, builder, typ, value, attr):
    if attr in typ.struct:
        inst_struct = cgutils.create_struct_proxy(typ)
        inst = inst_struct(context, builder, value=value)
        data_pointer = inst.data
        data_struct = cgutils.create_struct_proxy(typ.get_data_type(),
                                                  kind='data')
        data = data_struct(context, builder, ref=data_pointer)
        return imputils.impl_ret_borrowed(context, builder, typ.struct[attr],
                                          getattr(data, attr))
    elif attr in typ.jitprops:
        getter = typ.jitprops[attr]['get']
        sig = templates.signature(None, typ)
        dispatcher = types.Dispatcher(getter)
        sig = dispatcher.get_call_type(context.typing_context, [typ], {})
        call = context.get_function(dispatcher, sig)
        out = call(builder, [value])
        return imputils.impl_ret_new_ref(context, builder, sig.return_type,
                                         out)

    raise NotImplementedError('attribute {0!r} not implemented'.format(attr))
Exemple #12
0
def attr_impl(context, builder, sig, args, attr):
    """
    Generic setattr() for @jitclass instances.
    """
    typ, valty = sig.args
    target, val = args

    if attr in typ.struct:
        # It's a struct member
        instance_struct = cgutils.create_struct_proxy(typ)
        inst = instance_struct(context, builder, value=target)
        data_ptr = inst.data
        data_struct = cgutils.create_struct_proxy(typ.get_data_type(),
                                                  kind='data')
        data = data_struct(context, builder, ref=data_ptr)

        # Get old value
        attr_type = typ.struct[attr]
        oldvalue = getattr(data, attr)

        # Store n
        setattr(data, attr, val)
        context.nrt_incref(builder, attr_type, val)

        # Delete old value
        context.nrt_decref(builder, attr_type, oldvalue)

    elif attr in typ.jitprops:
        # It's a jitted property
        setter = typ.jitprops[attr]['set']
        disp_type = types.Dispatcher(setter)
        sig = disp_type.get_call_type(context.typing_context, (typ, valty), {})
        call = context.get_function(disp_type, sig)
        call(builder, (target, val))

    else:
        raise NotImplementedError(
            'attribute {0!r} not implemented'.format(attr))
Exemple #13
0
def set_attr_impl(context, builder, sig, args, attr):
    """
    Generic setattr() for @jitclass instances.
    """
    typ, valty = sig.args
    target, val = args

    if attr in typ.struct:
        # It's a struct member
        inst = context.make_helper(builder, typ, value=target)
        data_ptr = inst.data
        data = context.make_data_helper(builder,
                                        typ.get_data_type(),
                                        ref=data_ptr)

        # Get old value
        attr_type = typ.struct[attr]
        oldvalue = getattr(data, _mangle_attr(attr))

        # Store n
        setattr(data, _mangle_attr(attr), val)
        context.nrt.incref(builder, attr_type, val)

        # Delete old value
        context.nrt.decref(builder, attr_type, oldvalue)

    elif attr in typ.jitprops:
        # It's a jitted property
        setter = typ.jitprops[attr]['set']
        disp_type = types.Dispatcher(setter)
        sig = disp_type.get_call_type(context.typing_context, (typ, valty), {})
        call = context.get_function(disp_type, sig)
        call(builder, (target, val))
        _add_linking_libs(context, call)
    else:
        raise NotImplementedError(
            'attribute {0!r} not implemented'.format(attr))
Exemple #14
0
 def _numba_type_(self):
     return types.Dispatcher(self)
Exemple #15
0
 def insert_overloaded(self, overloaded):
     self._insert_global(overloaded, types.Dispatcher(overloaded))
Exemple #16
0
 def insert_overloaded(self, overloaded):
     self.globals[overloaded] = types.Dispatcher(overloaded)
Exemple #17
0
 def imp(context, builder, sig, args):
     method = instance_type.jitmethods[attr]
     call = self.targetctx.get_function(types.Dispatcher(method), sig)
     out = call(builder, args)
     return imputils.impl_ret_new_ref(context, builder, sig.return_type,
                                      out)