001: /*
002: * @(#)Reference.java 1.3 05/06/21
003: *
004: * Copyright (c) 1997-2003 Sun Microsystems, Inc. All Rights Reserved.
005: *
006: * See the file "LICENSE.txt" for information on usage and redistribution
007: * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
008: */
009: package pnuts.compiler;
010:
011: final class Reference {
012:
013: /**
014: * Name of the variable
015: */
016: String symbol;
017:
018: /**
019: * Register number (aload_<index>)
020: * or -1 if the variable is in the class field.
021: */
022: int index;
023:
024: /**
025: * 0 if the value is stored in an array. (ICONST_<offset>, AALOAD)
026: * Otherwise, -1 (ALOAD <offset>)
027: */
028: int offset;
029:
030: boolean initialized;
031:
032: Frame frame;
033:
034: Reference(String symbol, int index, int offset) {
035: this (symbol, index, offset, false);
036: }
037:
038: Reference(String symbol, int index, int offset, boolean initialized) {
039: this .symbol = symbol;
040: this .index = index;
041: this .offset = offset;
042: this .initialized = initialized;
043: }
044:
045: Reference(String symbol, int index, int offset,
046: boolean initialized, Frame frame) {
047: this .symbol = symbol;
048: this .index = index;
049: this .offset = offset;
050: this .initialized = initialized;
051: this .frame = frame;
052: }
053:
054: Reference(String symbol, LocalInfo info) {
055: this (symbol, info.map, info.index, info.initialized, info.frame);
056: }
057:
058: void set(ClassFile cf, int tgt) {
059: if (index >= 0) {
060: if (offset < 0) {
061: cf.loadLocal(tgt);
062: cf.storeLocal(index);
063: } else {
064: if (!initialized) {
065: cf.loadLocal(index);
066: Label cont = cf.getLabel();
067: cf.add(Opcode.IFNONNULL, cont);
068: cf.add(Opcode.ICONST_1);
069: cf.add(Opcode.ANEWARRAY, "java.lang.Object");
070: cf.storeLocal(index);
071: cont.fix();
072: }
073: cf.loadLocal(index);
074: cf.pushInteger(offset);
075: cf.loadLocal(tgt);
076: cf.add(Opcode.AASTORE);
077: }
078: } else {
079: cf.add(Opcode.ALOAD_0);
080: cf.add(Opcode.GETFIELD, cf.getClassName(), symbol,
081: "[Ljava/lang/Object;");
082: cf.pushInteger(offset);
083: cf.loadLocal(tgt);
084: cf.add(Opcode.AASTORE);
085: }
086: }
087:
088: void get(ClassFile cf, boolean local, int contextIndex) {
089: if (index >= 0) {
090: if (offset < 0) {
091: cf.loadLocal(index);
092: } else {
093: if (local && !initialized) {
094: cf.loadLocal(index);
095: Label cont = cf.getLabel();
096: Label next = cf.getLabel();
097: cf.add(Opcode.IFNONNULL, cont);
098: cf.loadLocal(contextIndex);
099: cf.add(Opcode.LDC, cf.addConstant(symbol));
100: cf.add(Opcode.INVOKEVIRTUAL, "pnuts.lang.Context",
101: "getId", "(Ljava/lang/String;)",
102: "Ljava/lang/Object;");
103: cf.add(Opcode.GOTO, next);
104: cont.fix();
105:
106: cf.loadLocal(index);
107: cf.pushInteger(offset);
108: cf.add(Opcode.AALOAD);
109: next.fix();
110: } else {
111: cf.loadLocal(index);
112: cf.pushInteger(offset);
113: cf.add(Opcode.AALOAD);
114: }
115: }
116: } else {
117: cf.add(Opcode.ALOAD_0);
118: cf.add(Opcode.GETFIELD, cf.getClassName(), symbol,
119: "[Ljava/lang/Object;");
120: if (local && !initialized) {
121: Label next = cf.getLabel();
122: Label cont = cf.getLabel();
123: cf.add(Opcode.IFNONNULL, cont);
124: cf.loadLocal(contextIndex);
125: cf.add(Opcode.LDC, cf.addConstant(symbol));
126: cf.add(Opcode.INVOKEVIRTUAL, "pnuts.lang.Context",
127: "getId", "(Ljava/lang/String;)",
128: "Ljava/lang/Object;");
129: cf.add(Opcode.GOTO, next);
130: cont.fix();
131: cf.popStack();
132: cf.add(Opcode.ALOAD_0);
133: cf.add(Opcode.GETFIELD, cf.getClassName(), symbol,
134: "[Ljava/lang/Object;");
135: if (offset >= 0) {
136: cf.pushInteger(offset);
137: cf.add(Opcode.AALOAD);
138: }
139: next.fix();
140: } else {
141: if (offset >= 0) {
142: cf.pushInteger(offset);
143: cf.add(Opcode.AALOAD);
144: }
145: }
146: }
147: }
148:
149: /**
150: * Returns a hash code value for the object.
151: */
152: public int hashCode() {
153: return ((symbol.hashCode() * 31) + index) * 31 + offset;
154: }
155:
156: /**
157: * Indicates whether some other object is "equal to" this one.
158: */
159: public boolean equals(Object object) {
160: if (object instanceof Reference) {
161: Reference r = (Reference) object;
162: if ((symbol == null && symbol == r.symbol || symbol != null
163: && symbol.equals(r.symbol))
164: && index == r.index && offset == r.offset) {
165: return true;
166: }
167: }
168: return false;
169: }
170:
171: /**
172: * Returns a string representation of the object.
173: */
174: public String toString() {
175: return getClass().getName() + "[" + symbol + "," + index + ","
176: + offset + "," + initialized + "," + frame + "]";
177: }
178: }
|