1 /* 2 * ProGuard -- shrinking, optimization, obfuscation, and preverification 3 * of Java bytecode. 4 * 5 * Copyright (c) 2002-2014 Eric Lafortune (eric (at) graphics.cornell.edu) 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the Free 9 * Software Foundation; either version 2 of the License, or (at your option) 10 * any later version. 11 * 12 * This program is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15 * more details. 16 * 17 * You should have received a copy of the GNU General Public License along 18 * with this program; if not, write to the Free Software Foundation, Inc., 19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 */ 21 package proguard.classfile.attribute.preverification; 22 23 import proguard.classfile.*; 24 import proguard.classfile.attribute.CodeAttribute; 25 import proguard.classfile.attribute.preverification.visitor.*; 26 27 /** 28 * This StackMapFrame represents an "append frame". 29 * 30 * @author Eric Lafortune 31 */ 32 public class MoreZeroFrame extends StackMapFrame 33 { 34 public int additionalVariablesCount; 35 public VerificationType[] additionalVariables; 36 37 38 /** 39 * Creates an uninitialized MoreZeroFrame. 40 */ 41 public MoreZeroFrame() 42 { 43 } 44 45 46 /** 47 * Creates a MoreZeroFrame with the given tag. 48 */ 49 public MoreZeroFrame(int tag) 50 { 51 additionalVariablesCount = tag + 1 - MORE_ZERO_FRAME; 52 } 53 54 55 /** 56 * Creates a MoreZeroFrame with the given additional variables. 57 */ 58 public MoreZeroFrame(VerificationType[] additionalVariables) 59 { 60 this(additionalVariables.length, additionalVariables); 61 } 62 63 64 /** 65 * Creates a MoreZeroFrame with the given additional variables. 66 */ 67 public MoreZeroFrame(int additionalVariablesCount, 68 VerificationType[] additionalVariables) 69 { 70 this.additionalVariablesCount = additionalVariablesCount; 71 this.additionalVariables = additionalVariables; 72 } 73 74 75 /** 76 * Applies the given verification type visitor to all variables. 77 */ 78 public void additionalVariablesAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VerificationTypeVisitor verificationTypeVisitor) 79 { 80 for (int index = 0; index < additionalVariablesCount; index++) 81 { 82 additionalVariables[index].accept(clazz, method, codeAttribute, offset, verificationTypeVisitor); 83 } 84 } 85 86 87 // Implementations for StackMapFrame. 88 89 public int getTag() 90 { 91 return MORE_ZERO_FRAME + additionalVariablesCount - 1; 92 } 93 94 95 public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, StackMapFrameVisitor stackMapFrameVisitor) 96 { 97 stackMapFrameVisitor.visitMoreZeroFrame(clazz, method, codeAttribute, offset, this); 98 } 99 100 101 // Implementations for Object. 102 103 public boolean equals(Object object) 104 { 105 if (!super.equals(object)) 106 { 107 return false; 108 } 109 110 MoreZeroFrame other = (MoreZeroFrame)object; 111 112 if (this.u2offsetDelta != other.u2offsetDelta || 113 this.additionalVariablesCount != other.additionalVariablesCount) 114 { 115 return false; 116 } 117 118 for (int index = 0; index < additionalVariablesCount; index++) 119 { 120 VerificationType thisType = this.additionalVariables[index]; 121 VerificationType otherType = other.additionalVariables[index]; 122 123 if (!thisType.equals(otherType)) 124 { 125 return false; 126 } 127 } 128 129 return true; 130 } 131 132 133 public int hashCode() 134 { 135 int hashCode = super.hashCode(); 136 137 for (int index = 0; index < additionalVariablesCount; index++) 138 { 139 hashCode ^= additionalVariables[index].hashCode(); 140 } 141 142 return hashCode; 143 } 144 145 146 public String toString() 147 { 148 StringBuffer buffer = new StringBuffer(super.toString()).append("Var: ..."); 149 150 for (int index = 0; index < additionalVariablesCount; index++) 151 { 152 buffer = buffer.append('[') 153 .append(additionalVariables[index].toString()) 154 .append(']'); 155 } 156 157 buffer.append(", Stack: (empty)"); 158 159 return buffer.toString(); 160 } 161 } 162