001: /*
002: * Copyright 1994-2004 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.tools.asm;
027:
028: import sun.tools.java.MemberDefinition;
029: import java.io.OutputStream;
030:
031: /**
032: * A label instruction. This is a 0 size instruction.
033: * It is the only valid target of a branch instruction.
034: *
035: * WARNING: The contents of this source file are not part of any
036: * supported API. Code that depends on them does so at its own risk:
037: * they are subject to change or removal without notice.
038: */
039: public final class Label extends Instruction {
040: static int labelCount = 0;
041: int ID;
042: int depth;
043: MemberDefinition locals[];
044:
045: /**
046: * Constructor
047: */
048: public Label() {
049: super (0, opc_label, null);
050: this .ID = ++labelCount;
051: }
052:
053: /**
054: * Get the final destination, eliminate jumps gotos, and jumps to
055: * labels that are immediately folowed by another label. The depth
056: * field is used to leave bread crumbs to avoid infinite loops.
057: */
058: Label getDestination() {
059: Label lbl = this ;
060: if ((next != null) && (next != this ) && (depth == 0)) {
061: depth = 1;
062:
063: switch (next.opc) {
064: case opc_label:
065: lbl = ((Label) next).getDestination();
066: break;
067:
068: case opc_goto:
069: lbl = ((Label) next.value).getDestination();
070: break;
071:
072: case opc_ldc:
073: case opc_ldc_w:
074: if (next.value instanceof Integer) {
075: Instruction inst = next.next;
076: if (inst.opc == opc_label) {
077: inst = ((Label) inst).getDestination().next;
078: }
079:
080: if (inst.opc == opc_ifeq) {
081: if (((Integer) next.value).intValue() == 0) {
082: lbl = (Label) inst.value;
083: } else {
084: lbl = new Label();
085: lbl.next = inst.next;
086: inst.next = lbl;
087: }
088: lbl = lbl.getDestination();
089: break;
090: }
091: if (inst.opc == opc_ifne) {
092: if (((Integer) next.value).intValue() == 0) {
093: lbl = new Label();
094: lbl.next = inst.next;
095: inst.next = lbl;
096: } else {
097: lbl = (Label) inst.value;
098: }
099: lbl = lbl.getDestination();
100: break;
101: }
102: }
103: break;
104: }
105: depth = 0;
106: }
107: return lbl;
108: }
109:
110: public String toString() {
111: String s = "$" + ID + ":";
112: if (value != null)
113: s = s + " stack=" + value;
114: return s;
115: }
116: }
|