001: package com.yworks.yguard.obf.classfile;
002:
003: import java.io.DataInput;
004: import java.io.DataOutput;
005: import java.util.List;
006: import java.util.Collection;
007: import java.util.ArrayList;
008:
009: /**
010: * Representation of an Local Variable table entry.
011: *
012: * @author Mark Welsh
013: */
014: public class StackMapFrameInfo {
015: private VerificationTypeInfo[] verificationTypeInfoStack;
016: private int u2_offset_delta;
017: private VerificationTypeInfo[] verificationTypeInfoLocals;
018: private int u1_frameType;
019:
020: // Constants -------------------------------------------------------------
021:
022: // Class Methods ---------------------------------------------------------
023: public static StackMapFrameInfo create(DataInput din)
024: throws java.io.IOException {
025: if (din == null)
026: throw new NullPointerException("DataInput cannot be null!");
027: StackMapFrameInfo smfi = new StackMapFrameInfo();
028: smfi.read(din);
029: return smfi;
030: }
031:
032: // Instance Methods ------------------------------------------------------
033: private StackMapFrameInfo() {
034: }
035:
036: /** Check for Utf8 references to constant pool and mark them. */
037: protected void markUtf8Refs(ConstantPool pool) {
038: if (u1_frameType < 64) {
039: // SAME
040: } else if (u1_frameType >= 64 && u1_frameType <= 127) {
041: // SAME_LOCALS_1_STACK_ITEM;
042: verificationTypeInfoStack[0].markUtf8Refs(pool);
043: } else if (u1_frameType == 247) {
044: // SAME_LOCALS_1_STACK_ITEM_EXTENDED
045: verificationTypeInfoStack[0].markUtf8Refs(pool);
046: } else if (u1_frameType >= 248 && u1_frameType <= 250) {
047: // CHOP
048: } else if (u1_frameType == 251) {
049: // SAME_FRAME_EXTENDED
050: } else if (u1_frameType >= 252 && u1_frameType <= 254) {
051: // APPEND
052: for (int i = 0; i < verificationTypeInfoStack.length; i++) {
053: verificationTypeInfoStack[i].markUtf8Refs(pool);
054: }
055: } else if (u1_frameType == 255) {
056: // FULL_FRAME
057: for (int i = 0; i < verificationTypeInfoLocals.length; i++) {
058: verificationTypeInfoLocals[i].markUtf8Refs(pool);
059: }
060: for (int i = 0; i < verificationTypeInfoStack.length; i++) {
061: verificationTypeInfoStack[i].markUtf8Refs(pool);
062: }
063: } else {
064: throw new IllegalArgumentException("Unknown frame type "
065: + u1_frameType);
066: }
067: }
068:
069: public Collection getVerificationTypeInfos() {
070: ArrayList result = new ArrayList();
071: if (verificationTypeInfoLocals != null) {
072: for (int i = 0; i < verificationTypeInfoLocals.length; i++) {
073: VerificationTypeInfo verificationTypeInfo = verificationTypeInfoLocals[i];
074: result.add(verificationTypeInfo);
075: }
076: }
077: if (verificationTypeInfoStack != null) {
078: for (int i = 0; i < verificationTypeInfoStack.length; i++) {
079: VerificationTypeInfo verificationTypeInfo = verificationTypeInfoStack[i];
080: result.add(verificationTypeInfo);
081: }
082: }
083: return result;
084: }
085:
086: private void read(DataInput din) throws java.io.IOException {
087: verificationTypeInfoLocals = null;
088: verificationTypeInfoStack = null;
089: u1_frameType = din.readUnsignedByte();
090: if (u1_frameType < 64) {
091: // SAME
092: } else if (u1_frameType >= 64 && u1_frameType <= 127) {
093: // SAME_LOCALS_1_STACK_ITEM;
094: verificationTypeInfoStack = new VerificationTypeInfo[1];
095: verificationTypeInfoStack[0] = VerificationTypeInfo
096: .create(din);
097: } else if (u1_frameType == 247) {
098: // SAME_LOCALS_1_STACK_ITEM_EXTENDED
099: u2_offset_delta = din.readUnsignedShort();
100: verificationTypeInfoStack = new VerificationTypeInfo[1];
101: verificationTypeInfoStack[0] = VerificationTypeInfo
102: .create(din);
103: } else if (u1_frameType >= 248 && u1_frameType <= 250) {
104: // CHOP
105: u2_offset_delta = din.readUnsignedShort();
106: } else if (u1_frameType == 251) {
107: // SAME_FRAME_EXTENDED
108: u2_offset_delta = din.readUnsignedShort();
109: } else if (u1_frameType >= 252 && u1_frameType <= 254) {
110: // APPEND
111: u2_offset_delta = din.readUnsignedShort();
112: int count = u1_frameType - 251;
113: verificationTypeInfoStack = new VerificationTypeInfo[count];
114: for (int i = 0; i < verificationTypeInfoStack.length; i++) {
115: verificationTypeInfoStack[i] = VerificationTypeInfo
116: .create(din);
117: }
118: } else if (u1_frameType == 255) {
119: // FULL_FRAME
120: u2_offset_delta = din.readUnsignedShort();
121: verificationTypeInfoLocals = new VerificationTypeInfo[din
122: .readUnsignedShort()];
123: for (int i = 0; i < verificationTypeInfoLocals.length; i++) {
124: verificationTypeInfoLocals[i] = VerificationTypeInfo
125: .create(din);
126: }
127: verificationTypeInfoStack = new VerificationTypeInfo[din
128: .readUnsignedShort()];
129: for (int i = 0; i < verificationTypeInfoStack.length; i++) {
130: verificationTypeInfoStack[i] = VerificationTypeInfo
131: .create(din);
132: }
133: } else {
134: throw new IllegalArgumentException("Unknown frame type "
135: + u1_frameType);
136: }
137: }
138:
139: /** Export the representation to a DataOutput stream. */
140: public void write(DataOutput dout) throws java.io.IOException {
141: dout.writeByte(u1_frameType);
142: if (u1_frameType < 64) {
143: // SAME
144: } else if (u1_frameType >= 64 && u1_frameType <= 127) {
145: // SAME_LOCALS_1_STACK_ITEM;
146: verificationTypeInfoStack[0].write(dout);
147: } else if (u1_frameType == 247) {
148: // SAME_LOCALS_1_STACK_ITEM_EXTENDED
149: dout.writeShort(u2_offset_delta);
150: verificationTypeInfoStack[0].write(dout);
151: } else if (u1_frameType >= 248 && u1_frameType <= 250) {
152: // CHOP
153: dout.writeShort(u2_offset_delta);
154: } else if (u1_frameType == 251) {
155: // SAME_FRAME_EXTENDED
156: dout.writeShort(u2_offset_delta);
157: } else if (u1_frameType >= 252 && u1_frameType <= 254) {
158: // APPEND
159: dout.writeShort(u2_offset_delta);
160: for (int i = 0; i < verificationTypeInfoStack.length; i++) {
161: verificationTypeInfoStack[i].write(dout);
162: }
163: } else if (u1_frameType == 255) {
164: // FULL_FRAME
165: dout.writeShort(u2_offset_delta);
166: dout.writeShort(verificationTypeInfoLocals.length);
167: for (int i = 0; i < verificationTypeInfoLocals.length; i++) {
168: verificationTypeInfoLocals[i].write(dout);
169: }
170: dout.writeShort(verificationTypeInfoStack.length);
171: for (int i = 0; i < verificationTypeInfoStack.length; i++) {
172: verificationTypeInfoStack[i].write(dout);
173: }
174: } else {
175: throw new IllegalArgumentException("Unknown frame type "
176: + u1_frameType);
177: }
178: }
179: }
|