Home | History | Annotate | Download | only in dexmaker
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.dexmaker;
     18 
     19 import com.android.dx.rop.code.BasicBlock;
     20 import com.android.dx.rop.code.Insn;
     21 import com.android.dx.rop.code.InsnList;
     22 import com.android.dx.util.IntList;
     23 import java.util.ArrayList;
     24 import java.util.Collections;
     25 import java.util.List;
     26 
     27 /**
     28  * A branch target in a list of instructions.
     29  */
     30 public final class Label {
     31 
     32     final List<Insn> instructions = new ArrayList<Insn>();
     33 
     34     Code code;
     35 
     36     boolean marked = false;
     37 
     38     /** an immutable list of labels corresponding to the types in the catch list */
     39     List<Label> catchLabels = Collections.emptyList();
     40 
     41     /** contains the next instruction if no branch occurs */
     42     Label primarySuccessor;
     43 
     44     /** contains the instruction to jump to if the if is true */
     45     Label alternateSuccessor;
     46 
     47     int id = -1;
     48 
     49     public Label() {}
     50 
     51     boolean isEmpty() {
     52         return instructions.isEmpty();
     53     }
     54 
     55     void compact() {
     56         for (int i = 0; i < catchLabels.size(); i++) {
     57             while (catchLabels.get(i).isEmpty()) {
     58                 catchLabels.set(i, catchLabels.get(i).primarySuccessor);
     59             }
     60         }
     61         while (primarySuccessor != null && primarySuccessor.isEmpty()) {
     62             primarySuccessor = primarySuccessor.primarySuccessor;
     63         }
     64         while (alternateSuccessor != null && alternateSuccessor.isEmpty()) {
     65             alternateSuccessor = alternateSuccessor.primarySuccessor;
     66         }
     67     }
     68 
     69     BasicBlock toBasicBlock() {
     70         InsnList result = new InsnList(instructions.size());
     71         for (int i = 0; i < instructions.size(); i++) {
     72             result.set(i, instructions.get(i));
     73         }
     74         result.setImmutable();
     75 
     76         int primarySuccessorIndex = -1;
     77         IntList successors = new IntList();
     78         for (Label catchLabel : catchLabels) {
     79             successors.add(catchLabel.id);
     80         }
     81         if (primarySuccessor != null) {
     82             primarySuccessorIndex = primarySuccessor.id;
     83             successors.add(primarySuccessorIndex);
     84         }
     85         if (alternateSuccessor != null) {
     86             successors.add(alternateSuccessor.id);
     87         }
     88         successors.setImmutable();
     89 
     90         return new BasicBlock(id, result, successors, primarySuccessorIndex);
     91     }
     92 }
     93