Пример #1
0
 def register_once_per_class(self):
     """
     Register code-generation information to the target context.
     The registration is executed once per (class, targetcontext)
     """
     registry = imputils.Registry()
     if (type(self), self.targetctx) not in self.registered_targetctx:
         self.implement_constructor(registry)
         self.implement_attribute(registry)
         self.targetctx.insert_func_defn(registry.functions)
         self.targetctx.insert_attr_defn(registry.attributes)
         self.registered_targetctx[type(self), self.targetctx] = registry
Пример #2
0
class ClassBuilder(object):
    """
    A jitclass builder for a mutable jitclass.  This will register
    typing and implementation hooks to the given typing and target contexts.
    """
    class_impl_registry = imputils.Registry()
    implemented_methods = set()

    def __init__(self, class_type, methods, typingctx, targetctx):
        self.class_type = class_type
        self.methods = methods
        self.typingctx = typingctx
        self.targetctx = targetctx

    def register(self):
        """
        Register to the frontend and backend.
        """
        # Register generic implementations for all jitclasses
        self._register_methods(self.class_impl_registry,
                               self.class_type.instance_type)
        # NOTE other registrations are done at the top-level
        # (see ctor_impl and attr_impl below)
        self.targetctx.install_registry(self.class_impl_registry)

    def _register_methods(self, registry, instance_type):
        """
        Register method implementations for the given instance type.
        """
        for meth in instance_type.jitmethods:
            # There's no way to retrive the particular method name
            # inside the implementation function, so we have to register a
            # specific closure for each different name
            if meth not in self.implemented_methods:
                self._implement_method(registry, meth)
                self.implemented_methods.add(meth)

    def _implement_method(self, registry, attr):
        @registry.lower((types.ClassInstanceType, attr),
                        types.ClassInstanceType, types.VarArg(types.Any))
        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(disp_type, sig)
            out = call(builder, args)
            _add_linking_libs(context, call)
            return imputils.impl_ret_new_ref(context, builder,
                                             sig.return_type, out)
Пример #3
0
 def implement_backend(self, instance_type):
     registry = imputils.Registry()
     self.register_methods(registry, instance_type)
     self.targetctx.insert_func_defn(registry.functions)
     self.targetctx.insert_attr_defn(registry.attributes)
Пример #4
0
class ClassBuilder(object):
    """
    A jitclass builder for a mutable jitclass.  This will register
    typing and implementation hooks to the given typing and target contexts.
    """
    class_impl_registry = imputils.Registry()
    implemented_methods = set()

    def __init__(self, class_type, methods, typingctx, targetctx):
        self.class_type = class_type
        self.methods = methods
        self.typingctx = typingctx
        self.targetctx = targetctx

    def register(self):
        """
        Register to the frontend and backend.
        """
        # Register generic implementations for all jitclasses
        self._register_methods(self.class_impl_registry,
                               self.class_type.instance_type)
        # NOTE other registrations are done at the top-level
        # (see ctor_impl and attr_impl below)
        self.targetctx.install_registry(self.class_impl_registry)

    def _register_methods(self, registry, instance_type):
        """
        Register method implementations for the given instance type.
        """
        for meth in instance_type.jitmethods:

            # There's no way to retrive the particular method name
            # inside the implementation function, so we have to register a
            # specific closure for each different name
            if meth not in self.implemented_methods:
                self._implement_method(registry, meth)
                self.implemented_methods.add(meth)

    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]
                method = instance_type.jitmethods[attr]
                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.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())

        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())