Example #1
0
 def test_regalloc_exitswitch_2(self):
     v1 = Variable(); v1.concretetype = rclass.CLASSTYPE
     v2 = Variable(); v2.concretetype = rclass.CLASSTYPE
     v3 = Variable(); v3.concretetype = rclass.CLASSTYPE
     v4 = Variable(); v4.concretetype = rclass.CLASSTYPE
     block = Block([])
     block.operations = [
         SpaceOperation('res_call', [], v1),
         SpaceOperation('-live-', [], None),
         ]
     graph = FunctionGraph('f', block, v4)
     exclink = Link([v2], graph.returnblock)
     exclink.llexitcase = 123     # normally an exception class
     exclink.last_exception = v2
     exclink.last_exc_value = "unused"
     block.exitswitch = c_last_exception
     block.closeblock(Link([v1], graph.returnblock),
                      exclink)
     #
     self.check_assembler(graph, """
         res_call -> %i0
         -live-
         catch_exception L1
         int_return %i0
         ---
         L1:
         goto_if_exception_mismatch $123, L2
         last_exception -> %i0
         int_return %i0
         ---
         L2:
         reraise
     """)
Example #2
0
 def copy_link(self, link, prevblock):
     newargs = [self.get_new_name(a) for a in link.args] + self.passon_vars(prevblock)
     newlink = Link(newargs, self.copy_block(link.target), link.exitcase)
     newlink.last_exception = self.get_new_name(link.last_exception)
     newlink.last_exc_value = self.get_new_name(link.last_exc_value)
     if hasattr(link, 'llexitcase'):
         newlink.llexitcase = link.llexitcase
     return newlink
Example #3
0
 def copy_link(self, link, prevblock):
     newargs = [self.get_new_name(a) for a in link.args] + self.passon_vars(prevblock)
     newlink = Link(newargs, self.copy_block(link.target), link.exitcase)
     newlink.last_exception = self.get_new_name(link.last_exception)
     newlink.last_exc_value = self.get_new_name(link.last_exc_value)
     if hasattr(link, 'llexitcase'):
         newlink.llexitcase = link.llexitcase
     return newlink
Example #4
0
    def generic_exception_matching(self, afterblock, copiedexceptblock):
        #XXXXX don't look: insert blocks that do exception matching
        #for the cases where direct matching did not work        
        exc_match = Constant(
            self.translator.rtyper.getexceptiondata().fn_exception_match)
        exc_match.concretetype = typeOf(exc_match.value)
        blocks = []
        for i, link in enumerate(afterblock.exits[1:]):
            etype = copyvar(None, copiedexceptblock.inputargs[0])
            evalue = copyvar(None, copiedexceptblock.inputargs[1])
            passon_vars = self.passon_vars(i)
            block = Block([etype, evalue] + passon_vars)
            res = Variable()
            res.concretetype = Bool
            cexitcase = Constant(link.llexitcase)
            cexitcase.concretetype = typeOf(cexitcase.value)
            args = [exc_match, etype, cexitcase]
            block.operations.append(SpaceOperation("direct_call", args, res))
            block.exitswitch = res
            linkargs = self.find_args_in_exceptional_case(link, link.target,
                                                          etype, evalue, afterblock,
                                                          passon_vars)
            l = Link(linkargs, link.target)
            l.prevblock = block
            l.exitcase = True
            l.llexitcase = True
            block.closeblock(l)
            if i > 0:
                l = Link(blocks[-1].inputargs, block)
                l.exitcase = False
                l.llexitcase = False
                blocks[-1].recloseblock(l, *blocks[-1].exits)
            blocks.append(block)

        blocks[-1].recloseblock(*blocks[-1].exits[:1])
        blocks[-1].operations = []
        blocks[-1].exitswitch = None
        blocks[-1].exits[0].exitcase = None
        del blocks[-1].exits[0].llexitcase
        linkargs = copiedexceptblock.inputargs
        copiedexceptblock.recloseblock(Link(linkargs, blocks[0]))
        copiedexceptblock.operations += self.generate_keepalive(linkargs)
