Example #1
0
    def __init__(self, *args, **kwargs):
        OOFunction.__init__(self, *args, **kwargs)

        if hasattr(self.db.genoo, 'exceptiontransformer'):
            self.auto_propagate_exceptions = False

        namespace = getattr(self.graph.func, '_namespace_', None)
        if namespace:
            if '.' in namespace:
                self.namespace, self.classname = namespace.rsplit('.', 1)
            else:
                self.namespace = None
                self.classname = namespace
        else:
            self.namespace = None
            self.classname = None
Example #2
0
 def __init__(self, db, classty, name, jargtypes,
              jrettype, graph, is_static):
     """
     classty: the JvmClassType object this is a part of (even static
     functions have a class)
     name: the name of the function
     jargtypes: JvmType of each argument
     jrettype: JvmType this function returns
     graph: the graph representing the body of the function
     is_static: boolean flag indicate whether func is static (!)
     """
     OOFunction.__init__(self, db, graph, name, not is_static)
     self.classty = classty
     self.jargtypes = jargtypes
     self.jrettype = jrettype
     self._block_labels = {}
Example #3
0
    def __init__(self, *args, **kwargs):
        OOFunction.__init__(self, *args, **kwargs)

        if hasattr(self.db.genoo, 'exceptiontransformer'):
            self.auto_propagate_exceptions = False
        
        namespace = getattr(self.graph.func, '_namespace_', None)
        if namespace:
            if '.' in namespace:
                self.namespace, self.classname = namespace.rsplit('.', 1)
            else:
                self.namespace = None
                self.classname = namespace
        else:
            self.namespace = None
            self.classname = None
Example #4
0
 def _dont_store(self, to_load, to_store):
     # ugly workaround to make the exceptiontransformer work with
     # valuetypes: when exceptiontransforming a function whose result is a
     # .NET valuetype, it tries to store a null into the return variable.
     # Since it is not possible to store a null into a valuetype, and that
     # in that case the value is not used anyway, we simply ignore it.
     from rpython.translator.cli.dotnet import NativeInstance
     if isinstance(to_load, flowmodel.Constant):
         value = to_load.value
         is_null = (not isinstance(value, CDefinedIntSymbolic)) and (not value)
         T = ootype.typeOf(to_load.value)
         if isinstance(T, NativeInstance) and T._is_value_type and is_null:
             return True
     return OOFunction._dont_store(self, to_load, to_store)
Example #5
0
 def _dont_store(self, to_load, to_store):
     # ugly workaround to make the exceptiontransformer work with
     # valuetypes: when exceptiontransforming a function whose result is a
     # .NET valuetype, it tries to store a null into the return variable.
     # Since it is not possible to store a null into a valuetype, and that
     # in that case the value is not used anyway, we simply ignore it.
     from rpython.translator.cli.dotnet import NativeInstance
     if isinstance(to_load, flowmodel.Constant):
         value = to_load.value
         is_null = (not isinstance(value,
                                   CDefinedIntSymbolic)) and (not value)
         T = ootype.typeOf(to_load.value)
         if isinstance(T, NativeInstance) and T._is_value_type and is_null:
             return True
     return OOFunction._dont_store(self, to_load, to_store)
Example #6
0
 def record_ll_meta_exc(self, ll_meta_exc):
     # record the type only if it doesn't belong to a native_class
     ll_exc = ll_meta_exc._INSTANCE
     NATIVE_INSTANCE = ll_exc._hints.get('NATIVE_INSTANCE', None)
     if NATIVE_INSTANCE is None:
         OOFunction.record_ll_meta_exc(self, ll_meta_exc)
Example #7
0
 def _render_op(self, op):
     self.generator.add_comment(str(op))
     OOFunction._render_op(self, op)
Example #8
0
    def render_normal_block(self, block):
        """
        Overload OOFunction.render_normal_block: we intercept blocks where the
        exitcase tests a bool variable with one use so as to generate more
        efficient code.  For example, the naive code generation for a test
        like 'if x < y' yields something like:
        
           push x
           push y
           jump_if_less_than true
        false:
           push 0
           jump done
        true:
           push 1
        done:
           store_into_local_var
           load_from_local_var
           jump_if_true true_destination
           jump false_destination

        when it could (should) be

           push x
           push y
           jump_if_less_than true_destination
           jump false_destination
        """

        def not_in_link_args(v):
            for link in block.exits:
                if v in link.args: return False
            return True

        def true_false_exits():
            if block.exits[0].exitcase:
                return block.exits[0], block.exits[1]
            return block.exits[1], block.exits[0]

        if block.operations:
            # Look for a case where the block switches on a bool variable
            # which is produced by the last operation and not used
            # anywhere else, and where the last operation is a comparison.

            # Watch out for a last operation like:
            #   v1 = same_as([int_lt(i, j)])
            last_op = block.operations[-1]
            while (last_op.opname == "same_as" and
                   isinstance(last_op.args[0], SubOperation)):
                last_op = last_op.args[0].op
            
            if (block.exitswitch is not None and
                block.exitswitch.concretetype is ootype.Bool and
                block.operations[-1].result is block.exitswitch and
                can_branch_directly(last_op.opname) and
                not_in_link_args(block.exitswitch)):

                self.generator.add_comment(
                    "short-circuit final comparison on %s, block has %d ops" % (
                    block.exitswitch, len(block.operations)))

                for op in block.operations[:-1]:
                    self._render_op(op)
                    
                self.generator.add_comment(
                    "inlining comparison: %r" % (last_op),)
                for arg in last_op.args:
                    self.ilasm.load(arg)
                truelink, falselink = true_false_exits()
                true_label = self.next_label('link_true')
                branch_if(self.ilasm, last_op.opname, true_label)
                self._follow_link(falselink)
                self.set_label(true_label)
                self._follow_link(truelink)
                return

        return OOFunction.render_normal_block(self, block)
Example #9
0
 def record_ll_meta_exc(self, ll_meta_exc):
     # record the type only if it doesn't belong to a native_class
     ll_exc = ll_meta_exc._INSTANCE
     NATIVE_INSTANCE = ll_exc._hints.get('NATIVE_INSTANCE', None)
     if NATIVE_INSTANCE is None:
         OOFunction.record_ll_meta_exc(self, ll_meta_exc)