1/*
2 * Copyright (c) 1994, 2004, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package sun.tools.asm;
27
28import sun.tools.java.MemberDefinition;
29import java.io.OutputStream;
30
31/**
32 * A label instruction. This is a 0 size instruction.
33 * It is the only valid target of a branch instruction.
34 *
35 * WARNING: The contents of this source file are not part of any
36 * supported API.  Code that depends on them does so at its own risk:
37 * they are subject to change or removal without notice.
38 */
39public final
40class Label extends Instruction {
41    static int labelCount = 0;
42    int ID;
43    int depth;
44    MemberDefinition locals[];
45
46    /**
47     * Constructor
48     */
49    public Label() {
50        super(0, opc_label, null);
51        this.ID = ++labelCount;
52    }
53
54    /**
55     * Get the final destination, eliminate jumps gotos, and jumps to
56     * labels that are immediately folowed by another label. The depth
57     * field is used to leave bread crumbs to avoid infinite loops.
58     */
59    Label getDestination() {
60        Label lbl = this;
61        if ((next != null) && (next != this) && (depth == 0)) {
62            depth = 1;
63
64            switch (next.opc) {
65              case opc_label:
66                lbl = ((Label)next).getDestination();
67                break;
68
69              case opc_goto:
70                lbl = ((Label)next.value).getDestination();
71                break;
72
73              case opc_ldc:
74              case opc_ldc_w:
75                if (next.value instanceof Integer) {
76                    Instruction inst = next.next;
77                    if (inst.opc == opc_label) {
78                        inst = ((Label)inst).getDestination().next;
79                    }
80
81                    if (inst.opc == opc_ifeq) {
82                        if (((Integer)next.value).intValue() == 0) {
83                            lbl = (Label)inst.value;
84                        } else {
85                            lbl = new Label();
86                            lbl.next = inst.next;
87                            inst.next = lbl;
88                        }
89                        lbl = lbl.getDestination();
90                        break;
91                    }
92                    if (inst.opc == opc_ifne) {
93                        if (((Integer)next.value).intValue() == 0) {
94                            lbl = new Label();
95                            lbl.next = inst.next;
96                            inst.next = lbl;
97                        } else {
98                            lbl = (Label)inst.value;
99                        }
100                        lbl = lbl.getDestination();
101                        break;
102                    }
103                }
104                break;
105            }
106            depth = 0;
107        }
108        return lbl;
109    }
110
111    public String toString() {
112        String s = "$" + ID + ":";
113        if (value != null)
114            s = s + " stack=" + value;
115        return s;
116    }
117}
118