Example #5
0
    def generic_exception_matching(self, afterblock, copiedexceptblock):
        #XXXXX don't look: insert blocks that do exception matching
        #for the cases where direct matching did not work        
        exc_match = Constant(
            self.translator.rtyper.getexceptiondata().fn_exception_match)
        exc_match.concretetype = typeOf(exc_match.value)
        blocks = []
        for i, link in enumerate(afterblock.exits[1:]):
            etype = copyvar(None, copiedexceptblock.inputargs[0])
            evalue = copyvar(None, copiedexceptblock.inputargs[1])
            passon_vars = self.passon_vars(i)
            block = Block([etype, evalue] + passon_vars)
            res = Variable()
            res.concretetype = Bool
            cexitcase = Constant(link.llexitcase)
            cexitcase.concretetype = typeOf(cexitcase.value)
            args = [exc_match, etype, cexitcase]
            block.operations.append(SpaceOperation("direct_call", args, res))
            block.exitswitch = res
            linkargs = self.find_args_in_exceptional_case(link, link.target,
                                                          etype, evalue, afterblock,
                                                          passon_vars)
            l = Link(linkargs, link.target)
            l.prevblock = block
            l.exitcase = True
            l.llexitcase = True
            block.closeblock(l)
            if i > 0:
                l = Link(blocks[-1].inputargs, block)
                l.exitcase = False
                l.llexitcase = False
                blocks[-1].recloseblock(l, *blocks[-1].exits)
            blocks.append(block)

        blocks[-1].recloseblock(*blocks[-1].exits[:1])
        blocks[-1].operations = []
        blocks[-1].exitswitch = None
        blocks[-1].exits[0].exitcase = None
        del blocks[-1].exits[0].llexitcase
        linkargs = copiedexceptblock.inputargs
        copiedexceptblock.recloseblock(Link(linkargs, blocks[0]))
        copiedexceptblock.operations += self.generate_keepalive(linkargs)
Example #6
0
 def test_regalloc_exitswitch_2(self):
     v1 = Variable()
     v1.concretetype = rclass.CLASSTYPE
     v2 = Variable()
     v2.concretetype = rclass.CLASSTYPE
     v3 = Variable()
     v3.concretetype = rclass.CLASSTYPE
     v4 = Variable()
     v4.concretetype = rclass.CLASSTYPE
     block = Block([])
     block.operations = [
         SpaceOperation('res_call', [], v1),
         SpaceOperation('-live-', [], None),
     ]
     graph = FunctionGraph('f', block, v4)
     exclink = Link([v2], graph.returnblock)
     exclink.llexitcase = 123  # normally an exception class
     exclink.last_exception = v2
     exclink.last_exc_value = "unused"
     block.exitswitch = c_last_exception
     block.closeblock(Link([v1], graph.returnblock), exclink)
     #
     self.check_assembler(
         graph, """
         res_call -> %i0
         -live-
         catch_exception L1
         int_return %i0
         ---
         L1:
         goto_if_exception_mismatch $123, L2
         last_exception -> %i0
         int_return %i0
         ---
         L2:
         reraise
     """)
Example #7
0
 def insert_integer_search(self, block, cases, defaultlink, blockset,
                           range_start, range_stop):
     # fix the exit of the 'block' to check for the given remaining
     # 'cases', knowing that if we get there then the value must
     # be contained in range(range_start, range_stop).
     if not cases:
         assert defaultlink is not None
         block.exitswitch = None
         block.recloseblock(Link(defaultlink.args, defaultlink.target))
     elif len(cases) == 1 and (defaultlink is None or
                               range_start == range_stop-1):
         block.exitswitch = None
         block.recloseblock(cases.values()[0])
     else:
         intvalues = cases.keys()
         intvalues.sort()
         if len(intvalues) <= 3:
             # not much point in being clever with no more than 3 cases
             intval = intvalues[-1]
             remainingcases = cases.copy()
             link = remainingcases.pop(intval)
             c_intval = inputconst(lltype.Signed, intval)
             v = self.genop(block, 'int_eq', [block.exitswitch, c_intval],
                            resulttype=lltype.Bool, red=True)
             link.exitcase = True
             link.llexitcase = True
             falseblock = Block([])
             falseblock.exitswitch = block.exitswitch
             blockset[falseblock] = False
             falselink = Link([], falseblock)
             falselink.exitcase = False
             falselink.llexitcase = False
             block.exitswitch = v
             block.recloseblock(falselink, link)
             if defaultlink is None or intval == range_stop-1:
                 range_stop = intval
             self.insert_integer_search(falseblock, remainingcases,
                                        defaultlink, blockset,
                                        range_start, range_stop)
         else:
             intval = intvalues[len(intvalues) // 2]
             c_intval = inputconst(lltype.Signed, intval)
             v = self.genop(block, 'int_ge', [block.exitswitch, c_intval],
                            resulttype=lltype.Bool, red=True)
             falseblock = Block([])
             falseblock.exitswitch = block.exitswitch
             trueblock  = Block([])
             trueblock.exitswitch = block.exitswitch
             blockset[falseblock] = False
             blockset[trueblock]  = False
             falselink = Link([], falseblock)
             falselink.exitcase = False
             falselink.llexitcase = False
             truelink = Link([], trueblock)
             truelink.exitcase = True
             truelink.llexitcase = True
             block.exitswitch = v
             block.recloseblock(falselink, truelink)
             falsecases = {}
             truecases = {}
             for intval1, link1 in cases.items():
                 if intval1 < intval:
                     falsecases[intval1] = link1
                 else:
                     truecases[intval1] = link1
             self.insert_integer_search(falseblock, falsecases,
                                        defaultlink, blockset,
                                        range_start, intval)
             self.insert_integer_search(trueblock, truecases,
                                        defaultlink, blockset,
                                        intval, range_stop)